diff --git a/.github/workflows/common-tests.yml b/.github/workflows/common-tests.yml new file mode 100644 index 00000000..c780f2b6 --- /dev/null +++ b/.github/workflows/common-tests.yml @@ -0,0 +1,32 @@ +name: Common + +on: + pull_request: + paths: + - .github/workflows/common-tests.yml + - "packages/common/**" + +jobs: + tests: + name: Tests + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: 18 + + - run: yarn install --immutable + working-directory: . + + - run: yarn workspace @red-kite/common test:cicd + working-directory: . + + - uses: tanmen/jest-reporter@v1 + if: always() + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + result-file: ./packages/common/test/jest-output.json diff --git a/.github/workflows/stalker-app-tests.yml b/.github/workflows/stalker-app-tests.yml index 2bd4531e..412e78ce 100644 --- a/.github/workflows/stalker-app-tests.yml +++ b/.github/workflows/stalker-app-tests.yml @@ -5,6 +5,7 @@ on: paths: - .github/workflows/frontend.yml - "packages/frontend/stalker-app/**" + - "packages/common/**" jobs: tests: diff --git a/.vscode/settings.json b/.vscode/settings.json index ce3c8652..16334da0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,5 +17,5 @@ "[scss]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, - "typescript.preferences.importModuleSpecifier": "relative" + "typescript.preferences.importModuleSpecifier": "shortest" } diff --git a/devspace.yaml b/devspace.yaml index f3fa75a2..68953c10 100644 --- a/devspace.yaml +++ b/devspace.yaml @@ -504,8 +504,8 @@ deployments: repo: https://charts.bitnami.com/bitnami version: "28.0.0" upgradeArgs: - - --timeout - - 1200s + - --timeout + - 1200s values: controller: nodeSelector: $(echo ${KAFKA_K8S_NODE_SELECTOR}) @@ -556,7 +556,7 @@ deployments: value: "no" provisioning: enabled: true - parallel: 10 + parallel: 1 nodeSelector: $(echo ${KAFKA_K8S_NODE_SELECTOR}) auth: tls: diff --git a/docs/docs/concepts/findings.md b/docs/docs/concepts/findings.md index 19774986..3faabccb 100644 --- a/docs/docs/concepts/findings.md +++ b/docs/docs/concepts/findings.md @@ -63,6 +63,23 @@ log_finding( ) ``` +### Attaching information to a domain + +Adding fields and using a custom finding type will add a finding to the domain resource. + +```python +from stalker_job_sdk import DomainFinding, log_finding, TextField + +hostname = "example.com" +log_finding( + DomainFinding( + "MyCustomHostnameFinding", hostname, None, "Domain info", [ + TextField("myfield", "Field Title", "Finding data") + ] + ) +) +``` + ## IpFinding An ip finding creates a new host. IP addresses are in the IPv4 format. @@ -93,9 +110,26 @@ log_finding( ) ``` +### Attaching information to a host + +Adding fields and using a custom finding type will add a finding to the host resource. + +```python +from stalker_job_sdk import IpFinding, log_finding, TextField +ip = "0.0.0.0" +mask = 16 +log_finding( + IpFinding( + "MyCustomIpFinding", ip, "New Info", [ + TextField("myfield", "Field Title", "Finding data") + ] + ) +) +``` + ## IpRangeFinding -An ip range finding creates a new ip range for a project. IP addresses are in the IPv4 format. +An ip range finding creates a new ip range for a project. IP addresses are in the IPv4 format. `IpRangeFindings` can also be used to attach information to an IP Range resource. | Field | Type | Description | | ------ | ------ | -------------------------------------------------------------------------------------------------------- | @@ -116,19 +150,32 @@ Example: Using the python SDK, you can emit this finding with the following code: ```python -from stalker_job_sdk import IpFinding, log_finding +from stalker_job_sdk import IpRangeFinding, log_finding ip = "0.0.0.0" mask = 16 log_finding( IpRangeFinding( - ip, mask + 'IpRangeFinding', ip, mask, None, [], "IpRangeFinding" ) ) ``` -> You can't attach fields to an IP range as they are different than other ressources. +### Attaching information to an IP range -Which is equivalent to the following python code, but with more metadata: +Adding fields and using a custom finding type will add a finding to the IP range resource. + +```python +from stalker_job_sdk import IpRangeFinding, log_finding, TextField +ip = "0.0.0.0" +mask = 16 +log_finding( + IpRangeFinding( + 'IpRangeFinding', ip, mask, "Finding title", [ + TextField("myfield", "Field Title", "Finding data") + ] + ) +) +``` ## HostnameIpFinding @@ -192,7 +239,7 @@ Example: Using the python SDK, you can emit this finding with the following code: ```python -from stalker_job_sdk import PortFinding, log_finding +from stalker_job_sdk import PortFinding, log_finding, TextField port = 80 ip = "1.2.3.4" log_finding( @@ -208,6 +255,29 @@ log_finding( ) ``` +### Attaching information to a port + +Adding fields and using a custom finding type will add a finding to the port resource. + +```python +from stalker_job_sdk import PortFinding, log_finding, TextField +port = 80 +ip = "1.2.3.4" +log_finding( + PortFinding( + "MyCustomPortFinding", + ip, + port, + "tcp", + "New port data", + [ + TextField("protocol", "This is a TCP port", "tcp"), + TextField("myfield", "Field Title", "Finding data") + ], + ) +) +``` + ## WebsiteFinding The `WebsiteFinding` will create a website resource. Websites are made from 4 characteristics: an IP address, a domain name, a port number @@ -269,49 +339,66 @@ log_finding( ) ``` +### Attaching information to a website + +Adding fields and using a custom finding type will add a finding to the website resource. + +```python +from stalker_job_sdk import WebsiteFinding, log_finding, TextField +port = 80 +ip = "1.2.3.4" +domain = "example.com" +path = "/" +ssl = False + +log_finding( + WebsiteFinding( + "MyCustomWebsiteFinding", + ip, + port, + domain, + path, + ssl, + "New website data", + [ + TextField("myfield", "Field Title", "Finding data") + ], + ) +) +``` + ## CustomFinding -Dynamic findings allow jobs to attach custom data to resources. +Custom findings attach finding field information to a resource. There are custom findings for every type of resources. When you do not specify the _type of finding_ that you are logging, you are creating a custom finding for the associated resource type. -| Field | Description | -| ------------ | --------------------------------------------------------------- | -| `domainName` | The domain to which to attach the custom finding | -| `host` | The host to which to attach the custom finding | -| `port` | The port to which to attach the custom finding | -| `fields` | A list of [fields](#dynamic-fields) containing the finding data | +| SDK finding class | Resources | +| ----------------- | --------- | +| HostnameFinding | Domains | +| IpFinding | Hosts | +| IpRangeFinding | IP ranges | +| PortFinding | Ports | +| WebsiteFinding | Websites | -Examples: -```json -{ - "type": "CustomFinding", - "host": "1.2.3.4", - "port": 80, - "fields": [ - { - "type": "image", - "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII" - } - ] -} -``` +Here is an example of a **custom finding** for a port with the python SDK. In this example, the port will show the custom information _This port +runs an HTTP server_, with a text field attached to it: -```json -{ - "type": "CustomFinding", - "domainName": "red-kite.io", - "fields": [ - { - "type": "text", - "label": "Domain greatness level", - "data": "This domain is great, would recommend" - } - ] -} +```python +from stalker_job_sdk import PortFinding, log_finding, TextField +port = 80 +ip = "0.0.0.0" +log_finding( + PortFinding( + "PortFunFact", ip, port, "tcp", "This is a fun fact about a port", [ + TextField('myfieldkey', 'My field title', 'My field data') + ] + ) +) ``` -Here is an example of a custom finding for a port with the python SDK. In this example, the port will show the custom information _This port -runs an HTTP server_: +Notice how the key `PortFunFact` can be anything, how information is provided through `TextField`s and how the finding type is not provided to use the default value. + +To compare, here is an example of how to create a port with the `PortFinding` class, which here is **not** used as a custom finding. You will see that the key is `PortFinding`, no fields are provided, and the type is `PortFinding` as well: ```python from stalker_job_sdk import PortFinding, log_finding @@ -319,7 +406,7 @@ port = 80 ip = "0.0.0.0" log_finding( PortFinding( - "PortFunFact", ip, port, "tcp", "This is a fun fact about a port" + "PortFinding", ip, port, "tcp", None, None, "PortFinding" ) ) ``` diff --git a/docs/docs/concepts/project.md b/docs/docs/concepts/project.md index 8c6f2527..c7889dc4 100644 --- a/docs/docs/concepts/project.md +++ b/docs/docs/concepts/project.md @@ -6,13 +6,9 @@ description: Organizing your data through projects # Projects -Projects are the way to organize and centralize resources. Resources are unique per project, and deleting the project will delete all its +Projects are the way to organize and centralize [resources](./resources.md). Resources are unique per project, and deleting the project will delete all its resources and related information. The project's name must be unique, but it can always be changed. You can also add a logo for display purposes, but it is not mandatory. -## Subnets - -In the case where a target owns a public subnet, you can add the different subnets in the projects page. - -For a subnet of `127.0.0.1/24`, you would simply add `127.0.0.1` in the _IP Address_ field, and the `/24` in the _Short Mask_ field. +> Red Kite allows to work on multiple projects at once, but using the global project filter in the navigation bar, you can also focus your work on a single project at a time. It will pre-filter data in displays such as tables and metrics. diff --git a/docs/docs/concepts/resources.md b/docs/docs/concepts/resources.mdx similarity index 84% rename from docs/docs/concepts/resources.md rename to docs/docs/concepts/resources.mdx index cac3afa8..e596b0cc 100644 --- a/docs/docs/concepts/resources.md +++ b/docs/docs/concepts/resources.mdx @@ -4,6 +4,8 @@ title: Resources description: What are resources --- +import EnterpriseNotice from "../../src/components/EnterpriseNotice"; + # Resources Resources represent the core entities of an exposed network. They are used to store and show the data found by @@ -22,7 +24,7 @@ up-to-date. Want to dive deeper? Check out the section on [learn more about find ## Types of Resources Resources come in various types, each created by specific findings. Some findings are generated through the user interface, while others -originate from the API. Regardless of their origin, every resource is tied to a specific project. +originate from the API. Regardless of their origin, every resource is [tied to a specific project](./project.md). ### Domains @@ -30,13 +32,24 @@ The domains represent domain names or a subdomains, such as `example.com` or `su information and can be managed via the `Domains` page in the user interface. Domains can be created using the `HostnameFinding`, via the API. They can also be created through the user interface's `Add domains` -functionality. +functionality. Adding a new domain will seed the automation process and start a scan. Typically, a domain resolves to one or more IP addresses, which are represented as host resources. A domain can be linked to one or more hosts through the `HostnameIpFinding`. If a `HostnameIpFinding` identifies a new domain or host, it will create these resources automatically. -Importantly, each domain's name, combined with its project identifier, must is unique within the database. +The combination of a domain's name and its project identifier is unique in the database. + + +### IP Ranges + +IP ranges consist in a network IP address and a network mask, and allow to designate full subnetworks as part of a project. These ranges would be owned, for instance, by your target, and they are a likely place to find relevant [hosts](#hosts). They can be found in the user interface under the `IP ranges` page. + +You can create an IP range by either adding it in the interface through the `Add IP ranges` capabilities, or by emitting an `IpRangeFinding` in a job. When an IP range is added, a **scan** for the range is **immediatly started**. A scan is also launched every two weeks to find new hosts and refresh data. + +The combination of an IP range's IP, mask and project identifier is unique in the database. + +> At the moment, only IPv4 addresses are supported. ### Hosts @@ -44,7 +57,7 @@ The hosts represent an exposed IP address: or a computer's network interface lis links between _domains_, hosts and _ports_. They can be seen in the user interface under the `Hosts` page. A host can be created through the `IpFinding` for a standalone host, or through a `HostnameIpFinding` for a host that is linked to a -_domain_. `IpFinding`s can be emitted by the API through the user interface's `Add hosts` capabilities. +_domain_. `IpFinding`s can be emitted by the API through the user interface's `Add hosts` capabilities. Adding a new host will seed the automation process and start a scan. An existing host can be linked to a _domain_ through the `HostnameIpFinding`. A host can be linked to one or many domains. @@ -136,8 +149,9 @@ by remembering its existence. ### Exporting Resources -In Red Kite Enterprise, resources can be exported from the list views in the `JSON` or `CSV` format. The `JSON` format is recommended as it -is more flexible than CSV, and therefore better suited to the task. + + +Resources can be exported from the list views in the `JSON` or `CSV` format. The `JSON` format is intended to be used by programs, while the `CSV` format is designed for humans. ### Merging Websites diff --git a/docs/docs/development/api.md b/docs/docs/development/api.md new file mode 100644 index 00000000..37062eac --- /dev/null +++ b/docs/docs/development/api.md @@ -0,0 +1,22 @@ +# API + +Every frontend-available data and more is accessible through the API. Simply create your API key in your profile, and then add it as a header when querying the API. + +The API is available at `/api/`. You can do an unauthenticated request at `/api/ping` that replies a simple string, and an authenticated request at `/api/` that gets the version. + +Unauthenticated `GET` request to `/api/ping`: + +```bash +curl https://your-red-kite-url/api/ping +``` + +# API Key + +Generate your API key in your profile page, giving it a meaningful name and an expiration date. Then, use it as a header in your following requests. + +Authenticated `GET` request to `/api/`: + +```bash +export MY_KEY="my key value" +curl -H "x-api-key: $MY_KEY" https://your-red-kite-url/api/ +``` diff --git a/docs/docs/intro.md b/docs/docs/intro.md index cc64d13e..511493c1 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -6,10 +6,18 @@ description: An overview of Red Kite # Overview -Red Kite is an Attack Surface Management (ASM) tool with a big focus on extendability. It streamlines and automates reconnaissance operations +Red Kite is an Attack Surface Management (ASM) tool with a big focus on extensibility. It streamlines and automates reconnaissance operations while giving you the flexibility to expand its functionalities. Its web interface enables easy data access and sharing with all stakeholders. +Through flexibility, Red Kite supports multiple use cases: + +* Real-time attack surface management +* Real-time attack surface discovery +* Regression testing of your attack surface +* Source of truth for security operations +* Custom testing at scale + Red Kite is powered by Kubernetes, enabling virtually infinite horizontal scaling. Combined with its flexibility, it makes it the ideal tool for hands-on security professionals committed to staying in full control while getting a clear picture of their attack surface. diff --git a/docs/src/components/EnterpriseNotice/index.js b/docs/src/components/EnterpriseNotice/index.js index cf939c40..9ab66de2 100644 --- a/docs/src/components/EnterpriseNotice/index.js +++ b/docs/src/components/EnterpriseNotice/index.js @@ -6,10 +6,9 @@ export default function EnterpriseNotice() {
✨ Unlock the Full Potential!
- This feature is part of our Enterprise version, offering advanced tools and premium support to elevate your workflow. + This feature is part of our Enterprise version, offering advanced tools and premium support to elevate your workflow.{" "} - {" "} - Get in touch today + Get in touch today {" "} and discover how we can help you achieve more!
diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..25235073 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,8 @@ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", + projects: [ + "/packages/backend/*/service/jest.config.js", + "/packages/*/jest.config.js", + ], +}; diff --git a/jobs/job-base-images/python/stalker_job_sdk/stalker_job_sdk/__init__.py b/jobs/job-base-images/python/stalker_job_sdk/stalker_job_sdk/__init__.py index c07e9121..6b536550 100644 --- a/jobs/job-base-images/python/stalker_job_sdk/stalker_job_sdk/__init__.py +++ b/jobs/job-base-images/python/stalker_job_sdk/stalker_job_sdk/__init__.py @@ -56,10 +56,14 @@ def __init__( class IpRangeFinding(Finding): def __init__( self, + key: str, ip: str, - mask: str + mask: str, + name: str = None, + fields: list[Field] = [], + type: str = "CustomFinding", ): - super().__init__("IpRangeFinding", "IpRangeFinding", "Ip Range", []) + super().__init__(key, type, name, fields) self.ip = ip self.mask = mask @@ -123,6 +127,7 @@ def __init__( protocol: str = None, domainName: str = None, path: str = None, + mask: int = None ): super().__init__("TagFinding", "TagFinding", "Tag", []) self.ip = ip @@ -131,6 +136,7 @@ def __init__( self.protocol = protocol self.path = path self.tag = tag + self.mask = mask class JobStatus: SUCCESS = "Success" diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 4215fced..00000000 --- a/package-lock.json +++ /dev/null @@ -1,27359 +0,0 @@ -{ - "name": "stalker", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "stalker", - "version": "1.0.0", - "workspaces": [ - "packages/frontend/stalker-app", - "packages/backend/jobs-manager/service", - "packages/backend/cron/service" - ], - "dependencies": { - "@nestjs/passport": "^10.0.3", - "passport": "^0.7.0", - "passport-headerapikey": "^1.2.2" - }, - "devDependencies": { - "husky": "^7.0.4", - "typescript": "^5.0.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@angular-devkit/architect": { - "version": "0.1703.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.9.tgz", - "integrity": "sha512-kEPfTOVnzrJxPGTvaXy8653HU9Fucxttx9gVfQR1yafs+yIEGx3fKGKe89YPmaEay32bIm7ZUpxDF1FO14nkdQ==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "17.3.9", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { - "version": "17.3.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.9.tgz", - "integrity": "sha512-/iKyn5YT7NW5ylrg9yufUydS8byExeQ2HHIwFC4Ebwb/JYYCz+k4tBf2LdP+zXpemDpLznXTQGWia0/yJjG8Vg==", - "dev": true, - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-webpack": { - "version": "0.1703.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1703.9.tgz", - "integrity": "sha512-3b0LND39Nc+DwCQ0N7Tbsd7RAFWTeIc4VDwk/7RO8EMYTP5Kfgr/TK66nwTBypHsjmD69IMKHZZaZuiDfGfx2A==", - "dev": true, - "dependencies": { - "@angular-devkit/architect": "0.1703.9", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "webpack": "^5.30.0", - "webpack-dev-server": "^4.0.0" - } - }, - "node_modules/@angular-devkit/core": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", - "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", - "dev": true, - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/schematics": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.8.tgz", - "integrity": "sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "17.3.8", - "jsonc-parser": "3.2.1", - "magic-string": "0.30.8", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/schematics-cli": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-17.3.8.tgz", - "integrity": "sha512-TjmiwWJarX7oqvNiRAroQ5/LeKUatxBOCNEuKXO/PV8e7pn/Hr/BqfFm+UcYrQoFdZplmtNAfqmbqgVziKvCpA==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "17.3.8", - "@angular-devkit/schematics": "17.3.8", - "ansi-colors": "4.1.3", - "inquirer": "9.2.15", - "symbol-observable": "4.0.0", - "yargs-parser": "21.1.1" - }, - "bin": { - "schematics": "bin/schematics.js" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { - "version": "9.2.15", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz", - "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==", - "dev": true, - "dependencies": { - "@ljharb/through": "^2.3.12", - "ansi-escapes": "^4.3.2", - "chalk": "^5.3.0", - "cli-cursor": "^3.1.0", - "cli-width": "^4.1.0", - "external-editor": "^3.1.0", - "figures": "^3.2.0", - "lodash": "^4.17.21", - "mute-stream": "1.0.0", - "ora": "^5.4.1", - "run-async": "^3.0.0", - "rxjs": "^7.8.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/@angular/compiler": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.3.12.tgz", - "integrity": "sha512-vwI8oOL/gM+wPnptOVeBbMfZYwzRxQsovojZf+Zol9szl0k3SZ3FycWlxxXZGFu3VIEfrP6pXplTmyODS/Lt1w==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/core": "17.3.12" - }, - "peerDependenciesMeta": { - "@angular/core": { - "optional": true - } - } - }, - "node_modules/@angular/compiler-cli": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.3.12.tgz", - "integrity": "sha512-1F8M7nWfChzurb7obbvuE7mJXlHtY1UG58pcwcomVtpPb+kPavgAO8OEvJHYBMV+bzSxkXt5UIwL9lt9jHUxZA==", - "dev": true, - "dependencies": { - "@babel/core": "7.23.9", - "@jridgewell/sourcemap-codec": "^1.4.14", - "chokidar": "^3.0.0", - "convert-source-map": "^1.5.1", - "reflect-metadata": "^0.2.0", - "semver": "^7.0.0", - "tslib": "^2.3.0", - "yargs": "^17.2.1" - }, - "bin": { - "ng-xi18n": "bundles/src/bin/ng_xi18n.js", - "ngc": "bundles/src/bin/ngc.js", - "ngcc": "bundles/ngcc/index.js" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/compiler": "17.3.12", - "typescript": ">=5.2 <5.5" - } - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "optional": true, - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "optional": true, - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "optional": true, - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "optional": true, - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "optional": true, - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.637.0.tgz", - "integrity": "sha512-391mca6yEfXVcSOTLGcxzlT0QCFfvoymLlVHfb//bzl806UUTq12cR2k+AnaCKLj+QSejmA7n6lwZWADm00Fvg==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.637.0", - "@aws-sdk/client-sts": "3.637.0", - "@aws-sdk/core": "3.635.0", - "@aws-sdk/credential-provider-node": "3.637.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.637.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.4.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.15", - "@smithy/util-defaults-mode-node": "^3.0.15", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.637.0.tgz", - "integrity": "sha512-+KjLvgX5yJYROWo3TQuwBJlHCY0zz9PsLuEolmXQn0BVK1L/m9GteZHtd+rEdAoDGBpE0Xqjy1oz5+SmtsaRUw==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.635.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.637.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.4.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.15", - "@smithy/util-defaults-mode-node": "^3.0.15", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.637.0.tgz", - "integrity": "sha512-27bHALN6Qb6m6KZmPvRieJ/QRlj1lyac/GT2Rn5kJpre8Mpp+yxrtvp3h9PjNBty4lCeFEENfY4dGNSozBuBcw==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.635.0", - "@aws-sdk/credential-provider-node": "3.637.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.637.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.4.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.15", - "@smithy/util-defaults-mode-node": "^3.0.15", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.637.0" - } - }, - "node_modules/@aws-sdk/client-sts": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.637.0.tgz", - "integrity": "sha512-xUi7x4qDubtA8QREtlblPuAcn91GS/09YVEY/RwU7xCY0aqGuFwgszAANlha4OUIqva8oVj2WO4gJuG+iaSnhw==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.637.0", - "@aws-sdk/core": "3.635.0", - "@aws-sdk/credential-provider-node": "3.637.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.637.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.4.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.15", - "@smithy/util-defaults-mode-node": "^3.0.15", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/core": { - "version": "3.635.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.635.0.tgz", - "integrity": "sha512-i1x/E/sgA+liUE1XJ7rj1dhyXpAKO1UKFUcTTHXok2ARjWTvszHnSXMOsB77aPbmn0fUp1JTx2kHUAZ1LVt5Bg==", - "optional": true, - "dependencies": { - "@smithy/core": "^2.4.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/signature-v4": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "fast-xml-parser": "4.4.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.637.0.tgz", - "integrity": "sha512-9qK1mF+EThtv3tsL1C/wb9MpWctJSkzjrLTFj+0Rtk8VYm6DlGepo/I6a2x3SeDmdBfHAFSrKFU39GqWDp1mwQ==", - "optional": true, - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.637.0", - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.620.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.620.1.tgz", - "integrity": "sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.635.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.635.0.tgz", - "integrity": "sha512-iJyRgEjOCQlBMXqtwPLIKYc7Bsc6nqjrZybdMDenPDa+kmLg7xh8LxHsu9088e+2/wtLicE34FsJJIfzu3L82g==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.637.0.tgz", - "integrity": "sha512-h+PFCWfZ0Q3Dx84SppET/TFpcQHmxFW8/oV9ArEvMilw4EBN+IlxgbL0CnHwjHW64szcmrM0mbebjEfHf4FXmw==", - "optional": true, - "dependencies": { - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.635.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.637.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.637.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.637.0.tgz", - "integrity": "sha512-yoEhoxJJfs7sPVQ6Is939BDQJZpZCoUgKr/ySse4YKOZ24t4VqgHA6+wV7rYh+7IW24Rd91UTvEzSuHYTlxlNA==", - "optional": true, - "dependencies": { - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.635.0", - "@aws-sdk/credential-provider-ini": "3.637.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.637.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.620.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.620.1.tgz", - "integrity": "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.637.0.tgz", - "integrity": "sha512-Mvz+h+e62/tl+dVikLafhv+qkZJ9RUb8l2YN/LeKMWkxQylPT83CPk9aimVhCV89zth1zpREArl97+3xsfgQvA==", - "optional": true, - "dependencies": { - "@aws-sdk/client-sso": "3.637.0", - "@aws-sdk/token-providers": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.621.0.tgz", - "integrity": "sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.621.0" - } - }, - "node_modules/@aws-sdk/credential-providers": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.637.0.tgz", - "integrity": "sha512-yW1scL3Z7JsrTrmhjyZsB6tsMJ49UCO42BGlNWZAW+kN1vNJ+qbv6XYQJWR4gjpuD2rdmtGcEawcgllE2Bmigw==", - "optional": true, - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.637.0", - "@aws-sdk/client-sso": "3.637.0", - "@aws-sdk/client-sts": "3.637.0", - "@aws-sdk/credential-provider-cognito-identity": "3.637.0", - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.635.0", - "@aws-sdk/credential-provider-ini": "3.637.0", - "@aws-sdk/credential-provider-node": "3.637.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.637.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.620.0.tgz", - "integrity": "sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz", - "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.620.0.tgz", - "integrity": "sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.637.0.tgz", - "integrity": "sha512-EYo0NE9/da/OY8STDsK2LvM4kNa79DBsf4YVtaG4P5pZ615IeFsD8xOHZeuJmUrSMlVQ8ywPRX7WMucUybsKug==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", - "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/token-providers": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz", - "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sso-oidc": "^3.614.0" - } - }, - "node_modules/@aws-sdk/types": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", - "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.637.0.tgz", - "integrity": "sha512-pAqOKUHeVWHEXXDIp/qoMk/6jyxIb6GGjnK1/f8dKHtKIEs4tKsnnL563gceEvdad53OPXIt86uoevCcCzmBnw==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "@smithy/util-endpoints": "^2.0.5", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.568.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", - "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz", - "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz", - "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", - "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.25.6", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", - "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", - "dev": true, - "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.25.6" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "dev": true - }, - "node_modules/@ljharb/through": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", - "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/@lukeed/csprng": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", - "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@nestjs/cli": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.5.tgz", - "integrity": "sha512-FP7Rh13u8aJbHe+zZ7hM0CC4785g9Pw4lz4r2TTgRtf0zTxSWMkJaPEwyjX8SK9oWK2GsYxl+fKpwVZNbmnj9A==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "17.3.8", - "@angular-devkit/schematics": "17.3.8", - "@angular-devkit/schematics-cli": "17.3.8", - "@nestjs/schematics": "^10.0.1", - "chalk": "4.1.2", - "chokidar": "3.6.0", - "cli-table3": "0.6.5", - "commander": "4.1.1", - "fork-ts-checker-webpack-plugin": "9.0.2", - "glob": "10.4.2", - "inquirer": "8.2.6", - "node-emoji": "1.11.0", - "ora": "5.4.1", - "tree-kill": "1.2.2", - "tsconfig-paths": "4.2.0", - "tsconfig-paths-webpack-plugin": "4.1.0", - "typescript": "5.3.3", - "webpack": "5.94.0", - "webpack-node-externals": "3.0.0" - }, - "bin": { - "nest": "bin/nest.js" - }, - "engines": { - "node": ">= 16.14" - }, - "peerDependencies": { - "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0", - "@swc/core": "^1.3.62" - }, - "peerDependenciesMeta": { - "@swc/cli": { - "optional": true - }, - "@swc/core": { - "optional": true - } - } - }, - "node_modules/@nestjs/cli/node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/@nestjs/common": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.1.tgz", - "integrity": "sha512-4CkrDx0s4XuWqFjX8WvOFV7Y6RGJd0P2OBblkhZS7nwoctoSuW5pyEa8SWak6YHNGrHRpFb6ymm5Ai4LncwRVA==", - "dependencies": { - "iterare": "1.2.1", - "tslib": "2.6.3", - "uid": "2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "class-transformer": "*", - "class-validator": "*", - "reflect-metadata": "^0.1.12 || ^0.2.0", - "rxjs": "^7.1.0" - }, - "peerDependenciesMeta": { - "class-transformer": { - "optional": true - }, - "class-validator": { - "optional": true - } - } - }, - "node_modules/@nestjs/passport": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-10.0.3.tgz", - "integrity": "sha512-znJ9Y4S8ZDVY+j4doWAJ8EuuVO7SkQN3yOBmzxbGaXbvcSwFDAdGJ+OMCg52NdzIO4tQoN4pYKx8W6M0ArfFRQ==", - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", - "passport": "^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0" - } - }, - "node_modules/@nestjs/schematics": { - "version": "10.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.4.tgz", - "integrity": "sha512-QpY8ez9cTvXXPr3/KBrtSgXQHMSV6BkOUYy2c2TTe6cBqriEdGnCYqGl8cnfrQl3632q3lveQPaZ/c127dHsEw==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "17.3.8", - "@angular-devkit/schematics": "17.3.8", - "comment-json": "4.2.3", - "jsonc-parser": "3.3.1", - "pluralize": "8.0.0" - }, - "peerDependencies": { - "typescript": ">=4.8.2" - } - }, - "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true - }, - "node_modules/@ngtools/webpack": { - "version": "17.3.9", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.9.tgz", - "integrity": "sha512-2+NvEQuYKRWdZaJbRJWEnR48tpW0uYbhwfHBHLDI9Kazb3mb0oAwYBVXdq+TtDLBypXnMsFpCewjRHTvkVx4/A==", - "dev": true, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "@angular/compiler-cli": "^17.0.0", - "typescript": ">=5.2 <5.5", - "webpack": "^5.54.0" - } - }, - "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==" - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@red-kite/cron": { - "resolved": "packages/backend/cron/service", - "link": true - }, - "node_modules/@red-kite/jobs-manager": { - "resolved": "packages/backend/jobs-manager/service", - "link": true - }, - "node_modules/@red-kite/stalker-app": { - "resolved": "packages/frontend/stalker-app", - "link": true - }, - "node_modules/@smithy/abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", - "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/config-resolver": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", - "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", - "optional": true, - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.0.tgz", - "integrity": "sha512-cHXq+FneIF/KJbt4q4pjN186+Jf4ZB0ZOqEaZMBhT79srEyGDDBV31NqBRBjazz8ppQ1bJbDJMY9ba5wKFV36w==", - "optional": true, - "dependencies": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.0.tgz", - "integrity": "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==", - "optional": true, - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "optional": true, - "dependencies": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/hash-node": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", - "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/invalid-dependency": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", - "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/is-array-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", - "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-content-length": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.5.tgz", - "integrity": "sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==", - "optional": true, - "dependencies": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-endpoint": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.0.tgz", - "integrity": "sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==", - "optional": true, - "dependencies": { - "@smithy/middleware-serde": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-retry": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.15.tgz", - "integrity": "sha512-iTMedvNt1ApdvkaoE8aSDuwaoc+BhvHqttbA/FO4Ty+y/S5hW6Ci/CTScG7vam4RYJWZxdTElc3MEfHRVH6cgQ==", - "optional": true, - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/service-error-classification": "^3.0.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-serde": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", - "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-stack": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", - "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-config-provider": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", - "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", - "optional": true, - "dependencies": { - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-http-handler": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.4.tgz", - "integrity": "sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==", - "optional": true, - "dependencies": { - "@smithy/abort-controller": "^3.1.1", - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/property-provider": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", - "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", - "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/service-error-classification": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", - "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", - "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/signature-v4": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.0.tgz", - "integrity": "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==", - "optional": true, - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-uri-escape": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/smithy-client": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.2.0.tgz", - "integrity": "sha512-pDbtxs8WOhJLJSeaF/eAbPgXg4VVYFlRcL/zoNYA5WbG3wBL06CHtBSg53ppkttDpAJ/hdiede+xApip1CwSLw==", - "optional": true, - "dependencies": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/url-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", - "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", - "optional": true, - "dependencies": { - "@smithy/querystring-parser": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "optional": true, - "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-body-length-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", - "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/util-body-length-node": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", - "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-buffer-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", - "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", - "optional": true, - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-config-provider": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", - "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.15.tgz", - "integrity": "sha512-FZ4Psa3vjp8kOXcd3HJOiDPBCWtiilLl57r0cnNtq/Ga9RSDrM5ERL6xt+tO43+2af6Pn5Yp92x2n5vPuduNfg==", - "optional": true, - "dependencies": { - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.15.tgz", - "integrity": "sha512-KSyAAx2q6d0t6f/S4XB2+3+6aQacm3aLMhs9aLMqn18uYGUepbdssfogW5JQZpc6lXNBnp0tEnR5e9CEKmEd7A==", - "optional": true, - "dependencies": { - "@smithy/config-resolver": "^3.0.5", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@smithy/util-endpoints": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", - "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", - "optional": true, - "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-hex-encoding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", - "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-middleware": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", - "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", - "optional": true, - "dependencies": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-retry": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", - "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", - "optional": true, - "dependencies": { - "@smithy/service-error-classification": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-stream": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.3.tgz", - "integrity": "sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==", - "optional": true, - "dependencies": { - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "optional": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", - "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", - "optional": true, - "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dev": true, - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" - }, - "node_modules/@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true - }, - "node_modules/@types/http-proxy": { - "version": "1.17.15", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", - "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true - }, - "node_modules/@types/node": { - "version": "22.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", - "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/ansi-colors": { - "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==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-timsort": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", - "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", - "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "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/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "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==" - }, - "node_modules/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", - "optional": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001655", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", - "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "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==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/comment-json": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz", - "integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==", - "dev": true, - "dependencies": { - "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", - "esprima": "^4.0.1", - "has-own-prop": "^2.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/config-chain": { - "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==", - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deepmerge": { - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/default-gateway/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/default-gateway/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/default-gateway/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-gateway/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/default-gateway/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/default-gateway/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-gateway/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==", - "dev": true - }, - "node_modules/default-gateway/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "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==" - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dev": true, - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/editorconfig": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", - "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", - "dependencies": { - "@one-ini/wasm": "0.1.1", - "commander": "^10.0.0", - "minimatch": "9.0.1", - "semver": "^7.5.3" - }, - "bin": { - "editorconfig": "bin/editorconfig" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/editorconfig/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/editorconfig/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "engines": { - "node": ">=14" - } - }, - "node_modules/editorconfig/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", - "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/engine.io": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", - "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", - "dependencies": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.11.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.7.tgz", - "integrity": "sha512-P+jDFbvK6lE3n1OL+q9KuzdOFWkkZ/cMV9gol/SbVfpyqfvrfrFTOFJ6fQm2VC3PZHlU3QPhVwmbsCnauHF2MQ==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", - "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "optional": true, - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.2.tgz", - "integrity": "sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.7", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cosmiconfig": "^8.2.0", - "deepmerge": "^4.2.2", - "fs-extra": "^10.0.0", - "memfs": "^3.4.1", - "minimatch": "^3.0.4", - "node-abort-controller": "^3.0.1", - "schema-utils": "^3.1.1", - "semver": "^7.3.5", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">=12.13.0", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "typescript": ">3.6.0", - "webpack": "^5.11.0" - } - }, - "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==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/glob/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/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-own-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", - "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-minifier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", - "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", - "dependencies": { - "camel-case": "^3.0.0", - "clean-css": "^4.2.1", - "commander": "^2.19.0", - "he": "^1.2.0", - "param-case": "^2.1.1", - "relateurl": "^0.2.7", - "uglify-js": "^3.5.1" - }, - "bin": { - "html-minifier": "cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "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==" - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dev": true, - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/husky": { - "version": "7.0.4", - "dev": true, - "license": "MIT", - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/inquirer": { - "version": "8.2.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", - "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^6.0.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/iterare": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", - "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-beautify": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz", - "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==", - "dependencies": { - "config-chain": "^1.1.13", - "editorconfig": "^1.0.4", - "glob": "^10.3.3", - "js-cookie": "^3.0.5", - "nopt": "^7.2.0" - }, - "bin": { - "css-beautify": "js/bin/css-beautify.js", - "html-beautify": "js/bin/html-beautify.js", - "js-beautify": "js/bin/js-beautify.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "engines": { - "node": ">=14" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/juice": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/juice/-/juice-10.0.1.tgz", - "integrity": "sha512-ZhJT1soxJCkOiO55/mz8yeBKTAJhRzX9WBO+16ZTqNTONnnVlUPyVBIzQ7lDRjaBdTbid+bAnyIon/GM3yp4cA==", - "dependencies": { - "cheerio": "1.0.0-rc.12", - "commander": "^6.1.0", - "mensch": "^0.3.4", - "slick": "^1.12.2", - "web-resource-inliner": "^6.0.1" - }, - "bin": { - "juice": "bin/juice" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/juice/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/launch-editor": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", - "integrity": "sha512-elBx2l/tp9z99X5H/qev8uyDywVh0VXAwEbjk8kJhnc5grOFkGh7aW6q55me9xnYbss261XtnUrysZ+XvGbhQA==", - "dev": true, - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==" - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" - }, - "node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dev": true, - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "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==" - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mjml": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml/-/mjml-4.15.3.tgz", - "integrity": "sha512-bW2WpJxm6HS+S3Yu6tq1DUPFoTxU9sPviUSmnL7Ua+oVO3WA5ILFWqvujUlz+oeuM+HCwEyMiP5xvKNPENVjYA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "mjml-cli": "4.15.3", - "mjml-core": "4.15.3", - "mjml-migrate": "4.15.3", - "mjml-preset-core": "4.15.3", - "mjml-validator": "4.15.3" - }, - "bin": { - "mjml": "bin/mjml" - } - }, - "node_modules/mjml-accordion": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-accordion/-/mjml-accordion-4.15.3.tgz", - "integrity": "sha512-LPNVSj1LyUVYT9G1gWwSw3GSuDzDsQCu0tPB2uDsq4VesYNnU6v3iLCQidMiR6azmIt13OEozG700ygAUuA6Ng==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-body": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-body/-/mjml-body-4.15.3.tgz", - "integrity": "sha512-7pfUOVPtmb0wC+oUOn4xBsAw4eT5DyD6xqaxj/kssu6RrFXOXgJaVnDPAI9AzIvXJ/5as9QrqRGYAddehwWpHQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-button": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-button/-/mjml-button-4.15.3.tgz", - "integrity": "sha512-79qwn9AgdGjJR1vLnrcm2rq2AsAZkKC5JPwffTMG+Nja6zGYpTDZFZ56ekHWr/r1b5WxkukcPj2PdevUug8c+Q==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-carousel": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-carousel/-/mjml-carousel-4.15.3.tgz", - "integrity": "sha512-3ju6I4l7uUhPRrJfN3yK9AMsfHvrYbRkcJ1GRphFHzUj37B2J6qJOQUpzA547Y4aeh69TSb7HFVf1t12ejQxVw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-cli": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-cli/-/mjml-cli-4.15.3.tgz", - "integrity": "sha512-+V2TDw3tXUVEptFvLSerz125C2ogYl8klIBRY1m5BHd4JvGVf3yhx8N3PngByCzA6PGcv/eydGQN+wy34SHf0Q==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "chokidar": "^3.0.0", - "glob": "^10.3.10", - "html-minifier": "^4.0.0", - "js-beautify": "^1.6.14", - "lodash": "^4.17.21", - "minimatch": "^9.0.3", - "mjml-core": "4.15.3", - "mjml-migrate": "4.15.3", - "mjml-parser-xml": "4.15.3", - "mjml-validator": "4.15.3", - "yargs": "^17.7.2" - }, - "bin": { - "mjml-cli": "bin/mjml" - } - }, - "node_modules/mjml-cli/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/mjml-cli/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mjml-column": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-column/-/mjml-column-4.15.3.tgz", - "integrity": "sha512-hYdEFdJGHPbZJSEysykrevEbB07yhJGSwfDZEYDSbhQQFjV2tXrEgYcFD5EneMaowjb55e3divSJxU4c5q4Qgw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-core": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-core/-/mjml-core-4.15.3.tgz", - "integrity": "sha512-Dmwk+2cgSD9L9GmTbEUNd8QxkTZtW9P7FN/ROZW/fGZD6Hq6/4TB0zEspg2Ow9eYjZXO2ofOJ3PaQEEShKV0kQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "cheerio": "1.0.0-rc.12", - "detect-node": "^2.0.4", - "html-minifier": "^4.0.0", - "js-beautify": "^1.6.14", - "juice": "^10.0.0", - "lodash": "^4.17.21", - "mjml-migrate": "4.15.3", - "mjml-parser-xml": "4.15.3", - "mjml-validator": "4.15.3" - } - }, - "node_modules/mjml-divider": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-divider/-/mjml-divider-4.15.3.tgz", - "integrity": "sha512-vh27LQ9FG/01y0b9ntfqm+GT5AjJnDSDY9hilss2ixIUh0FemvfGRfsGVeV5UBVPBKK7Ffhvfqc7Rciob9Spzw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-group": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-group/-/mjml-group-4.15.3.tgz", - "integrity": "sha512-HSu/rKnGZVKFq3ciT46vi1EOy+9mkB0HewO4+P6dP/Y0UerWkN6S3UK11Cxsj0cAp0vFwkPDCdOeEzRdpFEkzA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-head": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head/-/mjml-head-4.15.3.tgz", - "integrity": "sha512-o3mRuuP/MB5fZycjD3KH/uXsnaPl7Oo8GtdbJTKtH1+O/3pz8GzGMkscTKa97l03DAG2EhGrzzLcU2A6eshwFw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-head-attributes": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-attributes/-/mjml-head-attributes-4.15.3.tgz", - "integrity": "sha512-2ISo0r5ZKwkrvJgDou9xVPxxtXMaETe2AsAA02L89LnbB2KC0N5myNsHV0sEysTw9+CfCmgjAb0GAI5QGpxKkQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-head-breakpoint": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-breakpoint/-/mjml-head-breakpoint-4.15.3.tgz", - "integrity": "sha512-Eo56FA5C2v6ucmWQL/JBJ2z641pLOom4k0wP6CMZI2utfyiJ+e2Uuinj1KTrgDcEvW4EtU9HrfAqLK9UosLZlg==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-head-font": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-font/-/mjml-head-font-4.15.3.tgz", - "integrity": "sha512-CzV2aDPpiNIIgGPHNcBhgyedKY4SX3BJoTwOobSwZVIlEA6TAWB4Z9WwFUmQqZOgo1AkkiTHPZQvGcEhFFXH6g==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-head-html-attributes": { - "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==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-head-preview": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-head-preview/-/mjml-head-preview-4.15.3.tgz", - "integrity": "sha512-J2PxCefUVeFwsAExhrKo4lwxDevc5aKj888HBl/wN4EuWOoOg06iOGCxz4Omd8dqyFsrqvbBuPqRzQ+VycGmaA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-head-style": { - "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==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-head-title": { - "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==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-hero": { - "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==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-image": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-image/-/mjml-image-4.15.3.tgz", - "integrity": "sha512-g1OhSdofIytE9qaOGdTPmRIp7JsCtgO0zbsn1Fk6wQh2gEL55Z40j/VoghslWAWTgT2OHFdBKnMvWtN6U5+d2Q==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-migrate": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-migrate/-/mjml-migrate-4.15.3.tgz", - "integrity": "sha512-sr/+35RdxZroNQVegjpfRHJ5hda9XCgaS4mK2FGO+Mb1IUevKfeEPII3F/cHDpNwFeYH3kAgyqQ22ClhGLWNBA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "js-beautify": "^1.6.14", - "lodash": "^4.17.21", - "mjml-core": "4.15.3", - "mjml-parser-xml": "4.15.3", - "yargs": "^17.7.2" - }, - "bin": { - "migrate": "lib/cli.js" - } - }, - "node_modules/mjml-navbar": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-navbar/-/mjml-navbar-4.15.3.tgz", - "integrity": "sha512-VsKH/Jdlf8Yu3y7GpzQV5n7JMdpqvZvTSpF6UQXL0PWOm7k6+LX+sCZimOfpHJ+wCaaybpxokjWZ71mxOoCWoA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-parser-xml": { - "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==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "detect-node": "2.1.0", - "htmlparser2": "^9.1.0", - "lodash": "^4.17.15" - } - }, - "node_modules/mjml-parser-xml/node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, - "node_modules/mjml-preset-core": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-preset-core/-/mjml-preset-core-4.15.3.tgz", - "integrity": "sha512-1zZS8P4O0KweWUqNS655+oNnVMPQ1Rq1GaZq5S9JfwT1Vh/m516lSmiTW9oko6gGHytt5s6Yj6oOeu5Zm8FoLw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "mjml-accordion": "4.15.3", - "mjml-body": "4.15.3", - "mjml-button": "4.15.3", - "mjml-carousel": "4.15.3", - "mjml-column": "4.15.3", - "mjml-divider": "4.15.3", - "mjml-group": "4.15.3", - "mjml-head": "4.15.3", - "mjml-head-attributes": "4.15.3", - "mjml-head-breakpoint": "4.15.3", - "mjml-head-font": "4.15.3", - "mjml-head-html-attributes": "4.15.3", - "mjml-head-preview": "4.15.3", - "mjml-head-style": "4.15.3", - "mjml-head-title": "4.15.3", - "mjml-hero": "4.15.3", - "mjml-image": "4.15.3", - "mjml-navbar": "4.15.3", - "mjml-raw": "4.15.3", - "mjml-section": "4.15.3", - "mjml-social": "4.15.3", - "mjml-spacer": "4.15.3", - "mjml-table": "4.15.3", - "mjml-text": "4.15.3", - "mjml-wrapper": "4.15.3" - } - }, - "node_modules/mjml-raw": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-raw/-/mjml-raw-4.15.3.tgz", - "integrity": "sha512-IGyHheOYyRchBLiAEgw3UM11kFNmBSMupu2BDdejC6ZiDhEAdG+tyERlsCwDPYtXanvFpGWULIu3XlsUPc+RZw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-section": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-section/-/mjml-section-4.15.3.tgz", - "integrity": "sha512-JfVPRXH++Hd933gmQfG8JXXCBCR6fIzC3DwiYycvanL/aW1cEQ2EnebUfQkt5QzlYjOkJEH+JpccAsq3ln6FZQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-social": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-social/-/mjml-social-4.15.3.tgz", - "integrity": "sha512-7sD5FXrESOxpT9Z4Oh36bS6u/geuUrMP1aCg2sjyAwbPcF1aWa2k9OcatQfpRf6pJEhUZ18y6/WBBXmMVmSzXg==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-spacer": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-spacer/-/mjml-spacer-4.15.3.tgz", - "integrity": "sha512-3B7Qj+17EgDdAtZ3NAdMyOwLTX1jfmJuY7gjyhS2HtcZAmppW+cxqHUBwCKfvSRgTQiccmEvtNxaQK+tfyrZqA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-table": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-table/-/mjml-table-4.15.3.tgz", - "integrity": "sha512-FLx7DcRKTdKdcOCbMyBaeudeHaHpwPveRrBm6WyQe3LXx6FfdmOh59i71/16LFQMgBOD3N4/UJkzxLzlTJzMqQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-text": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-text/-/mjml-text-4.15.3.tgz", - "integrity": "sha512-+C0hxCmw9kg0XzT6vhE5mFkK6y225nC8UEQcN94K0fBCjPKkM+HqZMwGX205fzdGRi+Bxa55b/VhrIVwdv+8vw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3" - } - }, - "node_modules/mjml-validator": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-validator/-/mjml-validator-4.15.3.tgz", - "integrity": "sha512-Xb72KdqRwjv/qM2rJpV22syyP2N3cRQ9VVDrN6u2FSzLq02buFNxmSPJ7CKhat3PrUNdVHU75KZwOf/tz4UEhA==", - "dependencies": { - "@babel/runtime": "^7.23.9" - } - }, - "node_modules/mjml-wrapper": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/mjml-wrapper/-/mjml-wrapper-4.15.3.tgz", - "integrity": "sha512-ditsCijeHJrmBmObtJmQ18ddLxv5oPyMTdPU8Di8APOnD2zPk7Z4UAuJSl7HXB45oFiivr3MJf4koFzMUSZ6Gg==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "lodash": "^4.17.21", - "mjml-core": "4.15.3", - "mjml-section": "4.15.3" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dev": true, - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "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==", - "dependencies": { - "lower-case": "^1.1.1" - } - }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", - "dev": true - }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/node-fetch": { - "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==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-mailjet": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/node-mailjet/-/node-mailjet-6.0.5.tgz", - "integrity": "sha512-upufsTkMyrDF7Z6OiJ4M4Yw4L6MkB0vOQB27W1V9q0CxxSA6e2xOJif3koPwwwgDELpbJNG7asZjKFdghtxUCw==", - "dependencies": { - "axios": "1.6.2", - "json-bigint": "^1.0.0", - "url-join": "^4.0.0" - }, - "engines": { - "node": ">= 12.0.0", - "npm": ">= 6.9.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" - }, - "node_modules/nopt": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", - "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nth-check": { - "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==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dev": true, - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" - }, - "node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "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==", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/passport": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", - "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", - "dependencies": { - "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-headerapikey": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/passport-headerapikey/-/passport-headerapikey-1.2.2.tgz", - "integrity": "sha512-4BvVJRrWsNJPrd3UoZfcnnl4zvUWYKEtfYkoDsaOKBsrWHYmzTApCjs7qUbncOLexE9ul0IRiYBFfBG0y9IVQA==", - "dependencies": { - "lodash": "^4.17.15", - "passport-strategy": "^1.0.0" - } - }, - "node_modules/passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" - }, - "node_modules/picomatch": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", - "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pidtree": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", - "dev": true, - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "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==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "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/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/reflect-metadata": { - "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.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor/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==", - "dev": true - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dev": true, - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slick": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", - "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==", - "engines": { - "node": "*" - } - }, - "node_modules/socket.io": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.2.tgz", - "integrity": "sha512-Vp+lSks5k0dewYTfwgPT9UeGGd+ht7sCpB7p0e83VgO4X/AHYWhXITMrNk/pg8syY2bpx23ptClCQuHhqi2BgQ==", - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.2", - "engine.io": "~6.4.2", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", - "dependencies": { - "debug": "~4.3.4", - "ws": "~8.17.1" - } - }, - "node_modules/socket.io-adapter/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sockjs/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true, - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", - "optional": true - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/symbol-observable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", - "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser/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==" - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-fast-properties": { - "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==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "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==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/tsconfig-paths": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", - "dev": true, - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tsconfig-paths-webpack-plugin": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", - "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.7.0", - "tsconfig-paths": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/uid": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", - "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", - "dependencies": { - "@lukeed/csprng": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "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==" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/valid-data-url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", - "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/web-resource-inliner": { - "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==", - "dependencies": { - "ansi-colors": "^4.1.1", - "escape-goat": "^3.0.0", - "htmlparser2": "^5.0.0", - "mime": "^2.4.6", - "node-fetch": "^2.6.0", - "valid-data-url": "^3.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web-resource-inliner/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/dom-serializer/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/domhandler": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", - "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", - "dependencies": { - "domelementtype": "^2.0.1" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/domutils/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/htmlparser2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz", - "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^3.3.0", - "domutils": "^2.4.2", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/fb55/htmlparser2?sponsor=1" - } - }, - "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==" - }, - "node_modules/webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", - "dependencies": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dev": true, - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-node-externals": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", - "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "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==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "packages/backend/cron/service": { - "name": "@red-kite/cron", - "version": "0.0.1", - "license": "UNLICENSED", - "dependencies": { - "@nestjs/common": "^10.0.0", - "@nestjs/core": "^10.0.0", - "@nestjs/mongoose": "^10.0.0", - "@nestjs/platform-express": "^10.0.0", - "@nestjs/schedule": "^4.0.0", - "@types/node-fetch": "^2.6.9", - "async-mutex": "^0.4.0", - "cron-parser": "^4.9.0", - "mongodb-memory-server": "^9.1.1", - "mongoose": "^7.3.2", - "node-fetch": "^2.7.0", - "reflect-metadata": "^0.1.13", - "rxjs": "^7.8.1", - "webpack": "^5.90.3" - }, - "devDependencies": { - "@nestjs/cli": "^10.0.0", - "@nestjs/schematics": "^10.0.0", - "@nestjs/testing": "^10.0.0", - "@types/express": "^4.17.17", - "@types/jest": "^29.5.2", - "@types/node": "^20.3.1", - "@types/supertest": "^2.0.12", - "@typescript-eslint/eslint-plugin": "^5.59.11", - "@typescript-eslint/parser": "^5.59.11", - "eslint": "^8.42.0", - "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^4.2.1", - "jest": "^29.5.0", - "prettier": "^2.8.8", - "source-map-support": "^0.5.21", - "supertest": "^6.3.3", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.3", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.2.0", - "typescript": "^5.1.3" - } - }, - "packages/backend/cron/service/node_modules/@babel/core": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.9", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.9", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "packages/backend/cron/service/node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/backend/cron/service/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-jsx/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/cron/service/node_modules/@babel/plugin-syntax-typescript/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/backend/cron/service/node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "packages/backend/cron/service/node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "packages/backend/cron/service/node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "packages/backend/cron/service/node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "packages/backend/cron/service/node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/cron/service/node_modules/@eslint/js": { - "version": "8.57.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "packages/backend/cron/service/node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "packages/backend/cron/service/node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "packages/backend/cron/service/node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "packages/backend/cron/service/node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "packages/backend/cron/service/node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/cron/service/node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "packages/backend/cron/service/node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "packages/backend/cron/service/node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/@jest/console": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/console/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@jest/core": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/@jest/core/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@jest/environment": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/environment/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@jest/expect": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/expect-utils": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/fake-timers": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/fake-timers/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@jest/globals": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/reporters": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/@jest/reporters/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/@jest/schemas": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/source-map": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/test-result": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/transform": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/types": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/@jest/types/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@mongodb-js/saslprep": { - "version": "1.1.8", - "license": "MIT", - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - } - }, - "packages/backend/cron/service/node_modules/@nestjs/core": { - "version": "10.3.10", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@nuxtjs/opencollective": "0.3.2", - "fast-safe-stringify": "2.1.1", - "iterare": "1.2.1", - "path-to-regexp": "3.2.0", - "tslib": "2.6.3", - "uid": "2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "@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": { - "@nestjs/microservices": { - "optional": true - }, - "@nestjs/platform-express": { - "optional": true - }, - "@nestjs/websockets": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/@nestjs/mongoose": { - "version": "10.0.10", - "license": "MIT", - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", - "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0", - "mongoose": "^6.0.2 || ^7.0.0 || ^8.0.0", - "rxjs": "^7.0.0" - } - }, - "packages/backend/cron/service/node_modules/@nestjs/platform-express": { - "version": "10.3.10", - "license": "MIT", - "dependencies": { - "body-parser": "1.20.2", - "cors": "2.8.5", - "express": "4.19.2", - "multer": "1.4.4-lts.1", - "tslib": "2.6.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "@nestjs/common": "^10.0.0", - "@nestjs/core": "^10.0.0" - } - }, - "packages/backend/cron/service/node_modules/@nestjs/schedule": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "cron": "3.1.7", - "uuid": "10.0.0" - }, - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", - "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0" - } - }, - "packages/backend/cron/service/node_modules/@nestjs/testing": { - "version": "10.3.10", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "2.6.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "@nestjs/common": "^10.0.0", - "@nestjs/core": "^10.0.0", - "@nestjs/microservices": "^10.0.0", - "@nestjs/platform-express": "^10.0.0" - }, - "peerDependenciesMeta": { - "@nestjs/microservices": { - "optional": true - }, - "@nestjs/platform-express": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/backend/cron/service/node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/backend/cron/service/node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/backend/cron/service/node_modules/@nuxtjs/opencollective": { - "version": "0.3.2", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.0", - "node-fetch": "^2.6.1" - }, - "bin": { - "opencollective": "bin/opencollective.js" - }, - "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" - } - }, - "packages/backend/cron/service/node_modules/@sinclair/typebox": { - "version": "0.27.8", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@sinonjs/commons": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "packages/backend/cron/service/node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "packages/backend/cron/service/node_modules/@tsconfig/node10": { - "version": "1.0.11", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@tsconfig/node12": { - "version": "1.0.11", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@tsconfig/node14": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@tsconfig/node16": { - "version": "1.0.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@types/babel__core": { - "version": "7.20.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "packages/backend/cron/service/node_modules/@types/babel__generator": { - "version": "7.6.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "packages/backend/cron/service/node_modules/@types/babel__template": { - "version": "7.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "packages/backend/cron/service/node_modules/@types/babel__traverse": { - "version": "7.20.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "packages/backend/cron/service/node_modules/@types/cookiejar": { - "version": "2.1.5", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@types/graceful-fs": { - "version": "4.1.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "packages/backend/cron/service/node_modules/@types/graceful-fs/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "packages/backend/cron/service/node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "packages/backend/cron/service/node_modules/@types/jest": { - "version": "29.5.12", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "packages/backend/cron/service/node_modules/@types/luxon": { - "version": "3.4.2", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@types/methods": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@types/node": { - "version": "20.11.20", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@types/node-fetch": { - "version": "2.6.11", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "packages/backend/cron/service/node_modules/@types/node-fetch/node_modules/@types/node": { - "version": "20.14.11", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@types/semver": { - "version": "7.5.8", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@types/stack-utils": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@types/superagent": { - "version": "8.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/cookiejar": "^2.1.5", - "@types/methods": "^1.1.4", - "@types/node": "*" - } - }, - "packages/backend/cron/service/node_modules/@types/superagent/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@types/supertest": { - "version": "2.0.16", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/superagent": "*" - } - }, - "packages/backend/cron/service/node_modules/@types/webidl-conversions": { - "version": "7.0.3", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@types/whatwg-url": { - "version": "8.2.2", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/webidl-conversions": "*" - } - }, - "packages/backend/cron/service/node_modules/@types/whatwg-url/node_modules/@types/node": { - "version": "20.14.11", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/@types/yargs": { - "version": "17.0.32", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "packages/backend/cron/service/node_modules/@types/yargs-parser": { - "version": "21.0.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/backend/cron/service/node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/backend/cron/service/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "packages/backend/cron/service/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/backend/cron/service/node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "dev": true, - "license": "ISC" - }, - "packages/backend/cron/service/node_modules/acorn-jsx": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "packages/backend/cron/service/node_modules/acorn-walk": { - "version": "8.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "packages/backend/cron/service/node_modules/agent-base": { - "version": "7.1.1", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "packages/backend/cron/service/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "packages/backend/cron/service/node_modules/append-field": { - "version": "1.0.0", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/arg": { - "version": "4.1.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/asap": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/async": { - "version": "3.2.5", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/async-mutex": { - "version": "0.4.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "packages/backend/cron/service/node_modules/b4a": { - "version": "1.6.6", - "license": "Apache-2.0" - }, - "packages/backend/cron/service/node_modules/babel-jest": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "packages/backend/cron/service/node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/backend/cron/service/node_modules/babel-preset-jest": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/backend/cron/service/node_modules/bare-events": { - "version": "2.4.2", - "license": "Apache-2.0", - "optional": true - }, - "packages/backend/cron/service/node_modules/body-parser": { - "version": "1.20.2", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "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.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "packages/backend/cron/service/node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "packages/backend/cron/service/node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/cron/service/node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "packages/backend/cron/service/node_modules/bs-logger": { - "version": "0.2.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "packages/backend/cron/service/node_modules/bser": { - "version": "2.1.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "packages/backend/cron/service/node_modules/bson": { - "version": "5.5.1", - "license": "Apache-2.0", - "engines": { - "node": ">=14.20.1" - } - }, - "packages/backend/cron/service/node_modules/buffer-crc32": { - "version": "0.2.13", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "packages/backend/cron/service/node_modules/busboy": { - "version": "1.6.0", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "packages/backend/cron/service/node_modules/camelcase": { - "version": "6.3.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/char-regex": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/ci-info": { - "version": "3.9.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/cjs-module-lexer": { - "version": "1.3.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/co": { - "version": "4.6.0", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "packages/backend/cron/service/node_modules/collect-v8-coverage": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/commondir": { - "version": "1.0.1", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/component-emitter": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/concat-stream": { - "version": "1.6.2", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "packages/backend/cron/service/node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.8", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "packages/backend/cron/service/node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "packages/backend/cron/service/node_modules/consola": { - "version": "2.15.3", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/cookie": { - "version": "0.6.0", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "packages/backend/cron/service/node_modules/cookiejar": { - "version": "2.1.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/create-jest": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/create-require": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/cron": { - "version": "3.1.7", - "license": "MIT", - "dependencies": { - "@types/luxon": "~3.4.0", - "luxon": "~3.4.0" - } - }, - "packages/backend/cron/service/node_modules/cron-parser": { - "version": "4.9.0", - "license": "MIT", - "dependencies": { - "luxon": "^3.2.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "packages/backend/cron/service/node_modules/dedent": { - "version": "1.5.3", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/deep-is": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/detect-newline": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/dezalgo": { - "version": "1.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "packages/backend/cron/service/node_modules/diff": { - "version": "4.0.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "packages/backend/cron/service/node_modules/diff-sequences": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/doctrine": { - "version": "3.0.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "packages/backend/cron/service/node_modules/ejs": { - "version": "3.1.10", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/backend/cron/service/node_modules/emittery": { - "version": "0.13.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "packages/backend/cron/service/node_modules/eslint": { - "version": "8.57.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/cron/service/node_modules/eslint-config-prettier": { - "version": "8.10.0", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "packages/backend/cron/service/node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/cron/service/node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/cron/service/node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "packages/backend/cron/service/node_modules/espree": { - "version": "9.6.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/cron/service/node_modules/esquery": { - "version": "1.6.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "packages/backend/cron/service/node_modules/estraverse": { - "version": "5.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "packages/backend/cron/service/node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/backend/cron/service/node_modules/execa": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "packages/backend/cron/service/node_modules/exit": { - "version": "0.1.2", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/cron/service/node_modules/expect": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/express": { - "version": "4.19.2", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "packages/backend/cron/service/node_modules/express/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "packages/backend/cron/service/node_modules/express/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/express/node_modules/qs": { - "version": "6.11.0", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/cron/service/node_modules/fast-diff": { - "version": "1.3.0", - "dev": true, - "license": "Apache-2.0" - }, - "packages/backend/cron/service/node_modules/fast-fifo": { - "version": "1.3.2", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/fast-glob": { - "version": "3.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "packages/backend/cron/service/node_modules/fast-levenshtein": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/fast-safe-stringify": { - "version": "2.1.1", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/fastq": { - "version": "1.17.1", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "packages/backend/cron/service/node_modules/fb-watchman": { - "version": "2.0.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "packages/backend/cron/service/node_modules/file-entry-cache": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/backend/cron/service/node_modules/filelist": { - "version": "1.0.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "packages/backend/cron/service/node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/find-cache-dir": { - "version": "3.3.2", - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "packages/backend/cron/service/node_modules/find-up": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/find-up/node_modules/locate-path": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/find-up/node_modules/p-limit": { - "version": "2.3.0", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/find-up/node_modules/p-locate": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/flat-cache": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/backend/cron/service/node_modules/flatted": { - "version": "3.3.1", - "dev": true, - "license": "ISC" - }, - "packages/backend/cron/service/node_modules/formidable": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "dezalgo": "^1.0.4", - "hexoid": "^1.0.0", - "once": "^1.4.0", - "qs": "^6.11.0" - }, - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, - "packages/backend/cron/service/node_modules/get-package-type": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "packages/backend/cron/service/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/backend/cron/service/node_modules/globals": { - "version": "13.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/globby": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/graphemer": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/hexoid": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/html-escaper": { - "version": "2.0.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/https-proxy-agent": { - "version": "7.0.5", - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "packages/backend/cron/service/node_modules/human-signals": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "packages/backend/cron/service/node_modules/ignore": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "packages/backend/cron/service/node_modules/import-local": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "packages/backend/cron/service/node_modules/ip-address": { - "version": "9.0.5", - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/backend/cron/service/node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/cron/service/node_modules/is-generator-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/cron/service/node_modules/is-path-inside": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/is-stream": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/backend/cron/service/node_modules/istanbul-lib-report": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/istanbul-reports": { - "version": "3.1.7", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/jake": { - "version": "10.9.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/jest": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/jest-changed-files": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-circus": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-circus/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-cli": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/jest-config": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/jest-diff": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-docblock": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-each": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-environment-node": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-environment-node/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-get-type": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-haste-map": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "packages/backend/cron/service/node_modules/jest-haste-map/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-leak-detector": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-matcher-utils": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-message-util": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-mock": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-mock/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/jest-regex-util": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-resolve": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-runner": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-runner/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-runner/node_modules/source-map-support": { - "version": "0.5.13", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "packages/backend/cron/service/node_modules/jest-runtime": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-runtime/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/jest-snapshot": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-util": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-util/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-validate": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-watcher": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-watcher/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-worker": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/jest-worker/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/cron/service/node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "packages/backend/cron/service/node_modules/jsbn": { - "version": "1.1.0", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/json-buffer": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/kareem": { - "version": "2.5.1", - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, - "packages/backend/cron/service/node_modules/keyv": { - "version": "4.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "packages/backend/cron/service/node_modules/kleur": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/cron/service/node_modules/leven": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/cron/service/node_modules/levn": { - "version": "0.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/cron/service/node_modules/locate-path": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/lodash.memoize": { - "version": "4.1.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/lodash.merge": { - "version": "4.6.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/luxon": { - "version": "3.4.4", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "packages/backend/cron/service/node_modules/make-dir": { - "version": "3.1.0", - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/backend/cron/service/node_modules/make-error": { - "version": "1.3.6", - "dev": true, - "license": "ISC" - }, - "packages/backend/cron/service/node_modules/makeerror": { - "version": "1.0.12", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "packages/backend/cron/service/node_modules/memory-pager": { - "version": "1.5.0", - "license": "MIT", - "optional": true - }, - "packages/backend/cron/service/node_modules/merge2": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/backend/cron/service/node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/cron/service/node_modules/mkdirp": { - "version": "0.5.6", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "packages/backend/cron/service/node_modules/mongodb": { - "version": "5.9.2", - "license": "Apache-2.0", - "dependencies": { - "bson": "^5.5.0", - "mongodb-connection-string-url": "^2.6.0", - "socks": "^2.7.1" - }, - "engines": { - "node": ">=14.20.1" - }, - "optionalDependencies": { - "@mongodb-js/saslprep": "^1.1.0" - }, - "peerDependencies": { - "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.0.0", - "kerberos": "^1.0.0 || ^2.0.0", - "mongodb-client-encryption": ">=2.3.0 <3", - "snappy": "^7.2.2" - }, - "peerDependenciesMeta": { - "@aws-sdk/credential-providers": { - "optional": true - }, - "@mongodb-js/zstd": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "snappy": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/mongodb-connection-string-url": { - "version": "2.6.0", - "license": "Apache-2.0", - "dependencies": { - "@types/whatwg-url": "^8.2.1", - "whatwg-url": "^11.0.0" - } - }, - "packages/backend/cron/service/node_modules/mongodb-memory-server": { - "version": "9.4.1", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "mongodb-memory-server-core": "9.4.1", - "tslib": "^2.6.3" - }, - "engines": { - "node": ">=14.20.1" - } - }, - "packages/backend/cron/service/node_modules/mongodb-memory-server-core": { - "version": "9.4.1", - "license": "MIT", - "dependencies": { - "async-mutex": "^0.4.1", - "camelcase": "^6.3.0", - "debug": "^4.3.5", - "find-cache-dir": "^3.3.2", - "follow-redirects": "^1.15.6", - "https-proxy-agent": "^7.0.4", - "mongodb": "^5.9.2", - "new-find-package-json": "^2.0.0", - "semver": "^7.6.2", - "tar-stream": "^3.1.7", - "tslib": "^2.6.3", - "yauzl": "^3.1.3" - }, - "engines": { - "node": ">=14.20.1" - } - }, - "packages/backend/cron/service/node_modules/mongoose": { - "version": "7.7.0", - "license": "MIT", - "dependencies": { - "bson": "^5.5.0", - "kareem": "2.5.1", - "mongodb": "5.9.2", - "mpath": "0.9.0", - "mquery": "5.0.0", - "ms": "2.1.3", - "sift": "16.0.1" - }, - "engines": { - "node": ">=14.20.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mongoose" - } - }, - "packages/backend/cron/service/node_modules/mpath": { - "version": "0.9.0", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "packages/backend/cron/service/node_modules/mquery": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "debug": "4.x" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "packages/backend/cron/service/node_modules/ms": { - "version": "2.1.3", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/multer": { - "version": "1.4.4-lts.1", - "license": "MIT", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "packages/backend/cron/service/node_modules/natural-compare": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/natural-compare-lite": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/new-find-package-json": { - "version": "2.0.0", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "packages/backend/cron/service/node_modules/node-int64": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/npm-run-path": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/optionator": { - "version": "0.9.4", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/cron/service/node_modules/p-limit": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/p-locate": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/p-try": { - "version": "2.2.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/cron/service/node_modules/path-exists": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/path-to-regexp": { - "version": "3.2.0", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/pend": { - "version": "1.2.0", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/picomatch": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "packages/backend/cron/service/node_modules/pirates": { - "version": "4.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "packages/backend/cron/service/node_modules/pkg-dir": { - "version": "4.2.0", - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/prelude-ls": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/cron/service/node_modules/prettier": { - "version": "2.8.8", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "packages/backend/cron/service/node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "packages/backend/cron/service/node_modules/pretty-format": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/cron/service/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/backend/cron/service/node_modules/prompts": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "packages/backend/cron/service/node_modules/pure-rand": { - "version": "6.1.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/qs": { - "version": "6.12.3", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/cron/service/node_modules/queue-microtask": { - "version": "1.2.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/queue-tick": { - "version": "1.0.1", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/raw-body": { - "version": "2.5.2", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "packages/backend/cron/service/node_modules/react-is": { - "version": "18.3.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/reflect-metadata": { - "version": "0.1.14", - "license": "Apache-2.0" - }, - "packages/backend/cron/service/node_modules/resolve": { - "version": "1.22.8", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/cron/service/node_modules/resolve-cwd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/resolve.exports": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/reusify": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "packages/backend/cron/service/node_modules/run-parallel": { - "version": "1.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "packages/backend/cron/service/node_modules/sift": { - "version": "16.0.1", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "packages/backend/cron/service/node_modules/sisteransi": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/smart-buffer": { - "version": "4.2.0", - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "packages/backend/cron/service/node_modules/socks": { - "version": "2.8.3", - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "packages/backend/cron/service/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/backend/cron/service/node_modules/sparse-bitfield": { - "version": "3.0.3", - "license": "MIT", - "optional": true, - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "packages/backend/cron/service/node_modules/sprintf-js": { - "version": "1.1.3", - "license": "BSD-3-Clause" - }, - "packages/backend/cron/service/node_modules/stack-utils": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/streamsearch": { - "version": "1.1.0", - "engines": { - "node": ">=10.0.0" - } - }, - "packages/backend/cron/service/node_modules/streamx": { - "version": "2.18.0", - "license": "MIT", - "dependencies": { - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, - "packages/backend/cron/service/node_modules/string-length": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/cron/service/node_modules/strip-final-newline": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/cron/service/node_modules/strip-json-comments": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/superagent": { - "version": "8.1.2", - "dev": true, - "license": "MIT", - "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": "^2.1.2", - "methods": "^1.1.2", - "mime": "2.6.0", - "qs": "^6.11.0", - "semver": "^7.3.8" - }, - "engines": { - "node": ">=6.4.0 <13 || >=14" - } - }, - "packages/backend/cron/service/node_modules/supertest": { - "version": "6.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "methods": "^1.1.2", - "superagent": "^8.1.2" - }, - "engines": { - "node": ">=6.4.0" - } - }, - "packages/backend/cron/service/node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/cron/service/node_modules/tar-stream": { - "version": "3.1.7", - "license": "MIT", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "packages/backend/cron/service/node_modules/test-exclude": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/cron/service/node_modules/text-decoder": { - "version": "1.1.1", - "license": "Apache-2.0", - "dependencies": { - "b4a": "^1.6.4" - } - }, - "packages/backend/cron/service/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/tmpl": { - "version": "1.0.5", - "dev": true, - "license": "BSD-3-Clause" - }, - "packages/backend/cron/service/node_modules/tr46": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "packages/backend/cron/service/node_modules/ts-jest": { - "version": "29.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "ejs": "^3.1.10", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/transform": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/ts-loader": { - "version": "9.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "packages/backend/cron/service/node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "packages/backend/cron/service/node_modules/ts-node": { - "version": "10.9.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "packages/backend/cron/service/node_modules/tsutils": { - "version": "3.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "packages/backend/cron/service/node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "dev": true, - "license": "0BSD" - }, - "packages/backend/cron/service/node_modules/type-check": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/cron/service/node_modules/type-detect": { - "version": "4.0.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "packages/backend/cron/service/node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/cron/service/node_modules/typedarray": { - "version": "0.0.6", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/undici-types": { - "version": "5.26.5", - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/uuid": { - "version": "10.0.0", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "packages/backend/cron/service/node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/cron/service/node_modules/v8-to-istanbul": { - "version": "9.3.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "packages/backend/cron/service/node_modules/walker": { - "version": "1.0.8", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "packages/backend/cron/service/node_modules/webidl-conversions": { - "version": "7.0.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "packages/backend/cron/service/node_modules/whatwg-url": { - "version": "11.0.0", - "license": "MIT", - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "packages/backend/cron/service/node_modules/word-wrap": { - "version": "1.2.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/backend/cron/service/node_modules/write-file-atomic": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "packages/backend/cron/service/node_modules/xtend": { - "version": "4.0.2", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "packages/backend/cron/service/node_modules/yauzl": { - "version": "3.1.3", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "pend": "~1.2.0" - }, - "engines": { - "node": ">=12" - } - }, - "packages/backend/cron/service/node_modules/yn": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/cron/service/node_modules/yocto-queue": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service": { - "name": "@red-kite/jobs-manager", - "version": "0.0.1", - "license": "UNLICENSED", - "dependencies": { - "@nestjs/common": "^9.2.1", - "@nestjs/core": "^9.2.1", - "@nestjs/cqrs": "^9.0.1", - "@nestjs/jwt": "^10.0.1", - "@nestjs/microservices": "^9.2.1", - "@nestjs/mongoose": "^9.2.2", - "@nestjs/platform-express": "^9.2.1", - "@nestjs/platform-socket.io": "^9.2.1", - "@nestjs/schedule": "^2.1.0", - "@nestjs/websockets": "^9.2.1", - "@typegoose/typegoose": "^10.3.3", - "class-transformer": "^0.5.1", - "class-validator": "^0.14.0", - "cron-validator": "^1.3.1", - "dot-object": "^2.1.4", - "handlebars": "^4.7.8", - "jwt-decode": "^3.1.2", - "kafkajs": "^2.2.3", - "mjml": "^4.15.3", - "mongodb-memory-server": "^8.11.4", - "mongoose": "^6.10.0", - "node-forge": "^1.3.1", - "node-mailjet": "^6.0.5", - "passport": "^0.6.0", - "passport-jwt": "^4.0.1", - "passport-local": "^1.0.0", - "passport-unique-token": "^3.0.0", - "reflect-metadata": "^0.1.13", - "rimraf": "^4.1.2", - "rxjs": "^7.8.0", - "uuid": "^9.0.0", - "webpack": "^5.90.3" - }, - "devDependencies": { - "@nestjs/cli": "^9.1.9", - "@nestjs/passport": "^9.0.0", - "@nestjs/schematics": "^9.0.4", - "@nestjs/testing": "^9.2.1", - "@types/express": "^4.17.16", - "@types/jest": "^29.5.1", - "@types/mjml": "^4", - "@types/node": "^18.11.18", - "@types/passport-jwt": "^3.0.8", - "@types/passport-local": "^1.0.35", - "@types/supertest": "~6.0.2", - "@typescript-eslint/eslint-plugin": "^5.49.0", - "@typescript-eslint/parser": "^5.49.0", - "argon2": "^0.30.3", - "eslint": "^8.33.0", - "eslint-config-prettier": "8.6.0", - "eslint-plugin-prettier": "^4.2.1", - "jest": "^29.5.0", - "lint-staged": "^13.1.0", - "mongodb": "^4.13.0", - "prettier": "^2.8.3", - "supertest": "~7.0.0", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.1.2", - "typescript": "^4.9.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@angular-devkit/core": { - "version": "16.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@angular-devkit/core/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "packages/backend/jobs-manager/service/node_modules/@angular-devkit/core/node_modules/source-map": { - "version": "0.7.4", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "packages/backend/jobs-manager/service/node_modules/@angular-devkit/schematics": { - "version": "16.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "16.0.1", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.0", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@angular-devkit/schematics-cli": { - "version": "16.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "16.0.1", - "@angular-devkit/schematics": "16.0.1", - "ansi-colors": "4.1.3", - "inquirer": "8.2.4", - "symbol-observable": "4.0.0", - "yargs-parser": "21.1.1" - }, - "bin": { - "schematics": "bin/schematics.js" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/core": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.9", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.9", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-jsx/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@babel/plugin-syntax-typescript/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "packages/backend/jobs-manager/service/node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "packages/backend/jobs-manager/service/node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/jobs-manager/service/node_modules/@eslint/js": { - "version": "8.57.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "packages/backend/jobs-manager/service/node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "packages/backend/jobs-manager/service/node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "packages/backend/jobs-manager/service/node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "packages/backend/jobs-manager/service/node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "packages/backend/jobs-manager/service/node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/console": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/console/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/core": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/core/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/environment": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/environment/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/expect": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/expect-utils": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/fake-timers": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/fake-timers/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/globals": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/reporters": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/reporters/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/schemas": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/source-map": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/test-result": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/transform": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/types": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@jest/types/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "packages/backend/jobs-manager/service/node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { - "version": "5.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/backend/jobs-manager/service/node_modules/@mongodb-js/saslprep": { - "version": "1.1.8", - "license": "MIT", - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/cli": { - "version": "9.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "16.0.1", - "@angular-devkit/schematics": "16.0.1", - "@angular-devkit/schematics-cli": "16.0.1", - "@nestjs/schematics": "^9.0.4", - "chalk": "4.1.2", - "chokidar": "3.5.3", - "cli-table3": "0.6.3", - "commander": "4.1.1", - "fork-ts-checker-webpack-plugin": "8.0.0", - "inquirer": "8.2.5", - "node-emoji": "1.11.0", - "ora": "5.4.1", - "os-name": "4.0.1", - "rimraf": "4.4.1", - "shelljs": "0.8.5", - "source-map-support": "0.5.21", - "tree-kill": "1.2.2", - "tsconfig-paths": "4.2.0", - "tsconfig-paths-webpack-plugin": "4.0.1", - "typescript": "4.9.5", - "webpack": "5.82.1", - "webpack-node-externals": "3.0.0" - }, - "bin": { - "nest": "bin/nest.js" - }, - "engines": { - "node": ">= 12.9.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/cli/node_modules/fork-ts-checker-webpack-plugin": { - "version": "8.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.16.7", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "fs-extra": "^10.0.0", - "memfs": "^3.4.1", - "minimatch": "^3.0.4", - "node-abort-controller": "^3.0.1", - "schema-utils": "^3.1.1", - "semver": "^7.3.5", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">=12.13.0", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "typescript": ">3.6.0", - "webpack": "^5.11.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/cli/node_modules/fork-ts-checker-webpack-plugin/node_modules/chokidar": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/cli/node_modules/inquirer": { - "version": "8.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/cli/node_modules/webpack": { - "version": "5.82.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/common": { - "version": "9.4.3", - "license": "MIT", - "dependencies": { - "iterare": "1.2.1", - "tslib": "2.5.3", - "uid": "2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "cache-manager": "<=5", - "class-transformer": "*", - "class-validator": "*", - "reflect-metadata": "^0.1.12", - "rxjs": "^7.1.0" - }, - "peerDependenciesMeta": { - "cache-manager": { - "optional": true - }, - "class-transformer": { - "optional": true - }, - "class-validator": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/common/node_modules/tslib": { - "version": "2.5.3", - "license": "0BSD" - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/core": { - "version": "9.4.3", - "hasInstallScript": true, - "license": "MIT", - "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", - "uid": "2.0.2" - }, - "funding": { - "type": "opencollective", - "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", - "rxjs": "^7.1.0" - }, - "peerDependenciesMeta": { - "@nestjs/microservices": { - "optional": true - }, - "@nestjs/platform-express": { - "optional": true - }, - "@nestjs/websockets": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/core/node_modules/tslib": { - "version": "2.5.3", - "license": "0BSD" - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/cqrs": { - "version": "9.0.4", - "license": "MIT", - "dependencies": { - "uuid": "9.0.0" - }, - "peerDependencies": { - "@nestjs/common": "^9.0.0", - "@nestjs/core": "^9.0.0", - "reflect-metadata": "0.1.13", - "rxjs": "^7.2.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/cqrs/node_modules/uuid": { - "version": "9.0.0", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/jwt": { - "version": "10.2.0", - "license": "MIT", - "dependencies": { - "@types/jsonwebtoken": "9.0.5", - "jsonwebtoken": "9.0.2" - }, - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/jwt/node_modules/@types/jsonwebtoken": { - "version": "9.0.5", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/jwt/node_modules/@types/node": { - "version": "20.14.11", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/microservices": { - "version": "9.4.3", - "license": "MIT", - "dependencies": { - "iterare": "1.2.1", - "tslib": "2.5.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "@grpc/grpc-js": "*", - "@nestjs/common": "^9.0.0", - "@nestjs/core": "^9.0.0", - "@nestjs/websockets": "^9.0.0", - "amqp-connection-manager": "*", - "amqplib": "*", - "cache-manager": "*", - "ioredis": "*", - "kafkajs": "*", - "mqtt": "*", - "nats": "*", - "reflect-metadata": "^0.1.12", - "rxjs": "^7.1.0" - }, - "peerDependenciesMeta": { - "@grpc/grpc-js": { - "optional": true - }, - "@nestjs/websockets": { - "optional": true - }, - "amqp-connection-manager": { - "optional": true - }, - "amqplib": { - "optional": true - }, - "cache-manager": { - "optional": true - }, - "ioredis": { - "optional": true - }, - "kafkajs": { - "optional": true - }, - "mqtt": { - "optional": true - }, - "nats": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/microservices/node_modules/tslib": { - "version": "2.5.3", - "license": "0BSD" - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/mongoose": { - "version": "9.2.2", - "license": "MIT", - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0", - "@nestjs/core": "^8.0.0 || ^9.0.0", - "mongoose": "^6.0.2 || ^7.0.0", - "reflect-metadata": "^0.1.12", - "rxjs": "^7.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/passport": { - "version": "9.0.3", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0", - "passport": "^0.4.0 || ^0.5.0 || ^0.6.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/platform-express": { - "version": "9.4.3", - "license": "MIT", - "dependencies": { - "body-parser": "1.20.2", - "cors": "2.8.5", - "express": "4.18.2", - "multer": "1.4.4-lts.1", - "tslib": "2.5.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "@nestjs/common": "^9.0.0", - "@nestjs/core": "^9.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/platform-express/node_modules/tslib": { - "version": "2.5.3", - "license": "0BSD" - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/platform-socket.io": { - "version": "9.4.3", - "license": "MIT", - "dependencies": { - "socket.io": "4.6.2", - "tslib": "2.5.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "@nestjs/common": "^9.0.0", - "@nestjs/websockets": "^9.0.0", - "rxjs": "^7.1.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/platform-socket.io/node_modules/tslib": { - "version": "2.5.3", - "license": "0BSD" - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/schedule": { - "version": "2.2.3", - "license": "MIT", - "dependencies": { - "cron": "2.3.1", - "uuid": "9.0.0" - }, - "peerDependencies": { - "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0", - "@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0", - "reflect-metadata": "^0.1.12" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/schedule/node_modules/uuid": { - "version": "9.0.0", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/schematics": { - "version": "9.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "16.0.1", - "@angular-devkit/schematics": "16.0.1", - "jsonc-parser": "3.2.0", - "pluralize": "8.0.0" - }, - "peerDependencies": { - "typescript": ">=4.3.5" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/testing": { - "version": "9.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "2.5.3" - }, - "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" - }, - "peerDependenciesMeta": { - "@nestjs/microservices": { - "optional": true - }, - "@nestjs/platform-express": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/testing/node_modules/tslib": { - "version": "2.5.3", - "dev": true, - "license": "0BSD" - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/websockets": { - "version": "9.4.3", - "license": "MIT", - "dependencies": { - "iterare": "1.2.1", - "object-hash": "3.0.0", - "tslib": "2.5.3" - }, - "peerDependencies": { - "@nestjs/common": "^9.0.0", - "@nestjs/core": "^9.0.0", - "@nestjs/platform-socket.io": "^9.0.0", - "reflect-metadata": "^0.1.12", - "rxjs": "^7.1.0" - }, - "peerDependenciesMeta": { - "@nestjs/platform-socket.io": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@nestjs/websockets/node_modules/tslib": { - "version": "2.5.3", - "license": "0BSD" - }, - "packages/backend/jobs-manager/service/node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/backend/jobs-manager/service/node_modules/@nuxtjs/opencollective": { - "version": "0.3.2", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.0", - "node-fetch": "^2.6.1" - }, - "bin": { - "opencollective": "bin/opencollective.js" - }, - "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@phc/format": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/@sinclair/typebox": { - "version": "0.27.8", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@sinonjs/commons": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "packages/backend/jobs-manager/service/node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@tsconfig/node10": { - "version": "1.0.11", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@tsconfig/node12": { - "version": "1.0.11", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@tsconfig/node14": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@tsconfig/node16": { - "version": "1.0.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@typegoose/typegoose": { - "version": "10.5.0", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "loglevel": "^1.8.1", - "reflect-metadata": "^0.1.13", - "semver": "^7.5.4", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.17.0" - }, - "peerDependencies": { - "mongoose": "~6.12.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/babel__core": { - "version": "7.20.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/babel__generator": { - "version": "7.6.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/babel__template": { - "version": "7.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/babel__traverse": { - "version": "7.20.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/cookiejar": { - "version": "2.1.5", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/eslint": { - "version": "9.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/eslint-scope": { - "version": "3.7.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/graceful-fs": { - "version": "4.1.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/graceful-fs/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/jest": { - "version": "29.5.12", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/jsonwebtoken": { - "version": "9.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/jsonwebtoken/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/methods": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/mjml": { - "version": "4.7.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mjml-core": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/mjml-core": { - "version": "4.7.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/node": { - "version": "18.19.41", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/parse-json": { - "version": "4.0.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/passport": { - "version": "1.0.16", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/passport-jwt": { - "version": "3.0.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*", - "@types/jsonwebtoken": "*", - "@types/passport-strategy": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/passport-local": { - "version": "1.0.38", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*", - "@types/passport": "*", - "@types/passport-strategy": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/passport-strategy": { - "version": "0.2.38", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*", - "@types/passport": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/semver": { - "version": "7.5.8", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/stack-utils": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/superagent": { - "version": "8.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/cookiejar": "^2.1.5", - "@types/methods": "^1.1.4", - "@types/node": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/superagent/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/supertest": { - "version": "6.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/methods": "^1.1.4", - "@types/superagent": "^8.1.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/validator": { - "version": "13.12.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/webidl-conversions": { - "version": "7.0.3", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@types/whatwg-url": { - "version": "8.2.2", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/webidl-conversions": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/whatwg-url/node_modules/@types/node": { - "version": "20.14.11", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/yargs": { - "version": "17.0.32", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/@types/yargs-parser": { - "version": "21.0.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/backend/jobs-manager/service/node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/backend/jobs-manager/service/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/backend/jobs-manager/service/node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/abbrev": { - "version": "1.1.1", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/acorn-import-assertions": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, - "packages/backend/jobs-manager/service/node_modules/acorn-jsx": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/acorn-walk": { - "version": "8.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "packages/backend/jobs-manager/service/node_modules/ajv/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/append-field": { - "version": "1.0.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/aproba": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/are-we-there-yet": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/arg": { - "version": "4.1.3", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/argon2": { - "version": "0.30.3", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.10", - "@phc/format": "^1.0.0", - "node-addon-api": "^5.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/asap": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/async": { - "version": "3.2.5", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/async-mutex": { - "version": "0.3.2", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/babel-jest": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/babel-preset-jest": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/body-parser": { - "version": "1.20.2", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "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.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "packages/backend/jobs-manager/service/node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/brace-expansion": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/bs-logger": { - "version": "0.2.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "packages/backend/jobs-manager/service/node_modules/bser": { - "version": "2.1.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/bson": { - "version": "4.7.2", - "license": "Apache-2.0", - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/buffer-crc32": { - "version": "0.2.13", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "packages/backend/jobs-manager/service/node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "license": "BSD-3-Clause" - }, - "packages/backend/jobs-manager/service/node_modules/busboy": { - "version": "1.6.0", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/camelcase": { - "version": "6.3.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/char-regex": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/chokidar": { - "version": "3.5.3", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "packages/backend/jobs-manager/service/node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/ci-info": { - "version": "3.9.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/cjs-module-lexer": { - "version": "1.3.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/class-transformer": { - "version": "0.5.1", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/class-validator": { - "version": "0.14.1", - "license": "MIT", - "dependencies": { - "@types/validator": "^13.11.8", - "libphonenumber-js": "^1.10.53", - "validator": "^13.9.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/cli-table3": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/co": { - "version": "4.6.0", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/collect-v8-coverage": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/color-support": { - "version": "1.1.3", - "dev": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "packages/backend/jobs-manager/service/node_modules/commondir": { - "version": "1.0.1", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/component-emitter": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/concat-stream": { - "version": "1.6.2", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "packages/backend/jobs-manager/service/node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.8", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/consola": { - "version": "2.15.3", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/console-control-strings": { - "version": "1.1.0", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/cookiejar": { - "version": "2.1.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/cosmiconfig": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/create-jest": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/create-require": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/cron": { - "version": "2.3.1", - "license": "MIT", - "dependencies": { - "luxon": "^3.2.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/cron-validator": { - "version": "1.3.1", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/dedent": { - "version": "1.5.3", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/deep-is": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/delegates": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/detect-libc": { - "version": "2.0.3", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/detect-newline": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/dezalgo": { - "version": "1.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "packages/backend/jobs-manager/service/node_modules/diff": { - "version": "4.0.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/diff-sequences": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/doctrine": { - "version": "3.0.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/dot-object": { - "version": "2.1.5", - "license": "MIT", - "dependencies": { - "commander": "^6.1.0", - "glob": "^7.1.6" - }, - "bin": { - "dot-object": "bin/dot-object" - } - }, - "packages/backend/jobs-manager/service/node_modules/dot-object/node_modules/commander": { - "version": "6.2.1", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "packages/backend/jobs-manager/service/node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/ejs": { - "version": "3.1.10", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/emittery": { - "version": "0.13.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/end-of-stream": { - "version": "1.4.4", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/eslint": { - "version": "8.57.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/jobs-manager/service/node_modules/eslint-config-prettier": { - "version": "8.6.0", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/jobs-manager/service/node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/jobs-manager/service/node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/espree": { - "version": "9.6.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/backend/jobs-manager/service/node_modules/esquery": { - "version": "1.6.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "packages/backend/jobs-manager/service/node_modules/estraverse": { - "version": "5.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/eventemitter3": { - "version": "5.0.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/execa": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/execa/node_modules/get-stream": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/exit": { - "version": "0.1.2", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/expect": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/fast-diff": { - "version": "1.3.0", - "dev": true, - "license": "Apache-2.0" - }, - "packages/backend/jobs-manager/service/node_modules/fast-glob": { - "version": "3.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/fast-levenshtein": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/fast-safe-stringify": { - "version": "2.1.1", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/fastq": { - "version": "1.17.1", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/fb-watchman": { - "version": "2.0.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/fd-slicer": { - "version": "1.1.0", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/file-entry-cache": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/filelist": { - "version": "1.0.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/find-cache-dir": { - "version": "3.3.2", - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/find-up": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/find-up/node_modules/locate-path": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/find-up/node_modules/p-limit": { - "version": "2.3.0", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/find-up/node_modules/p-locate": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/flat-cache": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/backend/jobs-manager/service/node_modules/flatted": { - "version": "3.3.1", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/formidable": { - "version": "3.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "dezalgo": "^1.0.4", - "hexoid": "^1.0.0", - "once": "^1.4.0" - }, - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, - "packages/backend/jobs-manager/service/node_modules/fs-constants": { - "version": "1.0.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/backend/jobs-manager/service/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/gauge": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/get-package-type": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/get-port": { - "version": "5.1.1", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/glob": { - "version": "7.2.3", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/backend/jobs-manager/service/node_modules/globals": { - "version": "13.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/globby": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/graphemer": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/handlebars": { - "version": "4.7.8", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/has-unicode": { - "version": "2.0.1", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/hexoid": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/html-escaper": { - "version": "2.0.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/https-proxy-agent": { - "version": "5.0.1", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "packages/backend/jobs-manager/service/node_modules/https-proxy-agent/node_modules/agent-base": { - "version": "6.0.2", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/human-signals": { - "version": "1.1.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8.12.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/ignore": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "packages/backend/jobs-manager/service/node_modules/import-local": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "packages/backend/jobs-manager/service/node_modules/inquirer": { - "version": "8.2.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/interpret": { - "version": "1.4.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "packages/backend/jobs-manager/service/node_modules/ip-address": { - "version": "9.0.5", - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/backend/jobs-manager/service/node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/jobs-manager/service/node_modules/is-generator-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/is-path-inside": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/is-stream": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/backend/jobs-manager/service/node_modules/istanbul-lib-report": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/istanbul-reports": { - "version": "3.1.7", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/jake": { - "version": "10.9.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-changed-files": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-changed-files/node_modules/execa": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-changed-files/node_modules/human-signals": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-circus": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-circus/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-cli": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-config": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-diff": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-docblock": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-each": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-environment-node": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-environment-node/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-get-type": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-haste-map": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-haste-map/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-leak-detector": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-matcher-utils": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-message-util": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-mock": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-mock/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-regex-util": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-resolve": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-runner": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-runner/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-runner/node_modules/source-map-support": { - "version": "0.5.13", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-runtime": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-runtime/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-snapshot": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-util": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-util/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-validate": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-watcher": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-watcher/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-worker": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-worker/node_modules/@types/node": { - "version": "20.14.11", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/jsbn": { - "version": "1.1.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/json-buffer": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/jsonc-parser": { - "version": "3.2.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/jsonwebtoken": { - "version": "9.0.2", - "license": "MIT", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/jwa": { - "version": "1.4.1", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/jws": { - "version": "3.2.2", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/jwt-decode": { - "version": "3.1.2", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/kafkajs": { - "version": "2.2.4", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/kareem": { - "version": "2.5.1", - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/keyv": { - "version": "4.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/kleur": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/leven": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/levn": { - "version": "0.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/libphonenumber-js": { - "version": "1.11.4", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged": { - "version": "13.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "5.3.0", - "commander": "11.0.0", - "debug": "4.3.4", - "execa": "7.2.0", - "lilconfig": "2.1.0", - "listr2": "6.6.1", - "micromatch": "4.0.5", - "pidtree": "0.6.0", - "string-argv": "0.3.2", - "yaml": "2.3.1" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/commander": { - "version": "11.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/debug": { - "version": "4.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/execa": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/human-signals": { - "version": "4.3.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=14.18.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/is-stream": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/mimic-fn": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/npm-run-path": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/onetime": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/path-key": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/strip-final-newline": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/lint-staged/node_modules/yaml": { - "version": "2.3.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 14" - } - }, - "packages/backend/jobs-manager/service/node_modules/listr2": { - "version": "6.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^5.0.1", - "rfdc": "^1.3.0", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/listr2/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/listr2/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/listr2/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/listr2/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/listr2/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/listr2/node_modules/wrap-ansi": { - "version": "8.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/locate-path": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/lodash.includes": { - "version": "4.3.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lodash.isboolean": { - "version": "3.0.3", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lodash.isinteger": { - "version": "4.0.4", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lodash.isnumber": { - "version": "3.0.3", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lodash.isplainobject": { - "version": "4.0.6", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lodash.isstring": { - "version": "4.0.1", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lodash.memoize": { - "version": "4.1.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lodash.merge": { - "version": "4.6.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/lodash.once": { - "version": "4.1.1", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/log-update": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^5.0.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^5.0.0", - "strip-ansi": "^7.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/ansi-escapes": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/cli-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/restore-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/type-fest": { - "version": "1.4.0", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/log-update/node_modules/wrap-ansi": { - "version": "8.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/loglevel": { - "version": "1.9.1", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/loglevel" - } - }, - "packages/backend/jobs-manager/service/node_modules/luxon": { - "version": "3.4.4", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "packages/backend/jobs-manager/service/node_modules/macos-release": { - "version": "2.5.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/magic-string": { - "version": "0.30.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, - "packages/backend/jobs-manager/service/node_modules/make-dir": { - "version": "3.1.0", - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/backend/jobs-manager/service/node_modules/make-error": { - "version": "1.3.6", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/makeerror": { - "version": "1.0.12", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "packages/backend/jobs-manager/service/node_modules/md5-file": { - "version": "5.0.0", - "license": "MIT", - "bin": { - "md5-file": "cli.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/memory-pager": { - "version": "1.5.0", - "license": "MIT", - "optional": true - }, - "packages/backend/jobs-manager/service/node_modules/merge2": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/backend/jobs-manager/service/node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "packages/backend/jobs-manager/service/node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/backend/jobs-manager/service/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/mongodb": { - "version": "4.17.2", - "license": "Apache-2.0", - "dependencies": { - "bson": "^4.7.2", - "mongodb-connection-string-url": "^2.6.0", - "socks": "^2.7.1" - }, - "engines": { - "node": ">=12.9.0" - }, - "optionalDependencies": { - "@aws-sdk/credential-providers": "^3.186.0", - "@mongodb-js/saslprep": "^1.1.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/mongodb-connection-string-url": { - "version": "2.6.0", - "license": "Apache-2.0", - "dependencies": { - "@types/whatwg-url": "^8.2.1", - "whatwg-url": "^11.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/mongodb-connection-string-url/node_modules/tr46": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "packages/backend/jobs-manager/service/node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { - "version": "7.0.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "packages/backend/jobs-manager/service/node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { - "version": "11.0.0", - "license": "MIT", - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "packages/backend/jobs-manager/service/node_modules/mongodb-memory-server": { - "version": "8.16.1", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "mongodb-memory-server-core": "8.16.1", - "tslib": "^2.6.1" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/mongodb-memory-server-core": { - "version": "8.16.1", - "license": "MIT", - "dependencies": { - "async-mutex": "^0.3.2", - "camelcase": "^6.3.0", - "debug": "^4.3.4", - "find-cache-dir": "^3.3.2", - "follow-redirects": "^1.15.2", - "get-port": "^5.1.1", - "https-proxy-agent": "^5.0.1", - "md5-file": "^5.0.0", - "mongodb": "^4.16.0", - "new-find-package-json": "^2.0.0", - "semver": "^7.5.4", - "tar-stream": "^2.1.4", - "tslib": "^2.6.1", - "uuid": "^9.0.0", - "yauzl": "^2.10.0" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/mongoose": { - "version": "6.13.0", - "license": "MIT", - "dependencies": { - "bson": "^4.7.2", - "kareem": "2.5.1", - "mongodb": "4.17.2", - "mpath": "0.9.0", - "mquery": "4.0.3", - "ms": "2.1.3", - "sift": "16.0.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mongoose" - } - }, - "packages/backend/jobs-manager/service/node_modules/mpath": { - "version": "0.9.0", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/mquery": { - "version": "4.0.3", - "license": "MIT", - "dependencies": { - "debug": "4.x" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/ms": { - "version": "2.1.3", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/multer": { - "version": "1.4.4-lts.1", - "license": "MIT", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/multer/node_modules/mkdirp": { - "version": "0.5.6", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "packages/backend/jobs-manager/service/node_modules/natural-compare": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/natural-compare-lite": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/new-find-package-json": { - "version": "2.0.0", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/node-addon-api": { - "version": "5.1.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/node-int64": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/npm-run-path": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/npmlog": { - "version": "5.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/object-hash": { - "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "packages/backend/jobs-manager/service/node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/optionator": { - "version": "0.9.4", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/os-name": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "macos-release": "^2.5.0", - "windows-release": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/p-limit": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/p-locate": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/p-try": { - "version": "2.2.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/passport": { - "version": "0.6.0", - "license": "MIT", - "dependencies": { - "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "packages/backend/jobs-manager/service/node_modules/passport-jwt": { - "version": "4.0.1", - "license": "MIT", - "dependencies": { - "jsonwebtoken": "^9.0.0", - "passport-strategy": "^1.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/passport-local": { - "version": "1.0.0", - "dependencies": { - "passport-strategy": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/passport-unique-token": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "passport-strategy": "^1.0.0" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/backend/jobs-manager/service/node_modules/path-exists": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/path-to-regexp": { - "version": "3.2.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/pend": { - "version": "1.2.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/picomatch": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "packages/backend/jobs-manager/service/node_modules/pirates": { - "version": "4.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "packages/backend/jobs-manager/service/node_modules/pkg-dir": { - "version": "4.2.0", - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/prelude-ls": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/prettier": { - "version": "2.8.8", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/pretty-format": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/prompts": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "packages/backend/jobs-manager/service/node_modules/pump": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "packages/backend/jobs-manager/service/node_modules/pure-rand": { - "version": "6.1.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/queue-microtask": { - "version": "1.2.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/raw-body": { - "version": "2.5.2", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "packages/backend/jobs-manager/service/node_modules/react-is": { - "version": "18.3.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/rechoir": { - "version": "0.6.2", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "packages/backend/jobs-manager/service/node_modules/reflect-metadata": { - "version": "0.1.14", - "license": "Apache-2.0" - }, - "packages/backend/jobs-manager/service/node_modules/resolve": { - "version": "1.22.8", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/jobs-manager/service/node_modules/resolve-cwd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/resolve.exports": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/reusify": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/rimraf": { - "version": "4.4.1", - "license": "ISC", - "dependencies": { - "glob": "^9.2.0" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/backend/jobs-manager/service/node_modules/rimraf/node_modules/glob": { - "version": "9.3.5", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/backend/jobs-manager/service/node_modules/rimraf/node_modules/minimatch": { - "version": "8.0.4", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/backend/jobs-manager/service/node_modules/rimraf/node_modules/minipass": { - "version": "4.2.8", - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/run-parallel": { - "version": "1.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "packages/backend/jobs-manager/service/node_modules/set-blocking": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/shelljs": { - "version": "0.8.5", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "packages/backend/jobs-manager/service/node_modules/sift": { - "version": "16.0.1", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/sisteransi": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/smart-buffer": { - "version": "4.2.0", - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/socks": { - "version": "2.8.3", - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/source-map": { - "version": "0.6.1", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/sparse-bitfield": { - "version": "3.0.3", - "license": "MIT", - "optional": true, - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "packages/backend/jobs-manager/service/node_modules/sprintf-js": { - "version": "1.1.3", - "license": "BSD-3-Clause" - }, - "packages/backend/jobs-manager/service/node_modules/stack-utils": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/streamsearch": { - "version": "1.1.0", - "engines": { - "node": ">=10.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/string-length": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/strip-final-newline": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/strip-json-comments": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/superagent": { - "version": "9.0.1", - "dev": true, - "license": "MIT", - "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" - } - }, - "packages/backend/jobs-manager/service/node_modules/superagent/node_modules/qs": { - "version": "6.12.3", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/jobs-manager/service/node_modules/supertest": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "methods": "^1.1.2", - "superagent": "^9.0.1" - }, - "engines": { - "node": ">=14.18.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/backend/jobs-manager/service/node_modules/tar": { - "version": "6.2.1", - "dev": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/backend/jobs-manager/service/node_modules/tar-stream": { - "version": "2.2.0", - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/test-exclude": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "packages/backend/jobs-manager/service/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/tmpl": { - "version": "1.0.5", - "dev": true, - "license": "BSD-3-Clause" - }, - "packages/backend/jobs-manager/service/node_modules/ts-jest": { - "version": "29.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "ejs": "^3.1.10", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/transform": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/ts-loader": { - "version": "9.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "packages/backend/jobs-manager/service/node_modules/ts-node": { - "version": "10.9.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "packages/backend/jobs-manager/service/node_modules/tsconfig-paths-webpack-plugin": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.7.0", - "tsconfig-paths": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/tsutils": { - "version": "3.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "packages/backend/jobs-manager/service/node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "dev": true, - "license": "0BSD" - }, - "packages/backend/jobs-manager/service/node_modules/type-check": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/type-detect": { - "version": "4.0.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "packages/backend/jobs-manager/service/node_modules/typedarray": { - "version": "0.0.6", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/typescript": { - "version": "4.9.5", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/undici-types": { - "version": "5.26.5", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/v8-to-istanbul": { - "version": "9.3.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/validator": { - "version": "13.12.0", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "packages/backend/jobs-manager/service/node_modules/walker": { - "version": "1.0.8", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "packages/backend/jobs-manager/service/node_modules/wide-align": { - "version": "1.1.5", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "packages/backend/jobs-manager/service/node_modules/windows-release": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^4.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/backend/jobs-manager/service/node_modules/word-wrap": { - "version": "1.2.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/wordwrap": { - "version": "1.0.0", - "license": "MIT" - }, - "packages/backend/jobs-manager/service/node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/backend/jobs-manager/service/node_modules/write-file-atomic": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/xtend": { - "version": "4.0.2", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "packages/backend/jobs-manager/service/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "packages/backend/jobs-manager/service/node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "packages/backend/jobs-manager/service/node_modules/yauzl": { - "version": "2.10.0", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "packages/backend/jobs-manager/service/node_modules/yn": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/backend/jobs-manager/service/node_modules/yocto-queue": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app": { - "name": "@red-kite/stalker-app", - "version": "0.0.0", - "dependencies": { - "@angular-material-components/color-picker": "^16.0.1", - "@angular/animations": "^17.0.8", - "@angular/cdk": "^17.0.4", - "@angular/common": "^17.0.8", - "@angular/compiler": "^17.0.8", - "@angular/core": "^17.0.8", - "@angular/forms": "^17.0.8", - "@angular/material": "^17.0.4", - "@angular/material-moment-adapter": "^17.2.0", - "@angular/platform-browser": "^17.0.8", - "@angular/platform-browser-dynamic": "^17.0.8", - "@angular/router": "^17.0.8", - "@types/angular-material": "^1.1.73", - "ip-address": "^9.0.5", - "jwt-decode": "^4.0.0", - "moment": "^2.30.1", - "monaco-editor": "^0.45.0", - "ngx-file-drop": "^16.0.0", - "ngx-socket-io": "~4.5.0", - "ngx-toastr": "~16.2.0", - "prettier": "^3.1.1", - "rxjs": "~7.8.1", - "ts-md5": "^1.3.1", - "tslib": "^2.3.0", - "yaml": "^2.3.4", - "zone.js": "~0.14.2" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^17.0.8", - "@angular/cli": "^17.0.8", - "@angular/compiler-cli": "^17.0.8", - "@angular/localize": "^17.0.8", - "@types/jasmine": "~3.10.0", - "@types/jsbn": "^1.2.30", - "@types/md5": "^2.3.2", - "@types/node": "^12.11.1", - "@typescript-eslint/eslint-plugin": "^6.16.0", - "@typescript-eslint/parser": "^6.16.0", - "autoprefixer": "^10.4.16", - "eslint": "^8.56.0", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-prettier": "^5.1.2", - "jasmine-core": "~5.1.1", - "karma": "~6.4.2", - "karma-chrome-launcher": "~3.2.0", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.1.0", - "lint-staged": "^15.2.0", - "postcss": "^8.4.32", - "tailwindcss": "^3.4.0", - "typemoq": "^2.1.0", - "typescript": "~5.2.0" - } - }, - "packages/frontend/stalker-app/node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/architect": { - "version": "0.1703.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "17.3.8", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular": { - "version": "17.3.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.3.9.tgz", - "integrity": "sha512-EuAPSC4c2DSJLlL4ieviKLx1faTyY+ymWycq6KFwoxu1FgWly/dqBeWyXccYinLhPVZmoh6+A/5S4YWXlOGSnA==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1703.9", - "@angular-devkit/build-webpack": "0.1703.9", - "@angular-devkit/core": "17.3.9", - "@babel/core": "7.24.0", - "@babel/generator": "7.23.6", - "@babel/helper-annotate-as-pure": "7.22.5", - "@babel/helper-split-export-declaration": "7.22.6", - "@babel/plugin-transform-async-generator-functions": "7.23.9", - "@babel/plugin-transform-async-to-generator": "7.23.3", - "@babel/plugin-transform-runtime": "7.24.0", - "@babel/preset-env": "7.24.0", - "@babel/runtime": "7.24.0", - "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "17.3.9", - "@vitejs/plugin-basic-ssl": "1.1.0", - "ansi-colors": "4.1.3", - "autoprefixer": "10.4.18", - "babel-loader": "9.1.3", - "babel-plugin-istanbul": "6.1.1", - "browserslist": "^4.21.5", - "copy-webpack-plugin": "11.0.0", - "critters": "0.0.22", - "css-loader": "6.10.0", - "esbuild-wasm": "0.20.1", - "fast-glob": "3.3.2", - "http-proxy-middleware": "2.0.6", - "https-proxy-agent": "7.0.4", - "inquirer": "9.2.15", - "jsonc-parser": "3.2.1", - "karma-source-map-support": "1.4.0", - "less": "4.2.0", - "less-loader": "11.1.0", - "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.1", - "magic-string": "0.30.8", - "mini-css-extract-plugin": "2.8.1", - "mrmime": "2.0.0", - "open": "8.4.2", - "ora": "5.4.1", - "parse5-html-rewriting-stream": "7.0.0", - "picomatch": "4.0.1", - "piscina": "4.4.0", - "postcss": "8.4.35", - "postcss-loader": "8.1.1", - "resolve-url-loader": "5.0.0", - "rxjs": "7.8.1", - "sass": "1.71.1", - "sass-loader": "14.1.1", - "semver": "7.6.0", - "source-map-loader": "5.0.0", - "source-map-support": "0.5.21", - "terser": "5.29.1", - "tree-kill": "1.2.2", - "tslib": "2.6.2", - "undici": "6.11.1", - "vite": "5.1.7", - "watchpack": "2.4.0", - "webpack": "5.94.0", - "webpack-dev-middleware": "6.1.2", - "webpack-dev-server": "4.15.1", - "webpack-merge": "5.10.0", - "webpack-subresource-integrity": "5.1.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "optionalDependencies": { - "esbuild": "0.20.1" - }, - "peerDependencies": { - "@angular/compiler-cli": "^17.0.0", - "@angular/localize": "^17.0.0", - "@angular/platform-server": "^17.0.0", - "@angular/service-worker": "^17.0.0", - "@web/test-runner": "^0.18.0", - "browser-sync": "^3.0.2", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "karma": "^6.3.0", - "ng-packagr": "^17.0.0", - "protractor": "^7.0.0", - "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=5.2 <5.5" - }, - "peerDependenciesMeta": { - "@angular/localize": { - "optional": true - }, - "@angular/platform-server": { - "optional": true - }, - "@angular/service-worker": { - "optional": true - }, - "@web/test-runner": { - "optional": true - }, - "browser-sync": { - "optional": true - }, - "jest": { - "optional": true - }, - "jest-environment-jsdom": { - "optional": true - }, - "karma": { - "optional": true - }, - "ng-packagr": { - "optional": true - }, - "protractor": { - "optional": true - }, - "tailwindcss": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { - "version": "0.1703.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.9.tgz", - "integrity": "sha512-kEPfTOVnzrJxPGTvaXy8653HU9Fucxttx9gVfQR1yafs+yIEGx3fKGKe89YPmaEay32bIm7ZUpxDF1FO14nkdQ==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "17.3.9", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "17.3.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.9.tgz", - "integrity": "sha512-/iKyn5YT7NW5ylrg9yufUydS8byExeQ2HHIwFC4Ebwb/JYYCz+k4tBf2LdP+zXpemDpLznXTQGWia0/yJjG8Vg==", - "dev": true, - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/@babel/generator": { - "version": "7.23.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/autoprefixer": { - "version": "10.4.18", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001591", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/https-proxy-agent": { - "version": "7.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/loader-utils": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/postcss": { - "version": "8.4.35", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/postcss-loader": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cosmiconfig": "^9.0.0", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/postcss-loader/node_modules/semver": { - "version": "7.6.3", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/semver": { - "version": "7.6.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/@angular-devkit/build-angular/node_modules/tslib": { - "version": "2.6.2", - "dev": true, - "license": "0BSD" - }, - "packages/frontend/stalker-app/node_modules/@angular-material-components/color-picker": { - "version": "16.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/cdk": "^16.0.0", - "@angular/common": "^16.0.0", - "@angular/core": "^16.0.0", - "@angular/forms": "^16.0.0", - "@angular/material": "^16.0.0", - "@angular/platform-browser": "^16.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/animations": { - "version": "17.3.12", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/core": "17.3.12" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cdk": { - "version": "17.3.10", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "optionalDependencies": { - "parse5": "^7.1.2" - }, - "peerDependencies": { - "@angular/common": "^17.0.0 || ^18.0.0", - "@angular/core": "^17.0.0 || ^18.0.0", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli": { - "version": "17.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/architect": "0.1703.8", - "@angular-devkit/core": "17.3.8", - "@angular-devkit/schematics": "17.3.8", - "@schematics/angular": "17.3.8", - "@yarnpkg/lockfile": "1.1.0", - "ansi-colors": "4.1.3", - "ini": "4.1.2", - "inquirer": "9.2.15", - "jsonc-parser": "3.2.1", - "npm-package-arg": "11.0.1", - "npm-pick-manifest": "9.0.0", - "open": "8.4.2", - "ora": "5.4.1", - "pacote": "17.0.6", - "resolve": "1.22.8", - "semver": "7.6.0", - "symbol-observable": "4.0.0", - "yargs": "17.7.2" - }, - "bin": { - "ng": "bin/ng.js" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli/node_modules/npm-package-arg": { - "version": "11.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli/node_modules/npm-package-arg/node_modules/proc-log": { - "version": "3.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli/node_modules/npm-package-arg/node_modules/semver": { - "version": "7.6.3", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli/node_modules/npm-pick-manifest": { - "version": "9.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli/node_modules/npm-pick-manifest/node_modules/npm-package-arg": { - "version": "11.0.3", - "dev": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli/node_modules/npm-pick-manifest/node_modules/semver": { - "version": "7.6.3", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/cli/node_modules/semver": { - "version": "7.6.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/common": { - "version": "17.3.12", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/core": "17.3.12", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/core": { - "version": "17.3.12", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "rxjs": "^6.5.3 || ^7.4.0", - "zone.js": "~0.14.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/forms": { - "version": "17.3.12", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/common": "17.3.12", - "@angular/core": "17.3.12", - "@angular/platform-browser": "17.3.12", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/localize": { - "version": "17.3.12", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "7.23.9", - "@types/babel__core": "7.20.5", - "fast-glob": "3.3.2", - "yargs": "^17.2.1" - }, - "bin": { - "localize-extract": "tools/bundles/src/extract/cli.js", - "localize-migrate": "tools/bundles/src/migrate/cli.js", - "localize-translate": "tools/bundles/src/translate/cli.js" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/compiler": "17.3.12", - "@angular/compiler-cli": "17.3.12" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/localize/node_modules/@babel/core": { - "version": "7.23.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/localize/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/material": { - "version": "17.3.10", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/auto-init": "15.0.0-canary.7f224ddd4.0", - "@material/banner": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/button": "15.0.0-canary.7f224ddd4.0", - "@material/card": "15.0.0-canary.7f224ddd4.0", - "@material/checkbox": "15.0.0-canary.7f224ddd4.0", - "@material/chips": "15.0.0-canary.7f224ddd4.0", - "@material/circular-progress": "15.0.0-canary.7f224ddd4.0", - "@material/data-table": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dialog": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/drawer": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/fab": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/floating-label": "15.0.0-canary.7f224ddd4.0", - "@material/form-field": "15.0.0-canary.7f224ddd4.0", - "@material/icon-button": "15.0.0-canary.7f224ddd4.0", - "@material/image-list": "15.0.0-canary.7f224ddd4.0", - "@material/layout-grid": "15.0.0-canary.7f224ddd4.0", - "@material/line-ripple": "15.0.0-canary.7f224ddd4.0", - "@material/linear-progress": "15.0.0-canary.7f224ddd4.0", - "@material/list": "15.0.0-canary.7f224ddd4.0", - "@material/menu": "15.0.0-canary.7f224ddd4.0", - "@material/menu-surface": "15.0.0-canary.7f224ddd4.0", - "@material/notched-outline": "15.0.0-canary.7f224ddd4.0", - "@material/radio": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/segmented-button": "15.0.0-canary.7f224ddd4.0", - "@material/select": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/slider": "15.0.0-canary.7f224ddd4.0", - "@material/snackbar": "15.0.0-canary.7f224ddd4.0", - "@material/switch": "15.0.0-canary.7f224ddd4.0", - "@material/tab": "15.0.0-canary.7f224ddd4.0", - "@material/tab-bar": "15.0.0-canary.7f224ddd4.0", - "@material/tab-indicator": "15.0.0-canary.7f224ddd4.0", - "@material/tab-scroller": "15.0.0-canary.7f224ddd4.0", - "@material/textfield": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tooltip": "15.0.0-canary.7f224ddd4.0", - "@material/top-app-bar": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/animations": "^17.0.0 || ^18.0.0", - "@angular/cdk": "17.3.10", - "@angular/common": "^17.0.0 || ^18.0.0", - "@angular/core": "^17.0.0 || ^18.0.0", - "@angular/forms": "^17.0.0 || ^18.0.0", - "@angular/platform-browser": "^17.0.0 || ^18.0.0", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/material-moment-adapter": { - "version": "17.3.10", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/core": "^17.0.0 || ^18.0.0", - "@angular/material": "17.3.10", - "moment": "^2.18.1" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/platform-browser": { - "version": "17.3.12", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/animations": "17.3.12", - "@angular/common": "17.3.12", - "@angular/core": "17.3.12" - }, - "peerDependenciesMeta": { - "@angular/animations": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/@angular/platform-browser-dynamic": { - "version": "17.3.12", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/common": "17.3.12", - "@angular/compiler": "17.3.12", - "@angular/core": "17.3.12", - "@angular/platform-browser": "17.3.12" - } - }, - "packages/frontend/stalker-app/node_modules/@angular/router": { - "version": "17.3.12", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/common": "17.3.12", - "@angular/core": "17.3.12", - "@angular/platform-browser": "17.3.12", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/core": { - "version": "7.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.0", - "@babel/parser": "^7.24.0", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.0", - "@babel/types": "^7.24.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-classes": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-destructuring/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-simple-access": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-modules-commonjs/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-optional-chaining/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-runtime/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-typeof-symbol/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/preset-env": { - "version": "7.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.9", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.9", - "@babel/plugin-transform-modules-umd": "^7.23.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.24.0", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/preset-env/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@babel/regjsgen": { - "version": "0.8.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/@babel/runtime": { - "version": "7.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@esbuild/linux-x64": { - "version": "0.20.1", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "packages/frontend/stalker-app/node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/frontend/stalker-app/node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "packages/frontend/stalker-app/node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/@eslint/js": { - "version": "8.56.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "packages/frontend/stalker-app/node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "packages/frontend/stalker-app/node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/@material/animation": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/auto-init": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/banner": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/button": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/base": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/button": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/card": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/checkbox": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/chips": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/checkbox": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "safevalues": "^0.3.4", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/circular-progress": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/progress-indicator": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/data-table": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/checkbox": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/icon-button": "15.0.0-canary.7f224ddd4.0", - "@material/linear-progress": "15.0.0-canary.7f224ddd4.0", - "@material/list": "15.0.0-canary.7f224ddd4.0", - "@material/menu": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/select": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/density": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/dialog": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/button": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/icon-button": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/dom": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/drawer": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/list": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/elevation": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/fab": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/feature-targeting": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/floating-label": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/focus-ring": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/form-field": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/icon-button": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/image-list": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/layout-grid": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/line-ripple": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/linear-progress": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/progress-indicator": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/list": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/menu": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/list": "15.0.0-canary.7f224ddd4.0", - "@material/menu-surface": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/menu-surface": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/notched-outline": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/floating-label": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/progress-indicator": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/radio": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/ripple": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/rtl": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/segmented-button": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/touch-target": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/select": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/floating-label": "15.0.0-canary.7f224ddd4.0", - "@material/line-ripple": "15.0.0-canary.7f224ddd4.0", - "@material/list": "15.0.0-canary.7f224ddd4.0", - "@material/menu": "15.0.0-canary.7f224ddd4.0", - "@material/menu-surface": "15.0.0-canary.7f224ddd4.0", - "@material/notched-outline": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/shape": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/slider": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/snackbar": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/button": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/icon-button": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/switch": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "safevalues": "^0.3.4", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/tab": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/focus-ring": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/tab-indicator": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/tab-bar": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/tab": "15.0.0-canary.7f224ddd4.0", - "@material/tab-indicator": "15.0.0-canary.7f224ddd4.0", - "@material/tab-scroller": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/tab-indicator": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/tab-scroller": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/tab": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/textfield": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/density": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/floating-label": "15.0.0-canary.7f224ddd4.0", - "@material/line-ripple": "15.0.0-canary.7f224ddd4.0", - "@material/notched-outline": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/theme": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/tokens": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/elevation": "15.0.0-canary.7f224ddd4.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/tooltip": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/button": "15.0.0-canary.7f224ddd4.0", - "@material/dom": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/tokens": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "safevalues": "^0.3.4", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/top-app-bar": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/animation": "15.0.0-canary.7f224ddd4.0", - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/elevation": "15.0.0-canary.7f224ddd4.0", - "@material/ripple": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/shape": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "@material/typography": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/touch-target": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/base": "15.0.0-canary.7f224ddd4.0", - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/rtl": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@material/typography": { - "version": "15.0.0-canary.7f224ddd4.0", - "license": "MIT", - "dependencies": { - "@material/feature-targeting": "15.0.0-canary.7f224ddd4.0", - "@material/theme": "15.0.0-canary.7f224ddd4.0", - "tslib": "^2.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/agent": { - "version": "2.2.2", - "dev": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/fs": { - "version": "3.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/git": { - "version": "5.0.8", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "ini": "^4.1.3", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^4.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/git/node_modules/ini": { - "version": "4.1.3", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/installed-package-contents": { - "version": "2.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "bin": { - "installed-package-contents": "bin/index.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/node-gyp": { - "version": "3.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/package-json": { - "version": "5.2.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^4.0.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/promise-spawn": { - "version": "7.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/redact": { - "version": "1.1.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@npmcli/run-script": { - "version": "7.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@pkgr/core": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "packages/frontend/stalker-app/node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.19.0", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "packages/frontend/stalker-app/node_modules/@schematics/angular": { - "version": "17.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "17.3.8", - "@angular-devkit/schematics": "17.3.8", - "jsonc-parser": "3.2.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "packages/frontend/stalker-app/node_modules/@sigstore/bundle": { - "version": "2.3.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@sigstore/core": { - "version": "1.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@sigstore/protobuf-specs": { - "version": "0.3.2", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@sigstore/sign": { - "version": "2.3.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^13.0.1", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@sigstore/tuf": { - "version": "2.3.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2", - "tuf-js": "^2.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@sigstore/verify": { - "version": "1.2.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@tufjs/models": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@tufjs/models/node_modules/minimatch": { - "version": "9.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/frontend/stalker-app/node_modules/@types/angular": { - "version": "1.8.9", - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/@types/angular-material": { - "version": "1.1.77", - "license": "MIT", - "dependencies": { - "@types/angular": "*" - } - }, - "packages/frontend/stalker-app/node_modules/@types/babel__core": { - "version": "7.20.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "packages/frontend/stalker-app/node_modules/@types/babel__generator": { - "version": "7.6.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@types/babel__template": { - "version": "7.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@types/babel__traverse": { - "version": "7.20.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "packages/frontend/stalker-app/node_modules/@types/eslint": { - "version": "9.6.0", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "packages/frontend/stalker-app/node_modules/@types/jasmine": { - "version": "3.10.18", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/@types/jsbn": { - "version": "1.2.33", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/@types/md5": { - "version": "2.3.5", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/@types/node": { - "version": "12.20.55", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/@types/semver": { - "version": "7.5.7", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/frontend/stalker-app/node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "dev": true, - "license": "ISC" - }, - "packages/frontend/stalker-app/node_modules/@vitejs/plugin-basic-ssl": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.6.0" - }, - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "dev": true, - "license": "BSD-2-Clause" - }, - "packages/frontend/stalker-app/node_modules/acorn-jsx": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/adjust-sourcemap-loader": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, - "engines": { - "node": ">=8.9" - } - }, - "packages/frontend/stalker-app/node_modules/agent-base": { - "version": "7.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "packages/frontend/stalker-app/node_modules/ajv": { - "version": "8.17.1", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "packages/frontend/stalker-app/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/any-promise": { - "version": "1.3.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/arg": { - "version": "5.0.2", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/autoprefixer": { - "version": "10.4.19", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/babel-loader": { - "version": "9.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "packages/frontend/stalker-app/node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/babel-plugin-polyfill-corejs2/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/frontend/stalker-app/node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0", - "core-js-compat": "^3.34.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/big.js": { - "version": "5.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "packages/frontend/stalker-app/node_modules/body-parser": { - "version": "1.20.2", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "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.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "packages/frontend/stalker-app/node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/cacache": { - "version": "18.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/camelcase": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/frontend/stalker-app/node_modules/camelcase-css": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "packages/frontend/stalker-app/node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/circular-json": { - "version": "0.3.3", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/cli-truncate": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "10.3.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/cli-truncate/node_modules/string-width": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/cli-width": { - "version": "4.1.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 12" - } - }, - "packages/frontend/stalker-app/node_modules/clone-deep": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "packages/frontend/stalker-app/node_modules/commander": { - "version": "2.20.3", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/common-path-prefix": { - "version": "3.0.0", - "dev": true, - "license": "ISC" - }, - "packages/frontend/stalker-app/node_modules/connect": { - "version": "3.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/cookie": { - "version": "0.4.2", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "packages/frontend/stalker-app/node_modules/copy-anything": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-what": "^3.14.1" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "packages/frontend/stalker-app/node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/core-js": { - "version": "3.37.1", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "packages/frontend/stalker-app/node_modules/core-js-compat": { - "version": "3.37.1", - "dev": true, - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "packages/frontend/stalker-app/node_modules/cosmiconfig": { - "version": "9.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/critters": { - "version": "0.0.22", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "chalk": "^4.1.0", - "css-select": "^5.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.2", - "htmlparser2": "^8.0.2", - "postcss": "^8.4.23", - "postcss-media-query-parser": "^0.2.3" - } - }, - "packages/frontend/stalker-app/node_modules/css-loader": { - "version": "6.10.0", - "dev": true, - "license": "MIT", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.4", - "postcss-modules-scope": "^3.1.1", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/cssesc": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/custom-event": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/date-format": { - "version": "4.0.14", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "packages/frontend/stalker-app/node_modules/deep-is": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/di": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/didyoumean": { - "version": "1.2.2", - "dev": true, - "license": "Apache-2.0" - }, - "packages/frontend/stalker-app/node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/dlv": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/doctrine": { - "version": "3.0.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/dom-serialize": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/emojis-list": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "packages/frontend/stalker-app/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "packages/frontend/stalker-app/node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/engine.io": { - "version": "6.5.5", - "license": "MIT", - "dependencies": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "packages/frontend/stalker-app/node_modules/engine.io-client": { - "version": "6.5.4", - "license": "MIT", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/engine.io-parser": { - "version": "5.2.3", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/engine.io/node_modules/@types/node": { - "version": "20.14.11", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "packages/frontend/stalker-app/node_modules/ent": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^1.4.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "packages/frontend/stalker-app/node_modules/ent/node_modules/punycode": { - "version": "1.4.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/frontend/stalker-app/node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/errno": { - "version": "0.1.8", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "packages/frontend/stalker-app/node_modules/esbuild": { - "version": "0.20.1", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.1", - "@esbuild/android-arm": "0.20.1", - "@esbuild/android-arm64": "0.20.1", - "@esbuild/android-x64": "0.20.1", - "@esbuild/darwin-arm64": "0.20.1", - "@esbuild/darwin-x64": "0.20.1", - "@esbuild/freebsd-arm64": "0.20.1", - "@esbuild/freebsd-x64": "0.20.1", - "@esbuild/linux-arm": "0.20.1", - "@esbuild/linux-arm64": "0.20.1", - "@esbuild/linux-ia32": "0.20.1", - "@esbuild/linux-loong64": "0.20.1", - "@esbuild/linux-mips64el": "0.20.1", - "@esbuild/linux-ppc64": "0.20.1", - "@esbuild/linux-riscv64": "0.20.1", - "@esbuild/linux-s390x": "0.20.1", - "@esbuild/linux-x64": "0.20.1", - "@esbuild/netbsd-x64": "0.20.1", - "@esbuild/openbsd-x64": "0.20.1", - "@esbuild/sunos-x64": "0.20.1", - "@esbuild/win32-arm64": "0.20.1", - "@esbuild/win32-ia32": "0.20.1", - "@esbuild/win32-x64": "0.20.1" - } - }, - "packages/frontend/stalker-app/node_modules/esbuild-wasm": { - "version": "0.20.1", - "dev": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - } - }, - "packages/frontend/stalker-app/node_modules/eslint": { - "version": "8.56.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/frontend/stalker-app/node_modules/eslint-config-prettier": { - "version": "9.1.0", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/eslint-plugin-prettier": { - "version": "5.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/eslint-scope": { - "version": "7.2.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/frontend/stalker-app/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/frontend/stalker-app/node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "packages/frontend/stalker-app/node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/espree": { - "version": "9.6.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/frontend/stalker-app/node_modules/esquery": { - "version": "1.6.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "packages/frontend/stalker-app/node_modules/estraverse": { - "version": "5.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "packages/frontend/stalker-app/node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/execa": { - "version": "8.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/execa/node_modules/mimic-fn": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/execa/node_modules/onetime": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/execa/node_modules/signal-exit": { - "version": "4.1.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/frontend/stalker-app/node_modules/exponential-backoff": { - "version": "3.1.1", - "dev": true, - "license": "Apache-2.0" - }, - "packages/frontend/stalker-app/node_modules/extend": { - "version": "3.0.2", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/fast-diff": { - "version": "1.3.0", - "dev": true, - "license": "Apache-2.0" - }, - "packages/frontend/stalker-app/node_modules/fast-glob": { - "version": "3.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "packages/frontend/stalker-app/node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "packages/frontend/stalker-app/node_modules/fast-levenshtein": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/fast-uri": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/fastq": { - "version": "1.17.1", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "packages/frontend/stalker-app/node_modules/file-entry-cache": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/finalhandler": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "packages/frontend/stalker-app/node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/finalhandler/node_modules/on-finished": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "packages/frontend/stalker-app/node_modules/finalhandler/node_modules/statuses": { - "version": "1.5.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "packages/frontend/stalker-app/node_modules/find-cache-dir": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/find-up": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/flat": { - "version": "5.0.2", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "packages/frontend/stalker-app/node_modules/flat-cache": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/flatted": { - "version": "3.3.1", - "dev": true, - "license": "ISC" - }, - "packages/frontend/stalker-app/node_modules/fraction.js": { - "version": "4.3.7", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "packages/frontend/stalker-app/node_modules/fs-extra": { - "version": "8.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "packages/frontend/stalker-app/node_modules/fs-minipass": { - "version": "3.0.3", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/get-east-asian-width": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/get-package-type": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/get-stream": { - "version": "8.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/glob": { - "version": "10.4.5", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/frontend/stalker-app/node_modules/glob-parent": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "packages/frontend/stalker-app/node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/frontend/stalker-app/node_modules/globby": { - "version": "13.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/graphemer": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/hosted-git-info": { - "version": "7.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/html-escaper": { - "version": "2.0.2", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/http-cache-semantics": { - "version": "4.1.1", - "dev": true, - "license": "BSD-2-Clause" - }, - "packages/frontend/stalker-app/node_modules/http-proxy-agent": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "packages/frontend/stalker-app/node_modules/https-proxy-agent": { - "version": "7.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "packages/frontend/stalker-app/node_modules/human-signals": { - "version": "5.0.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=16.17.0" - } - }, - "packages/frontend/stalker-app/node_modules/icss-utils": { - "version": "5.1.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/ignore": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "packages/frontend/stalker-app/node_modules/ignore-walk": { - "version": "6.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/ignore-walk/node_modules/minimatch": { - "version": "9.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/frontend/stalker-app/node_modules/image-size": { - "version": "0.5.5", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/immutable": { - "version": "4.3.7", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "packages/frontend/stalker-app/node_modules/ini": { - "version": "4.1.2", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/inquirer": { - "version": "9.2.15", - "dev": true, - "license": "MIT", - "dependencies": { - "@ljharb/through": "^2.3.12", - "ansi-escapes": "^4.3.2", - "chalk": "^5.3.0", - "cli-cursor": "^3.1.0", - "cli-width": "^4.1.0", - "external-editor": "^3.1.0", - "figures": "^3.2.0", - "lodash": "^4.17.21", - "mute-stream": "1.0.0", - "ora": "^5.4.1", - "run-async": "^3.0.0", - "rxjs": "^7.8.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=18" - } - }, - "packages/frontend/stalker-app/node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/inquirer/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/inquirer/node_modules/wrap-ansi": { - "version": "6.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/ip-address": { - "version": "9.0.5", - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/frontend/stalker-app/node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/frontend/stalker-app/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/is-path-inside": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/is-plain-object": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/is-what": { - "version": "3.14.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/isbinaryfile": { - "version": "4.0.10", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "packages/frontend/stalker-app/node_modules/isobject": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/istanbul-lib-instrument/node_modules/@babel/core": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.9", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.9", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "packages/frontend/stalker-app/node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "packages/frontend/stalker-app/node_modules/istanbul-lib-report": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/istanbul-reports": { - "version": "3.1.7", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/jasmine-core": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/jiti": { - "version": "1.21.6", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "packages/frontend/stalker-app/node_modules/jsbn": { - "version": "1.1.0", - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/json-buffer": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/json-parse-even-better-errors": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/jsonfile": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "packages/frontend/stalker-app/node_modules/jsonparse": { - "version": "1.3.1", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/jwt-decode": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "packages/frontend/stalker-app/node_modules/karma": { - "version": "6.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.7.2", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "bin": { - "karma": "bin/karma" - }, - "engines": { - "node": ">= 10" - } - }, - "packages/frontend/stalker-app/node_modules/karma-chrome-launcher": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "which": "^1.2.1" - } - }, - "packages/frontend/stalker-app/node_modules/karma-chrome-launcher/node_modules/which": { - "version": "1.3.1", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "packages/frontend/stalker-app/node_modules/karma-coverage": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.1", - "istanbul-reports": "^3.0.5", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/karma-jasmine": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "jasmine-core": "^4.1.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "karma": "^6.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/karma-jasmine-html-reporter": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "peerDependencies": { - "jasmine-core": "^4.0.0 || ^5.0.0", - "karma": "^6.0.0", - "karma-jasmine": "^5.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/karma-jasmine/node_modules/jasmine-core": { - "version": "4.6.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/karma-source-map-support": { - "version": "1.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map-support": "^0.5.5" - } - }, - "packages/frontend/stalker-app/node_modules/karma/node_modules/cliui": { - "version": "7.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/karma/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/frontend/stalker-app/node_modules/karma/node_modules/mime": { - "version": "2.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/karma/node_modules/mkdirp": { - "version": "0.5.6", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "packages/frontend/stalker-app/node_modules/karma/node_modules/tmp": { - "version": "0.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, - "packages/frontend/stalker-app/node_modules/karma/node_modules/yargs": { - "version": "16.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/karma/node_modules/yargs-parser": { - "version": "20.2.9", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/keyv": { - "version": "4.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "packages/frontend/stalker-app/node_modules/kind-of": { - "version": "6.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/klona": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/less": { - "version": "4.2.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "copy-anything": "^2.0.1", - "parse-node-version": "^1.0.1", - "tslib": "^2.3.0" - }, - "bin": { - "lessc": "bin/lessc" - }, - "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "needle": "^3.1.0", - "source-map": "~0.6.0" - } - }, - "packages/frontend/stalker-app/node_modules/less-loader": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "klona": "^2.0.4" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "less": "^3.5.0 || ^4.0.0", - "webpack": "^5.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/less/node_modules/make-dir": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "packages/frontend/stalker-app/node_modules/less/node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "packages/frontend/stalker-app/node_modules/less/node_modules/semver": { - "version": "5.7.2", - "dev": true, - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver" - } - }, - "packages/frontend/stalker-app/node_modules/levn": { - "version": "0.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/frontend/stalker-app/node_modules/license-webpack-plugin": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "webpack-sources": "^3.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-sources": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/lilconfig": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "packages/frontend/stalker-app/node_modules/lint-staged": { - "version": "15.2.7", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "~5.3.0", - "commander": "~12.1.0", - "debug": "~4.3.4", - "execa": "~8.0.1", - "lilconfig": "~3.1.1", - "listr2": "~8.2.1", - "micromatch": "~4.0.7", - "pidtree": "~0.6.0", - "string-argv": "~0.3.2", - "yaml": "~2.4.2" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "engines": { - "node": ">=18.12.0" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "packages/frontend/stalker-app/node_modules/lint-staged/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/lint-staged/node_modules/commander": { - "version": "12.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "packages/frontend/stalker-app/node_modules/listr2": { - "version": "8.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", - "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/listr2/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/listr2/node_modules/emoji-regex": { - "version": "10.3.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/listr2/node_modules/eventemitter3": { - "version": "5.0.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/listr2/node_modules/string-width": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/listr2/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/listr2/node_modules/wrap-ansi": { - "version": "9.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/loader-utils": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/locate-path": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/lodash.debounce": { - "version": "4.0.8", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/lodash.merge": { - "version": "4.6.2", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/log-update": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/ansi-escapes": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/cli-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/emoji-regex": { - "version": "10.3.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/restore-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/string-width": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/log-update/node_modules/wrap-ansi": { - "version": "9.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/log4js": { - "version": "6.9.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - }, - "engines": { - "node": ">=8.0" - } - }, - "packages/frontend/stalker-app/node_modules/make-dir": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/make-fetch-happen": { - "version": "13.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/merge2": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/frontend/stalker-app/node_modules/mini-css-extract-plugin": { - "version": "2.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-collect": { - "version": "2.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-fetch": { - "version": "3.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-json-stream": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-pipeline": { - "version": "1.2.4", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-sized": { - "version": "1.0.3", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/moment": { - "version": "2.30.1", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "packages/frontend/stalker-app/node_modules/monaco-editor": { - "version": "0.45.0", - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/mrmime": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/mute-stream": { - "version": "1.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/mz": { - "version": "2.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/nanoid": { - "version": "3.3.7", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "packages/frontend/stalker-app/node_modules/natural-compare": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/needle": { - "version": "3.3.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.3", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, - "packages/frontend/stalker-app/node_modules/needle/node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/ngx-file-drop": { - "version": "16.0.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": ">= 14.5.0", - "npm": ">= 6.9.0" - }, - "peerDependencies": { - "@angular/common": ">=14.0.0", - "@angular/core": ">=14.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/ngx-socket-io": { - "version": "4.5.1", - "license": "MIT", - "dependencies": { - "core-js": "^3.0.0", - "reflect-metadata": "^0.1.10", - "socket.io": "^4.5.1", - "socket.io-client": "^4.5.1", - "tslib": "^2.3.0", - "zone.js": "~0.11.4" - }, - "peerDependencies": { - "@angular/common": "^16.0.0", - "@angular/core": "^16.0.0", - "rxjs": "^7.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/ngx-socket-io/node_modules/zone.js": { - "version": "0.11.8", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - } - }, - "packages/frontend/stalker-app/node_modules/ngx-toastr": { - "version": "16.2.0", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/common": ">=14.0.0-0", - "@angular/core": ">=14.0.0-0", - "@angular/platform-browser": ">=14.0.0-0" - } - }, - "packages/frontend/stalker-app/node_modules/nice-napi": { - "version": "1.0.2", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "!win32" - ], - "dependencies": { - "node-addon-api": "^3.0.0", - "node-gyp-build": "^4.2.2" - } - }, - "packages/frontend/stalker-app/node_modules/node-addon-api": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "packages/frontend/stalker-app/node_modules/node-gyp": { - "version": "10.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^4.1.0", - "semver": "^7.3.5", - "tar": "^6.2.1", - "which": "^4.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/node-gyp-build": { - "version": "4.8.1", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "packages/frontend/stalker-app/node_modules/normalize-package-data": { - "version": "6.0.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/normalize-range": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/npm-bundled": { - "version": "3.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/npm-install-checks": { - "version": "6.3.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/npm-package-arg": { - "version": "11.0.3", - "dev": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/npm-packlist": { - "version": "8.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "ignore-walk": "^6.0.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/npm-pick-manifest": { - "version": "9.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/npm-registry-fetch": { - "version": "16.2.1", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/redact": "^1.1.0", - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/object-hash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "packages/frontend/stalker-app/node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/optionator": { - "version": "0.9.4", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/frontend/stalker-app/node_modules/p-limit": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/p-locate": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/frontend/stalker-app/node_modules/pacote": { - "version": "17.0.6", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", - "cacache": "^18.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.2.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/pacote/node_modules/proc-log": { - "version": "3.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/parse-node-version": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "packages/frontend/stalker-app/node_modules/parse5-html-rewriting-stream": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^4.3.0", - "parse5": "^7.0.0", - "parse5-sax-parser": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/parse5-sax-parser": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/path-exists": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/pify": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/pirates": { - "version": "4.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "packages/frontend/stalker-app/node_modules/piscina": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "nice-napi": "^1.0.2" - } - }, - "packages/frontend/stalker-app/node_modules/pkg-dir": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/postcss": { - "version": "8.4.39", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-import": { - "version": "15.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-js": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-load-config": { - "version": "4.0.2", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/postcss-media-query-parser": { - "version": "0.2.3", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-modules-scope": { - "version": "3.2.0", - "dev": true, - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-modules-values": { - "version": "4.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-nested": { - "version": "6.2.0", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-selector-parser": { - "version": "6.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/postcss-value-parser": { - "version": "4.2.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/postinstall-build": { - "version": "5.0.3", - "dev": true, - "license": "MIT", - "bin": { - "postinstall-build": "cli.js" - } - }, - "packages/frontend/stalker-app/node_modules/prelude-ls": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/frontend/stalker-app/node_modules/prettier": { - "version": "3.3.3", - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/proc-log": { - "version": "4.2.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, - "packages/frontend/stalker-app/node_modules/promise-retry": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/prr": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "packages/frontend/stalker-app/node_modules/qjobs": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.9" - } - }, - "packages/frontend/stalker-app/node_modules/queue-microtask": { - "version": "1.2.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/raw-body": { - "version": "2.5.2", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "packages/frontend/stalker-app/node_modules/read-cache": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "packages/frontend/stalker-app/node_modules/read-package-json": { - "version": "7.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/read-package-json-fast": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/reflect-metadata": { - "version": "0.1.14", - "license": "Apache-2.0" - }, - "packages/frontend/stalker-app/node_modules/regenerate": { - "version": "1.4.2", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/regenerator-transform": { - "version": "0.15.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "packages/frontend/stalker-app/node_modules/regenerator-transform/node_modules/@babel/runtime": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/frontend/stalker-app/node_modules/regex-parser": { - "version": "2.3.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/regexpu-core": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/regjsparser": { - "version": "0.9.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "packages/frontend/stalker-app/node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "packages/frontend/stalker-app/node_modules/resolve": { - "version": "1.22.8", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/frontend/stalker-app/node_modules/resolve-url-loader": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.14", - "source-map": "0.6.1" - }, - "engines": { - "node": ">=12" - } - }, - "packages/frontend/stalker-app/node_modules/resolve-url-loader/node_modules/convert-source-map": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/retry": { - "version": "0.12.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "packages/frontend/stalker-app/node_modules/reusify": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/rollup": { - "version": "4.19.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.0", - "@rollup/rollup-android-arm64": "4.19.0", - "@rollup/rollup-darwin-arm64": "4.19.0", - "@rollup/rollup-darwin-x64": "4.19.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", - "@rollup/rollup-linux-arm-musleabihf": "4.19.0", - "@rollup/rollup-linux-arm64-gnu": "4.19.0", - "@rollup/rollup-linux-arm64-musl": "4.19.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", - "@rollup/rollup-linux-riscv64-gnu": "4.19.0", - "@rollup/rollup-linux-s390x-gnu": "4.19.0", - "@rollup/rollup-linux-x64-gnu": "4.19.0", - "@rollup/rollup-linux-x64-musl": "4.19.0", - "@rollup/rollup-win32-arm64-msvc": "4.19.0", - "@rollup/rollup-win32-ia32-msvc": "4.19.0", - "@rollup/rollup-win32-x64-msvc": "4.19.0", - "fsevents": "~2.3.2" - } - }, - "packages/frontend/stalker-app/node_modules/run-async": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "packages/frontend/stalker-app/node_modules/run-parallel": { - "version": "1.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "packages/frontend/stalker-app/node_modules/safevalues": { - "version": "0.3.4", - "license": "Apache-2.0" - }, - "packages/frontend/stalker-app/node_modules/sass": { - "version": "1.71.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/sass-loader": { - "version": "14.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/sax": { - "version": "1.4.1", - "dev": true, - "license": "ISC", - "optional": true - }, - "packages/frontend/stalker-app/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "packages/frontend/stalker-app/node_modules/shallow-clone": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "packages/frontend/stalker-app/node_modules/sigstore": { - "version": "2.3.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^2.3.2", - "@sigstore/tuf": "^2.3.4", - "@sigstore/verify": "^1.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/slash": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/smart-buffer": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/socket.io": { - "version": "4.7.5", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.5.2", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "packages/frontend/stalker-app/node_modules/socket.io-client": { - "version": "4.7.5", - "license": "MIT", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/socks": { - "version": "2.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/socks-proxy-agent": { - "version": "8.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.1", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "packages/frontend/stalker-app/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/source-map-js": { - "version": "1.2.0", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/source-map-loader": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.72.1" - } - }, - "packages/frontend/stalker-app/node_modules/source-map-loader/node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/spdx-exceptions": { - "version": "2.5.0", - "dev": true, - "license": "CC-BY-3.0" - }, - "packages/frontend/stalker-app/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/spdx-license-ids": { - "version": "3.0.18", - "dev": true, - "license": "CC0-1.0" - }, - "packages/frontend/stalker-app/node_modules/sprintf-js": { - "version": "1.1.3", - "license": "BSD-3-Clause" - }, - "packages/frontend/stalker-app/node_modules/ssri": { - "version": "10.0.6", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/streamroller": { - "version": "3.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "packages/frontend/stalker-app/node_modules/strip-json-comments": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/sucrase": { - "version": "3.35.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "packages/frontend/stalker-app/node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "packages/frontend/stalker-app/node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/frontend/stalker-app/node_modules/synckit": { - "version": "0.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "packages/frontend/stalker-app/node_modules/tailwindcss": { - "version": "3.4.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/tailwindcss/node_modules/lilconfig": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/tar": { - "version": "6.2.1", - "dev": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/frontend/stalker-app/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/terser": { - "version": "5.29.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "packages/frontend/stalker-app/node_modules/test-exclude": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "packages/frontend/stalker-app/node_modules/test-exclude/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/frontend/stalker-app/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/thenify": { - "version": "3.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/thenify-all": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "packages/frontend/stalker-app/node_modules/ts-api-utils": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "packages/frontend/stalker-app/node_modules/ts-interface-checker": { - "version": "0.1.13", - "dev": true, - "license": "Apache-2.0" - }, - "packages/frontend/stalker-app/node_modules/ts-md5": { - "version": "1.3.1", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "packages/frontend/stalker-app/node_modules/tuf-js": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/type-check": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/frontend/stalker-app/node_modules/typed-assert": { - "version": "1.0.9", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/typemoq": { - "version": "2.1.0", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "circular-json": "^0.3.1", - "lodash": "^4.17.4", - "postinstall-build": "^5.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/typescript": { - "version": "5.2.2", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "packages/frontend/stalker-app/node_modules/ua-parser-js": { - "version": "0.7.38", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - }, - { - "type": "github", - "url": "https://github.com/sponsors/faisalman" - } - ], - "license": "MIT", - "engines": { - "node": "*" - } - }, - "packages/frontend/stalker-app/node_modules/undici": { - "version": "6.11.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.0" - } - }, - "packages/frontend/stalker-app/node_modules/undici-types": { - "version": "5.26.5", - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "packages/frontend/stalker-app/node_modules/unique-filename": { - "version": "3.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/unique-slug": { - "version": "4.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/universalify": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/validate-npm-package-name": { - "version": "5.0.1", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/vite": { - "version": "5.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "packages/frontend/stalker-app/node_modules/vite/node_modules/esbuild": { - "version": "0.19.12", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" - } - }, - "packages/frontend/stalker-app/node_modules/void-elements": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/watchpack": { - "version": "2.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "packages/frontend/stalker-app/node_modules/webpack-dev-middleware": { - "version": "6.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.12", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/webpack-merge": { - "version": "5.10.0", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/webpack-subresource-integrity": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "typed-assert": "^1.0.8" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", - "webpack": "^5.12.0" - }, - "peerDependenciesMeta": { - "html-webpack-plugin": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/which": { - "version": "4.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "packages/frontend/stalker-app/node_modules/which/node_modules/isexe": { - "version": "3.1.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "packages/frontend/stalker-app/node_modules/wildcard": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "packages/frontend/stalker-app/node_modules/word-wrap": { - "version": "1.2.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/frontend/stalker-app/node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/frontend/stalker-app/node_modules/ws": { - "version": "8.17.1", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "packages/frontend/stalker-app/node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "engines": { - "node": ">=0.4.0" - } - }, - "packages/frontend/stalker-app/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "packages/frontend/stalker-app/node_modules/yaml": { - "version": "2.4.5", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "packages/frontend/stalker-app/node_modules/yocto-queue": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/frontend/stalker-app/node_modules/zone.js": { - "version": "0.14.8", - "license": "MIT" - } - } -} diff --git a/package.json b/package.json index 56045d2c..ede8b5da 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "workspaces": [ "packages/frontend/stalker-app", "packages/backend/jobs-manager/service", - "packages/backend/cron/service" + "packages/backend/cron/service", + "packages/common" ], "scripts": { "prepare": "husky install" @@ -22,6 +23,8 @@ "homepage": "https://github.com/lm-sec/Stalker#readme", "devDependencies": { "husky": "^7.0.4", + "jest": "^29.7.0", + "ts-jest": "^29.2.5", "typescript": "^5.0.0" }, "dependencies": { diff --git a/packages/Dockerfile.base b/packages/Dockerfile.base index 41063da6..efccbcfe 100644 --- a/packages/Dockerfile.base +++ b/packages/Dockerfile.base @@ -13,11 +13,14 @@ RUN yarn set version 4.1.0 COPY yarn.lock yarn.lock COPY package.json package.json +COPY packages/common/package.json packages/common/package.json COPY packages/frontend/stalker-app/package.json packages/frontend/stalker-app/package.json COPY packages/backend/jobs-manager/service/package.json packages/backend/jobs-manager/service/package.json COPY packages/backend/cron/service/package.json packages/backend/cron/service/package.json COPY packages/backend/orchestrator/service/package.json packages/backend/orchestrator/service/package.json COPY .yarnrc.yml .yarnrc.yml +COPY tsconfig.base.json tsconfig.base.json +COPY tsconfig.json tsconfig.json RUN yarn install --immutable diff --git a/packages/backend/jobs-manager/service/Dockerfile b/packages/backend/jobs-manager/service/Dockerfile index 63d64a15..45335431 100644 --- a/packages/backend/jobs-manager/service/Dockerfile +++ b/packages/backend/jobs-manager/service/Dockerfile @@ -5,6 +5,7 @@ RUN yarn workspace @red-kite/jobs-manager build:prod RUN ls /app/packages/backend/jobs-manager/service/ FROM node:19.6.1-alpine3.16 + COPY --from=build /app/packages/backend/jobs-manager/service/dist /server/dist COPY --from=build /app/packages/backend/jobs-manager/service/node_modules /server/node_modules diff --git a/packages/backend/jobs-manager/service/jest.config.js b/packages/backend/jobs-manager/service/jest.config.js index b77c6f14..76eee2ad 100644 --- a/packages/backend/jobs-manager/service/jest.config.js +++ b/packages/backend/jobs-manager/service/jest.config.js @@ -1,3 +1,6 @@ +const { pathsToModuleNameMapper } = require('ts-jest'); +const { compilerOptions } = require('../../../../tsconfig.base.json'); + module.exports = { moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], modulePathIgnorePatterns: ['/dist/'], @@ -13,4 +16,10 @@ module.exports = { coverageReporters: ['json', 'lcov'], globalSetup: './global-setup.ts', globalTeardown: './global-teardown.ts', + rootDir: './', + roots: [''], + modulePaths: [compilerOptions.baseUrl], + moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { + prefix: '/../../../..', + }), }; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/generated/search-parser.d.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/generated/search-parser.d.ts new file mode 100644 index 00000000..e0ce7752 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/generated/search-parser.d.ts @@ -0,0 +1,209 @@ +/** Provides information pointing to a location within a source. */ +export interface Location { + /** Line in the parsed source (1-based). */ + readonly line: number; + /** Column in the parsed source (1-based). */ + readonly column: number; + /** Offset in the parsed source (0-based). */ + readonly offset: number; +} + +/** + * Anything that can successfully be converted to a string with `String()` + * so that it can be used in error messages. + * + * The GrammarLocation class in Peggy is a good example. + */ +export interface GrammarSourceObject { + readonly toString: () => string; + + /** + * If specified, allows the grammar source to be embedded in a larger file + * at some offset. + */ + readonly offset?: undefined | ((loc: Location) => Location); +} + +/** + * Most often, you just use a string with the file name. + */ +export type GrammarSource = string | GrammarSourceObject; + +/** The `start` and `end` position's of an object within the source. */ +export interface LocationRange { + /** + * A string or object that was supplied to the `parse()` call as the + * `grammarSource` option. + */ + readonly source: GrammarSource; + /** Position at the beginning of the expression. */ + readonly start: Location; + /** Position after the end of the expression. */ + readonly end: Location; +} + +/** + * Expected a literal string, like `"foo"i`. + */ +export interface LiteralExpectation { + readonly type: "literal"; + readonly text: string; + readonly ignoreCase: boolean; +} + +/** + * Range of characters, like `a-z` + */ +export type ClassRange = [ + start: string, + end: string, +] + +export interface ClassParts extends Array { +} + +/** + * Expected a class, such as `[^acd-gz]i` + */ +export interface ClassExpectation { + readonly type: "class"; + readonly parts: ClassParts; + readonly inverted: boolean; + readonly ignoreCase: boolean; +} + +/** + * Expected any character, with `.` + */ +export interface AnyExpectation { + readonly type: "any"; +} + +/** + * Expected the end of input. + */ +export interface EndExpectation { + readonly type: "end"; +} + +/** + * Expected some other input. These are specified with a rule's + * "human-readable name", or with the `expected(message, location)` + * function. + */ +export interface OtherExpectation { + readonly type: "other"; + readonly description: string; +} + +export type Expectation = + | AnyExpectation + | ClassExpectation + | EndExpectation + | LiteralExpectation + | OtherExpectation; + +/** + * Pass an array of these into `SyntaxError.prototype.format()` + */ +export interface SourceText { + /** + * Identifier of an input that was used as a grammarSource in parse(). + */ + readonly source: GrammarSource; + /** Source text of the input. */ + readonly text: string; +} + +export declare class SyntaxError extends Error { + /** + * Constructs the human-readable message from the machine representation. + * + * @param expected Array of expected items, generated by the parser + * @param found Any text that will appear as found in the input instead of + * expected + */ + static buildMessage(expected: Expectation[], found?: string | null | undefined): string; + readonly message: string; + readonly expected: Expectation[]; + readonly found: string | null | undefined; + readonly location: LocationRange; + readonly name: string; + constructor( + message: string, + expected: Expectation[], + found: string | null, + location: LocationRange, + ); + + /** + * With good sources, generates a feature-rich error message pointing to the + * error in the input. + * @param sources List of {source, text} objects that map to the input. + */ + format(sources: SourceText[]): string; +} + +/** + * Trace execution of the parser. + */ +export interface ParserTracer { + trace: (event: ParserTracerEvent) => void; +} + +export type ParserTracerEvent + = { + readonly type: "rule.enter"; + readonly rule: string; + readonly location: LocationRange + } + | { + readonly type: "rule.fail"; + readonly rule: string; + readonly location: LocationRange + } + | { + readonly type: "rule.match"; + readonly rule: string; + readonly location: LocationRange + /** Return value from the rule. */ + readonly result: unknown; + }; + +export type StartRuleNames = "start"; +export interface ParseOptions { + /** + * String or object that will be attached to the each `LocationRange` object + * created by the parser. For example, this can be path to the parsed file + * or even the File object. + */ + readonly grammarSource?: GrammarSource; + readonly startRule?: T; + readonly tracer?: ParserTracer; + + // Internal use only: + readonly peg$library?: boolean; + // Internal use only: + peg$currPos?: number; + // Internal use only: + peg$silentFails?: number; + // Internal use only: + peg$maxFailExpected?: Expectation[]; + // Extra application-specific properties + [key: string]: unknown; +} + +export declare const StartRules: StartRuleNames[]; +export declare const parse: typeof ParseFunction; + +// Overload of ParseFunction for each allowedStartRule + +declare function ParseFunction>( + input: string, + options?: Options, +): any; + +declare function ParseFunction>( + input: string, + options?: Options, +): any; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/generated/search-parser.js b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/generated/search-parser.js new file mode 100644 index 00000000..d1fdb11c --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/generated/search-parser.js @@ -0,0 +1,1440 @@ +// @generated by Peggy 4.2.0. +// +// https://peggyjs.org/ + +"use strict"; + + +function peg$subclass(child, parent) { + function C() { this.constructor = child; } + C.prototype = parent.prototype; + child.prototype = new C(); +} + +function peg$SyntaxError(message, expected, found, location) { + var self = Error.call(this, message); + // istanbul ignore next Check is a necessary evil to support older environments + if (Object.setPrototypeOf) { + Object.setPrototypeOf(self, peg$SyntaxError.prototype); + } + self.expected = expected; + self.found = found; + self.location = location; + self.name = "SyntaxError"; + return self; +} + +peg$subclass(peg$SyntaxError, Error); + +function peg$padEnd(str, targetLength, padString) { + padString = padString || " "; + if (str.length > targetLength) { return str; } + targetLength -= str.length; + padString += padString.repeat(targetLength); + return str + padString.slice(0, targetLength); +} + +peg$SyntaxError.prototype.format = function(sources) { + var str = "Error: " + this.message; + if (this.location) { + var src = null; + var k; + for (k = 0; k < sources.length; k++) { + if (sources[k].source === this.location.source) { + src = sources[k].text.split(/\r\n|\n|\r/g); + break; + } + } + var s = this.location.start; + var offset_s = (this.location.source && (typeof this.location.source.offset === "function")) + ? this.location.source.offset(s) + : s; + var loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; + if (src) { + var e = this.location.end; + var filler = peg$padEnd("", offset_s.line.toString().length, ' '); + var line = src[s.line - 1]; + var last = s.line === e.line ? e.column : line.length + 1; + var hatLen = (last - s.column) || 1; + str += "\n --> " + loc + "\n" + + filler + " |\n" + + offset_s.line + " | " + line + "\n" + + filler + " | " + peg$padEnd("", s.column - 1, ' ') + + peg$padEnd("", hatLen, "^"); + } else { + str += "\n at " + loc; + } + } + return str; +}; + +peg$SyntaxError.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + class: function(expectation) { + var escapedParts = expectation.parts.map(function(part) { + return Array.isArray(part) + ? classEscape(part[0]) + "-" + classEscape(part[1]) + : classEscape(part); + }); + + return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]"; + }, + + any: function() { + return "any character"; + }, + + end: function() { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/"/g, "\\\"") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/\]/g, "\\]") + .replace(/\^/g, "\\^") + .replace(/-/g, "\\-") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = expected.map(describeExpectation); + var i, j; + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse(input, options) { + options = options !== undefined ? options : {}; + + var peg$FAILED = {}; + var peg$source = options.grammarSource; + + var peg$startRuleFunctions = { start: peg$parsestart }; + var peg$startRuleFunction = peg$parsestart; + + var peg$c0 = ":"; + var peg$c1 = "-"; + var peg$c2 = "exists"; + var peg$c3 = "finding."; + var peg$c4 = "."; + var peg$c5 = "finding"; + var peg$c6 = "project.name"; + var peg$c7 = "project.id"; + var peg$c8 = "project"; + var peg$c9 = "domain.name"; + var peg$c10 = "domain.id"; + var peg$c11 = "domain"; + var peg$c12 = "host.ip"; + var peg$c13 = "host.id"; + var peg$c14 = "host"; + var peg$c15 = "port.number"; + var peg$c16 = "port.id"; + var peg$c17 = "port.protocol"; + var peg$c18 = "port"; + var peg$c19 = "tag.id"; + var peg$c20 = "tag.name"; + var peg$c21 = "tag"; + var peg$c22 = "is"; + + var peg$r0 = /^[a-zA-Z._]/; + var peg$r1 = /^[a-zA-Z0-9:_\-:\/.*]/; + var peg$r2 = /^["]/; + var peg$r3 = /^[a-zA-Z0-9._\- :\/*]/; + var peg$r4 = /^[a-zA-Z0-9\-]/; + var peg$r5 = /^[a-zA-Z0-9]/; + var peg$r6 = /^[ \t\n\r]/; + + var peg$e0 = peg$literalExpectation(":", false); + var peg$e1 = peg$classExpectation([["a", "z"], ["A", "Z"], ".", "_"], false, false); + var peg$e2 = peg$literalExpectation("-", false); + var peg$e3 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], ":", "_", "-", ":", "/", ".", "*"], false, false); + var peg$e4 = peg$classExpectation(["\""], false, false); + var peg$e5 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], ".", "_", "-", " ", ":", "/", "*"], false, false); + var peg$e6 = peg$literalExpectation("exists", false); + var peg$e7 = peg$literalExpectation("finding.", false); + var peg$e8 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "-"], false, false); + var peg$e9 = peg$literalExpectation(".", false); + var peg$e10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false); + var peg$e11 = peg$literalExpectation("finding", false); + var peg$e12 = peg$literalExpectation("project.name", false); + var peg$e13 = peg$literalExpectation("project.id", false); + var peg$e14 = peg$literalExpectation("project", false); + var peg$e15 = peg$literalExpectation("domain.name", false); + var peg$e16 = peg$literalExpectation("domain.id", false); + var peg$e17 = peg$literalExpectation("domain", false); + var peg$e18 = peg$literalExpectation("host.ip", false); + var peg$e19 = peg$literalExpectation("host.id", false); + var peg$e20 = peg$literalExpectation("host", false); + var peg$e21 = peg$literalExpectation("port.number", false); + var peg$e22 = peg$literalExpectation("port.id", false); + var peg$e23 = peg$literalExpectation("port.protocol", false); + var peg$e24 = peg$literalExpectation("port", false); + var peg$e25 = peg$literalExpectation("tag.id", false); + var peg$e26 = peg$literalExpectation("tag.name", false); + var peg$e27 = peg$literalExpectation("tag", false); + var peg$e28 = peg$literalExpectation("is", false); + var peg$e29 = peg$otherExpectation("whitespace"); + var peg$e30 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false); + + var peg$f0 = function(terms) { + return terms ? [terms[0]].concat(terms[1].map(([_, t]) => t)) : []; + }; + var peg$f1 = function(not, type, value) { + return { not: not ?? false, type, value }; + }; + var peg$f2 = function(not, key) { + return { incomplete: true, not: not ?? false, type: key, value: null } + }; + var peg$f3 = function(not, key) { + return { incomplete: true, not: not ?? false, key, type: "findingField", value: null } + }; + var peg$f4 = function(not, key) { + return { incomplete: true, not: not ?? false, key, type: "finding", value: null } + }; + var peg$f5 = function(not, key) { + return { incomplete: true, not: not ?? false, key, value: null, type: null } + }; + var peg$f6 = function(not, key, value) { + return { not: not ?? false, key, value, type: "findingField" }; + }; + var peg$f7 = function(not, key, value) { + return { not: not ?? false, key, value, type: "finding" }; + }; + var peg$f8 = function() { return true; }; + var peg$f9 = function(value) { + return value; + }; + var peg$f10 = function() { return null; }; + var peg$f11 = function(string) { + return string; + }; + var peg$f12 = function() { return "exists"; }; + var peg$f13 = function(finding_key, field_key) { + return { findingKey: finding_key, fieldKey: field_key }; + }; + var peg$f14 = function(finding_key) { + return { findingKey: finding_key }; + }; + var peg$f15 = function() { return "project.name"; }; + var peg$f16 = function() { return "project.id"; }; + var peg$f17 = function() { return "project.name"; }; + var peg$f18 = function() { return "domain.name"; }; + var peg$f19 = function() { return "domain.id"; }; + var peg$f20 = function() { return "domain.name"; }; + var peg$f21 = function() { return "host.ip"; }; + var peg$f22 = function() { return "host.id"; }; + var peg$f23 = function() { return "host.ip"; }; + var peg$f24 = function() { return "port.number"; }; + var peg$f25 = function() { return "port.id"; }; + var peg$f26 = function() { return "port.protocol"; }; + var peg$f27 = function() { return "port.number"; }; + var peg$f28 = function() { return "tag.id"; }; + var peg$f29 = function() { return "tag.name"; }; + var peg$f30 = function() { return "tag.name"; }; + var peg$f31 = function() { return "is"; }; + var peg$currPos = options.peg$currPos | 0; + var peg$savedPos = peg$currPos; + var peg$posDetailsCache = [{ line: 1, column: 1 }]; + var peg$maxFailPos = peg$currPos; + var peg$maxFailExpected = options.peg$maxFailExpected || []; + var peg$silentFails = options.peg$silentFails | 0; + + var peg$result; + + if (options.startRule) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$savedPos, peg$currPos); + } + + function offset() { + return peg$savedPos; + } + + function range() { + return { + source: peg$source, + start: peg$savedPos, + end: peg$currPos + }; + } + + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); + } + + function expected(description, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildStructuredError( + [peg$otherExpectation(description)], + input.substring(peg$savedPos, peg$currPos), + location + ); + } + + function error(message, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildSimpleError(message, location); + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$otherExpectation(description) { + return { type: "other", description: description }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos]; + var p; + + if (details) { + return details; + } else { + if (pos >= peg$posDetailsCache.length) { + p = peg$posDetailsCache.length - 1; + } else { + p = pos; + while (!peg$posDetailsCache[--p]) {} + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + + return details; + } + } + + function peg$computeLocation(startPos, endPos, offset) { + var startPosDetails = peg$computePosDetails(startPos); + var endPosDetails = peg$computePosDetails(endPos); + + var res = { + source: peg$source, + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + if (offset && peg$source && (typeof peg$source.offset === "function")) { + res.start = peg$source.offset(res.start); + res.end = peg$source.offset(res.end); + } + return res; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildSimpleError(message, location) { + return new peg$SyntaxError(message, null, null, location); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError( + peg$SyntaxError.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parsestart() { + var s0; + + s0 = peg$parseterms(); + + return s0; + } + + function peg$parseterms() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$parseterm(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseterm(); + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseterm(); + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parse_(); + if (s2 === peg$FAILED) { + s2 = null; + } + peg$savedPos = s0; + s0 = peg$f0(s1); + + return s0; + } + + function peg$parseterm() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$parsefinding_field_term(); + if (s0 === peg$FAILED) { + s0 = peg$parsefinding_term(); + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsekey(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f1(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsekey(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f2(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_field_key(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f3(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_key(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f4(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r0.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r0.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f5(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsefinding_field_term() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_field_key(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f6(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefinding_term() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_key(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f7(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsenot() { + var s0, s1; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s1 = peg$c1; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e2); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f8(); + } + s0 = s1; + + return s0; + } + + function peg$parsevalue() { + var s0; + + s0 = peg$parseraw_value(); + if (s0 === peg$FAILED) { + s0 = peg$parsestring(); + if (s0 === peg$FAILED) { + s0 = peg$parseexists(); + if (s0 === peg$FAILED) { + s0 = peg$parseempty_value(); + } + } + } + + return s0; + } + + function peg$parseraw_value() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = []; + s3 = input.charAt(peg$currPos); + if (peg$r1.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = input.charAt(peg$currPos); + if (peg$r1.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f9(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseempty_value() { + var s0, s1; + + s0 = peg$currPos; + s1 = ''; + peg$savedPos = s0; + s1 = peg$f10(); + s0 = s1; + + return s0; + } + + function peg$parsestring() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = input.charAt(peg$currPos); + if (peg$r2.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r3.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r3.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + s3 = input.charAt(peg$currPos); + if (peg$r2.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f11(s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseexists() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c2) { + s1 = peg$c2; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e6); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f12(); + } + s0 = s1; + + return s0; + } + + function peg$parsefinding_field_key() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c3) { + s1 = peg$c3; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e7); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r4.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r4.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c4; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + s5 = []; + s6 = input.charAt(peg$currPos); + if (peg$r5.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + s6 = input.charAt(peg$currPos); + if (peg$r5.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + } + s4 = input.substring(s4, peg$currPos); + peg$savedPos = s0; + s0 = peg$f13(s2, s4); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefinding_key() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c5) { + s1 = peg$c5; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e11); } + } + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s2 = peg$c4; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + s3 = peg$currPos; + s4 = []; + s5 = input.charAt(peg$currPos); + if (peg$r4.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = input.charAt(peg$currPos); + if (peg$r4.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + } + s3 = input.substring(s3, peg$currPos); + peg$savedPos = s0; + s0 = peg$f14(s3); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsekey() { + var s0; + + s0 = peg$parseproject(); + if (s0 === peg$FAILED) { + s0 = peg$parsedomain(); + if (s0 === peg$FAILED) { + s0 = peg$parsehost(); + if (s0 === peg$FAILED) { + s0 = peg$parseport(); + if (s0 === peg$FAILED) { + s0 = peg$parsetags(); + if (s0 === peg$FAILED) { + s0 = peg$parseis(); + } + } + } + } + } + + return s0; + } + + function peg$parseproject() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c6) { + s1 = peg$c6; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e12); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f15(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 10) === peg$c7) { + s1 = peg$c7; + peg$currPos += 10; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e13); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f16(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c8) { + s1 = peg$c8; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f17(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parsedomain() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 11) === peg$c9) { + s1 = peg$c9; + peg$currPos += 11; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e15); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f18(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 9) === peg$c10) { + s1 = peg$c10; + peg$currPos += 9; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e16); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f19(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c11) { + s1 = peg$c11; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e17); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f20(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parsehost() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c12) { + s1 = peg$c12; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e18); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f21(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c13) { + s1 = peg$c13; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e19); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f22(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c14) { + s1 = peg$c14; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e20); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f23(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parseport() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 11) === peg$c15) { + s1 = peg$c15; + peg$currPos += 11; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e21); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f24(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c16) { + s1 = peg$c16; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e22); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f25(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 13) === peg$c17) { + s1 = peg$c17; + peg$currPos += 13; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e23); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f26(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c18) { + s1 = peg$c18; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e24); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f27(); + } + s0 = s1; + } + } + } + + return s0; + } + + function peg$parsetags() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c19) { + s1 = peg$c19; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e25); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f28(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c20) { + s1 = peg$c20; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e26); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f29(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c21) { + s1 = peg$c21; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e27); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f30(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parseis() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c22) { + s1 = peg$c22; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e28); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f31(); + } + s0 = s1; + + return s0; + } + + function peg$parse_() { + var s0, s1; + + peg$silentFails++; + s0 = []; + s1 = input.charAt(peg$currPos); + if (peg$r6.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e30); } + } + if (s1 !== peg$FAILED) { + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = input.charAt(peg$currPos); + if (peg$r6.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e30); } + } + } + } else { + s0 = peg$FAILED; + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e29); } + } + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (options.peg$library) { + return /** @type {any} */ ({ + peg$result, + peg$currPos, + peg$FAILED, + peg$maxFailExpected, + peg$maxFailPos + }); + } + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +module.exports = { + StartRules: ["start"], + SyntaxError: peg$SyntaxError, + parse: peg$parse +}; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/index.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/index.ts new file mode 100644 index 00000000..868f886d --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/index.ts @@ -0,0 +1,2 @@ +export * from './search-query-parser'; +export * from './search-query-parser.types'; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/peggy.config.mjs b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/peggy.config.mjs new file mode 100644 index 00000000..ba1e6b4b --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/peggy.config.mjs @@ -0,0 +1,6 @@ +// MJS +export default { + input: 'src/search-query/search-grammar.peggy', + output: 'src/search-query/generated/search-parser.js', + dts: true, +}; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-grammar.peggy b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-grammar.peggy new file mode 100644 index 00000000..3537bc31 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-grammar.peggy @@ -0,0 +1,109 @@ +start + = terms + +terms + = terms:(term (_ term)*)? _? { + return terms ? [terms[0]].concat(terms[1].map(([_, t]) => t)) : []; + } + +term + = finding_field_term + / finding_term + / not:not? type:(key) ":" _? value:value { + return { not: not ?? false, type, value }; + } + / not:not? key:key { + return { incomplete: true, not: not ?? false, type: key, value: null } + } + / not:not? key:finding_field_key { + return { incomplete: true, not: not ?? false, key, type: "findingField", value: null } + } + / not:not? key:finding_key { + return { incomplete: true, not: not ?? false, key, type: "finding", value: null } + } + / not:not? key:$[a-zA-Z._]+ { + return { incomplete: true, not: not ?? false, key, value: null, type: null } + } + +finding_field_term + = not:not? key:finding_field_key ":" _? value:value { + return { not: not ?? false, key, value, type: "findingField" }; + } + +finding_term + = not:not? key:finding_key ":" _? value:value { + return { not: not ?? false, key, value, type: "finding" }; + } + +not + = "-" { return true; } + +value + = raw_value + / string + / exists + / empty_value + +raw_value + = value:$[a-zA-Z0-9:_\-:/.\*]+ { + return value; + } + +empty_value + = "" { return null; } + +string + = [\"] string:$[a-zA-Z0-9._\- :/\*]+ [\"] { + return string; + } + +exists = "exists" { return "exists"; } + +finding_field_key + = "finding." finding_key:$[a-zA-Z0-9-]+ "." field_key:$[a-zA-Z0-9]* { + return { findingKey: finding_key, fieldKey: field_key }; + } + +finding_key + = "finding" "."? finding_key:$[a-zA-Z0-9-]* { + return { findingKey: finding_key }; + } + +key = project / domain / host / port / tags / other / is + +project + = "project.name" { return "project.name"; } + / "project.id" { return "project.id"; } + / "project" { return "project.name"; } + +domain + = "domain.name" { return "domain.name"; } + / "domain.id" { return "domain.id"; } + / "domain" { return "domain.name"; } + +host + = "host.ip" { return "host.ip"; } + / "host.id" { return "host.id"; } + / "host" { return "host.ip"; } + +port + = "port.number" { return "port.number"; } + / "port.id" { return "port.id"; } + / "port.protocol" { return "port.protocol"; } + / "port" { return "port.number"; } + / "port.service" { return "port.service"; } + / "port.product" { return "port.product"; } + / "port.version" { return "port.version"; } + +tags + = "tag.id" { return "tag.id"; } + / "tag.name" { return "tag.name"; } + / "tag" { return "tag.name"; } + +other + = "mergedIn.id" { return "mergedIn.id" } + +is = "is" { return "is"; } + +_ "whitespace" + = [ \t\n\r]+ \ No newline at end of file diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.spec.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.spec.ts new file mode 100644 index 00000000..5536722b --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.spec.ts @@ -0,0 +1,391 @@ +import { SearchQueryParser } from './search-query-parser'; +import { + SearchTerm, + SearchTerms, + TermTypes as TermType, +} from './search-query-parser.types'; + +interface HappyTestCase { + input: string; + expected: SearchTerms; +} + +describe('Search Query Parser', () => { + const parser = new SearchQueryParser(); + + const generalUseCases: HappyTestCase[] = [ + { + input: 'domain: "I am confusing: I have spaces and colons"', + expected: [ + term('domain.name', 'I am confusing: I have spaces and colons'), + ], + }, + { + input: 'domain: http://a1b2.ca -is: blocked', + expected: [ + term('domain.name', 'http://a1b2.ca'), + notTerm('is', 'blocked'), + ], + }, + + // Incomplete + { + input: 'dom', + expected: [ + { + not: false, + incomplete: true, + key: 'dom', + value: null, + type: null, + }, + ], + }, + { + input: '-dom', + expected: [ + { + incomplete: true, + not: true, + key: 'dom', + value: null, + type: null, + }, + ], + }, + { + input: 'domain', + expected: [ + { + not: false, + incomplete: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: '-domain', + expected: [ + { + incomplete: true, + not: true, + type: 'domain.name', + value: null, + }, + ], + }, + ]; + + const isTestCases: HappyTestCase[] = [ + { + input: 'is', + expected: [ + { + not: false, + incomplete: true, + type: 'is', + value: null, + }, + ], + }, + { + input: '-is', + expected: [ + { + incomplete: true, + not: true, + type: 'is', + value: null, + }, + ], + }, + { + input: '-is: blocked', + expected: [notTerm('is', 'blocked')], + }, + { + input: 'is: blocked', + expected: [term('is', 'blocked')], + }, + ]; + + const tagsTestCases: HappyTestCase[] = [ + { + input: 'tag.name', + expected: [ + { + not: false, + incomplete: true, + type: 'tag.name', + value: null, + }, + ], + }, + { + input: '-tag.name', + expected: [ + { + incomplete: true, + not: true, + type: 'tag.name', + value: null, + }, + ], + }, + { + input: 'tag: my-tag', + expected: [term('tag.name', 'my-tag')], + }, + { + input: '-tag: my-tag', + expected: [notTerm('tag.name', 'my-tag')], + }, + { + input: 'tag.name: my-tag', + expected: [term('tag.name', 'my-tag')], + }, + { + input: '-tag.name: my-tag', + expected: [notTerm('tag.name', 'my-tag')], + }, + { + input: 'tag.id: my-id', + expected: [term('tag.id', 'my-id')], + }, + { + input: '-tag.id: my-id', + expected: [notTerm('tag.id', 'my-id')], + }, + ]; + + const domainTestCases: HappyTestCase[] = [ + { + input: 'domain.name', + expected: [ + { + not: false, + incomplete: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: '-domain.name', + expected: [ + { + incomplete: true, + not: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: 'domain: example.org', + expected: [term('domain.name', 'example.org')], + }, + { + input: '-domain: example.org', + expected: [notTerm('domain.name', 'example.org')], + }, + { + input: 'domain.name: example.org', + expected: [term('domain.name', 'example.org')], + }, + { + input: '-domain.name: example.org', + expected: [notTerm('domain.name', 'example.org')], + }, + { + input: 'domain.id: my-id', + expected: [term('domain.id', 'my-id')], + }, + { + input: '-domain.id: my-id', + expected: [notTerm('domain.id', 'my-id')], + }, + ]; + + const hostTestCases: HappyTestCase[] = [ + { + input: 'host.id', + expected: [ + { + not: false, + incomplete: true, + type: 'host.id', + value: null, + }, + ], + }, + { + input: 'host', + expected: [ + { + not: false, + incomplete: true, + type: 'host.ip', + value: null, + }, + ], + }, + { + input: '-host', + expected: [ + { + incomplete: true, + not: true, + type: 'host.ip', + value: null, + }, + ], + }, + ]; + + const portTestCases: HappyTestCase[] = [ + { + input: 'port', + expected: [ + { + not: false, + incomplete: true, + type: 'port.number', + value: null, + }, + ], + }, + { + input: '-port.number', + expected: [ + { + incomplete: true, + not: true, + type: 'port.number', + value: null, + }, + ], + }, + ]; + + const findingTestCases: HappyTestCase[] = [ + { + input: 'finding', + expected: [ + { + not: false, + incomplete: true, + type: 'finding', + key: { + findingKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.', + expected: [ + { + not: false, + incomplete: true, + type: 'finding', + key: { + findingKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.foo.', + expected: [ + { + not: false, + incomplete: true, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.foo.bar: 123', + expected: [ + { + not: false, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: 'bar', + }, + value: '123', + }, + ], + }, + { + input: '-finding.foo.bar: 123', + expected: [ + { + not: true, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: 'bar', + }, + value: '123', + }, + ], + }, + { + input: 'finding.foo: exists', + expected: [ + { + not: false, + type: 'finding', + key: { + findingKey: 'foo', + }, + value: 'exists', + }, + ], + }, + ]; + + it.each([ + ...generalUseCases, + ...domainTestCases, + ...hostTestCases, + ...portTestCases, + ...findingTestCases, + ...tagsTestCases, + ...isTestCases, + ])(`Should parse "$input" correctly`, ({ input, expected }) => { + // Arrange + // Act + const parsed = parser.parse(input); + + // Assert + expect(parsed).toEqual(expected); + }); +}); + +function term(type: TermType, value: string): SearchTerm { + return { + not: false, + type, + value, + }; +} + +function notTerm(type: TermType, value: string): SearchTerm { + return { + not: true, + type, + value, + }; +} diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.ts new file mode 100644 index 00000000..80487169 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.ts @@ -0,0 +1,47 @@ +import * as searchParser from './generated/search-parser'; +import { + isFindingFieldTerm, + isFindingTerm, + SearchTerms, +} from './search-query-parser.types'; + +export interface ParseOptions { + completeTermsOnly?: boolean; + excludeEmptyValues?: boolean; +} + +export class SearchQueryParser { + public parse(query: string, options?: ParseOptions): SearchTerms { + let terms = searchParser.parse(query) as SearchTerms; + if (options?.completeTermsOnly) { + terms = terms.filter((x) => !x.incomplete); + } + + if (options?.excludeEmptyValues) { + terms = terms.filter((x) => x.value != null && x.value !== ''); + } + + return terms; + } + + public toQueryString(query: string | SearchTerms) { + if (typeof query === 'string') return query; + + return query + .filter((x) => !x.incomplete && x.value != null) + .map((x) => { + if (isFindingTerm(x)) { + return `${x.not ? '-' : ''}finding.${x.key.findingKey}: ${x.value}`; + } + + if (isFindingFieldTerm(x)) { + return `${x.not ? '-' : ''}finding.${x.key.findingKey}.${ + x.key.fieldKey + }: ${x.value}`; + } + + return `${x.not ? '-' : ''}${x.type}: ${x.value}`; + }) + .join(' '); + } +} diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.types.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.types.ts new file mode 100644 index 00000000..8ef988b9 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query-parser.types.ts @@ -0,0 +1,98 @@ +/** Base type for a single search term */ +export type SearchTerm = + | NormalTerm + | FindingTerm + | FindingFieldTerm + | IncompleteTerm; + +export interface IncompleteTerm { + /** Indicates if the term is incomplete */ + incomplete?: true; + /** Indicates if the term is negated with "-" */ + not?: boolean; + /** Key for this term. */ + key: string; + /** Type for these terms */ + type: undefined | null; + /** The value for the term */ + value: null; +} + +export type TermTypes = + | 'is' + | 'project.id' + | 'project.name' + | 'domain.id' + | 'domain.name' + | 'host.id' + | 'host.ip' + | 'port.id' + | 'port.number' + | 'port.protocol' + | 'port.service' + | 'port.product' + | 'port.version' + | 'tag.name' + | 'tag.id' + | 'mergedIn.id' + | 'website' + | 'website.id'; + +/** Normal term */ +export interface NormalTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "-" */ + not?: boolean; + /** Type for these terms */ + type: TermTypes; + /** The value for the term */ + value: string | null; +} + +/** Term for finding type */ +export interface FindingTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "!" */ + not?: boolean; + /** Explicit type for finding */ + type: 'finding'; + /** The key for the finding */ + key: { + /** The main key for the finding */ + findingKey: string; + }; + /** The value for the term */ + value: string | null; +} + +/** Term for finding field type */ +export interface FindingFieldTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "!" */ + not?: boolean; + /** Explicit type for finding field */ + type: 'findingField'; + /** The key for the finding field */ + key: { + /** The main key for the finding */ + findingKey: string; + /** The field key for the finding */ + fieldKey: string; + }; + /** The value for the term */ + value: string | null; +} + +/** Type for a list of terms */ +export type SearchTerms = SearchTerm[]; + +export function isFindingTerm(term: SearchTerm): term is FindingTerm { + return term.type === 'finding'; +} + +export function isFindingFieldTerm(term: SearchTerm): term is FindingFieldTerm { + return term.type === 'findingField'; +} diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/generated/search-parser.d.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/generated/search-parser.d.ts new file mode 100644 index 00000000..e0ce7752 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/generated/search-parser.d.ts @@ -0,0 +1,209 @@ +/** Provides information pointing to a location within a source. */ +export interface Location { + /** Line in the parsed source (1-based). */ + readonly line: number; + /** Column in the parsed source (1-based). */ + readonly column: number; + /** Offset in the parsed source (0-based). */ + readonly offset: number; +} + +/** + * Anything that can successfully be converted to a string with `String()` + * so that it can be used in error messages. + * + * The GrammarLocation class in Peggy is a good example. + */ +export interface GrammarSourceObject { + readonly toString: () => string; + + /** + * If specified, allows the grammar source to be embedded in a larger file + * at some offset. + */ + readonly offset?: undefined | ((loc: Location) => Location); +} + +/** + * Most often, you just use a string with the file name. + */ +export type GrammarSource = string | GrammarSourceObject; + +/** The `start` and `end` position's of an object within the source. */ +export interface LocationRange { + /** + * A string or object that was supplied to the `parse()` call as the + * `grammarSource` option. + */ + readonly source: GrammarSource; + /** Position at the beginning of the expression. */ + readonly start: Location; + /** Position after the end of the expression. */ + readonly end: Location; +} + +/** + * Expected a literal string, like `"foo"i`. + */ +export interface LiteralExpectation { + readonly type: "literal"; + readonly text: string; + readonly ignoreCase: boolean; +} + +/** + * Range of characters, like `a-z` + */ +export type ClassRange = [ + start: string, + end: string, +] + +export interface ClassParts extends Array { +} + +/** + * Expected a class, such as `[^acd-gz]i` + */ +export interface ClassExpectation { + readonly type: "class"; + readonly parts: ClassParts; + readonly inverted: boolean; + readonly ignoreCase: boolean; +} + +/** + * Expected any character, with `.` + */ +export interface AnyExpectation { + readonly type: "any"; +} + +/** + * Expected the end of input. + */ +export interface EndExpectation { + readonly type: "end"; +} + +/** + * Expected some other input. These are specified with a rule's + * "human-readable name", or with the `expected(message, location)` + * function. + */ +export interface OtherExpectation { + readonly type: "other"; + readonly description: string; +} + +export type Expectation = + | AnyExpectation + | ClassExpectation + | EndExpectation + | LiteralExpectation + | OtherExpectation; + +/** + * Pass an array of these into `SyntaxError.prototype.format()` + */ +export interface SourceText { + /** + * Identifier of an input that was used as a grammarSource in parse(). + */ + readonly source: GrammarSource; + /** Source text of the input. */ + readonly text: string; +} + +export declare class SyntaxError extends Error { + /** + * Constructs the human-readable message from the machine representation. + * + * @param expected Array of expected items, generated by the parser + * @param found Any text that will appear as found in the input instead of + * expected + */ + static buildMessage(expected: Expectation[], found?: string | null | undefined): string; + readonly message: string; + readonly expected: Expectation[]; + readonly found: string | null | undefined; + readonly location: LocationRange; + readonly name: string; + constructor( + message: string, + expected: Expectation[], + found: string | null, + location: LocationRange, + ); + + /** + * With good sources, generates a feature-rich error message pointing to the + * error in the input. + * @param sources List of {source, text} objects that map to the input. + */ + format(sources: SourceText[]): string; +} + +/** + * Trace execution of the parser. + */ +export interface ParserTracer { + trace: (event: ParserTracerEvent) => void; +} + +export type ParserTracerEvent + = { + readonly type: "rule.enter"; + readonly rule: string; + readonly location: LocationRange + } + | { + readonly type: "rule.fail"; + readonly rule: string; + readonly location: LocationRange + } + | { + readonly type: "rule.match"; + readonly rule: string; + readonly location: LocationRange + /** Return value from the rule. */ + readonly result: unknown; + }; + +export type StartRuleNames = "start"; +export interface ParseOptions { + /** + * String or object that will be attached to the each `LocationRange` object + * created by the parser. For example, this can be path to the parsed file + * or even the File object. + */ + readonly grammarSource?: GrammarSource; + readonly startRule?: T; + readonly tracer?: ParserTracer; + + // Internal use only: + readonly peg$library?: boolean; + // Internal use only: + peg$currPos?: number; + // Internal use only: + peg$silentFails?: number; + // Internal use only: + peg$maxFailExpected?: Expectation[]; + // Extra application-specific properties + [key: string]: unknown; +} + +export declare const StartRules: StartRuleNames[]; +export declare const parse: typeof ParseFunction; + +// Overload of ParseFunction for each allowedStartRule + +declare function ParseFunction>( + input: string, + options?: Options, +): any; + +declare function ParseFunction>( + input: string, + options?: Options, +): any; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/generated/search-parser.js b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/generated/search-parser.js new file mode 100644 index 00000000..7f927ff6 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/generated/search-parser.js @@ -0,0 +1,1520 @@ +// @generated by Peggy 4.2.0. +// +// https://peggyjs.org/ + +"use strict"; + + +function peg$subclass(child, parent) { + function C() { this.constructor = child; } + C.prototype = parent.prototype; + child.prototype = new C(); +} + +function peg$SyntaxError(message, expected, found, location) { + var self = Error.call(this, message); + // istanbul ignore next Check is a necessary evil to support older environments + if (Object.setPrototypeOf) { + Object.setPrototypeOf(self, peg$SyntaxError.prototype); + } + self.expected = expected; + self.found = found; + self.location = location; + self.name = "SyntaxError"; + return self; +} + +peg$subclass(peg$SyntaxError, Error); + +function peg$padEnd(str, targetLength, padString) { + padString = padString || " "; + if (str.length > targetLength) { return str; } + targetLength -= str.length; + padString += padString.repeat(targetLength); + return str + padString.slice(0, targetLength); +} + +peg$SyntaxError.prototype.format = function(sources) { + var str = "Error: " + this.message; + if (this.location) { + var src = null; + var k; + for (k = 0; k < sources.length; k++) { + if (sources[k].source === this.location.source) { + src = sources[k].text.split(/\r\n|\n|\r/g); + break; + } + } + var s = this.location.start; + var offset_s = (this.location.source && (typeof this.location.source.offset === "function")) + ? this.location.source.offset(s) + : s; + var loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; + if (src) { + var e = this.location.end; + var filler = peg$padEnd("", offset_s.line.toString().length, ' '); + var line = src[s.line - 1]; + var last = s.line === e.line ? e.column : line.length + 1; + var hatLen = (last - s.column) || 1; + str += "\n --> " + loc + "\n" + + filler + " |\n" + + offset_s.line + " | " + line + "\n" + + filler + " | " + peg$padEnd("", s.column - 1, ' ') + + peg$padEnd("", hatLen, "^"); + } else { + str += "\n at " + loc; + } + } + return str; +}; + +peg$SyntaxError.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + class: function(expectation) { + var escapedParts = expectation.parts.map(function(part) { + return Array.isArray(part) + ? classEscape(part[0]) + "-" + classEscape(part[1]) + : classEscape(part); + }); + + return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]"; + }, + + any: function() { + return "any character"; + }, + + end: function() { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/"/g, "\\\"") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/\]/g, "\\]") + .replace(/\^/g, "\\^") + .replace(/-/g, "\\-") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = expected.map(describeExpectation); + var i, j; + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse(input, options) { + options = options !== undefined ? options : {}; + + var peg$FAILED = {}; + var peg$source = options.grammarSource; + + var peg$startRuleFunctions = { start: peg$parsestart }; + var peg$startRuleFunction = peg$parsestart; + + var peg$c0 = ":"; + var peg$c1 = "-"; + var peg$c2 = "exists"; + var peg$c3 = "finding."; + var peg$c4 = "."; + var peg$c5 = "finding"; + var peg$c6 = "project.name"; + var peg$c7 = "project.id"; + var peg$c8 = "project"; + var peg$c9 = "domain.name"; + var peg$c10 = "domain.id"; + var peg$c11 = "domain"; + var peg$c12 = "host.ip"; + var peg$c13 = "host.id"; + var peg$c14 = "host"; + var peg$c15 = "port.number"; + var peg$c16 = "port.id"; + var peg$c17 = "port.protocol"; + var peg$c18 = "port"; + var peg$c19 = "port.service"; + var peg$c20 = "port.product"; + var peg$c21 = "port.version"; + var peg$c22 = "tag.id"; + var peg$c23 = "tag.name"; + var peg$c24 = "tag"; + var peg$c25 = "mergedIn.id"; + var peg$c26 = "is"; + + var peg$r0 = /^[a-zA-Z._]/; + var peg$r1 = /^[a-zA-Z0-9:_\-:\/.*]/; + var peg$r2 = /^["]/; + var peg$r3 = /^[a-zA-Z0-9._\- :\/*]/; + var peg$r4 = /^[a-zA-Z0-9\-]/; + var peg$r5 = /^[a-zA-Z0-9]/; + var peg$r6 = /^[ \t\n\r]/; + + var peg$e0 = peg$literalExpectation(":", false); + var peg$e1 = peg$classExpectation([["a", "z"], ["A", "Z"], ".", "_"], false, false); + var peg$e2 = peg$literalExpectation("-", false); + var peg$e3 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], ":", "_", "-", ":", "/", ".", "*"], false, false); + var peg$e4 = peg$classExpectation(["\""], false, false); + var peg$e5 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], ".", "_", "-", " ", ":", "/", "*"], false, false); + var peg$e6 = peg$literalExpectation("exists", false); + var peg$e7 = peg$literalExpectation("finding.", false); + var peg$e8 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "-"], false, false); + var peg$e9 = peg$literalExpectation(".", false); + var peg$e10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false); + var peg$e11 = peg$literalExpectation("finding", false); + var peg$e12 = peg$literalExpectation("project.name", false); + var peg$e13 = peg$literalExpectation("project.id", false); + var peg$e14 = peg$literalExpectation("project", false); + var peg$e15 = peg$literalExpectation("domain.name", false); + var peg$e16 = peg$literalExpectation("domain.id", false); + var peg$e17 = peg$literalExpectation("domain", false); + var peg$e18 = peg$literalExpectation("host.ip", false); + var peg$e19 = peg$literalExpectation("host.id", false); + var peg$e20 = peg$literalExpectation("host", false); + var peg$e21 = peg$literalExpectation("port.number", false); + var peg$e22 = peg$literalExpectation("port.id", false); + var peg$e23 = peg$literalExpectation("port.protocol", false); + var peg$e24 = peg$literalExpectation("port", false); + var peg$e25 = peg$literalExpectation("port.service", false); + var peg$e26 = peg$literalExpectation("port.product", false); + var peg$e27 = peg$literalExpectation("port.version", false); + var peg$e28 = peg$literalExpectation("tag.id", false); + var peg$e29 = peg$literalExpectation("tag.name", false); + var peg$e30 = peg$literalExpectation("tag", false); + var peg$e31 = peg$literalExpectation("mergedIn.id", false); + var peg$e32 = peg$literalExpectation("is", false); + var peg$e33 = peg$otherExpectation("whitespace"); + var peg$e34 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false); + + var peg$f0 = function(terms) { + return terms ? [terms[0]].concat(terms[1].map(([_, t]) => t)) : []; + }; + var peg$f1 = function(not, type, value) { + return { not: not ?? false, type, value }; + }; + var peg$f2 = function(not, key) { + return { incomplete: true, not: not ?? false, type: key, value: null } + }; + var peg$f3 = function(not, key) { + return { incomplete: true, not: not ?? false, key, type: "findingField", value: null } + }; + var peg$f4 = function(not, key) { + return { incomplete: true, not: not ?? false, key, type: "finding", value: null } + }; + var peg$f5 = function(not, key) { + return { incomplete: true, not: not ?? false, key, value: null, type: null } + }; + var peg$f6 = function(not, key, value) { + return { not: not ?? false, key, value, type: "findingField" }; + }; + var peg$f7 = function(not, key, value) { + return { not: not ?? false, key, value, type: "finding" }; + }; + var peg$f8 = function() { return true; }; + var peg$f9 = function(value) { + return value; + }; + var peg$f10 = function() { return null; }; + var peg$f11 = function(string) { + return string; + }; + var peg$f12 = function() { return "exists"; }; + var peg$f13 = function(finding_key, field_key) { + return { findingKey: finding_key, fieldKey: field_key }; + }; + var peg$f14 = function(finding_key) { + return { findingKey: finding_key }; + }; + var peg$f15 = function() { return "project.name"; }; + var peg$f16 = function() { return "project.id"; }; + var peg$f17 = function() { return "project.name"; }; + var peg$f18 = function() { return "domain.name"; }; + var peg$f19 = function() { return "domain.id"; }; + var peg$f20 = function() { return "domain.name"; }; + var peg$f21 = function() { return "host.ip"; }; + var peg$f22 = function() { return "host.id"; }; + var peg$f23 = function() { return "host.ip"; }; + var peg$f24 = function() { return "port.number"; }; + var peg$f25 = function() { return "port.id"; }; + var peg$f26 = function() { return "port.protocol"; }; + var peg$f27 = function() { return "port.number"; }; + var peg$f28 = function() { return "port.service"; }; + var peg$f29 = function() { return "port.product"; }; + var peg$f30 = function() { return "port.version"; }; + var peg$f31 = function() { return "tag.id"; }; + var peg$f32 = function() { return "tag.name"; }; + var peg$f33 = function() { return "tag.name"; }; + var peg$f34 = function() { return "mergedIn.id" }; + var peg$f35 = function() { return "is"; }; + var peg$currPos = options.peg$currPos | 0; + var peg$savedPos = peg$currPos; + var peg$posDetailsCache = [{ line: 1, column: 1 }]; + var peg$maxFailPos = peg$currPos; + var peg$maxFailExpected = options.peg$maxFailExpected || []; + var peg$silentFails = options.peg$silentFails | 0; + + var peg$result; + + if (options.startRule) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$savedPos, peg$currPos); + } + + function offset() { + return peg$savedPos; + } + + function range() { + return { + source: peg$source, + start: peg$savedPos, + end: peg$currPos + }; + } + + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); + } + + function expected(description, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildStructuredError( + [peg$otherExpectation(description)], + input.substring(peg$savedPos, peg$currPos), + location + ); + } + + function error(message, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildSimpleError(message, location); + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$otherExpectation(description) { + return { type: "other", description: description }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos]; + var p; + + if (details) { + return details; + } else { + if (pos >= peg$posDetailsCache.length) { + p = peg$posDetailsCache.length - 1; + } else { + p = pos; + while (!peg$posDetailsCache[--p]) {} + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + + return details; + } + } + + function peg$computeLocation(startPos, endPos, offset) { + var startPosDetails = peg$computePosDetails(startPos); + var endPosDetails = peg$computePosDetails(endPos); + + var res = { + source: peg$source, + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + if (offset && peg$source && (typeof peg$source.offset === "function")) { + res.start = peg$source.offset(res.start); + res.end = peg$source.offset(res.end); + } + return res; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildSimpleError(message, location) { + return new peg$SyntaxError(message, null, null, location); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError( + peg$SyntaxError.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parsestart() { + var s0; + + s0 = peg$parseterms(); + + return s0; + } + + function peg$parseterms() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$parseterm(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseterm(); + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseterm(); + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parse_(); + if (s2 === peg$FAILED) { + s2 = null; + } + peg$savedPos = s0; + s0 = peg$f0(s1); + + return s0; + } + + function peg$parseterm() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$parsefinding_field_term(); + if (s0 === peg$FAILED) { + s0 = peg$parsefinding_term(); + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsekey(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f1(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsekey(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f2(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_field_key(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f3(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_key(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f4(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r0.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r0.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f5(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsefinding_field_term() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_field_key(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f6(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefinding_term() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_key(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f7(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsenot() { + var s0, s1; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s1 = peg$c1; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e2); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f8(); + } + s0 = s1; + + return s0; + } + + function peg$parsevalue() { + var s0; + + s0 = peg$parseraw_value(); + if (s0 === peg$FAILED) { + s0 = peg$parsestring(); + if (s0 === peg$FAILED) { + s0 = peg$parseexists(); + if (s0 === peg$FAILED) { + s0 = peg$parseempty_value(); + } + } + } + + return s0; + } + + function peg$parseraw_value() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = []; + s3 = input.charAt(peg$currPos); + if (peg$r1.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = input.charAt(peg$currPos); + if (peg$r1.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f9(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseempty_value() { + var s0, s1; + + s0 = peg$currPos; + s1 = ''; + peg$savedPos = s0; + s1 = peg$f10(); + s0 = s1; + + return s0; + } + + function peg$parsestring() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = input.charAt(peg$currPos); + if (peg$r2.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r3.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r3.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + s3 = input.charAt(peg$currPos); + if (peg$r2.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f11(s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseexists() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c2) { + s1 = peg$c2; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e6); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f12(); + } + s0 = s1; + + return s0; + } + + function peg$parsefinding_field_key() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c3) { + s1 = peg$c3; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e7); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r4.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r4.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c4; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + s5 = []; + s6 = input.charAt(peg$currPos); + if (peg$r5.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + s6 = input.charAt(peg$currPos); + if (peg$r5.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + } + s4 = input.substring(s4, peg$currPos); + peg$savedPos = s0; + s0 = peg$f13(s2, s4); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefinding_key() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c5) { + s1 = peg$c5; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e11); } + } + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s2 = peg$c4; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + s3 = peg$currPos; + s4 = []; + s5 = input.charAt(peg$currPos); + if (peg$r4.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = input.charAt(peg$currPos); + if (peg$r4.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + } + s3 = input.substring(s3, peg$currPos); + peg$savedPos = s0; + s0 = peg$f14(s3); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsekey() { + var s0; + + s0 = peg$parseproject(); + if (s0 === peg$FAILED) { + s0 = peg$parsedomain(); + if (s0 === peg$FAILED) { + s0 = peg$parsehost(); + if (s0 === peg$FAILED) { + s0 = peg$parseport(); + if (s0 === peg$FAILED) { + s0 = peg$parsetags(); + if (s0 === peg$FAILED) { + s0 = peg$parseother(); + if (s0 === peg$FAILED) { + s0 = peg$parseis(); + } + } + } + } + } + } + + return s0; + } + + function peg$parseproject() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c6) { + s1 = peg$c6; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e12); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f15(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 10) === peg$c7) { + s1 = peg$c7; + peg$currPos += 10; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e13); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f16(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c8) { + s1 = peg$c8; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f17(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parsedomain() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 11) === peg$c9) { + s1 = peg$c9; + peg$currPos += 11; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e15); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f18(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 9) === peg$c10) { + s1 = peg$c10; + peg$currPos += 9; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e16); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f19(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c11) { + s1 = peg$c11; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e17); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f20(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parsehost() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c12) { + s1 = peg$c12; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e18); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f21(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c13) { + s1 = peg$c13; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e19); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f22(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c14) { + s1 = peg$c14; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e20); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f23(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parseport() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 11) === peg$c15) { + s1 = peg$c15; + peg$currPos += 11; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e21); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f24(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c16) { + s1 = peg$c16; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e22); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f25(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 13) === peg$c17) { + s1 = peg$c17; + peg$currPos += 13; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e23); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f26(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c18) { + s1 = peg$c18; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e24); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f27(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c19) { + s1 = peg$c19; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e25); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f28(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c20) { + s1 = peg$c20; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e26); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f29(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c21) { + s1 = peg$c21; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e27); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f30(); + } + s0 = s1; + } + } + } + } + } + } + + return s0; + } + + function peg$parsetags() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c22) { + s1 = peg$c22; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e28); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f31(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c23) { + s1 = peg$c23; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e29); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f32(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c24) { + s1 = peg$c24; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e30); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f33(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parseother() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 11) === peg$c25) { + s1 = peg$c25; + peg$currPos += 11; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e31); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f34(); + } + s0 = s1; + + return s0; + } + + function peg$parseis() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c26) { + s1 = peg$c26; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e32); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f35(); + } + s0 = s1; + + return s0; + } + + function peg$parse_() { + var s0, s1; + + peg$silentFails++; + s0 = []; + s1 = input.charAt(peg$currPos); + if (peg$r6.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e34); } + } + if (s1 !== peg$FAILED) { + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = input.charAt(peg$currPos); + if (peg$r6.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e34); } + } + } + } else { + s0 = peg$FAILED; + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e33); } + } + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (options.peg$library) { + return /** @type {any} */ ({ + peg$result, + peg$currPos, + peg$FAILED, + peg$maxFailExpected, + peg$maxFailPos + }); + } + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +module.exports = { + StartRules: ["start"], + SyntaxError: peg$SyntaxError, + parse: peg$parse +}; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/index.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/index.ts new file mode 100644 index 00000000..868f886d --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/index.ts @@ -0,0 +1,2 @@ +export * from './search-query-parser'; +export * from './search-query-parser.types'; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/peggy.config.mjs b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/peggy.config.mjs new file mode 100644 index 00000000..ba1e6b4b --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/peggy.config.mjs @@ -0,0 +1,6 @@ +// MJS +export default { + input: 'src/search-query/search-grammar.peggy', + output: 'src/search-query/generated/search-parser.js', + dts: true, +}; diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-grammar.peggy b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-grammar.peggy new file mode 100644 index 00000000..3537bc31 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-grammar.peggy @@ -0,0 +1,109 @@ +start + = terms + +terms + = terms:(term (_ term)*)? _? { + return terms ? [terms[0]].concat(terms[1].map(([_, t]) => t)) : []; + } + +term + = finding_field_term + / finding_term + / not:not? type:(key) ":" _? value:value { + return { not: not ?? false, type, value }; + } + / not:not? key:key { + return { incomplete: true, not: not ?? false, type: key, value: null } + } + / not:not? key:finding_field_key { + return { incomplete: true, not: not ?? false, key, type: "findingField", value: null } + } + / not:not? key:finding_key { + return { incomplete: true, not: not ?? false, key, type: "finding", value: null } + } + / not:not? key:$[a-zA-Z._]+ { + return { incomplete: true, not: not ?? false, key, value: null, type: null } + } + +finding_field_term + = not:not? key:finding_field_key ":" _? value:value { + return { not: not ?? false, key, value, type: "findingField" }; + } + +finding_term + = not:not? key:finding_key ":" _? value:value { + return { not: not ?? false, key, value, type: "finding" }; + } + +not + = "-" { return true; } + +value + = raw_value + / string + / exists + / empty_value + +raw_value + = value:$[a-zA-Z0-9:_\-:/.\*]+ { + return value; + } + +empty_value + = "" { return null; } + +string + = [\"] string:$[a-zA-Z0-9._\- :/\*]+ [\"] { + return string; + } + +exists = "exists" { return "exists"; } + +finding_field_key + = "finding." finding_key:$[a-zA-Z0-9-]+ "." field_key:$[a-zA-Z0-9]* { + return { findingKey: finding_key, fieldKey: field_key }; + } + +finding_key + = "finding" "."? finding_key:$[a-zA-Z0-9-]* { + return { findingKey: finding_key }; + } + +key = project / domain / host / port / tags / other / is + +project + = "project.name" { return "project.name"; } + / "project.id" { return "project.id"; } + / "project" { return "project.name"; } + +domain + = "domain.name" { return "domain.name"; } + / "domain.id" { return "domain.id"; } + / "domain" { return "domain.name"; } + +host + = "host.ip" { return "host.ip"; } + / "host.id" { return "host.id"; } + / "host" { return "host.ip"; } + +port + = "port.number" { return "port.number"; } + / "port.id" { return "port.id"; } + / "port.protocol" { return "port.protocol"; } + / "port" { return "port.number"; } + / "port.service" { return "port.service"; } + / "port.product" { return "port.product"; } + / "port.version" { return "port.version"; } + +tags + = "tag.id" { return "tag.id"; } + / "tag.name" { return "tag.name"; } + / "tag" { return "tag.name"; } + +other + = "mergedIn.id" { return "mergedIn.id" } + +is = "is" { return "is"; } + +_ "whitespace" + = [ \t\n\r]+ \ No newline at end of file diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.spec.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.spec.ts new file mode 100644 index 00000000..5536722b --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.spec.ts @@ -0,0 +1,391 @@ +import { SearchQueryParser } from './search-query-parser'; +import { + SearchTerm, + SearchTerms, + TermTypes as TermType, +} from './search-query-parser.types'; + +interface HappyTestCase { + input: string; + expected: SearchTerms; +} + +describe('Search Query Parser', () => { + const parser = new SearchQueryParser(); + + const generalUseCases: HappyTestCase[] = [ + { + input: 'domain: "I am confusing: I have spaces and colons"', + expected: [ + term('domain.name', 'I am confusing: I have spaces and colons'), + ], + }, + { + input: 'domain: http://a1b2.ca -is: blocked', + expected: [ + term('domain.name', 'http://a1b2.ca'), + notTerm('is', 'blocked'), + ], + }, + + // Incomplete + { + input: 'dom', + expected: [ + { + not: false, + incomplete: true, + key: 'dom', + value: null, + type: null, + }, + ], + }, + { + input: '-dom', + expected: [ + { + incomplete: true, + not: true, + key: 'dom', + value: null, + type: null, + }, + ], + }, + { + input: 'domain', + expected: [ + { + not: false, + incomplete: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: '-domain', + expected: [ + { + incomplete: true, + not: true, + type: 'domain.name', + value: null, + }, + ], + }, + ]; + + const isTestCases: HappyTestCase[] = [ + { + input: 'is', + expected: [ + { + not: false, + incomplete: true, + type: 'is', + value: null, + }, + ], + }, + { + input: '-is', + expected: [ + { + incomplete: true, + not: true, + type: 'is', + value: null, + }, + ], + }, + { + input: '-is: blocked', + expected: [notTerm('is', 'blocked')], + }, + { + input: 'is: blocked', + expected: [term('is', 'blocked')], + }, + ]; + + const tagsTestCases: HappyTestCase[] = [ + { + input: 'tag.name', + expected: [ + { + not: false, + incomplete: true, + type: 'tag.name', + value: null, + }, + ], + }, + { + input: '-tag.name', + expected: [ + { + incomplete: true, + not: true, + type: 'tag.name', + value: null, + }, + ], + }, + { + input: 'tag: my-tag', + expected: [term('tag.name', 'my-tag')], + }, + { + input: '-tag: my-tag', + expected: [notTerm('tag.name', 'my-tag')], + }, + { + input: 'tag.name: my-tag', + expected: [term('tag.name', 'my-tag')], + }, + { + input: '-tag.name: my-tag', + expected: [notTerm('tag.name', 'my-tag')], + }, + { + input: 'tag.id: my-id', + expected: [term('tag.id', 'my-id')], + }, + { + input: '-tag.id: my-id', + expected: [notTerm('tag.id', 'my-id')], + }, + ]; + + const domainTestCases: HappyTestCase[] = [ + { + input: 'domain.name', + expected: [ + { + not: false, + incomplete: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: '-domain.name', + expected: [ + { + incomplete: true, + not: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: 'domain: example.org', + expected: [term('domain.name', 'example.org')], + }, + { + input: '-domain: example.org', + expected: [notTerm('domain.name', 'example.org')], + }, + { + input: 'domain.name: example.org', + expected: [term('domain.name', 'example.org')], + }, + { + input: '-domain.name: example.org', + expected: [notTerm('domain.name', 'example.org')], + }, + { + input: 'domain.id: my-id', + expected: [term('domain.id', 'my-id')], + }, + { + input: '-domain.id: my-id', + expected: [notTerm('domain.id', 'my-id')], + }, + ]; + + const hostTestCases: HappyTestCase[] = [ + { + input: 'host.id', + expected: [ + { + not: false, + incomplete: true, + type: 'host.id', + value: null, + }, + ], + }, + { + input: 'host', + expected: [ + { + not: false, + incomplete: true, + type: 'host.ip', + value: null, + }, + ], + }, + { + input: '-host', + expected: [ + { + incomplete: true, + not: true, + type: 'host.ip', + value: null, + }, + ], + }, + ]; + + const portTestCases: HappyTestCase[] = [ + { + input: 'port', + expected: [ + { + not: false, + incomplete: true, + type: 'port.number', + value: null, + }, + ], + }, + { + input: '-port.number', + expected: [ + { + incomplete: true, + not: true, + type: 'port.number', + value: null, + }, + ], + }, + ]; + + const findingTestCases: HappyTestCase[] = [ + { + input: 'finding', + expected: [ + { + not: false, + incomplete: true, + type: 'finding', + key: { + findingKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.', + expected: [ + { + not: false, + incomplete: true, + type: 'finding', + key: { + findingKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.foo.', + expected: [ + { + not: false, + incomplete: true, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.foo.bar: 123', + expected: [ + { + not: false, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: 'bar', + }, + value: '123', + }, + ], + }, + { + input: '-finding.foo.bar: 123', + expected: [ + { + not: true, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: 'bar', + }, + value: '123', + }, + ], + }, + { + input: 'finding.foo: exists', + expected: [ + { + not: false, + type: 'finding', + key: { + findingKey: 'foo', + }, + value: 'exists', + }, + ], + }, + ]; + + it.each([ + ...generalUseCases, + ...domainTestCases, + ...hostTestCases, + ...portTestCases, + ...findingTestCases, + ...tagsTestCases, + ...isTestCases, + ])(`Should parse "$input" correctly`, ({ input, expected }) => { + // Arrange + // Act + const parsed = parser.parse(input); + + // Assert + expect(parsed).toEqual(expected); + }); +}); + +function term(type: TermType, value: string): SearchTerm { + return { + not: false, + type, + value, + }; +} + +function notTerm(type: TermType, value: string): SearchTerm { + return { + not: true, + type, + value, + }; +} diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.ts new file mode 100644 index 00000000..50e5d609 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.ts @@ -0,0 +1,33 @@ +import * as searchParser from './generated/search-parser'; +import { + isFindingFieldTerm, + isFindingTerm, + SearchTerms, +} from './search-query-parser.types'; + +export class SearchQueryParser { + public parse(query: string): SearchTerms { + return searchParser.parse(query); + } + + public toQueryString(query: string | SearchTerms) { + if (typeof query === 'string') return query; + + return query + .filter((x) => !x.incomplete && x.value != null) + .map((x) => { + if (isFindingTerm(x)) { + return `${x.not ? '-' : ''}finding.${x.key.findingKey}: ${x.value}`; + } + + if (isFindingFieldTerm(x)) { + return `${x.not ? '-' : ''}finding.${x.key.findingKey}.${ + x.key.fieldKey + }: ${x.value}`; + } + + return `${x.not ? '-' : ''}${x.type}: ${x.value}`; + }) + .join(' '); + } +} diff --git a/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.types.ts b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.types.ts new file mode 100644 index 00000000..8ef988b9 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/common-duplicates/search-query/search-query/search-query-parser.types.ts @@ -0,0 +1,98 @@ +/** Base type for a single search term */ +export type SearchTerm = + | NormalTerm + | FindingTerm + | FindingFieldTerm + | IncompleteTerm; + +export interface IncompleteTerm { + /** Indicates if the term is incomplete */ + incomplete?: true; + /** Indicates if the term is negated with "-" */ + not?: boolean; + /** Key for this term. */ + key: string; + /** Type for these terms */ + type: undefined | null; + /** The value for the term */ + value: null; +} + +export type TermTypes = + | 'is' + | 'project.id' + | 'project.name' + | 'domain.id' + | 'domain.name' + | 'host.id' + | 'host.ip' + | 'port.id' + | 'port.number' + | 'port.protocol' + | 'port.service' + | 'port.product' + | 'port.version' + | 'tag.name' + | 'tag.id' + | 'mergedIn.id' + | 'website' + | 'website.id'; + +/** Normal term */ +export interface NormalTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "-" */ + not?: boolean; + /** Type for these terms */ + type: TermTypes; + /** The value for the term */ + value: string | null; +} + +/** Term for finding type */ +export interface FindingTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "!" */ + not?: boolean; + /** Explicit type for finding */ + type: 'finding'; + /** The key for the finding */ + key: { + /** The main key for the finding */ + findingKey: string; + }; + /** The value for the term */ + value: string | null; +} + +/** Term for finding field type */ +export interface FindingFieldTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "!" */ + not?: boolean; + /** Explicit type for finding field */ + type: 'findingField'; + /** The key for the finding field */ + key: { + /** The main key for the finding */ + findingKey: string; + /** The field key for the finding */ + fieldKey: string; + }; + /** The value for the term */ + value: string | null; +} + +/** Type for a list of terms */ +export type SearchTerms = SearchTerm[]; + +export function isFindingTerm(term: SearchTerm): term is FindingTerm { + return term.type === 'finding'; +} + +export function isFindingFieldTerm(term: SearchTerm): term is FindingFieldTerm { + return term.type === 'findingField'; +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/custom-jobs/custom-jobs.controller.ts b/packages/backend/jobs-manager/service/src/modules/database/custom-jobs/custom-jobs.controller.ts index 1cecd55d..9b4d0a97 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/custom-jobs/custom-jobs.controller.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/custom-jobs/custom-jobs.controller.ts @@ -45,7 +45,6 @@ export class CustomJobsController { return await this.customJobsService.duplicate(dto.jobId); } else { const jobDto = plainToInstance(JobDto, dto); - console.log(jobDto); await validateOrReject(jobDto); return await this.customJobsService.create(dto); } diff --git a/packages/backend/jobs-manager/service/src/modules/database/database.constants.ts b/packages/backend/jobs-manager/service/src/modules/database/database.constants.ts index c4128d72..9ea150d7 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/database.constants.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/database.constants.ts @@ -11,5 +11,13 @@ export const MONGO_TIMESTAMP_SCHEMA_CONFIG: SchemaOptions = { }, }; -export const detailsLevel = ['extended', 'full', 'summary', 'number'] as const; -export type DetailsLevel = (typeof detailsLevel)[number]; +export const resourceDetailsLevel = ['extended', 'full', 'summary'] as const; +export type ResourceDetailsLevel = (typeof resourceDetailsLevel)[number]; + +export const portDetailsLevel = [ + 'extended', + 'full', + 'summary', + 'number', +] as const; +export type PortDetailsLevel = (typeof portDetailsLevel)[number]; diff --git a/packages/backend/jobs-manager/service/src/modules/database/database.dto.ts b/packages/backend/jobs-manager/service/src/modules/database/database.dto.ts index bae03c9e..9263e7b9 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/database.dto.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/database.dto.ts @@ -1,5 +1,9 @@ import { Type } from 'class-transformer'; import { IsIn, IsInt, IsOptional, Max, Min } from 'class-validator'; +import { + ResourceDetailsLevel, + resourceDetailsLevel, +} from './database.constants'; export class PagingDto { @IsInt() @@ -13,6 +17,12 @@ export class PagingDto { pageSize: number = 25; } +export class ResourceDetailsLevelDto { + @IsOptional() + @IsIn(resourceDetailsLevel) + detailsLevel?: ResourceDetailsLevel = 'full'; +} + export const sortDirections = ['ascending', 'descending'] as const; export type SortDirection = (typeof sortDirections)[number]; diff --git a/packages/backend/jobs-manager/service/src/modules/database/datalayer.module.ts b/packages/backend/jobs-manager/service/src/modules/database/datalayer.module.ts index fbd18da4..6c955d36 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/datalayer.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/datalayer.module.ts @@ -11,6 +11,7 @@ import { DomainModelModule } from './reporting/domain/domain-model.module'; import { FindingDefinitionsModelModule } from './reporting/finding-definitions/finding-definition-model.module'; import { FindingModelModule } from './reporting/findings/findings-model.module'; import { HostModelModule } from './reporting/host/host-model.module'; +import { IpRangeModelModule } from './reporting/ip-ranges/ip-range-model.module'; import { PortModelModule } from './reporting/port/port-model.module'; import { ProjectModelModule } from './reporting/project-model.module'; import { WebsiteModelModule } from './reporting/websites/website-model.module'; @@ -41,6 +42,7 @@ import { UserModelModule } from './users/users-model.module'; ApiKeyModelModule, UserModelModule, JobContainerModelModule, + IpRangeModelModule, FindingDefinitionsModelModule, TableModelModule, ], @@ -64,6 +66,7 @@ import { UserModelModule } from './users/users-model.module'; DomainModelModule, ApiKeyModelModule, JobContainerModelModule, + IpRangeModelModule, FindingDefinitionsModelModule, TableModelModule, ], diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/correlation.utils.spec.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/correlation.utils.spec.ts index 7c6afa62..9f41b799 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/correlation.utils.spec.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/correlation.utils.spec.ts @@ -56,7 +56,7 @@ describe('Finding utils', () => { // Assert expect(correlationKey).toBe( - `project:507f1f77bcf86cd799439011;host:1.2.3.4;mask:24`, + `project:507f1f77bcf86cd799439011;host:1.2.3.0;mask:24`, ); }); @@ -267,7 +267,7 @@ describe('Finding utils', () => { // Assert expect(correlationKey).toBe( - `project:507f1f77bcf86cd799439011;host:1.2.3.4;mask:24`, + `project:507f1f77bcf86cd799439011;host:1.2.3.0;mask:24`, ); }); diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/correlation.utils.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/correlation.utils.ts index 5630a2f8..d59c02bd 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/correlation.utils.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/correlation.utils.ts @@ -1,4 +1,8 @@ import { HttpBadRequestException } from '../../../exceptions/http.exceptions'; +import { + ipv4RangeValuesToMinMax, + numberToIpv4, +} from '../../../utils/ip-address.utils'; export class CorrelationKeyUtils { private static buildCorrelationKey(...parts: string[]) { @@ -21,8 +25,9 @@ export class CorrelationKeyUtils { ip: string, mask: number, ) { + const targetIp = numberToIpv4(ipv4RangeValuesToMinMax(ip, mask).min); return CorrelationKeyUtils.buildCorrelationKey( - CorrelationKeyUtils.hostCorrelationKey(projectId, ip), + CorrelationKeyUtils.hostCorrelationKey(projectId, targetIp), `mask:${mask}`, ); } @@ -171,9 +176,16 @@ export class CorrelationKeyUtils { | 'DomainsService' | 'HostService' | 'WebsiteService' + | 'IpRangeService' | null { // Host match if (correlationKey.match(/^project\:[a-f0-9]{24}\;host\:.+/)?.length > 0) { + // IP Range match + if ( + correlationKey.match(/^project\:[a-f0-9]{24}\;host\:.+\;mask\:\d\d?$/) + ?.length > 0 + ) + return 'IpRangeService'; // Port match if ( correlationKey.match(/.+\;port\:\d{1,5}\;protocol\:(tcp|udp)(\;.+)?$/) diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.dto.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.dto.ts index a7218bf9..a07fa138 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.dto.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.dto.ts @@ -9,11 +9,17 @@ import { } from 'class-validator'; import { Types } from 'mongoose'; import { PagingDto } from '../../database.dto'; -import { FilterByDomainDto, ResourceFilterDto } from '../resource.dto'; + +import { + FilterByDomainDto, + FilterByHostDto, + ResourceFilterDto, +} from '../resource.dto'; export class DomainFilterDto extends IntersectionType( ResourceFilterDto, FilterByDomainDto, + FilterByHostDto, ) {} export class DomainsPagingDto extends IntersectionType( diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.module.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.module.ts index bdb97e3c..70bc06cc 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.module.ts @@ -8,6 +8,7 @@ import { HostModule } from '../host/host.module'; import { WebsiteModule } from '../websites/website.module'; import { DomainsController } from './domain.controller'; import { DomainsService } from './domain.service'; +import { DomainsFilterParser } from './domains-filter-parser'; @Module({ imports: [ @@ -20,7 +21,7 @@ import { DomainsService } from './domain.service'; WebsiteModule, ], controllers: [DomainsController], - providers: [DomainsService], - exports: [DomainsService], + providers: [DomainsService, DomainsFilterParser], + exports: [DomainsService, DomainsFilterParser], }) export class DomainsModule {} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.service.spec.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.service.spec.ts index 165571de..8c80c6b6 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.service.spec.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.service.spec.ts @@ -1,7 +1,9 @@ import { Test, TestingModule } from '@nestjs/testing'; import { randomUUID } from 'crypto'; import { AppModule } from '../../../app.module'; +import { TagsDocument } from '../../tags/tag.model'; import { TagsService } from '../../tags/tag.service'; +import { HostDocument } from '../host/host.model'; import { HostService } from '../host/host.service'; import { ProjectDocument } from '../project.model'; import { ProjectService } from '../project.service'; @@ -62,168 +64,113 @@ describe('Domain Service', () => { }); describe('Get all', () => { - it('Filter by project', async () => { - // Arrange - const c1 = await project('my first project'); - const d1 = await domain('project5.example.org', c1); + let project1: ProjectDocument; + let project2: ProjectDocument; - const c2 = await project('my second project'); - const d2 = await domain('project6.example.org', c1); - - // Act - const allDomains = await domainService.getAll(0, 10, { - domains: null, - tags: null, - hosts: null, - projects: [c1._id.toString()], - page: 0, - pageSize: 10, - firstSeenStartDate: undefined, - firstSeenEndDate: undefined, - blocked: undefined, - }); - - // Assert - expect(allDomains.length).toBe(2); + let foo: TagsDocument; + let bar: TagsDocument; + let baz: TagsDocument; + let qux: TagsDocument; - const d1Res = allDomains[0]; - expect(d1Res.projectId.toString()).toBe(c1._id.toString()); - expect(d1Res.name).toStrictEqual(d1.name); + let h1: HostDocument; + let h2: HostDocument; + let h3: HostDocument; - const d2Res = allDomains[1]; - expect(d2Res.projectId.toString()).toBe(c1._id.toString()); - expect(d2Res.name).toStrictEqual(d2.name); - }); + let d1: DomainDocument; + let d2: DomainDocument; + let d3: DomainDocument; - it.each([ - [ - ['foo'], - 'foo.example.org', - 'bar.foo.project.example.org', - 'foo.bar.somethingelse.example.org', - ], - [ - ['foo', 'bar'], - 'bar.foo.project.example.org', - 'foo.bar.somethingelse.example.org', - ], - ])( - 'Filter by domain', - async (domains: string[], ...expectedDomains: string[]) => { - // Arrange - const c1 = await project('c1'); - const c2 = await project('c2'); + beforeEach(async () => { + // Arrange + project1 = await project('project 1'); + project2 = await project('project 2'); + [foo, bar, baz, qux] = await tags('foo', 'bar', 'baz', 'qux'); - const d1 = await domain('foo.example.org', c1); - const d2 = await domain('bar.foo.project.example.org', c1); - const d3 = await domain('foo.bar.somethingelse.example.org', c2); - const d4 = await domain('unrelated.example.org', c2); + d1 = await domain('d1.org', project1, [foo, bar]); + d2 = await domain('sub.d1.org', project1, [foo, baz]); + d3 = await domain('d1.biz', project2, [qux]); - // Act - const allDomains = await domainService.getAll(0, 10, { - domains: domains, - tags: null, - projects: null, - hosts: null, - page: 0, - pageSize: 10, - firstSeenStartDate: undefined, - firstSeenEndDate: undefined, - blocked: undefined, - }); + h1 = await host('1.1.1.1', d1.name, project1); + h2 = await host('1.2.2.2', d2.name, project1); + h3 = await host('1.2.2.3', d3.name, project2); - // Assert - expect(allDomains.map((x) => x.name).sort()).toStrictEqual( - expectedDomains.sort(), - ); - }, - ); + await block(d3); + }); it.each([ + ['', ['d1.org', 'sub.d1.org', 'd1.biz']], + + // Projects + ['project: "project*"', ['d1.org', 'sub.d1.org', 'd1.biz']], + ['project: "project 1"', ['d1.org', 'sub.d1.org']], + ['project: "project 2"', ['d1.biz']], + ['-project: "project 2"', ['d1.org', 'sub.d1.org']], + ['project.name: "project*"', ['d1.org', 'sub.d1.org', 'd1.biz']], + ['project.name: "project 1"', ['d1.org', 'sub.d1.org']], + ['project.name: "project 2"', ['d1.biz']], + ['-project.name: "project 2"', ['d1.org', 'sub.d1.org']], + [() => `project.id: ${project1.id}`, ['d1.org', 'sub.d1.org']], + [() => `project.id: ${project2.id}`, ['d1.biz']], + [() => `-project.id: ${project2.id}`, ['d1.org', 'sub.d1.org']], + + // Host + ['host: 1.1.1.1', ['d1.org']], + ['host.ip: 1.1.1.1', ['d1.org']], + [() => `host.id: ${h1._id}`, ['d1.org']], + ['host: 1.*', ['d1.org', 'sub.d1.org', 'd1.biz']], + ['host: 1.2.2*', ['sub.d1.org', 'd1.biz']], + ['-host: 1.1.1.1', ['sub.d1.org', 'd1.biz']], + ['-host.ip: 1.1.1.1', ['sub.d1.org', 'd1.biz']], + [() => `-host.id: ${h1.id}`, ['sub.d1.org', 'd1.biz']], + ['-host: 1.2.2*', ['d1.org']], + + // Domain + ['domain: d1.org', ['d1.org']], + ['domain: sub.d1.org', ['sub.d1.org']], + ['domain: d1.*', ['d1.org', 'd1.biz']], + ['-domain: d1.org', ['sub.d1.org', 'd1.biz']], + ['domain.name: d1.org', ['d1.org']], + ['domain.name: sub.d1.org', ['sub.d1.org']], + ['domain.name: d1.*', ['d1.org', 'd1.biz']], + ['-domain.name: d1.org', ['sub.d1.org', 'd1.biz']], + [() => `domain.id: ${d1.id}`, ['d1.org']], [ - ['159'], - 'foo.example.org', - 'bar.example.org', - 'bar.foo.project.example.org', + () => `domain.id: ${d2.id} domain.id: ${d3.id}`, + ['sub.d1.org', 'd1.biz'], ], - [['1.1.159.1'], 'foo.example.org', 'bar.example.org'], - [[' 1.1.159.1 '], 'foo.example.org', 'bar.example.org'], + + // Tag + ['tag: foo', ['d1.org', 'sub.d1.org']], + ['-tag: foo', ['d1.biz']], + [() => `tag.id: ${foo._id}`, ['d1.org', 'sub.d1.org']], + [() => `-tag.id: ${foo._id}`, ['d1.biz']], + ['-tag: ba*', ['d1.biz']], + ['tag: qux', ['d1.biz']], + ['tag: foo tag: bar', ['d1.org']], + ['-tag: foo tag: qux', ['d1.biz']], + + // Is + ['is: blocked', ['d1.biz']], + ['-is: blocked', ['d1.org', 'sub.d1.org']], ])( - 'Filter by host %s', - async (hosts: string[], ...expectedDomains: string[]) => { + 'Filter by "%s"', + async (query: string | (() => string), expected: string[]) => { // Arrange - const c1 = await project('c1'); - const c2 = await project('c2'); - - await domain('foo.example.org', c1); - await host('1.1.159.1', 'foo.example.org', c1); - await host('2.2.2.2', 'foo.example.org', c1); - - await domain('bar.example.org', c1); - await host('1.1.159.1', 'bar.example.org', c1); - - await domain('bar.foo.project.example.org', c2); - await host('6.6.159.6', 'bar.foo.project.example.org', c2); - - await domain('unrelated.example.org', c2); + if (typeof query !== 'string') query = query(); // Act - const allDomains = await domainService.getAll(0, 10, { - domains: null, - tags: null, - projects: null, - hosts: hosts, + const domains = await domainService.getAll(0, 10, { + query, page: 0, - pageSize: 10, - firstSeenStartDate: undefined, - firstSeenEndDate: undefined, - blocked: undefined, + pageSize: 100, }); // Assert - expect(allDomains.map((x) => x.name).sort()).toStrictEqual( - expectedDomains.sort(), + expect(domains.map((x) => x.name).sort()).toStrictEqual( + expected.sort(), ); }, ); - - it('Filter by tag', async () => { - // Arrange - const c1 = await project('c1'); - const c2 = await project('c2'); - - const t1 = await tag('t1'); - const t2 = await tag('t2'); - - const d1 = await domain('abc.example.org', c1); - const d2 = await domain('abc.project.example.org', c1); - const d3 = await domain('xyz.example.org', c2); - const d4 = await domain('unrelated.example.org', c2); - - await domainService.tagDomain(d1._id.toString(), t1._id.toString(), true); - await domainService.tagDomain(d4._id.toString(), t1._id.toString(), true); - await domainService.tagDomain(d2._id.toString(), t2._id.toString(), true); - - // Act - const allDomains = await domainService.getAll(0, 10, { - domains: null, - tags: [t1._id.toString()], - projects: null, - hosts: null, - page: 0, - pageSize: 10, - firstSeenStartDate: undefined, - firstSeenEndDate: undefined, - blocked: undefined, - }); - - // Assert - expect(allDomains.length).toStrictEqual(2); - expect(allDomains.map((x) => x.name).sort()).toStrictEqual([ - d1.name, - d4.name, - ]); - }); }); describe('Delete domains', () => { @@ -270,17 +217,50 @@ describe('Domain Service', () => { }); } - async function domain(domain: string, project: ProjectDocument) { - return ( + async function domain( + domain: string, + project: ProjectDocument, + tags: TagsDocument[] = [], + ) { + const d = ( await domainService.addDomains([domain], project._id) )[0] as DomainDocument; + + for (const tag of tags) { + await domainService.tagDomain(d.id, tag.id, true); + } + + return d; } async function host( ip: string, domainName: string, project: ProjectDocument, + tags: TagsDocument[] = [], ) { - return await hostService.addHostsWithDomain([ip], domainName, project._id); + const foo = await hostService.addHostsWithDomain( + [ip], + domainName, + project._id, + tags.map((x) => x.id), + ); + return foo[0]; + } + + async function tags(...tags: string[]) { + const createdTags: TagsDocument[] = []; + for (const tag of tags) { + createdTags.push(await tagsService.create(tag, '#ffffff')); + } + + return createdTags; + } + + async function block(...domains: DomainDocument[]) { + await domainService.batchEdit({ + block: true, + domainIds: domains.map((x) => x.id), + }); } }); diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.service.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.service.ts index ffc15f72..d57e4bac 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.service.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domain.service.ts @@ -6,7 +6,6 @@ import { HttpNotFoundException, HttpNotImplementedException, } from '../../../../exceptions/http.exceptions'; -import escapeStringRegexp from '../../../../utils/escape-string-regexp'; import { HostnameFinding } from '../../../findings/findings.service'; import { FindingsQueue } from '../../../queues/finding-queue/findings-queue'; import { ConfigService } from '../../admin/config/config.service'; @@ -20,6 +19,7 @@ import { Project } from '../project.model'; import { WebsiteService } from '../websites/website.service'; import { BatchEditDomainsDto, DomainsPagingDto } from './domain.dto'; import { Domain, DomainDocument } from './domain.model'; +import { DomainsFilterParser } from './domains-filter-parser'; @Injectable() export class DomainsService { @@ -35,6 +35,7 @@ export class DomainsService { private findingsQueue: FindingsQueue, private tagsService: TagsService, private websiteService: WebsiteService, + private readonly domainsFilterParser: DomainsFilterParser, ) {} /** @@ -233,7 +234,13 @@ export class DomainsService { ): Promise { let query; if (filter) { - query = this.domainModel.find(this.buildFilters(filter)); + query = this.domainModel.find( + await this.domainsFilterParser.buildFilter( + filter.query, + filter.firstSeenStartDate, + filter.firstSeenEndDate, + ), + ); } else { query = this.domainModel.find({}); } @@ -248,7 +255,13 @@ export class DomainsService { if (!filter) { return await this.domainModel.estimatedDocumentCount(); } else { - return await this.domainModel.countDocuments(this.buildFilters(filter)); + return await this.domainModel.countDocuments( + await this.domainsFilterParser.buildFilter( + filter.query, + filter.firstSeenStartDate, + filter.firstSeenEndDate, + ), + ); } } @@ -367,89 +380,6 @@ export class DomainsService { } } - public buildFilters(dto: DomainsPagingDto) { - const finalFilter = {}; - // Filter by domain - if (dto.domains) { - const preppedDomainArray = dto.domains - .filter((x) => x) - .map((x) => x.toLowerCase()) - .map((x) => escapeStringRegexp(x)) - .map((x) => new RegExp(x, 'i')); - - if (preppedDomainArray.length > 0) { - finalFilter['name'] = { $all: preppedDomainArray }; - } - } - - // Filter by host - if (dto.hosts) { - const hosts = dto.hosts - .filter((x) => x) - .map((x) => x.toLowerCase().trim()) - .map((x) => escapeStringRegexp(x)) - .map((x) => new RegExp(`.*${x}.*`)); - - if (hosts.length > 0) { - finalFilter['hosts.ip'] = { $in: hosts }; - } - } - - // Filter by project - if (dto.projects) { - const projectIds = dto.projects - .filter((x) => x) - .map((x) => new Types.ObjectId(x)); - - if (projectIds.length > 0) { - finalFilter['projectId'] = { $in: projectIds }; - } - } - - // Filter by tag - if (dto.tags) { - const preppedTagsArray = dto.tags - .filter((x) => x) - .map((x) => x.toLowerCase()) - .map((x) => new Types.ObjectId(x)); - - if (preppedTagsArray.length > 0) { - finalFilter['tags'] = { $all: preppedTagsArray }; - } - } - - // Filter by createdAt - if (dto.firstSeenStartDate || dto.firstSeenEndDate) { - let createdAtFilter = {}; - - if (dto.firstSeenStartDate && dto.firstSeenEndDate) { - createdAtFilter = [ - { createdAt: { $gte: dto.firstSeenStartDate } }, - { createdAt: { $lte: dto.firstSeenEndDate } }, - ]; - finalFilter['$and'] = createdAtFilter; - } else { - if (dto.firstSeenStartDate) - createdAtFilter = { $gte: dto.firstSeenStartDate }; - else if (dto.firstSeenEndDate) - createdAtFilter = { $lte: dto.firstSeenEndDate }; - finalFilter['createdAt'] = createdAtFilter; - } - } - - // Filter by blocked - if (dto.blocked === false) { - finalFilter['$or'] = [ - { blocked: { $exists: false } }, - { blocked: { $eq: false } }, - ]; - } else if (dto.blocked === true) { - finalFilter['blocked'] = { $eq: true }; - } - - return finalFilter; - } - public async batchEdit(dto: BatchEditDomainsDto) { const update: Partial = {}; if (dto.block || dto.block === false) update.blocked = dto.block; diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domains-filter-parser.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domains-filter-parser.ts new file mode 100644 index 00000000..37b72dc0 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/domain/domains-filter-parser.ts @@ -0,0 +1,136 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { SearchTerms } from '@red-kite/jobs-manager/common-duplicates/search-query'; +import { FilterQuery, Model, Types } from 'mongoose'; +import { Tag } from '../../tags/tag.model'; +import { FilterParserBase } from '../filters-parser/filter-parser-base'; +import { Host } from '../host/host.model'; +import { Port } from '../port/port.model'; +import { Project } from '../project.model'; +import { Domain, DomainDocument } from './domain.model'; + +@Injectable() +export class DomainsFilterParser extends FilterParserBase { + constructor( + @InjectModel('host') private readonly hostModel: Model, + @InjectModel('port') private readonly portsModel: Model, + @InjectModel('domain') private readonly domainsModel: Model, + @InjectModel('project') projectModel: Model, + @InjectModel('tags') tagModel: Model, + ) { + super(projectModel, tagModel); + } + + public async buildResourceFilters(terms: SearchTerms) { + return [ + ...this.domainIdFilters(terms), + ...this.domainNameFilters(terms), + ...(await this.hostFilters(terms)), + ]; + } + + /** Handles "domain.id" terms. */ + private domainIdFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'domain.id'); + if (t.length) { + const domains = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ _id: { $in: domains } }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'domain.id'); + if (t.length) { + const notDomains = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ _id: { $not: { $in: notDomains } } }); + } + } + return filters; + } + /** Handles "domain.name" terms. */ + private domainNameFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'domain.name'); + if (t.length) { + const domains = this.toInclusionList(t, { lowercase: true }); + filters.push({ name: { $in: domains } }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'domain.name'); + if (t.length) { + const notDomains = this.toInclusionList(t, { lowercase: true }); + filters.push({ name: { $not: { $in: notDomains } } }); + } + } + return filters; + } + + /** Handles "host.id" terms. */ + private async hostFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // "host.id" filters + { + // Include + { + const t = this.consumeTerms(terms, '', 'host.id'); + if (t.length) { + const hosts = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ 'hosts.id': { $in: hosts } }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'host.id'); + if (t.length) { + const notHosts = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ 'hosts.id': { $not: { $in: notHosts } } }); + } + } + } + + // Include + { + { + const t = this.consumeTerms(terms, '', 'host.ip'); + if (t.length) { + const hosts = await this.hostModel.find( + { ip: { $in: this.toInclusionList(t) } }, + '_id', + ); + + filters.push({ 'hosts.id': { $in: hosts.map((x) => x._id) } }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'host.ip'); + if (t.length) { + const hosts = await this.hostModel.find( + { ip: { $in: this.toInclusionList(t) } }, + '_id', + ); + + filters.push({ + 'hosts.id': { $not: { $in: hosts.map((x) => x._id) } }, + }); + } + } + } + + return filters; + } +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/filters-parser/filter-parser-base.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/filters-parser/filter-parser-base.ts new file mode 100644 index 00000000..6bac1e66 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/filters-parser/filter-parser-base.ts @@ -0,0 +1,287 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { + SearchQueryParser, + SearchTerm, + SearchTerms, + TermTypes, +} from '@red-kite/jobs-manager/common-duplicates/search-query'; +import { FilterQuery, Model, Types } from 'mongoose'; +import { BadRequestError } from 'passport-headerapikey'; +import escapeStringRegexp from '../../../../utils/escape-string-regexp'; +import { Tag } from '../../tags/tag.model'; +import { Project } from '../project.model'; +import { Resource } from '../resource.type'; +import { SearchTermsValidator } from './search-terms-validator'; + +@Injectable() +export abstract class FilterParserBase { + private validator = new SearchTermsValidator(); + protected queryParser = new SearchQueryParser(); + protected searchTermsValidator = new SearchTermsValidator(); + + constructor( + @InjectModel('project') private readonly projectModel: Model, + @InjectModel('tags') private readonly tagModel: Model, + ) {} + + public async buildFilter( + query: string, + firstSeenStartDate: number, + firstSeenEndDate: number, + ): Promise> { + const terms = this.queryParser.parse(query || '', { + completeTermsOnly: true, + excludeEmptyValues: true, + }); + + if (!terms.length) return {}; + this.validator.ensureTerms(terms); + + const finalFilter: FilterQuery = { + $and: [ + ...this.isBlockedFilters(terms), + ...this.firstSeenFilters(firstSeenStartDate, firstSeenEndDate), + ...(await this.projectFilters(terms)), + ...(await this.tagFilters(terms)), + ...(await this.buildResourceFilters(terms)), + ], + }; + + console.log(JSON.stringify(finalFilter)); + + if (terms.length) { + throw new BadRequestError( + `Some search terms were not handled: ${JSON.stringify(terms)}`, + ); + } + + return finalFilter; + } + + protected abstract buildResourceFilters( + terms: SearchTerms, + ): Promise[]>; + + protected consumeTerms( + terms: SearchTerms, + not: '-' | '', + type: TermTypes, + value?: string, + ): SearchTerms { + const selected = []; + + for (let i = 0; i < terms.length; ) { + const term = terms[i]; + if ( + term.type === type && + (not === '-') === term.not && + (value == null || term.value === value) + ) { + selected.push(terms[i]); + terms.splice(i, 1); + } else { + i++; + } + } + + return selected; + } + + protected toInclusionList( + terms: SearchTerm[], + options?: { lowercase: boolean }, + ): (string | RegExp)[] { + let values = terms.map((x) => x.value).map((x) => x.trim()); + if (options?.lowercase) { + values = values.map((x) => x.toLowerCase()); + } + + if (values.some((x) => x[x.length - 1] === '*')) { + return values + .map((x) => escapeStringRegexp(x)) + .map( + (x) => + new RegExp( + `^${x.substring(0, x.length - 2)}${ + x[x.length - 1] === '*' ? '.*' : x[x.length - 1] + }`, + ), + ); + } else { + return values; + } + } + + /** Creates inclusion and exclusion filters for "is: blocked" */ + private isBlockedFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // "is: blocked" filter + { + // Include + { + const t = this.consumeTerms(terms, '', 'is', 'blocked'); + if (t.length) { + filters.push({ blocked: true }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'is', 'blocked'); + if (t.length) { + filters.push({ blocked: { $not: { $eq: true } } }); + } + } + } + + return filters; + } + + /** Creates filters using created at date. */ + private firstSeenFilters( + firstSeenStartDate: number, + firstSeenEndDate: number, + ) { + const filters: FilterQuery[] = []; + + // Filter by createdAt + { + // Start + if (firstSeenStartDate) { + filters.push({ createdAt: { $gte: firstSeenStartDate } }); + } + + // End + if (firstSeenEndDate) { + filters.push({ createdAt: { $lt: firstSeenEndDate } }); + } + } + + return filters; + } + + private async tagFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // "tag.name" + { + // Include + { + const t = this.consumeTerms(terms, '', 'tag.name'); + if (t.length) { + const tags = await this.tagModel.find({ + text: { $in: this.toInclusionList(t, { lowercase: true }) }, + }); + + filters.push({ + tags: { $all: tags.map((x) => x._id) }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'tag.name'); + if (t.length) { + const tags = await this.tagModel.find( + { text: { $in: this.toInclusionList(t, { lowercase: true }) } }, + '_id', + ); + + filters.push({ + tags: { $nin: tags.map((x) => x._id) }, + }); + } + } + } + + // "tag.id" filters + { + // Include + { + const t = this.consumeTerms(terms, '', 'tag.id'); + if (t.length) { + const tagIds = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ + tags: { $all: tagIds }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'tag.id'); + if (t.length) { + const tagIds = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ + tags: { $nin: tagIds }, + }); + } + } + } + + return filters; + } + + private async projectFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // "project.id" filters + { + // Include + { + const t = this.consumeTerms(terms, '', 'project.id'); + if (t.length) { + const projects = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ projectId: { $in: projects } }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'project.id'); + if (t.length) { + const projects = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ projectId: { $not: { $in: projects } } }); + } + } + } + + // "project.name" filters + { + // Include + { + const t = this.consumeTerms(terms, '', 'project.name'); + if (t.length) { + const projects = await this.projectModel.find( + { name: { $in: this.toInclusionList(t) } }, + '_id', + ); + + filters.push({ + projectId: { $in: projects.map((x) => x._id) }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'project.name'); + if (t.length) { + const projects = await this.projectModel.find( + { name: { $in: this.toInclusionList(t) } }, + '_id', + ); + + filters.push({ + projectId: { $not: { $in: projects.map((x) => x._id) } }, + }); + } + } + } + + return filters; + } +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/filters-parser/search-terms-validator.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/filters-parser/search-terms-validator.ts new file mode 100644 index 00000000..71547389 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/filters-parser/search-terms-validator.ts @@ -0,0 +1,82 @@ +import { + SearchTerm, + SearchTerms, +} from '@red-kite/jobs-manager/common-duplicates/search-query'; +import { isIP } from 'class-validator'; +import { ObjectId } from 'mongodb'; +import { HttpBadRequestException } from '../../../../exceptions/http.exceptions'; + +export class SearchTermsValidator { + public ensureTerms(terms: SearchTerms): void { + for (const term of terms) { + switch (term.type) { + case 'is': + return this.ensureAllowedValues(term, ['blocked']); + + case 'domain.id': + case 'tag.id': + case 'host.id': + case 'port.id': + case 'project.id': + return this.ensureObjectId(term); + + case 'port.number': + return this.ensureNumber(term); + + case 'port.protocol': + return this.ensureAllowedValues(term, ['udp', 'tcp']); + + case 'finding': + return this.ensureAllowedValues(term, ['exists']); + + case 'host.ip': + case 'domain.name': + case 'tag.name': + case 'project.name': + case 'findingField': + // No validation required + return; + + default: + throw new HttpBadRequestException( + `${(term as any)?.type} filter not allowed.`, + ); + } + } + } + + protected ensureAllowedValues( + { value, type }: SearchTerm, + allowedValues: string[], + ) { + if (allowedValues.includes(value)) return; + + throw new HttpBadRequestException( + `Value ${value} not allowed for ${type} filter.`, + ); + } + + protected ensureObjectId({ value, type }: SearchTerm) { + if (ObjectId.isValid(value)) return; + + throw new HttpBadRequestException( + `Value should be an ObjectId for ${type} filter.`, + ); + } + + protected ensureNumber({ value, type }: SearchTerm) { + if (!Number.isNaN(value)) return; + + throw new HttpBadRequestException( + `Value should be a number for ${type} filter.`, + ); + } + + protected ensureIp({ value, type }: SearchTerm) { + if (isIP(value, 4) || isIP(value.replace(/\*$/, ''))) return; + + throw new HttpBadRequestException( + `Value should be a valid IP address for ${type} filter, but got "${value}".`, + ); + } +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/findings/finding.model.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/findings/finding.model.ts index 5f96e03d..2914041e 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/findings/finding.model.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/findings/finding.model.ts @@ -50,7 +50,7 @@ export class CustomFinding { @Prop() public name: string; - @Prop() + @Prop({ index: true }) public key: string; @Prop({ index: true }) diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host-filter-parser.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host-filter-parser.ts new file mode 100644 index 00000000..04ae9440 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host-filter-parser.ts @@ -0,0 +1,93 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { SearchTerms } from '@red-kite/jobs-manager/common-duplicates/search-query'; +import { FilterQuery, Model, Types } from 'mongoose'; +import { Tag } from '../../tags/tag.model'; + +import { FilterParserBase } from '../filters-parser/filter-parser-base'; +import { Port } from '../port/port.model'; +import { Project } from '../project.model'; +import { Host, HostDocument } from './host.model'; + +@Injectable() +export class HostsFilterParser extends FilterParserBase { + constructor( + @InjectModel('host') private readonly hostModel: Model, + @InjectModel('port') private readonly portsModel: Model, + @InjectModel('project') projectModel: Model, + @InjectModel('tags') tagModel: Model, + ) { + super(projectModel, tagModel); + } + + protected async buildResourceFilters(terms: SearchTerms) { + return [...this.idFilters(terms), ...this.ipFilters(terms)]; + + // TODO #319 + // // if (dto.ranges) { + // // const ranges: { min: number; max: number }[] = dto.ranges.map((range) => { + // // return ipv4RangeToMinMax(cidrStringToipv4Range(range)); + // // }); + // // finalFilter['$and'].push({ + // // $or: ranges.map((r) => { + // // return { + // // ipInt: { + // // $gte: r.min, + // // $lte: r.max, + // // }, + // // }; + // // }), + // // }); + // // } + } + + /** Handles "host.id" terms. */ + private idFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'host.id'); + if (t.length) { + const hosts = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ _id: { $in: hosts } }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'host.id'); + if (t.length) { + const notHosts = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ _id: { $not: { $in: notHosts } } }); + } + } + + return filters; + } + + /** Handles "host.ip" terms. */ + private ipFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'host.ip'); + if (t.length) { + filters.push({ ip: { $in: this.toInclusionList(t) } }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'host.ip'); + if (t.length) { + filters.push({ + ip: { $not: { $in: this.toInclusionList(t) } }, + }); + } + } + + return filters; + } +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host-filter.model.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host-filter.model.ts deleted file mode 100644 index e726b51f..00000000 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host-filter.model.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class HostFilterModel { - domains?: Array; - tags?: Array; - projects?: Array; - hosts?: Array; - firstSeenStartDate?: number; - firstSeenEndDate?: number; - blocked?: boolean; -} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.dto.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.dto.ts index a4f07fd4..d54fa070 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.dto.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.dto.ts @@ -10,12 +10,20 @@ import { IsPort, } from 'class-validator'; import { Types } from 'mongoose'; -import { PagingDto } from '../../database.dto'; -import { FilterByDomainDto, ResourceFilterDto } from '../resource.dto'; +import { PagingDto, ResourceDetailsLevelDto } from '../../database.dto'; +import { + FilterByDomainDto, + FilterByHostDto, + FilterByIpRangeDto, + ResourceFilterDto, +} from '../resource.dto'; export class HostsFilterDto extends IntersectionType( ResourceFilterDto, FilterByDomainDto, + FilterByHostDto, + FilterByIpRangeDto, + ResourceDetailsLevelDto, ) {} export class HostsPagingDto extends IntersectionType( diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.model.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.model.ts index e62ad93a..03587a49 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.model.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.model.ts @@ -10,6 +10,9 @@ export class Host { @Prop({ index: true }) public ip!: string; + @Prop({ index: true }) + public ipInt!: number; + /** * A pseudo-unique key identifying this entity. Used for findings. * This key should not change if this entity were to be recreated. diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.module.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.module.ts index e83deda5..5781e15b 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.module.ts @@ -7,6 +7,7 @@ import { TagsModule } from '../../tags/tag.module'; import { DomainsModule } from '../domain/domain.module'; import { PortModule } from '../port/port.module'; import { WebsiteModule } from '../websites/website.module'; +import { HostsFilterParser } from './host-filter-parser'; import { HostController } from './host.controller'; import { HostService } from './host.service'; @@ -22,7 +23,7 @@ import { HostService } from './host.service'; WebsiteModule, ], controllers: [HostController], - providers: [HostService], - exports: [HostService], + providers: [HostService, HostsFilterParser], + exports: [HostService, HostsFilterParser], }) export class HostModule {} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.service.spec.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.service.spec.ts index 00255a5c..9a071d93 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.service.spec.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.service.spec.ts @@ -1,11 +1,14 @@ import { Test, TestingModule } from '@nestjs/testing'; import { randomUUID } from 'crypto'; import { AppModule } from '../../../app.module'; +import { TagsDocument } from '../../tags/tag.model'; import { TagsService } from '../../tags/tag.service'; -import { Domain } from '../domain/domain.model'; +import { Domain, DomainDocument } from '../domain/domain.model'; import { DomainsService } from '../domain/domain.service'; +import { CreateProjectDto } from '../project.dto'; import { ProjectDocument } from '../project.model'; import { ProjectService } from '../project.service'; +import { HostDocument } from './host.model'; import { HostService } from './host.service'; describe('Host Service', () => { @@ -30,6 +33,10 @@ describe('Host Service', () => { for (const c of allProjects) { await projectService.delete(c._id); } + const allTags = await tagsService.getAll(); + for (const t of allTags) { + await tagsService.delete(t._id.toString()); + } }); afterAll(async () => { @@ -37,7 +44,7 @@ describe('Host Service', () => { }); describe('Add hosts', () => { - it('Should only return new hosts', async () => { + it('Should only return hosts', async () => { // Arrange const c = await projectService.addProject({ name: randomUUID(), @@ -55,7 +62,7 @@ describe('Host Service', () => { newHosts = await host(d, c, [], '1.1.1.1'); // Assert - expect(newHosts.length).toBe(0); + expect(newHosts.length).toBe(1); }); it('Should support same ip for multiple hosts', async () => { @@ -83,134 +90,149 @@ describe('Host Service', () => { }); describe('Get all', () => { - it('Filter by project', async () => { - // Arrange - const c1 = await project('my first project'); - const d1 = await domain('project5.example.org', c1); + let project1: ProjectDocument; + let project2: ProjectDocument; - const c2 = await project('my second project'); - const d2 = await domain('project6.example.org', c2); + let domain1: DomainDocument; + let domain2: DomainDocument; + let domain3: DomainDocument; - await host(d1, c1, [], '8.8.8.8', '1.2.3.4'); - await host(d2, c2, [], '2.3.4.5', '6.7.8.9'); + let foo: TagsDocument; + let bar: TagsDocument; + let baz: TagsDocument; + let qux: TagsDocument; - // Act - const allHosts = await hostService.getAll(0, 10, { - projects: [c1.id], - }); + let h1: HostDocument; + let h2: HostDocument; + let h3: HostDocument; - // Assert - expect(allHosts.length).toBe(2); + beforeEach(async () => { + // Arrange + project1 = await project('project 1'); + project2 = await project('project 2'); + [foo, bar, baz, qux] = await tags('foo', 'bar', 'baz', 'qux'); - const h1 = allHosts[0]; - expect(h1.projectId.toString()).toBe(c1._id.toString()); - expect(h1.ip).toBe('8.8.8.8'); + domain1 = await domain('d1', project1); + domain2 = await domain('d2', project1); + domain3 = await domain('d3', project2); - const h2 = allHosts[1]; - expect(h2.projectId.toString()).toBe(c1._id.toString()); - expect(h2.ip).toBe('1.2.3.4'); + [h1, h2] = await host(domain1, project1, [foo], '1.1.1.1', '1.2.2.2'); + [h2] = await host(domain3, project2, [foo, bar], '1.2.2.2'); + [h3] = await host(domain3, project2, [foo, baz, qux], '1.2.2.3'); + + block(h3); }); it.each([ - [['foo'], '1.1.1.1', '2.2.2.2', '3.3.3.3', '4.4.4.4', '5.5.5.5'], - [['foo', 'bar'], '1.1.1.1', '3.3.3.3', '4.4.4.4', '5.5.5.5'], + ['', ['1.1.1.1', '1.2.2.2', '1.2.2.2', '1.2.2.3']], + + // Projects + ['project: "project*"', ['1.1.1.1', '1.2.2.2', '1.2.2.2', '1.2.2.3']], + ['project: "project 1"', ['1.1.1.1', '1.2.2.2']], + ['project: "project 2"', ['1.2.2.2', '1.2.2.3']], + ['-project: "project 2"', ['1.1.1.1', '1.2.2.2']], + [ + 'project.name: "project*"', + ['1.1.1.1', '1.2.2.2', '1.2.2.2', '1.2.2.3'], + ], + ['project.name: "project 1"', ['1.1.1.1', '1.2.2.2']], + ['project.name: "project 2"', ['1.2.2.2', '1.2.2.3']], + ['-project.name: "project 2"', ['1.1.1.1', '1.2.2.2']], + [() => `project.id: ${project1.id}`, ['1.1.1.1', '1.2.2.2']], + [() => `project.id: ${project2.id}`, ['1.2.2.2', '1.2.2.3']], + [() => `-project.id: ${project2.id}`, ['1.1.1.1', '1.2.2.2']], + + // Host + ['host: 1.1.1.1', ['1.1.1.1']], + ['host.ip: 1.1.1.1', ['1.1.1.1']], + [() => `host.id: ${h1.id}`, ['1.1.1.1']], + ['host: 1.*', ['1.1.1.1', '1.2.2.2', '1.2.2.2', '1.2.2.3']], + ['host: 1.2.2*', ['1.2.2.2', '1.2.2.2', '1.2.2.3']], + ['-host: 1.1.1.1', ['1.2.2.2', '1.2.2.2', '1.2.2.3']], + ['-host.ip: 1.1.1.1', ['1.2.2.2', '1.2.2.2', '1.2.2.3']], + [() => `-host.id: ${h1.id}`, ['1.2.2.2', '1.2.2.2', '1.2.2.3']], + ['-host: 1.2.2*', ['1.1.1.1']], + + // Tag + ['tag: foo', ['1.1.1.1', '1.2.2.2', '1.2.2.2', '1.2.2.3']], + ['-tag: foo', ['1.2.2.3']], + [() => `tag.id: ${foo.id}`, ['1.1.1.1', '1.2.2.2']], + [() => `-tag.id: ${foo.id}`, ['1.2.2.3']], + ['-tag: ba*', ['1.2.2.3']], + ['tag: qux', ['1.2.2.3']], + ['tag: foo tag: bar', ['1.1.1.1']], + ['-tag: foo tag: qux', ['1.2.2.3']], + + // Is + ['is: blocked', ['1.2.2.3']], + ['-is: blocked', ['1.1.1.1', '1.2.2.2']], ])( - 'Filter by domain', - async (domains: string[], ...expectedIps: string[]) => { + 'Filter by "%s"', + async (query: string | (() => string), expected: string[]) => { + console.log('### START'); // Arrange - const c1 = await project('c1'); - const c2 = await project('c2'); - - const d1 = await domain('foo.example.org', c1); - await host(d1, c1, [], '1.1.1.1', '2.2.2.2'); - - const d2 = await domain('bar.foo.project.example.org', c1); - await host(d2, c1, [], '1.1.1.1', '3.3.3.3'); - - const d3 = await domain('foo.bar.somethingelse.example.org', c2); - await host(d3, c2, [], '4.4.4.4', '5.5.5.5'); - - const d4 = await domain('unrelated.example.org', c2); - await host(d4, c2, [], '6.6.6.6'); + if (typeof query !== 'string') query = query(); + console.log(query); // Act - const allHosts = await hostService.getAll(0, 10, { - domains: domains, + const allHosts = await hostService.getAll(0, 10); + console.log(allHosts); + const hosts = await hostService.getAll(0, 10, { + query, }); // Assert - expect(allHosts.map((x) => x.ip).sort()).toStrictEqual( - expectedIps.sort(), - ); + expect(hosts.map((x) => x.ip).sort()).toStrictEqual(expected.sort()); + console.log('### END'); }, ); - it.each([ - [['159'], '1.1.159.1', '6.6.159.6'], - [['1.1.159.1'], '1.1.159.1'], - [[' 1.1.159.1 '], '1.1.159.1'], - [['2.2.2.2', '6.6.159.6'], '2.2.2.2', '6.6.159.6'], - ])('Filter by host', async (hosts: string[], ...expectedIps: string[]) => { - // Arrange - const c1 = await project('c1'); - const c2 = await project('c2'); - - const d1 = await domain('foo.example.org', c1); - await host(d1, c1, [], '1.1.159.1', '2.2.2.2'); - - const d2 = await domain('bar.foo.project.example.org', c1); - await host(d2, c1, [], '1.1.159.1', '3.3.3.3'); - - const d3 = await domain('foo.bar.somethingelse.example.org', c2); - await host(d3, c2, [], '4.4.4.4', '5.5.5.5'); - - const d4 = await domain('unrelated.example.org', c2); - await host(d4, c2, [], '6.6.159.6'); - - // Act - const allHosts = await hostService.getAll(0, 10, { - hosts: hosts, - }); - - // Assert - expect(allHosts.map((x) => x.ip).sort()).toStrictEqual( - expectedIps.sort(), - ); - }); - - it('Filter by tag', async () => { - // Arrange - const c1 = await project('c1'); - const c2 = await project('c2'); - - const t1 = await tag('t1'); - const t2 = await tag('t2'); - - const d1 = await domain('abc.example.org', c1); - await host(d1, c1, [t1._id.toString()], '1.1.1.1', '2.2.2.2'); - - const d2 = await domain('abc.project.example.org', c1); - await host(d2, c1, [t1._id.toString()], '1.1.1.1', '3.3.3.3'); - - const d3 = await domain('xyz.example.org', c2); - await host(d3, c2, [t2._id.toString()], '4.4.4.4', '5.5.5.5'); - - const d4 = await domain('unrelated.example.org', c2); - await host(d4, c2, [], '6.6.6.6'); - - // Act - const allHosts = await hostService.getAll(0, 10, { - tags: [t1._id.toString()], - }); - const allHosts2 = await hostService.getAll(0, 10, {}); - - // Assert - expect(allHosts.map((x) => x.ip).sort()).toStrictEqual([ - '1.1.1.1', - '2.2.2.2', - '3.3.3.3', - ]); - }); + // TODO #319: ADD IP RANGE TESTS + // it.each([ + // { + // ranges: ['1.1.1.1/16', '4.4.4.4/32'], + // expectedIps: ['1.1.159.1', '4.4.4.4'], + // }, + // { + // ranges: ['0.0.0.0/0'], + // expectedIps: [ + // '1.1.159.1', + // '2.2.2.2', + // '3.3.3.3', + // '4.4.4.4', + // '5.5.5.5', + // '6.6.159.6', + // ], + // }, + // { + // ranges: ['5.0.0.1/8'], + // expectedIps: ['5.5.5.5'], + // }, + // ])('Filter by ip range', async ({ ranges, expectedIps }) => { + // // Arrange + // const c1 = await project('c1'); + // const c2 = await project('c2'); + + // const d1 = await domain('foo.example.org', c1); + // await host(d1, c1, [], '1.1.159.1', '2.2.2.2'); + + // const d2 = await domain('bar.foo.project.example.org', c1); + // await host(d2, c1, [], '1.1.159.1', '3.3.3.3'); + + // const d3 = await domain('foo.bar.somethingelse.example.org', c2); + // await host(d3, c2, [], '4.4.4.4', '5.5.5.5'); + + // const d4 = await domain('unrelated.example.org', c2); + // await host(d4, c2, [], '6.6.159.6'); + + // // Act + // const allHosts = await hostService.getAll(0, 10, { ranges }); + + // // Assert + // expect(allHosts.map((x) => x.ip).sort()).toStrictEqual( + // expectedIps.sort(), + // ); + // }); }); describe('Delete hosts', () => { @@ -233,13 +255,20 @@ describe('Host Service', () => { const c1 = await project('my first project'); const d2 = await domain('project6.example.org', c1); - const h = await host(d2, c1, [], '2.3.4.5', '1.1.1.1', '3.3.3.3'); + const [h1, h2, h3] = await host( + d2, + c1, + [], + '2.3.4.5', + '1.1.1.1', + '3.3.3.3', + ); // Act const res = await hostService.deleteMany([ - h[0]._id.toString(), - h[1]._id.toString(), - h[2]._id.toString(), + h1._id.toString(), + h2._id.toString(), + h3._id.toString(), ]); // Assert @@ -247,33 +276,42 @@ describe('Host Service', () => { }); }); + async function project(name: string = '') { + const ccDto: CreateProjectDto = { name }; + return await projectService.addProject(ccDto); + } + async function host( domain: Domain, project: ProjectDocument, - tags: string[], + tags: TagsDocument[], ...ips: string[] ) { return await hostService.addHostsWithDomain( ips, domain.name, project._id.toString(), - tags, + tags.map((x) => x.id), ); } - async function tag(name: string) { - return await tagsService.create(name, '#cccccc'); - } + async function tags(...tags: string[]) { + const createdTags: TagsDocument[] = []; + for (const tag of tags) { + createdTags.push(await tagsService.create(tag, '#ffffff')); + } - async function project(name: string) { - return await projectService.addProject({ - name: name, - imageType: null, - logo: null, - }); + return createdTags; } async function domain(domain: string, project: ProjectDocument) { - return (await domainService.addDomains([domain], project._id))[0] as Domain; + return (await domainService.addDomains([domain], project._id))[0]; + } + + async function block(...hosts: HostDocument[]) { + await hostService.batchEdit({ + block: true, + hostIds: hosts.map((x) => x.id), + }); } }); diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.service.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.service.ts index d3006995..c4b66ed7 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.service.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/host/host.service.ts @@ -1,9 +1,9 @@ import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { DeleteResult, UpdateResult } from 'mongodb'; -import { FilterQuery, Model, Types } from 'mongoose'; +import { FilterQuery, Model, Query, Types } from 'mongoose'; import { HttpNotFoundException } from '../../../../exceptions/http.exceptions'; -import escapeStringRegexp from '../../../../utils/escape-string-regexp'; +import { ipv4ToNumber } from '../../../../utils/ip-address.utils'; import { IpFinding } from '../../../findings/findings.service'; import { FindingsQueue } from '../../../queues/finding-queue/findings-queue'; import { ConfigService } from '../../admin/config/config.service'; @@ -11,11 +11,12 @@ import { TagsService } from '../../tags/tag.service'; import { CorrelationKeyUtils } from '../correlation.utils'; import { DomainsService } from '../domain/domain.service'; import { DomainSummary } from '../domain/domain.summary'; +import { IpRange } from '../ip-ranges/ip-range.model'; import { PortService } from '../port/port.service'; import { Project } from '../project.model'; import { WebsiteService } from '../websites/website.service'; -import { HostFilterModel } from './host-filter.model'; -import { BatchEditHostsDto } from './host.dto'; +import { HostsFilterParser } from './host-filter-parser'; +import { BatchEditHostsDto, HostsFilterDto } from './host.dto'; import { Host, HostDocument } from './host.model'; import { HostSummary } from './host.summary'; @@ -25,6 +26,7 @@ export class HostService { constructor( @InjectModel('host') private readonly hostModel: Model, + @InjectModel('iprange') private readonly ipRangeModel: Model, @InjectModel('project') private readonly projectModel: Model, private configService: ConfigService, private tagsService: TagsService, @@ -33,18 +35,30 @@ export class HostService { private portsService: PortService, private findingsQueue: FindingsQueue, private websiteService: WebsiteService, + private hostsFilterParser: HostsFilterParser, ) {} public async getAll( page: number = null, pageSize: number = null, - filter: HostFilterModel = null, + filter: HostsFilterDto = null, ): Promise { - let query; + let query: Query; + let projection = + filter && filter.detailsLevel === 'summary' + ? '_id ip correlationKey' + : undefined; + if (filter) { - query = this.hostModel.find(this.buildFilters(filter)); + query = this.hostModel.find( + await this.hostsFilterParser.buildFilter( + filter.query, + filter.firstSeenStartDate, + filter.firstSeenEndDate, + ), + ); } else { - query = this.hostModel.find({}); + query = this.hostModel.find({}, projection); } if (page != null && pageSize != null) { @@ -88,11 +102,17 @@ export class HostService { return h && h.blocked; } - public async count(filter: HostFilterModel = null) { + public async count(filter: HostsFilterDto = null) { if (!filter) { return await this.hostModel.estimatedDocumentCount(); } else { - return await this.hostModel.countDocuments(this.buildFilters(filter)); + return await this.hostModel.countDocuments( + await this.hostsFilterParser.buildFilter( + filter.query, + filter.firstSeenStartDate, + filter.firstSeenEndDate, + ), + ); } } @@ -106,6 +126,7 @@ export class HostService { domainName, projectId, ); + if (!domain) { this.logger.debug(`Could not find the domain (domainName=${domainName})`); throw new HttpNotFoundException(`domainName=${domainName})`); @@ -132,8 +153,7 @@ export class HostService { } let hostSummaries: HostSummary[] = []; - let newIps: string[] = []; - let newHosts: Partial[] = []; + let newHosts: HostDocument[] = []; for (let ip of ips) { const ds: DomainSummary = { @@ -150,6 +170,7 @@ export class HostService { { $setOnInsert: { _id: mongoId, + ipInt: ipv4ToNumber(ip), projectId: new Types.ObjectId(projectId), projectName: project.name, correlationKey: CorrelationKeyUtils.hostCorrelationKey( @@ -160,28 +181,12 @@ export class HostService { $addToSet: { domains: ds, tags: { $each: existingTags } }, lastSeen: Date.now(), }, - { upsert: true, useFindAndModify: false }, + { upsert: true, useFindAndModify: false, returnDocument: 'after' }, ) .exec(); - if (!hostResult) { - // inserted - newIps.push(ip); - newHosts.push({ - ip: ip, - _id: mongoId.toString(), - domains: [ds], - projectId: new Types.ObjectId(projectId), - correlationKey: CorrelationKeyUtils.hostCorrelationKey(projectId, ip), - }); - hostSummaries.push({ id: mongoId, ip: ip }); - } else if ( - !hostResult.domains || - !hostResult.domains.some((ds) => ds.name === domainName) - ) { - // updated, so sync with relevant domain document must be done - hostSummaries.push({ id: hostResult._id, ip: ip }); - } + newHosts.push(hostResult); + hostSummaries.push({ id: hostResult._id, ip: ip }); } await this.domainService.addHostsToDomain(domain._id, hostSummaries); @@ -209,6 +214,7 @@ export class HostService { const model = new this.hostModel({ _id: new Types.ObjectId(), ip: ip, + ipInt: ipv4ToNumber(ip), projectId: new Types.ObjectId(projectId), correlationKey: CorrelationKeyUtils.hostCorrelationKey(projectId, ip), lastSeen: Date.now(), @@ -237,7 +243,7 @@ export class HostService { }); const findings: IpFinding[] = []; - // For each new domain name found, a finding is created + // For each new ip found, a finding is created newIps.forEach((ip) => { findings.push({ type: 'IpFinding', @@ -272,6 +278,7 @@ export class HostService { lastSeen: Date.now(), $setOnInsert: { ip: host, + ipInt: ipv4ToNumber(host), correlationKey: CorrelationKeyUtils.hostCorrelationKey( projectId, host, @@ -320,84 +327,6 @@ export class HostService { ); } - private buildFilters(dto: HostFilterModel) { - const finalFilter = {}; - - // Filter by domain - if (dto.domains) { - const domainRegexes = dto.domains - .filter((x) => x) - .map((x) => x.toLowerCase()) - .map((x) => escapeStringRegexp(x)) - .map((x) => new RegExp(x, 'i')); - - if (domainRegexes.length > 0) { - finalFilter['domains.name'] = { $all: domainRegexes }; - } - } - - // Filter by host - if (dto.hosts) { - const hosts = dto.hosts - .filter((x) => x) - .map((x) => x.toLowerCase().trim()) - .map((x) => escapeStringRegexp(x)) - .map((x) => new RegExp(`.*${x}.*`)); - - if (hosts.length > 0) { - finalFilter['ip'] = { $in: hosts }; - } - } - - // Filter by project - if (dto.projects) { - const projectIds = dto.projects - .filter((x) => x) - .map((x) => new Types.ObjectId(x)); - - if (projectIds.length > 0) { - finalFilter['projectId'] = { $in: projectIds }; - } - } - - // Filter by tag - if (dto.tags) { - const preppedTagsArray = dto.tags.map((x) => new Types.ObjectId(x)); - finalFilter['tags'] = { $all: preppedTagsArray }; - } - - // Filter by createdAt - if (dto.firstSeenStartDate || dto.firstSeenEndDate) { - let createdAtFilter = {}; - - if (dto.firstSeenStartDate && dto.firstSeenEndDate) { - createdAtFilter = [ - { createdAt: { $gte: dto.firstSeenStartDate } }, - { createdAt: { $lte: dto.firstSeenEndDate } }, - ]; - finalFilter['$and'] = createdAtFilter; - } else { - if (dto.firstSeenStartDate) - createdAtFilter = { $gte: dto.firstSeenStartDate }; - else if (dto.firstSeenEndDate) - createdAtFilter = { $lte: dto.firstSeenEndDate }; - finalFilter['createdAt'] = createdAtFilter; - } - } - - // Filter by blocked - if (dto.blocked === false) { - finalFilter['$or'] = [ - { blocked: { $exists: false } }, - { blocked: { $eq: false } }, - ]; - } else if (dto.blocked === true) { - finalFilter['blocked'] = { $eq: true }; - } - - return finalFilter; - } - public async tagHost( hostId: string, tagId: string, diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range-model.module.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range-model.module.ts new file mode 100644 index 00000000..58c8f793 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range-model.module.ts @@ -0,0 +1,9 @@ +import { MongooseModule } from '@nestjs/mongoose'; +import { IpRangeSchema } from './ip-range.model'; + +export const IpRangeModelModule = MongooseModule.forFeature([ + { + name: 'iprange', + schema: IpRangeSchema, + }, +]); diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.controller.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.controller.ts new file mode 100644 index 00000000..85deea8a --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.controller.ts @@ -0,0 +1,100 @@ +import { + Body, + Controller, + Delete, + Get, + Param, + Patch, + Post, + Put, + Query, + UseGuards, +} from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; +import { DeleteResult } from 'mongodb'; +import { MongoIdDto } from '../../../../types/dto/mongo-id.dto'; +import { TagItemDto } from '../../../../types/dto/tag-item.dto'; +import { Page } from '../../../../types/page.type'; +import { Role } from '../../../auth/constants'; +import { Roles } from '../../../auth/decorators/roles.decorator'; +import { RolesGuard } from '../../../auth/guards/role.guard'; +import { ApiKeyStrategy } from '../../../auth/strategies/api-key.strategy'; +import { JwtStrategy } from '../../../auth/strategies/jwt.strategy'; +import { + BatchEditIpRangesDto, + DeleteIpRangesDto, + IpRangesPagingDto, + SubmitIpRangesDto, +} from './ip-range.dto'; +import { ExtendedIpRange, IpRangeDocument } from './ip-range.model'; +import { IpRangeService } from './ip-range.service'; + +@Controller('ip-ranges') +export class IpRangeController { + constructor(private readonly ipRangesService: IpRangeService) {} + + @UseGuards(AuthGuard([JwtStrategy.name, ApiKeyStrategy.name]), RolesGuard) + @Roles(Role.User) + @Patch() + async batchEdit(@Body() dto: BatchEditIpRangesDto) { + return await this.ipRangesService.batchEdit(dto); + } + + @UseGuards(AuthGuard([JwtStrategy.name, ApiKeyStrategy.name]), RolesGuard) + @Roles(Role.User) + @Put(':id/tags') + async tag(@Param() idDto: MongoIdDto, @Body() tagDto: TagItemDto) { + return await this.ipRangesService.tagIpRange( + idDto.id, + tagDto.tagId, + tagDto.isTagged, + ); + } + + @UseGuards(AuthGuard([JwtStrategy.name, ApiKeyStrategy.name]), RolesGuard) + @Roles(Role.ReadOnly) + @Get(':id') + async get(@Param() dto: MongoIdDto): Promise { + return await this.ipRangesService.get(dto.id); + } + + @UseGuards(AuthGuard([JwtStrategy.name, ApiKeyStrategy.name]), RolesGuard) + @Roles(Role.User) + @Delete(':id') + async deleteIpRange(@Param() dto: MongoIdDto): Promise { + return await this.ipRangesService.delete(dto.id); + } + + @UseGuards(AuthGuard([JwtStrategy.name, ApiKeyStrategy.name]), RolesGuard) + @Roles(Role.ReadOnly) + @Get() + async getAll( + @Query() dto: IpRangesPagingDto, + ): Promise> { + const totalRecords = await this.ipRangesService.count(dto); + const items = await this.ipRangesService.getAll( + dto.page, + dto.pageSize, + dto, + ); + + return { + items, + totalRecords, + }; + } + + @UseGuards(AuthGuard([JwtStrategy.name, ApiKeyStrategy.name]), RolesGuard) + @Roles(Role.User) + @Delete() + async deleteIpRanges(@Body() dto: DeleteIpRangesDto): Promise { + return await this.ipRangesService.deleteMany(dto.ipRangeIds); + } + + @UseGuards(AuthGuard([JwtStrategy.name, ApiKeyStrategy.name]), RolesGuard) + @Roles(Role.User) + @Post() + async submit(@Body() dto: SubmitIpRangesDto) { + return await this.ipRangesService.submitIpRanges(dto); + } +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.dto.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.dto.ts new file mode 100644 index 00000000..ae665ac5 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.dto.ts @@ -0,0 +1,79 @@ +// import { Type } from 'class-transformer'; +import { IntersectionType } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { + IsArray, + IsBoolean, + IsIP, + IsMongoId, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, + Max, + Min, + ValidateNested, +} from 'class-validator'; +import { IsProjectId } from '../../../../validators/is-project-id.validator'; +import { PagingDto, ResourceDetailsLevelDto } from '../../database.dto'; +import { ResourceFilterDto } from '../resource.dto'; + +export class IpRangesFilterDto extends IntersectionType( + ResourceFilterDto, + ResourceDetailsLevelDto, +) { + @IsOptional() + @IsString({ each: true }) + @IsArray() + ips?: string[]; + + @IsOptional() + @IsIP(4, { each: true }) + @IsArray() + contains?: string[]; +} + +export class IpRangesPagingDto extends IntersectionType( + PagingDto, + IpRangesFilterDto, +) {} + +export class DeleteIpRangesDto { + @IsArray() + @IsMongoId({ each: true }) + ipRangeIds: string[]; +} + +export class BatchEditIpRangesDto { + @IsArray() + @IsMongoId({ each: true }) + ipRangeIds: string[]; + + @IsOptional() + @IsBoolean() + block: boolean; +} + +export class IpRangeDto { + @IsIP(4) + @IsNotEmpty() + @IsString() + ip: string; + + @Max(32) + @Min(0) + @IsNumber() + mask: number; +} + +export class SubmitIpRangesDto { + @ValidateNested({ each: true }) + @IsNotEmpty() + @IsArray() + @Type(() => IpRangeDto) + ranges: IpRangeDto[]; + + @IsProjectId() + @IsNotEmpty() + projectId: string; +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.model.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.model.ts new file mode 100644 index 00000000..fcbc8977 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.model.ts @@ -0,0 +1,57 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document, Types } from 'mongoose'; +import { MONGO_TIMESTAMP_SCHEMA_CONFIG } from '../../database.constants'; +import { HostSummary } from '../host/host.summary'; + +export interface ExtendedIpRange extends IpRange { + _id?: Types.ObjectId; + hosts?: HostSummary[]; +} + +export type IpRangeDocument = IpRange & Document; + +@Schema(MONGO_TIMESTAMP_SCHEMA_CONFIG) +export class IpRange { + @Prop({ index: true }) + public ip!: string; + + @Prop() + public mask!: number; + + @Prop() + public projectId!: Types.ObjectId; + + /** + * A pseudo-unique key identifying this entity. Used for findings. + * This key should not change if this entity were to be recreated. + */ + @Prop() + public correlationKey!: string; + + @Prop({ index: true }) + ipMinInt!: number; + + @Prop({ index: true }) + ipMaxInt!: number; + + @Prop() + public tags?: Types.ObjectId[]; + + @Prop() + public updatedAt: number; + + @Prop() + public createdAt: number; + + @Prop() + public lastSeen: number; + + @Prop() + blocked?: boolean; + + @Prop() + blockedAt?: number; +} + +export const IpRangeSchema = SchemaFactory.createForClass(IpRange); +IpRangeSchema.index({ ip: 1, projectId: 1, mask: 1 }, { unique: true }); diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.module.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.module.ts new file mode 100644 index 00000000..51006e94 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { QueueModule } from '../../../queues/queue.module'; +import { DatalayerModule } from '../../datalayer.module'; +import { JobsModule } from '../../jobs/jobs.module'; +import { TagsModule } from '../../tags/tag.module'; +import { IpRangeController } from './ip-range.controller'; +import { IpRangeService } from './ip-range.service'; + +@Module({ + imports: [DatalayerModule, JobsModule, TagsModule, QueueModule], + controllers: [IpRangeController], + providers: [IpRangeService], + exports: [IpRangeService], +}) +export class IpRangeModule {} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.service.spec.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.service.spec.ts new file mode 100644 index 00000000..310abebe --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.service.spec.ts @@ -0,0 +1,529 @@ +import { getModelToken } from '@nestjs/mongoose'; +import { Test, TestingModule } from '@nestjs/testing'; +import { Model } from 'mongoose'; +import { + ipv4RangeValuesToMinMax, + numberToIpv4, +} from '../../../../utils/ip-address.utils'; +import { AppModule } from '../../../app.module'; +import { TagsService } from '../../tags/tag.service'; +import { SubmitHostsDto } from '../host/host.dto'; +import { Host } from '../host/host.model'; +import { HostService } from '../host/host.service'; +import { ProjectService } from '../project.service'; +import { SubmitIpRangesDto } from './ip-range.dto'; +import { ExtendedIpRange, IpRange, IpRangeDocument } from './ip-range.model'; +import { IpRangeService } from './ip-range.service'; + +describe('IP Range Service', () => { + let moduleFixture: TestingModule; + let ipRangeService: IpRangeService; + let projectService: ProjectService; + let tagsService: TagsService; + let ipRangeModel: Model; + let hostModel: Model; + let hostService: HostService; + + beforeAll(async () => { + moduleFixture = await Test.createTestingModule({ + imports: [AppModule], + }).compile(); + ipRangeService = moduleFixture.get(IpRangeService); + projectService = moduleFixture.get(ProjectService); + tagsService = moduleFixture.get(TagsService); + ipRangeModel = moduleFixture.get>(getModelToken('iprange')); + hostModel = moduleFixture.get>(getModelToken('host')); + hostService = moduleFixture.get(HostService); + }); + + beforeEach(async () => { + const allProjects = await projectService.getAll(); + for (const c of allProjects) { + await projectService.delete(c._id); + } + const allTags = await tagsService.getAll(); + for (const t of allTags) { + await tagsService.delete(t._id.toString()); + } + }); + + afterAll(async () => { + await moduleFixture.close(); + }); + + describe('CRUD IP ranges', () => { + it.each([ + { ranges: [{ ip: '1.1.1.1', mask: 32 }] }, + { + ranges: [ + { ip: '1.1.1.1', mask: 32 }, + { ip: '1.1.1.1', mask: 18 }, + ], + }, + { + ranges: [ + { ip: '1.1.1.1', mask: 32 }, + { ip: '1.1.1.2', mask: 18 }, + ], + }, + ])('Submit IP ranges: %s', async ({ ranges }) => { + // Arrange + const p = await project('test'); + const data: SubmitIpRangesDto = { + projectId: p._id.toString(), + ranges, + }; + + // Act + const ipRanges = await ipRangeService.submitIpRanges(data); + + // Assert + expect(ipRanges.length).toStrictEqual(ranges.length); + + for (let i = 0; i < ipRanges.length; ++i) { + const minMax = ipv4RangeValuesToMinMax( + data.ranges[i].ip, + data.ranges[i].mask, + ); + expect(ipRanges[i].ip).toStrictEqual(numberToIpv4(minMax.min)); + expect(ipRanges[i].mask).toStrictEqual(data.ranges[i].mask); + expect(ipRanges[i].lastSeen).toBeTruthy(); + expect(ipRanges[i].projectId.toString()).toStrictEqual( + p._id.toString(), + ); + expect(ipRanges[i].ipMinInt).toStrictEqual(minMax.min); + expect(ipRanges[i].ipMaxInt).toStrictEqual(minMax.max); + expect(ipRanges[i].correlationKey).toStrictEqual( + `project:${p._id.toString()};host:${numberToIpv4(minMax.min)};mask:${ + data.ranges[i].mask + }`, + ); + } + }); + + it.each([ + { ranges: [{ ip: '1.1.1.1', mask: 32 }] }, + { + ranges: [ + { ip: '1.1.1.1', mask: 32 }, + { ip: '1.1.1.1', mask: 18 }, + ], + }, + { + ranges: [ + { ip: '1.1.1.1', mask: 32 }, + { ip: '1.1.1.2', mask: 18 }, + ], + }, + ])('Create IP ranges: %s', async ({ ranges }) => { + // Arrange + const p = await project('test'); + const data: SubmitIpRangesDto = { + projectId: p._id.toString(), + ranges, + }; + + // Act + const ipRanges: IpRangeDocument[] = []; + for (const range of ranges) { + ipRanges.push( + await ipRangeService.addIpRange( + range.ip, + range.mask, + p._id.toString(), + ), + ); + } + + // Assert + expect(ipRanges.length).toStrictEqual(ranges.length); + + for (let i = 0; i < ipRanges.length; ++i) { + const minMax = ipv4RangeValuesToMinMax( + data.ranges[i].ip, + data.ranges[i].mask, + ); + expect(ipRanges[i].ip).toStrictEqual(numberToIpv4(minMax.min)); + expect(ipRanges[i].mask).toStrictEqual(data.ranges[i].mask); + expect(ipRanges[i].lastSeen).toBeTruthy(); + expect(ipRanges[i].projectId.toString()).toStrictEqual( + p._id.toString(), + ); + expect(ipRanges[i].ipMinInt).toStrictEqual(minMax.min); + expect(ipRanges[i].ipMaxInt).toStrictEqual(minMax.max); + expect(ipRanges[i].correlationKey).toStrictEqual( + `project:${p._id.toString()};host:${numberToIpv4(minMax.min)};mask:${ + data.ranges[i].mask + }`, + ); + } + }); + + it('Read an IP range from the database by id', async () => { + // Arrange + const p = await project('test'); + const r = { ip: '1.1.1.1', mask: 32 }; + + const createdRange = await ipRangeService.addIpRange( + r.ip, + r.mask, + p._id.toString(), + ); + + // Act + const range = await ipRangeService.get(createdRange._id.toString()); + + // Assert + const minMax = ipv4RangeValuesToMinMax(r.ip, r.mask); + expect(range.ip).toStrictEqual(r.ip); + expect(range.mask).toStrictEqual(r.mask); + expect(range.lastSeen).toBeTruthy(); + expect(range.projectId.toString()).toStrictEqual(p._id.toString()); + expect(range.ipMinInt).toStrictEqual(minMax.min); + expect(range.ipMaxInt).toStrictEqual(minMax.max); + expect(range.correlationKey).toStrictEqual( + `project:${p._id.toString()};host:${r.ip};mask:${r.mask}`, + ); + }); + + it('Read IP ranges with paging', async () => { + // Arrange + const p = await project('test'); + const ranges = [ + { ip: '1.1.1.1', mask: 32 }, + { ip: '1.1.1.1', mask: 31 }, + { ip: '1.1.1.1', mask: 30 }, + { ip: '1.1.1.1', mask: 29 }, + { ip: '1.1.1.1', mask: 28 }, + { ip: '1.1.1.1', mask: 27 }, + ]; + for (const r of ranges) { + await ipRangeService.addIpRange(r.ip, r.mask, p._id.toString()); + } + + // Act + const rangePage = await ipRangeService.getAll(1, 2); + + // Assert + expect(rangePage.length).toStrictEqual(2); + expect(rangePage[0].mask).toStrictEqual(30); + expect(rangePage[1].mask).toStrictEqual(29); + }); + + it('Tag an IP range', async () => { + // Arrange + const p = await project('test'); + const r = { ip: '1.1.1.1', mask: 32 }; + + const createdRange = await ipRangeService.addIpRange( + r.ip, + r.mask, + p._id.toString(), + ); + const t = await tag('tag1'); + + // Act + await ipRangeService.tagIpRange( + createdRange._id.toString(), + t._id.toString(), + true, + ); + + // Assert + const taggedRange = await ipRangeService.get(createdRange._id.toString()); + expect(taggedRange.tags.length).toStrictEqual(1); + expect(taggedRange.tags[0].toString()).toStrictEqual(t._id.toString()); + }); + + it('Tag an IP range by IP and mask', async () => { + // Arrange + const p = await project('test'); + const r = { ip: '1.1.1.1', mask: 32 }; + + const createdRange = await ipRangeService.addIpRange( + r.ip, + r.mask, + p._id.toString(), + ); + const t = await tag('tag1'); + + // Act + await ipRangeService.tagIpRangeByIp( + createdRange.ip, + createdRange.mask, + createdRange.projectId.toString(), + t._id.toString(), + true, + ); + + // Assert + const taggedRange = await ipRangeService.get(createdRange._id.toString()); + expect(taggedRange.tags.length).toStrictEqual(1); + expect(taggedRange.tags[0].toString()).toStrictEqual(t._id.toString()); + }); + + it('Block an IP range', async () => { + // Arrange + const p = await project('test'); + const r = { ip: '1.1.1.1', mask: 32 }; + + const createdRange = await ipRangeService.addIpRange( + r.ip, + r.mask, + p._id.toString(), + ); + + // Act + await ipRangeService.batchEdit({ + block: true, + ipRangeIds: [createdRange._id.toString()], + }); + + // Assert + const blockedRange = await ipRangeService.get( + createdRange._id.toString(), + ); + expect(blockedRange.blocked).toStrictEqual(true); + expect(blockedRange.blockedAt).toBeTruthy(); + }); + + it('Delete an IP range from the database', async () => { + // Arrange + const p = await project('test'); + const ranges = [ + { ip: '1.1.1.1', mask: 32 }, + { ip: '1.1.1.1', mask: 31 }, + { ip: '1.1.1.1', mask: 30 }, + { ip: '1.1.1.1', mask: 29 }, + { ip: '1.1.1.1', mask: 28 }, + ]; + + const createdRanges: IpRangeDocument[] = []; + for (const r of ranges) { + createdRanges.push( + await ipRangeService.addIpRange(r.ip, r.mask, p._id.toString()), + ); + } + + // Act + await ipRangeService.delete(createdRanges[0]._id.toString()); + await ipRangeService.delete(createdRanges[1]._id.toString()); + + // Assert + const allRanges = await ipRangeService.getAll(); + expect(allRanges.length).toStrictEqual(3); + }); + }); + + describe('Filters', () => { + it('Filters for ranges containing IP', async () => { + // Arrange + const p = await project('test'); + const ranges = [{ ip: '1.1.1.1', mask: 24 }]; + + const hostsInRange: SubmitHostsDto = { + ips: ['1.1.1.1', '1.1.1.34', '1.1.1.255', '1.1.1.0'], + projectId: p._id.toString(), + }; + + const hostsOutOfRange: SubmitHostsDto = { + ips: ['1.1.2.0', '127.0.0.1', '1.1.0.255'], + projectId: p._id.toString(), + }; + + const allHosts = hostsInRange.ips.concat(hostsOutOfRange.ips); + + const createdRanges: IpRangeDocument[] = []; + for (const r of ranges) { + createdRanges.push( + await ipRangeService.addIpRange(r.ip, r.mask, p._id.toString()), + ); + } + + // Act + let range = await ipRangeService.getAll(null, null, { + contains: hostsInRange.ips, + }); + + // Assert + expect(range.length).toStrictEqual(1); + + // Act + range = await ipRangeService.getAll(null, null, { + contains: hostsOutOfRange.ips, + }); + + // Assert + expect(range.length).toStrictEqual(0); + }); + + it('Filters by project id', async () => { + // Arrange + const p = await project('test'); + const p2 = await project('test2'); + const ranges = [ + { ip: '1.1.1.1', mask: 24, pid: p._id.toString() }, + { ip: '1.1.1.1', mask: 24, pid: p2._id.toString() }, + ]; + + const createdRanges: IpRangeDocument[] = []; + for (const r of ranges) { + createdRanges.push( + await ipRangeService.addIpRange(r.ip, r.mask, r.pid), + ); + } + + // Act + let range = await ipRangeService.getAll(null, null, { + projects: [p._id.toString()], + }); + + // Assert + expect(range.length).toStrictEqual(1); + }); + + it('Filters by tag', async () => { + // Arrange + const p = await project('test'); + const ranges = [ + { ip: '1.1.1.1', mask: 24, pid: p._id.toString() }, + { ip: '1.1.1.1', mask: 23, pid: p._id.toString() }, + ]; + + const t = await tag('asdf'); + + const createdRanges: IpRangeDocument[] = []; + for (const r of ranges) { + createdRanges.push( + await ipRangeService.addIpRange(r.ip, r.mask, p._id.toString()), + ); + } + + await ipRangeService.tagIpRange( + createdRanges[0]._id.toString(), + t._id.toString(), + true, + ); + + // Act + let range = await ipRangeService.getAll(null, null, { + tags: [t._id.toString()], + }); + + // Assert + expect(range.length).toStrictEqual(1); + expect(range[0].tags[0].toString()).toStrictEqual(t._id.toString()); + }); + + it('Extended getAll includes the ip range hosts', async () => { + // Arrange + const p = await project('test'); + const ranges = [{ ip: '1.1.1.1', mask: 24 }]; + + const hostsInRange: SubmitHostsDto = { + ips: ['1.1.1.1', '1.1.1.34', '1.1.1.255', '1.1.1.0'], + projectId: p._id.toString(), + }; + + const hostsOutOfRange: SubmitHostsDto = { + ips: ['1.1.2.0', '127.0.0.1', '1.1.0.255'], + projectId: p._id.toString(), + }; + + const createdRanges: IpRangeDocument[] = []; + for (const r of ranges) { + createdRanges.push( + await ipRangeService.addIpRange(r.ip, r.mask, p._id.toString()), + ); + } + + const allHosts = hostsInRange.ips.concat(hostsOutOfRange.ips); + await hostService.addHosts(allHosts, p._id.toString()); + + // Act + let range: ExtendedIpRange[] = await ipRangeService.getAll(null, null, { + detailsLevel: 'extended', + }); + + // Assert + expect(range.length).toStrictEqual(1); + expect(range[0].hosts.length).toStrictEqual(hostsInRange.ips.length); + expect(range[0].hosts.map((h) => h.ip)).toStrictEqual(hostsInRange.ips); + }); + }); + + describe('Automation mechanics', () => { + it('A blocked IP range is identified as so with its correlation key', async () => { + // Arrange + const p = await project('test'); + const r = { ip: '1.1.1.1', mask: 32 }; + + const createdRange = await ipRangeService.addIpRange( + r.ip, + r.mask, + p._id.toString(), + ); + + await ipRangeService.batchEdit({ + block: true, + ipRangeIds: [createdRange._id.toString()], + }); + + // Act + let blocked = await ipRangeService.keyIsBlocked( + createdRange.correlationKey, + ); + + // Assert + expect(blocked).toStrictEqual(true); + + // Act + await ipRangeService.batchEdit({ + block: false, + ipRangeIds: [createdRange._id.toString()], + }); + blocked = await ipRangeService.keyIsBlocked(createdRange.correlationKey); + + // Assert + expect(blocked).toStrictEqual(false); + }); + + it('Update the lastSeen when a known IP range is added', async () => { + // Arrange + const range = { ip: '1.1.1.1', mask: 32 }; + const p = await project('test'); + + const ipRangeBefore = await ipRangeService.addIpRange( + range.ip, + range.mask, + p._id.toString(), + ); + + await new Promise((r) => setTimeout(r, 5)); + + // Act + const ipRangeAfter = await ipRangeService.addIpRange( + range.ip, + range.mask, + p._id.toString(), + ); + + // Assert + expect(ipRangeBefore.lastSeen).toBeTruthy(); + expect(ipRangeAfter.lastSeen).toBeTruthy(); + expect(ipRangeBefore.lastSeen).toBeLessThan(ipRangeAfter.lastSeen); + }); + }); + + async function tag(name: string) { + return await tagsService.create(name, '#cccccc'); + } + + async function project(name: string) { + return await projectService.addProject({ + name: name, + imageType: null, + logo: null, + }); + } +}); diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.service.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.service.ts new file mode 100644 index 00000000..7d94e806 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/ip-ranges/ip-range.service.ts @@ -0,0 +1,422 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { DeleteResult, UpdateResult } from 'mongodb'; +import { Model, PipelineStage, Query, Types } from 'mongoose'; +import { HttpNotFoundException } from '../../../../exceptions/http.exceptions'; +import escapeStringRegexp from '../../../../utils/escape-string-regexp'; +import { + ipv4RangeValuesToMinMax, + ipv4ToNumber, + numberToIpv4, +} from '../../../../utils/ip-address.utils'; +import { IpRangeFinding } from '../../../findings/findings.service'; +import { FindingsQueue } from '../../../queues/finding-queue/findings-queue'; +import { TagsService } from '../../tags/tag.service'; +import { CorrelationKeyUtils } from '../correlation.utils'; +import { Host } from '../host/host.model'; +import { HostSummary } from '../host/host.summary'; +import { Project } from '../project.model'; +import { + BatchEditIpRangesDto, + IpRangeDto, + IpRangesFilterDto, + SubmitIpRangesDto, +} from './ip-range.dto'; +import { ExtendedIpRange, IpRange, IpRangeDocument } from './ip-range.model'; + +@Injectable() +export class IpRangeService { + private logger = new Logger(IpRangeService.name); + + constructor( + @InjectModel('iprange') private readonly ipRangeModel: Model, + @InjectModel('host') private readonly hostModel: Model, + @InjectModel('project') private readonly projectModel: Model, + private tagsService: TagsService, + private findingsQueue: FindingsQueue, + ) {} + + public async getAll( + page: number = null, + pageSize: number = null, + filter: IpRangesFilterDto = null, + hostsLimit: number = 5, + ): Promise<(IpRangeDocument | ExtendedIpRange)[]> { + let query: Query = + undefined; + if (filter) { + query = this.ipRangeModel.find(this.buildFilters(filter)); + } else { + query = this.ipRangeModel.find({}); + } + + if (page != null && pageSize != null) { + query = query.skip(page * pageSize).limit(pageSize); + } + let results = await query.lean().exec(); + + if (filter && filter.detailsLevel === 'extended') { + return await this.extendRangesWithHosts(results, hostsLimit); + } + + return results; + } + + private async extendRangesWithHosts( + ipRanges: IpRangeDocument[], + limit: number, + ): Promise { + const facets: Record = {}; + + if (!ipRanges.length) return []; + + for (const range of ipRanges) { + facets[range.correlationKey.replaceAll('.', '-')] = [ + { + $match: { + projectId: { $eq: range.projectId }, + ipInt: { $gte: range.ipMinInt, $lte: range.ipMaxInt }, + }, + }, + { + $project: { + ip: 1, + id: '$_id', + _id: 0, + }, + }, + { + $limit: limit, + }, + ]; + } + + if (!Object.keys(facets).length) return []; + + const results: Record[] = + await this.hostModel.aggregate([ + { + $facet: facets, + }, + ]); + + if (results.length === 0) return ipRanges; + + return ipRanges.map((range) => { + return { + ...range, + hosts: results[0][range.correlationKey.replaceAll('.', '-')] ?? [], + }; + }); + } + + public async keyIsBlocked(correlationKey: string): Promise { + const h = await this.ipRangeModel.findOne( + { correlationKey: { $eq: correlationKey } }, + 'blocked', + ); + + return h && h.blocked; + } + + public async count(filter: IpRangesFilterDto = null) { + if (!filter) { + return await this.ipRangeModel.estimatedDocumentCount(); + } else { + return await this.ipRangeModel.countDocuments(this.buildFilters(filter)); + } + } + + public async deleteAllForProject(projectId: string): Promise { + return await this.ipRangeModel.deleteMany({ + projectId: { $eq: new Types.ObjectId(projectId) }, + }); + } + + public async get(id: string) { + return this.ipRangeModel.findById(id); + } + + private buildFilters(dto: IpRangesFilterDto) { + const finalFilter = { $and: [] }; + + // Filter by ip + if (dto.ips) { + const ips = dto.ips + .filter((x) => x) + .map((x) => x.toLowerCase().trim()) + .map((x) => escapeStringRegexp(x)) + .map((x) => new RegExp(`.*${x}.*`)); + + if (ips.length > 0) { + finalFilter['ip'] = { $in: ips }; + } + } + + // Filter by ip contained in range + if (dto.contains) { + const or = []; + for (const ip of dto.contains) { + const ipInt = ipv4ToNumber(ip); + const and = { + $and: [{ ipMinInt: { $lte: ipInt } }, { ipMaxInt: { $gte: ipInt } }], + }; + or.push(and); + } + finalFilter.$and.push({ $or: or }); + } + + // Filter by project + if (dto.projects) { + const projectIds = dto.projects + .filter((x) => x) + .map((x) => new Types.ObjectId(x)); + + if (projectIds.length > 0) { + finalFilter['projectId'] = { $in: projectIds }; + } + } + + // Filter by tag + if (dto.tags) { + const preppedTagsArray = dto.tags.map((x) => new Types.ObjectId(x)); + finalFilter['tags'] = { $all: preppedTagsArray }; + } + + // Filter by createdAt + if (dto.firstSeenStartDate || dto.firstSeenEndDate) { + let createdAtFilter = {}; + + if (dto.firstSeenStartDate && dto.firstSeenEndDate) { + createdAtFilter = [ + { createdAt: { $gte: dto.firstSeenStartDate } }, + { createdAt: { $lte: dto.firstSeenEndDate } }, + ]; + finalFilter.$and.push(createdAtFilter); + } else { + if (dto.firstSeenStartDate) + createdAtFilter = { $gte: dto.firstSeenStartDate }; + else if (dto.firstSeenEndDate) + createdAtFilter = { $lte: dto.firstSeenEndDate }; + finalFilter['createdAt'] = createdAtFilter; + } + } + + // Filter by blocked + if (dto.blocked === false) { + finalFilter['$or'] = [ + { blocked: { $exists: false } }, + { blocked: { $eq: false } }, + ]; + } else if (dto.blocked === true) { + finalFilter['blocked'] = { $eq: true }; + } + + if (finalFilter.$and.length === 0) delete finalFilter.$and; + + return finalFilter; + } + + public async tagIpRange( + ipRangeId: string, + tagId: string, + isTagged: boolean, + ): Promise { + const ipRange = await this.ipRangeModel.findById(ipRangeId); + if (!ipRange) throw new HttpNotFoundException(); + + if (!isTagged) { + return await this.ipRangeModel.updateOne( + { _id: { $eq: new Types.ObjectId(ipRangeId) } }, + { $pull: { tags: new Types.ObjectId(tagId) } }, + ); + } else { + if (!(await this.tagsService.tagExists(tagId))) + throw new HttpNotFoundException(); + + return await this.ipRangeModel.updateOne( + { _id: { $eq: new Types.ObjectId(ipRangeId) } }, + { $addToSet: { tags: new Types.ObjectId(tagId) } }, + ); + } + } + + /** + * Tag an ip range according to its IP, mask and projectId + * @param ip + * @param mask + * @param projectId + * @param tagId Expects a valid tagId + * @param isTagged True to tag, False to untag + * @returns + */ + public async tagIpRangeByIp( + ip: string, + mask: number, + projectId: string, + tagId: string, + isTagged: boolean, + ): Promise { + const targetIp = numberToIpv4(ipv4RangeValuesToMinMax(ip, mask).min); + if (!isTagged) { + return await this.ipRangeModel.updateOne( + { + ip: { $eq: targetIp }, + mask: { $eq: mask }, + projectId: { $eq: new Types.ObjectId(projectId) }, + }, + { $pull: { tags: new Types.ObjectId(tagId) } }, + ); + } else { + return await this.ipRangeModel.updateOne( + { + ip: { $eq: targetIp }, + projectId: { $eq: new Types.ObjectId(projectId) }, + }, + { $addToSet: { tags: new Types.ObjectId(tagId) } }, + ); + } + } + + public async batchEdit(dto: BatchEditIpRangesDto) { + const update: Partial = {}; + if (dto.block || dto.block === false) update.blocked = dto.block; + if (dto.block) update.blockedAt = Date.now(); + + return await this.ipRangeModel.updateMany( + { _id: { $in: dto.ipRangeIds.map((v) => new Types.ObjectId(v)) } }, + update, + ); + } + + public async delete(id: string) { + return await this.ipRangeModel.deleteOne({ + _id: { $eq: new Types.ObjectId(id) }, + }); + } + + public async deleteMany(ids: string[]) { + return await this.ipRangeModel.deleteMany({ + _id: { $in: ids.map((id) => new Types.ObjectId(id)) }, + }); + } + + /** + * Creates new Ip ranges in the database and publishes new + * IpRangeFindings to the queue to seed the automation. + * @param dto + */ + public async submitIpRanges(dto: SubmitIpRangesDto) { + const project = await this.projectModel.findById(dto.projectId); + if (!project) + throw new HttpNotFoundException(`Project ${dto.projectId} not found`); + + const ipRangeDocuments: IpRangeDocument[] = []; + for (const range of dto.ranges) { + const minMax = ipv4RangeValuesToMinMax(range.ip, range.mask); + const targetIp = numberToIpv4(minMax.min); + const model = new this.ipRangeModel({ + _id: new Types.ObjectId(), + ip: targetIp, + mask: range.mask, + projectId: new Types.ObjectId(dto.projectId), + correlationKey: CorrelationKeyUtils.ipRangeCorrelationKey( + dto.projectId, + targetIp, + range.mask, + ), + ipMinInt: minMax.min, + ipMaxInt: minMax.max, + lastSeen: Date.now(), + }); + + ipRangeDocuments.push(model); + } + + let insertedRanges: IpRangeDocument[] = []; + + // insertmany with ordered false to continue on fail and use the exception + try { + insertedRanges = await this.ipRangeModel.insertMany(ipRangeDocuments, { + ordered: false, + }); + } catch (err) { + if (!err.writeErrors) { + throw err; + } + insertedRanges = err.insertedDocs; + } + + await this.publishIpRangeFindings(insertedRanges, dto.projectId); + + return insertedRanges; + } + + public async addIpRange(ip: string, mask: number, projectId: string) { + const project = await this.projectModel.findById(projectId); + if (!project) { + this.logger.debug(`Could not find the project (projectId=${projectId})`); + throw new HttpNotFoundException(`projectId=${projectId}`); + } + + const projectIdObject = new Types.ObjectId(projectId); + const minMax = ipv4RangeValuesToMinMax(ip, mask); + const targetIp = numberToIpv4(minMax.min); + + return await this.ipRangeModel.findOneAndUpdate( + { + ip: { $eq: targetIp }, + mask: { $eq: mask }, + projectId: { $eq: projectIdObject }, + }, + { + lastSeen: Date.now(), + $setOnInsert: { + _id: new Types.ObjectId(), + ip: targetIp, + mask: mask, + projectId: projectIdObject, + correlationKey: CorrelationKeyUtils.ipRangeCorrelationKey( + projectId, + targetIp, + mask, + ), + ipMinInt: minMax.min, + ipMaxInt: minMax.max, + }, + }, + { upsert: true, new: true }, + ); + } + + /** + * For each new ip range found, a finding is created + * We submit them by batch to hopefully better support large loads + * @param newIpRanges New domains for which to create IpRangeFindings + * @param projectId The project associated with the ip range/findings + */ + private async publishIpRangeFindings( + newIpRanges: IpRangeDto[], + projectId: string, + ) { + if (newIpRanges.length <= 0) return; + + const batchSize = 30; + + let findings: IpRangeFinding[] = []; + for (let i = 0; i < newIpRanges.length; ++i) { + findings.push({ + type: 'IpRangeFinding', + key: 'IpRangeFinding', + ip: newIpRanges[i].ip, + mask: newIpRanges[i].mask, + projectId: projectId, + }); + if (i % batchSize === 0) { + await this.findingsQueue.publish(...findings); + findings = []; + } + } + this.findingsQueue.publish(...findings); + } +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.dto.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.dto.ts index 2ed3bc91..0c940be4 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.dto.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.dto.ts @@ -7,27 +7,49 @@ import { IsMongoId, IsNotEmpty, IsOptional, + IsString, } from 'class-validator'; import { Types } from 'mongoose'; -import { DetailsLevel, detailsLevel } from '../../database.constants'; +import { PortDetailsLevel, portDetailsLevel } from '../../database.constants'; import { PagingDto } from '../../database.dto'; -import { FilterByPortDto, ResourceFilterDto } from '../resource.dto'; +import { + FilterByHostDto, + FilterByPortDto, + ResourceFilterDto, +} from '../resource.dto'; export class PortFilterDto extends IntersectionType( ResourceFilterDto, FilterByPortDto, + FilterByHostDto, ) { @IsOptional() @IsIn(['tcp', 'udp']) protocol: string = 'tcp'; @IsNotEmpty() - @IsIn(detailsLevel) - detailsLevel: DetailsLevel = 'full'; + @IsIn(portDetailsLevel) + detailsLevel: PortDetailsLevel = 'full'; + /** @deprecated : Use query instead */ @IsOptional() @IsMongoId() hostId: string; + + @IsOptional() + @IsString({ each: true }) + @IsArray() + services: string[]; + + @IsOptional() + @IsString({ each: true }) + @IsArray() + products: string[]; + + @IsOptional() + @IsString({ each: true }) + @IsArray() + versions: string[]; } export class GetPortsDto extends IntersectionType(PagingDto, PortFilterDto) {} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.model.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.model.ts index a17a0bef..58503e3e 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.model.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.model.ts @@ -56,6 +56,12 @@ export class Port { @Prop() service: string; + + @Prop() + product: string; + + @Prop() + version: string; } export const PortSchema = SchemaFactory.createForClass(Port); diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.module.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.module.ts index 5ed5bcbf..0186e36d 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.module.ts @@ -4,11 +4,12 @@ import { TagsModule } from '../../tags/tag.module'; import { WebsiteModule } from '../websites/website.module'; import { PortController } from './port.controller'; import { PortService } from './port.service'; +import { PortsFilterParser } from './ports-filter-parser'; @Module({ imports: [DatalayerModule, TagsModule, WebsiteModule], controllers: [PortController], - providers: [PortService], - exports: [PortService], + providers: [PortService, PortsFilterParser], + exports: [PortService, PortsFilterParser], }) export class PortModule {} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.service.spec.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.service.spec.ts index c39a3a30..dd76faf2 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.service.spec.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.service.spec.ts @@ -1,13 +1,16 @@ +import { getModelToken } from '@nestjs/mongoose'; import { Test, TestingModule } from '@nestjs/testing'; -import { getName } from '../../../../test/test.utils'; +import { Model } from 'mongoose'; import { AppModule } from '../../../app.module'; import { TagsDocument } from '../../tags/tag.model'; import { TagsService } from '../../tags/tag.service'; import { DomainsService } from '../domain/domain.service'; +import { HostDocument } from '../host/host.model'; import { HostService } from '../host/host.service'; import { CreateProjectDto } from '../project.dto'; +import { ProjectDocument } from '../project.model'; import { ProjectService } from '../project.service'; -import { GetPortsDto } from './port.dto'; +import { Port, PortDocument } from './port.model'; import { PortService } from './port.service'; describe('Port Service', () => { @@ -17,7 +20,9 @@ describe('Port Service', () => { let projectService: ProjectService; let tagsService: TagsService; let portService: PortService; - const testPrefix = 'port-service-ut'; + + let project1: ProjectDocument; + let portModel: Model; beforeAll(async () => { moduleFixture = await Test.createTestingModule({ @@ -28,6 +33,7 @@ describe('Port Service', () => { projectService = moduleFixture.get(ProjectService); tagsService = moduleFixture.get(TagsService); portService = moduleFixture.get(PortService); + portModel = moduleFixture.get>(getModelToken('port')); }); beforeEach(async () => { @@ -39,24 +45,25 @@ describe('Port Service', () => { for (const t of tags) { await tagsService.delete(t._id); } + + project1 = await project('my first project'); }); describe('Add ports', () => { it('Should add ports to a host', async () => { // Arrange - const c = await project(); - const h = await host('1.1.1.1', c._id.toString()); + const h = await host('1.1.1.1', project1); // Act const p1 = await portService.addPort( - h[0]._id.toString(), - c._id.toString(), + h._id.toString(), + project1._id.toString(), 22, 'tcp', ); const p2 = await portService.addPort( - h[0]._id.toString(), - c._id.toString(), + h._id.toString(), + project1._id.toString(), 21, 'tcp', ); @@ -64,29 +71,28 @@ describe('Port Service', () => { // Assert expect(p1._id).toBeTruthy(); expect(p1.port).toStrictEqual(22); - expect(p1.host.id.toString()).toStrictEqual(h[0]._id.toString()); + expect(p1.host.id.toString()).toStrictEqual(h._id.toString()); expect(p2._id).toBeTruthy(); expect(p2.port).toStrictEqual(21); - expect(p2.host.id.toString()).toStrictEqual(h[0]._id.toString()); + expect(p2.host.id.toString()).toStrictEqual(h._id.toString()); }); it('Should add ports to a host IP', async () => { // Arrange const hostIp = '1.1.1.1'; - const c = await project(); - const h = await host(hostIp, c._id.toString()); + const h = await host(hostIp, project1); // Act const p1 = await portService.addPortByIp( hostIp, - c._id.toString(), + project1._id.toString(), 22, 'tcp', ); const p2 = await portService.addPortByIp( hostIp, - c._id.toString(), + project1._id.toString(), 21, 'tcp', ); @@ -94,24 +100,23 @@ describe('Port Service', () => { // Assert expect(p1._id).toBeTruthy(); expect(p1.port).toStrictEqual(22); - expect(p1.host.id.toString()).toStrictEqual(h[0]._id.toString()); + expect(p1.host.id.toString()).toStrictEqual(h._id.toString()); expect(p2._id).toBeTruthy(); expect(p2.port).toStrictEqual(21); - expect(p2.host.id.toString()).toStrictEqual(h[0]._id.toString()); + expect(p2.host.id.toString()).toStrictEqual(h._id.toString()); }); it('Should add ports with a service to a host IP', async () => { // Arrange const hostIp = '1.1.1.1'; const service = 'ssh'; - const c = await project(); - const h = await host(hostIp, c._id.toString()); + const h = await host(hostIp, project1); // Act const p1 = await portService.addPortByIp( hostIp, - c._id.toString(), + project1._id.toString(), 22, 'tcp', service, @@ -120,7 +125,7 @@ describe('Port Service', () => { // Assert expect(p1._id).toBeTruthy(); expect(p1.port).toStrictEqual(22); - expect(p1.host.id.toString()).toStrictEqual(h[0]._id.toString()); + expect(p1.host.id.toString()).toStrictEqual(h._id.toString()); expect(p1.service).toStrictEqual(service); }); @@ -128,20 +133,19 @@ describe('Port Service', () => { // Arrange const hostIp = '1.1.1.1'; const service = 'ssh'; - const c = await project(); - const h = await host(hostIp, c._id.toString()); + const h = await host(hostIp, project1); // Act let p1 = await portService.addPortByIp( hostIp, - c._id.toString(), + project1._id.toString(), 22, 'tcp', ); p1 = await portService.addPortByIp( hostIp, - c._id.toString(), + project1._id.toString(), 22, 'tcp', service, @@ -150,19 +154,18 @@ describe('Port Service', () => { // Assert expect(p1._id).toBeTruthy(); expect(p1.port).toStrictEqual(22); - expect(p1.host.id.toString()).toStrictEqual(h[0]._id.toString()); + expect(p1.host.id.toString()).toStrictEqual(h._id.toString()); expect(p1.service).toStrictEqual(service); }); it('Should update a port that already exists instead of creating it', async () => { // Arrange - const c = await project(); - const h = await host('1.1.1.1', c._id.toString()); + const h = await host('1.1.1.1', project1); const portNumber = 80; const samePort = async () => { return await portService.addPort( - h[0]._id.toString(), - c._id.toString(), + h._id.toString(), + project1._id.toString(), portNumber, 'tcp', ); @@ -179,21 +182,21 @@ describe('Port Service', () => { it('Should add the same port to a different host', async () => { // Arrange - const c = await project(); - const h1 = await host('1.1.1.1', c._id.toString()); - const h2 = await host('1.1.1.2', c._id.toString()); + const p = await project(); + const h1 = await host('1.1.1.1', p); + const h2 = await host('1.1.1.2', p); const portNumber = 80; // Act const p1 = await portService.addPort( - h1[0]._id.toString(), - c._id.toString(), + h1._id.toString(), + p._id.toString(), portNumber, 'tcp', ); const p2 = await portService.addPort( - h2[0]._id.toString(), - c._id.toString(), + h2._id.toString(), + p._id.toString(), portNumber, 'tcp', ); @@ -205,57 +208,49 @@ describe('Port Service', () => { it('Should add the same port to two hosts with the same ip for a different project', async () => { // Arrange - const c = await project('project 1'); - const c2 = await project('project 2'); - const h1 = await host('1.1.1.1', c._id.toString()); - const h2 = await host('1.1.1.1', c2._id.toString()); + const proj1 = await project('project 1'); + const proj2 = await project('project 2'); + const h1 = await host('1.1.1.1', proj1); + const h2 = await host('1.1.1.1', proj2); const portNumber = 80; // Act const p1 = await portService.addPort( - h1[0]._id.toString(), - c._id.toString(), + h1._id.toString(), + proj1._id.toString(), portNumber, 'tcp', ); const p2 = await portService.addPort( - h2[0]._id.toString(), - c2._id.toString(), + h2._id.toString(), + proj2._id.toString(), portNumber, 'tcp', ); // Assert expect(p1.port).toStrictEqual(80); - expect(p1.host.ip).toStrictEqual(h1[0].ip); - expect(p1.projectId.toString()).toStrictEqual(c._id.toString()); + expect(p1.host.ip).toStrictEqual(h1.ip); + expect(p1.projectId.toString()).toStrictEqual(proj1._id.toString()); expect(p2.port).toStrictEqual(80); - expect(p2.host.ip).toStrictEqual(h2[0].ip); - expect(p2.projectId.toString()).toStrictEqual(c2._id.toString()); + expect(p2.host.ip).toStrictEqual(h2.ip); + expect(p2.projectId.toString()).toStrictEqual(proj2._id.toString()); }); }); describe('Get ports', () => { it('Should get the TCP ports in an arbitrary order', async () => { // Arrange - const c = await project(); - const h = await host('1.1.1.1', c._id.toString()); - const portNumbers = [22, 8080, 21, 443, 80]; - const portsAdded = []; - for (let portNumber of portNumbers) { - portsAdded.push( - await portService.addPort( - h[0]._id.toString(), - c._id.toString(), - portNumber, - 'tcp', - ), - ); - } + const h = await host('1.1.1.1', project1); + await port(22, h, project1); + await port(8080, h, project1); + await port(21, h, project1); + await port(443, h, project1); + await port(80, h, project1); // Act const ports = await portService.getHostPorts( - h[0]._id.toString(), + h._id.toString(), 0, 10, 'tcp', @@ -263,28 +258,25 @@ describe('Port Service', () => { // Assert expect(ports.length).toStrictEqual(5); + expect(ports.map((x) => x.port)).toContain(22); + expect(ports.map((x) => x.port)).toContain(8080); + expect(ports.map((x) => x.port)).toContain(21); + expect(ports.map((x) => x.port)).toContain(443); + expect(ports.map((x) => x.port)).toContain(80); }); it('Should get the TCP ports in an arbitrary order with paging', async () => { // Arrange - const c = await project(); - const h = await host('1.1.1.1', c._id.toString()); - const portNumbers = [22, 8080, 21, 443, 80]; - const portsAdded = []; - for (let portNumber of portNumbers) { - portsAdded.push( - await portService.addPort( - h[0]._id.toString(), - c._id.toString(), - portNumber, - 'tcp', - ), - ); - } + const h = await host('1.1.1.1', project1); + await port(22, h, project1); + await port(8080, h, project1); + await port(21, h, project1); + await port(443, h, project1); + await port(80, h, project1); // Act const ports = await portService.getHostPorts( - h[0]._id.toString(), + h._id.toString(), 0, 3, 'tcp', @@ -298,14 +290,8 @@ describe('Port Service', () => { describe('Delete ports', () => { it('Should delete a port by id', async () => { // Arrange - const c = await project(); - const h = await host('1.1.1.1', c._id.toString()); - const p1 = await portService.addPort( - h[0]._id.toString(), - c._id.toString(), - 22, - 'tcp', - ); + const h = await host('1.1.1.1', project1); + const [p1] = await port(22, h, project1); // Act const res = await portService.delete(p1._id.toString()); @@ -316,24 +302,12 @@ describe('Port Service', () => { it('Should delete all ports for a host', async () => { // Arrange - const c = await project(); - const h = await host('1.1.1.1', c._id.toString()); - const p1 = await portService.addPort( - h[0]._id.toString(), - c._id.toString(), - 22, - 'tcp', - ); - - const p2 = await portService.addPort( - h[0]._id.toString(), - c._id.toString(), - 80, - 'tcp', - ); + const h = await host('1.1.1.1', project1); + await port(22, h, project1); + await port(80, h, project1); // Act - const res = await portService.deleteAllForHost(h[0]._id.toString()); + const res = await portService.deleteAllForHost(h._id.toString()); // Assert expect(res.deletedCount).toStrictEqual(2); @@ -341,240 +315,262 @@ describe('Port Service', () => { }); describe('Get all', () => { - it.each([ - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3] }, - { host: '1.1.1.2', ports: [4, 5, 6] }, - ], - { hosts: ['1.1.1.1'] }, - [1, 2, 3], - ], - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3] }, - { host: '1.1.1.2', ports: [4, 5, 6] }, - ], - { hosts: ['1.2'] }, - [4, 5, 6], - ], - [ - [ - { host: '1.2.1.1', ports: [1, 2, 3] }, - { host: '1.1.1.2', ports: [4, 5, 6] }, - ], - { hosts: ['1.2'] }, - [1, 2, 3, 4, 5, 6], - ], - ])( - 'Filter by host', - async ( - hosts: { host: string; ports: number[] }[], - dto: Partial, - expectedPorts: number[], - ) => { - // Arrange - const p1 = await project('p1'); - - for (const h of hosts) { - const htmp = await host(h.host, p1._id.toString()); - for (const p of h.ports) { - await portService.addPort( - htmp[0]._id.toString(), - p1._id.toString(), - p, - 'tcp', - ); - } - } - - // Act - const allPorts = await portService.getAll(0, 10, dto); + let project1: ProjectDocument; + let project2: ProjectDocument; + + let foo: TagsDocument; + let bar: TagsDocument; + let baz: TagsDocument; + let qux: TagsDocument; + + let h1: HostDocument; + let h2: HostDocument; + let h3: HostDocument; + + let p1: PortDocument; + let p2: PortDocument; + let p3: PortDocument; + let p4: PortDocument; + let p5: PortDocument; + let p6: PortDocument; + + beforeEach(async () => { + // Arrange + project1 = await project('project 1'); + project2 = await project('project 2'); + [foo, bar, baz, qux] = await tags('foo', 'bar', 'baz', 'qux'); - // Assert - expect(allPorts.map((x) => x.port).sort()).toStrictEqual( - expectedPorts.sort(), - ); - }, - ); + h1 = await host('1.1.1.1', project1); + [p1, p2] = await port([1, 2], h1, project1, [foo, qux]); - it.each([ - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3], tags: ['asdf'] }, - { host: '1.1.1.2', ports: [4, 5, 6], tags: ['qwerty'] }, - ], - { tags: ['asdf'] }, - [1, 2, 3], - ['asdf', 'qwerty'], - ], - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3], tags: ['asdf'] }, - { host: '1.1.1.2', ports: [4, 5, 6], tags: ['qwerty'] }, - ], - { tags: ['qwerty'] }, - [4, 5, 6], - ['asdf', 'qwerty'], - ], - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3], tags: ['asdf'] }, - { host: '1.1.1.2', ports: [4, 5, 6], tags: ['qwerty'] }, - ], - { hosts: ['1.2'], tags: ['qwerty'] }, - [4, 5, 6], - ['asdf', 'qwerty'], - ], - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3], tags: ['asdf'] }, - { host: '1.1.1.2', ports: [4, 5, 6], tags: ['qwerty', 'asdf'] }, - ], - { tags: ['asdf'] }, - [1, 2, 3, 4, 5, 6], - ['asdf', 'qwerty'], - ], - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3], tags: ['asdf'] }, - { host: '1.1.1.2', ports: [4, 5, 6], tags: ['qwerty'] }, - ], - { hosts: ['1.2'], tags: ['asdf'] }, - [], - ['asdf', 'qwerty'], - ], - ])( - 'Filter by tag', - async ( - hosts: { host: string; ports: number[]; tags: string[] }[], - dto: Partial, - expectedPorts: number[], - tags: string[], - ) => { - // Arrange - const p1 = await project('p1'); - - const tagsMap: Map = new Map< - string, - TagsDocument - >(); - for (const t of tags) { - tagsMap.set(t, await tagsService.create(t, '#ffffff')); - } - - const hDocs = []; - - for (let j = 0; j < hosts.length; ++j) { - const htmp = await host(hosts[j].host, p1._id.toString()); - hDocs.push(htmp[0]); - for (let i = 0; i < hosts[j].tags.length; ++i) { - hosts[j].tags[i] = tagsMap.get(hosts[j].tags[i])._id.toString(); - } - - for (const p of hosts[j].ports) { - const ptmp = await portService.addPort( - htmp[0]._id.toString(), - p1._id.toString(), - p, - 'tcp', - ); - for (const t of hosts[j].tags) { - await portService.tagPort(ptmp._id.toString(), t, true); - } - } - } - - for (let i = 0; i < dto.tags.length; ++i) { - dto.tags[i] = tagsMap.get(dto.tags[i])._id.toString(); - } + h2 = await host('1.2.2.2', project1); + [p3, p4] = await port([3, 4], h2, project1, [bar, qux]); - // Act - const allPorts = await portService.getAll(0, 10, dto); - - // Assert - expect(allPorts.map((x) => x.port).sort()).toStrictEqual( - expectedPorts.sort(), - ); - }, - ); + h3 = await host('1.2.2.3', project2); + [p5] = await port([5], h3, project2, [baz, qux]); + [p6] = await port([6], h3, project2, [baz, qux], 'udp'); + await block(p6); + }); it.each([ - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3] }, - { host: '1.1.1.2', ports: [4, 5, 6] }, - ], - { ports: [5] }, - [5], - ], - [ - [ - { host: '1.2.1.1', ports: [1, 2, 3] }, - { host: '1.1.1.2', ports: [4, 5, 6] }, - ], - { ports: [3] }, - [3], - ], - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3] }, - { host: '1.1.1.2', ports: [4, 5, 6] }, - ], - { hosts: ['1.1.1.1'], ports: [3] }, - [3], - ], - [ - [ - { host: '1.1.1.1', ports: [1, 2, 3] }, - { host: '1.1.1.2', ports: [4, 5, 6] }, - ], - { hosts: ['1.1.1.1'], ports: [5] }, - [], - ], + ['', [1, 2, 3, 4, 5, 6]], + + // Projects + ['project: "project*"', [1, 2, 3, 4, 5, 6]], + ['project: "project 1"', [1, 2, 3, 4]], + ['project: "project 2"', [5, 6]], + ['-project: "project 2"', [1, 2, 3, 4]], + ['project.name: "project*"', [1, 2, 3, 4, 5, 6]], + ['project.name: "project 1"', [1, 2, 3, 4]], + ['project.name: "project 2"', [5, 6]], + ['-project.name: "project 2"', [1, 2, 3, 4]], + [() => `project.id: ${project1.id}`, [1, 2, 3, 4]], + [() => `project.id: ${project2.id}`, [5, 6]], + [() => `-project.id: ${project2.id}`, [1, 2, 3, 4]], + + // Host + ['host: 1.1.1.1', [1, 2]], + ['host.ip: 1.1.1.1', [1, 2]], + [() => `host.id: ${h1._id}`, [1, 2]], + ['host: 1.*', [1, 2, 3, 4, 5, 6]], + ['host: 1.2.2*', [3, 4, 5, 6]], + ['-host: 1.1.1.1', [3, 4, 5, 6]], + ['-host.ip: 1.1.1.1', [3, 4, 5, 6]], + [() => `-host.id: ${h1.id}`, [3, 4, 5, 6]], + ['-host: 1.2.2*', [1, 2]], + + // Port + ['port: 1', [1]], + ['port.number: 1', [1]], + [() => `port.id: ${p1.id}`, [1]], + [() => `-port.id: ${p1.id} -port.id: ${p3.id}`, [2, 4, 5, 6]], + ['-port: 1', [2, 3, 4, 5, 6]], + ['port.protocol: tcp', [1, 2, 3, 4, 5]], + ['-port.protocol: tcp', [6]], + ['port.protocol: udp', [6]], + ['-port.protocol: udp', [1, 2, 3, 4, 5]], + + // Tag + ['tag: foo', [1, 2]], + [() => `tag.id: ${foo._id}`, [1, 2]], + [() => `-tag.id: ${foo._id}`, [3, 4, 5, 6]], + ['-tag: ba*', [1, 2]], + ['-tag: foo', [3, 4, 5, 6]], + ['tag: qux', [1, 2, 3, 4, 5, 6]], + ['tag: foo tag: qux', [1, 2]], + ['-tag: foo tag: qux', [3, 4, 5, 6]], + + // Is + ['is: blocked', [6]], + ['-is: blocked', [1, 2, 3, 4, 5]], ])( - 'Filter by port', - async ( - hosts: { host: string; ports: number[] }[], - dto: Partial, - expectedPorts: number[], - ) => { + 'Filter by "%s"', + async (query: string | (() => string), expected: number[]) => { // Arrange - const p1 = await project('p1'); - - const hDocs = []; - - for (const h of hosts) { - const htmp = await host(h.host, p1._id.toString()); - hDocs.push(htmp[0]); - for (const p of h.ports) { - await portService.addPort( - htmp[0]._id.toString(), - p1._id.toString(), - p, - 'tcp', - ); - } - } + if (typeof query !== 'string') query = query(); // Act - const allPorts = await portService.getAll(0, 10, dto); + const allPorts = await portService.getAll(0, 10, { query }); // Assert expect(allPorts.map((x) => x.port).sort()).toStrictEqual( - expectedPorts.sort(), + expected.sort(), ); }, ); + + // TODO #319 + // // it.each([ + // // { + // // service: 'asdf', + // // product: 'qwerty', + // // version: 'uiop', + // // dto: { services: ['asdf1', 'asdf2'] }, + // // expectedPorts: [1, 2], + // // }, + // // { + // // service: 'asdf', + // // product: 'qwerty', + // // version: 'uiop', + // // dto: { services: ['asdf1', 'asdf2'], products: ['qwerty1'] }, + // // expectedPorts: [1], + // // }, + // // { + // // service: 'asdf', + // // product: 'qwerty', + // // version: 'uiop', + // // dto: { services: ['asdf1', 'asdf2'], versions: ['uiop2'] }, + // // expectedPorts: [2], + // // }, + // // { + // // service: 'asdf', + // // product: 'qWErty', + // // version: 'uiop', + // // dto: { services: ['asdf1', 'asdf2'], products: ['qwerty2', 'qwerty3'] }, + // // expectedPorts: [2], + // // }, + // // { + // // service: 'asdf', + // // product: 'qWErty', + // // version: 'uiOP', + // // dto: { versions: ['uiop3'], products: ['qwerty2', 'qwerty3'] }, + // // expectedPorts: [3], + // // }, + // // ])( + // // 'Filter by service, product, version: %s', + // // async ({ service, product, version, dto, expectedPorts }) => { + // // // Arrange + // // const p1 = await project('p1'); + + // // const hosts = [{ host: '1.1.1.1', ports: [1, 2, 3, 4] }]; + // // const hDocs = []; + + // // const ports: PortDocument[] = []; + + // // for (const h of hosts) { + // // const htmp = await host(h.host, p1._id.toString()); + // // hDocs.push(htmp[0]); + // // for (const p of h.ports) { + // // ports.push( + // // await portService.addPort( + // // htmp[0]._id.toString(), + // // p1._id.toString(), + // // p, + // // 'tcp', + // // ), + // // ); + // // } + // // } + + // // for (const port of ports) { + // // await portModel.updateOne( + // // { _id: { $eq: port._id } }, + // // { + // // service: service + port.port, + // // product: product + port.port, + // // version: version + port.port, + // // }, + // // ); + // // } + + // // // Act + // // const allPorts = await portService.getAll(0, 10, dto); + + // // // Assert + // // expect(allPorts.map((x) => x.port).sort()).toStrictEqual( + // // expectedPorts.sort(), + // // ); + // // }, + // // ); }); async function project(name: string = '') { - const ccDto: CreateProjectDto = { name: `${getName(testPrefix)}` }; + const ccDto: CreateProjectDto = { name }; return await projectService.addProject(ccDto); } - async function host(ip: string, projectId: string) { - return await hostService.addHosts([ip], projectId); + async function host( + ip: string, + project: ProjectDocument, + tags: TagsDocument[] = [], + ) { + const h = (await hostService.addHosts([ip], project._id.toString()))[0]; + + for (const t of tags) { + await hostService.tagHost(h._id.toString(), t._id.toString(), true); + } + + return h; + } + + async function tags(...tags: string[]) { + const createdTags: TagsDocument[] = []; + for (const tag of tags) { + createdTags.push(await tagsService.create(tag, '#ffffff')); + } + + return createdTags; + } + + async function port( + ports: number | number[], + host: HostDocument, + project: ProjectDocument, + tags: TagsDocument[] = [], + protocol: 'tcp' | 'udp' = 'tcp', + ) { + if (typeof ports === 'number') { + ports = [ports]; + } + + const portDocuments = []; + for (const p of ports) { + const bobbyNewport = await portService.addPort( + host._id.toString(), + project._id.toString(), + p, + protocol, + ); + + portDocuments.push(bobbyNewport); + + for (const t of tags) { + await portService.tagPort( + bobbyNewport._id.toString(), + t._id.toString(), + true, + ); + } + } + + return portDocuments; + } + + async function block(...ports: PortDocument[]) { + await portService.batchEdit({ + block: true, + portIds: ports.map((x) => x.id), + }); } afterAll(async () => { diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.service.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.service.ts index 7089e306..0f655ff4 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.service.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/port.service.ts @@ -6,13 +6,13 @@ import { HttpBadRequestException, HttpNotFoundException, } from '../../../../exceptions/http.exceptions'; -import escapeStringRegexp from '../../../../utils/escape-string-regexp'; import { TagsService } from '../../tags/tag.service'; import { CorrelationKeyUtils } from '../correlation.utils'; import { Host, HostDocument } from '../host/host.model'; import { WebsiteService } from '../websites/website.service'; import { BatchEditPortsDto, GetPortsDto } from './port.dto'; import { ExtendedPort, Port, PortDocument } from './port.model'; +import { PortsFilterParser } from './ports-filter-parser'; @Injectable() export class PortService { @@ -23,6 +23,7 @@ export class PortService { private tagsService: TagsService, @InjectModel('port') private readonly portsModel: Model, private readonly websiteService: WebsiteService, + private readonly portsFilterParser: PortsFilterParser, ) {} private readonly hostNotFoundError = 'Invalid host and project combination.'; @@ -42,6 +43,8 @@ export class PortService { portNumber: number, protocol: 'tcp' | 'udp', service: string = undefined, + product: string = undefined, + version: string = undefined, ) { const host: Pick = await this.hostModel.findOne( { @@ -64,6 +67,8 @@ export class PortService { protocol, correlationKey, service, + product, + version, ); } @@ -111,6 +116,8 @@ export class PortService { protocol: string, correlationKey: string, service: string = undefined, + product: string = undefined, + version: string = undefined, ) { if (!(protocol === 'tcp' || protocol === 'udp')) throw new HttpBadRequestException(this.badProtocolError); @@ -143,7 +150,12 @@ export class PortService { let setter = service === undefined ? { lastSeen: Date.now() } - : { lastSeen: Date.now(), service: service }; + : { + lastSeen: Date.now(), + service: service, + product: product, + version: version, + }; res = await this.portsModel.findOneAndUpdate( { @@ -322,7 +334,14 @@ export class PortService { let query: Query = null; if (filter) { - query = this.portsModel.find(await this.buildFilters(filter), projection); + query = this.portsModel.find( + await this.portsFilterParser.buildFilter( + filter.query, + filter.firstSeenStartDate, + filter.firstSeenEndDate, + ), + projection, + ); } else { query = this.portsModel.find({}, projection); } @@ -356,103 +375,15 @@ export class PortService { return await this.portsModel.estimatedDocumentCount(); } else { return await this.portsModel.countDocuments( - await this.buildFilters(filter), + await this.portsFilterParser.buildFilter( + filter.query, + filter.firstSeenStartDate, + filter.firstSeenEndDate, + ), ); } } - public async buildFilters(dto: Partial) { - const finalFilter = {}; - // Filter by host id - if (dto.hostId) { - finalFilter['host.id'] = { $eq: new Types.ObjectId(dto.hostId) }; - } - - // Filter by host ip - if (dto.hosts && !dto.hostId) { - const hostsRegex = dto.hosts - .filter((x) => x) - .map((x) => x.toLowerCase().trim()) - .map((x) => escapeStringRegexp(x)) - .map((x) => new RegExp(`.*${x}.*`)); - - if (hostsRegex.length > 0) { - const hosts = await this.hostModel.find( - { ip: { $in: hostsRegex } }, - '_id', - ); - if (hosts) finalFilter['host.id'] = { $in: hosts.map((h) => h._id) }; - } - } - - // Filter by project - if (dto.projects) { - const projectIds = dto.projects - .filter((x) => x) - .map((x) => new Types.ObjectId(x)); - - if (projectIds.length > 0) { - finalFilter['projectId'] = { $in: projectIds }; - } - } - - // Filter by tag - if (dto.tags) { - const preppedTagsArray = dto.tags - .filter((x) => x) - .map((x) => x.toLowerCase()) - .map((x) => new Types.ObjectId(x)); - - if (preppedTagsArray.length > 0) { - finalFilter['tags'] = { - $all: preppedTagsArray.map((t) => new Types.ObjectId(t)), - }; - } - } - - // Filter by createdAt - if (dto.firstSeenStartDate || dto.firstSeenEndDate) { - let createdAtFilter = {}; - - if (dto.firstSeenStartDate && dto.firstSeenEndDate) { - createdAtFilter = [ - { createdAt: { $gte: dto.firstSeenStartDate } }, - { createdAt: { $lte: dto.firstSeenEndDate } }, - ]; - finalFilter['$and'] = createdAtFilter; - } else { - if (dto.firstSeenStartDate) - createdAtFilter = { $gte: dto.firstSeenStartDate }; - else if (dto.firstSeenEndDate) - createdAtFilter = { $lte: dto.firstSeenEndDate }; - finalFilter['createdAt'] = createdAtFilter; - } - } - - // Filter by port - if (dto.ports) { - const validPorts = dto.ports.filter((x) => x); - finalFilter['port'] = { $in: validPorts }; - } - - // Filter by protocol - if (dto.protocol) { - finalFilter['layer4Protocol'] = { $eq: dto.protocol }; - } - - // Filter by blocked - if (dto.blocked === false) { - finalFilter['$or'] = [ - { blocked: { $exists: false } }, - { blocked: { $eq: false } }, - ]; - } else if (dto.blocked === true) { - finalFilter['blocked'] = { $eq: true }; - } - - return finalFilter; - } - public async batchEdit(dto: BatchEditPortsDto) { const update: Partial = {}; if (dto.block || dto.block === false) update.blocked = dto.block; diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/port/ports-filter-parser.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/ports-filter-parser.ts new file mode 100644 index 00000000..19812257 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/port/ports-filter-parser.ts @@ -0,0 +1,271 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { SearchTerms } from '@red-kite/jobs-manager/common-duplicates/search-query'; +import { FilterQuery, Model, Types } from 'mongoose'; +import { Tag } from '../../tags/tag.model'; +import { FilterParserBase } from '../filters-parser/filter-parser-base'; +import { Host } from '../host/host.model'; +import { Project } from '../project.model'; +import { Port, PortDocument } from './port.model'; + +@Injectable() +export class PortsFilterParser extends FilterParserBase { + constructor( + @InjectModel('host') private readonly hostModel: Model, + @InjectModel('port') private readonly portsModel: Model, + @InjectModel('project') projectModel: Model, + @InjectModel('tags') tagModel: Model, + ) { + super(projectModel, tagModel); + } + + protected async buildResourceFilters(terms: SearchTerms) { + return [ + ...(await this.idFilters(terms)), + ...(await this.numberFilters(terms)), + ...(await this.protocolFilters(terms)), + ...(await this.serviceFilters(terms)), + ...(await this.versionFilters(terms)), + ...(await this.productFilters(terms)), + ...(await this.idFilters(terms)), + ...(await this.hostFilters(terms)), + ]; + } + + /** Handles "port.id" search terms. */ + private async idFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.id'); + if (t.length) { + const portIds = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ + _id: { $in: portIds }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.id'); + if (t.length) { + const portIds = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ + _id: { $not: { $in: portIds } }, + }); + } + } + + return filters; + } + + /** Handles "port.number" search terms. */ + private async numberFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.number'); + const ports = t.map((x) => +x.value); + if (t.length) { + filters.push({ + port: { $in: ports }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.number'); + if (t.length) { + const ports = t.map((x) => +x.value); + + filters.push({ + port: { $not: { $in: ports } }, + }); + } + } + + return filters; + } + + /** Handles "port.protocol" search terms. */ + private async protocolFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.protocol'); + if (t.length) { + const protocols = this.toInclusionList(t, { lowercase: true }); + filters.push({ + layer4Protocol: { $in: protocols }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.protocol'); + if (t.length) { + const protocols = this.toInclusionList(t, { lowercase: true }); + filters.push({ + layer4Protocol: { $not: { $in: protocols } }, + }); + } + } + + return filters; + } + + /** Handles "port.service" search terms. */ + private async serviceFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.service'); + if (t.length) { + const service = this.toInclusionList(t, { lowercase: true }); + filters.push({ + service: { $in: service }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.service'); + if (t.length) { + const services = this.toInclusionList(t, { lowercase: true }); + filters.push({ + service: { $not: { $in: services } }, + }); + } + } + + return filters; + } + + /** Handles "port.version" search terms. */ + private async versionFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.version'); + if (t.length) { + const version = this.toInclusionList(t, { lowercase: true }); + filters.push({ + service: { $in: version }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.version'); + if (t.length) { + const version = this.toInclusionList(t, { lowercase: true }); + filters.push({ + version: { $not: { $in: version } }, + }); + } + } + + return filters; + } + + /** Handles "port.product" search terms. */ + private async productFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // "port.product" filters + { + // Include + { + const t = this.consumeTerms(terms, '', 'port.product'); + if (t.length) { + const product = this.toInclusionList(t, { lowercase: true }); + filters.push({ + product: { $in: product }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.product'); + if (t.length) { + const product = this.toInclusionList(t, { lowercase: true }); + filters.push({ + product: { $not: { $in: product } }, + }); + } + } + } + + return filters; + } + + /** Handles "host.id" and "host.ip" search terms. */ + private async hostFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // "host.id" filters + { + // Inclusion + { + const t = this.consumeTerms(terms, '', 'host.id'); + if (t.length) { + const hosts = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ 'host.id': { $in: hosts } }); + } + } + + // Exclusion + { + const t = this.consumeTerms(terms, '-', 'host.id'); + if (t.length) { + const notHosts = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ 'host.id': { $not: { $in: notHosts } } }); + } + } + } + + // "host.ip" filters + { + // Inclusion + { + const t = this.consumeTerms(terms, '', 'host.ip'); + if (t.length) { + const hosts = await this.hostModel.find( + { ip: { $in: this.toInclusionList(t) } }, + '_id', + ); + + filters.push({ 'host.id': { $in: hosts.map((x) => x._id) } }); + } + } + + // Exclusion + { + const t = this.consumeTerms(terms, '-', 'host.ip'); + if (t.length) { + const hosts = await this.hostModel.find( + { ip: { $in: this.toInclusionList(t) } }, + '_id', + ); + + filters.push({ + 'host.id': { $not: { $in: hosts.map((x) => x._id) } }, + }); + } + } + } + + return filters; + } +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.controller.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.controller.ts index 8245c31c..19e8e766 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.controller.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.controller.ts @@ -37,23 +37,6 @@ export class ProjectController { private readonly configService: ConfigService, ) {} - private isValidIpRange(ipRange: string) { - if (!/^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?\/\d\d?$/.test(ipRange)) - return false; - - const ipMask = ipRange.split('/'); - - if (parseInt(ipMask[1]) > 32) return false; - - const ipParts = ipMask[0].split('.'); - - for (const part of ipParts) { - if (parseInt(part) > 255) return false; - } - - return true; - } - @UseGuards(AuthGuard([JwtStrategy.name, ApiKeyStrategy.name]), RolesGuard) @Roles(Role.ReadOnly) @Get() @@ -112,24 +95,6 @@ export class ProjectController { data['logo'] = dto.logo; } - if (dto.ipRanges) { - data['ipRanges'] = []; - for (const range of dto.ipRanges) { - // TODO: Validate the ip ranges through a decorator - if (!this.isValidIpRange(range)) { - throw new HttpBadRequestException(); - } - data['ipRanges'].push(range); - } - } else if (Array.isArray(dto.ipRanges)) { - // ^ This previous line checks for an empty array. The check is needed because the value - // may also be, at this point, null or undefined - // If an empty array is explicitly provided, it is because the user wants to - // empty the project's ipRanges array. Therefore, we assign an empty array to overwrite the - // existing one in the database. - data['ipRanges'] = []; - } - if (dto.name === '') { throw new HttpBadRequestException(); } else if (dto.name) { diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.dto.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.dto.ts index beacc27f..a2888909 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.dto.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.dto.ts @@ -1,5 +1,4 @@ import { - IsArray, IsBase64, IsIn, IsNotEmpty, @@ -41,8 +40,4 @@ export class EditProjectDto { @IsOptional() @IsString() public notes: string; - - @IsOptional() - @IsArray() - public ipRanges: string[]; } diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.e2e-spec.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.e2e-spec.ts index c58ab257..75792a82 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.e2e-spec.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.e2e-spec.ts @@ -66,7 +66,6 @@ describe('Project Controller (e2e)', () => { const notesEdit = 'great notes over here'; let r = await putReq(app, testData.user.token, `/project/${projectId}`, { name: nameEdit, - ipRanges: subnetEdit, notes: notesEdit, }); expect(r.statusCode).toBe(HttpStatus.OK); @@ -74,7 +73,6 @@ describe('Project Controller (e2e)', () => { r = await getReq(app, testData.user.token, `/project/${projectId}`); expect(r.body._id).toBeTruthy(); expect(r.body.name).toBe(nameEdit); - expect(r.body.ipRanges).toEqual(subnetEdit); expect(r.body.notes).toBe(notesEdit); }); diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.model.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.model.ts index 15443d6f..accd9b83 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.model.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.model.ts @@ -8,9 +8,6 @@ export class Project { @Prop({ index: true, unique: true }) public name: string; - @Prop() - public ipRanges?: string[]; - @Prop() public logo: string; diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.module.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.module.ts index 019d0101..6794b5d3 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.module.ts @@ -8,6 +8,7 @@ import { EventSubscriptionsModule } from '../subscriptions/event-subscriptions/e import { SubscriptionTriggersModule } from '../subscriptions/subscription-triggers/subscription-triggers.module'; import { DomainsModule } from './domain/domain.module'; import { HostModule } from './host/host.module'; +import { IpRangeModule } from './ip-ranges/ip-range.module'; import { PortModule } from './port/port.module'; import { ProjectController } from './project.controller'; import { ProjectService } from './project.service'; @@ -26,6 +27,7 @@ import { WebsiteModule } from './websites/website.module'; SecretsModule, WebsiteModule, SubscriptionTriggersModule, + IpRangeModule, ], controllers: [ProjectController], providers: [ProjectService], diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.service.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.service.ts index 45e0b3ec..63eafae7 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/project.service.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/project.service.ts @@ -1,9 +1,7 @@ import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; -import { isIP } from 'class-validator'; import { DeleteResult, UpdateResult } from 'mongodb'; import { Model, Types } from 'mongoose'; -import { HttpBadRequestException } from '../../../exceptions/http.exceptions'; import { JobExecutionsService } from '../jobs/job-executions.service'; import { SecretsService } from '../secrets/secrets.service'; import { CronSubscription } from '../subscriptions/cron-subscriptions/cron-subscriptions.model'; @@ -12,6 +10,7 @@ import { SubscriptionTriggersService } from '../subscriptions/subscription-trigg import { DomainsService } from './domain/domain.service'; import { CustomFinding } from './findings/finding.model'; import { HostService } from './host/host.service'; +import { IpRangeService } from './ip-ranges/ip-range.service'; import { PortService } from './port/port.service'; import { CreateProjectDto } from './project.dto'; import { Project, ProjectDocument } from './project.model'; @@ -33,6 +32,7 @@ export class ProjectService { private readonly secretsService: SecretsService, private readonly websiteService: WebsiteService, private readonly triggerService: SubscriptionTriggersService, + private readonly ipRangeService: IpRangeService, ) {} public async getAll( @@ -103,6 +103,7 @@ export class ProjectService { await this.portsService.deleteAllForProject(id); await this.websiteService.deleteAllForProject(id); await this.triggerService.deleteAllForProject(id); + await this.ipRangeService.deleteAllForProject(id); await this.findingModel.deleteMany({ correlationKey: { $regex: new RegExp(`^project:${id}`) }, }); @@ -126,25 +127,4 @@ export class ProjectService { { ...project }, ); } - - public async getIpRanges( - id: string, - ): Promise> { - return await this.projectModel.findById(id, 'ipRanges'); - } - - public async addIpRangeWithMask(id: string, ip: string, mask: number) { - if (0 > mask || mask > 32) - throw new HttpBadRequestException( - 'Mask of ip range is not between 0 and 32', - ); - if (!isIP(ip, 4)) - throw new HttpBadRequestException('Ip is not an IPv4 address'); - - const range = `${ip}/${mask}`; - await this.projectModel.updateOne( - { _id: { $eq: new Types.ObjectId(id) } }, - { $addToSet: { ipRanges: range } }, - ); - } } diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/resource.dto.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/resource.dto.ts index 7dac582c..9189ce53 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/resource.dto.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/resource.dto.ts @@ -10,56 +10,77 @@ import { IsString, } from 'class-validator'; import { booleanStringToBoolean } from '../../../utils/boolean-string-to-boolean'; +import { IsIpRange } from '../../../validators/is-ip-range.validator'; +// TODO 319: REMOVE ME export class FilterByDomainDto { @IsOptional() @IsString({ each: true }) @IsArray() - domains: string[]; + domains?: string[]; } export class FilterByHostDto { + // TODO 319: REMOVE ME + /** @deprecated : Use query instead */ @IsOptional() @IsString({ each: true }) @IsArray() - hosts: string[]; + hosts?: string[]; +} + +export class FilterByIpRangeDto { + // TODO 319: REMOVE ME + /** @deprecated: use "query" syntax instead */ + @IsOptional() + @IsIpRange({ each: true }) + @IsArray() + ranges?: string[]; } export class FilterByPortDto { + // TODO 319: REMOVE ME + /** @deprecated: use "query" syntax instead */ @IsOptional() @IsPort({ each: true }) @IsArray() - ports: number[]; + ports?: number[]; } export class FilterByProjectDto { + /** @deprecated: use "query" syntax instead */ @IsOptional() @IsMongoId({ each: true }) @IsArray() - projects: string[]; + projects?: string[]; } -export class ResourceFilterDto extends IntersectionType( - FilterByHostDto, - FilterByProjectDto, -) { +export class ResourceFilterDto extends IntersectionType(FilterByProjectDto) { @IsOptional() @IsInt() @Type(() => Number) - firstSeenStartDate: number; + firstSeenStartDate?: number; @IsOptional() @IsInt() @Type(() => Number) - firstSeenEndDate: number; + firstSeenEndDate?: number; + + @IsOptional() + @IsString() + query: string; + // TODO 319: REMOVE ME + /** @deprecated: use "query" syntax instead */ @IsOptional() @IsBoolean() @Transform(booleanStringToBoolean) - blocked: boolean; + blocked?: boolean; + // TODO 319: REMOVE ME + /** @deprecated: use "query" syntax instead */ @IsOptional() @IsMongoId({ each: true }) @IsArray() - tags: string[]; + tags?: string[]; } diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/resource.type.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/resource.type.ts index 16f9e6c4..75d91caf 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/resource.type.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/resource.type.ts @@ -1,2 +1,15 @@ +import { DomainDocument } from './domain/domain.model'; +import { HostDocument } from './host/host.model'; +import { IpRangeDocument } from './ip-ranges/ip-range.model'; +import { PortDocument } from './port/port.model'; +import { WebsiteDocument } from './websites/website.model'; + export const resourceTypes = ['domain', 'host', 'port', 'website'] as const; export type ResourceType = (typeof resourceTypes)[number]; + +export type Resource = + | HostDocument + | PortDocument + | DomainDocument + | IpRangeDocument + | WebsiteDocument; diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/websites/website.dto.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/websites/website.dto.ts index 2896e1f1..3c468ef4 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/reporting/websites/website.dto.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/websites/website.dto.ts @@ -12,6 +12,7 @@ import { booleanStringToBoolean } from '../../../../utils/boolean-string-to-bool import { PagingDto } from '../../database.dto'; import { FilterByDomainDto, + FilterByHostDto, FilterByPortDto, ResourceFilterDto, } from '../resource.dto'; @@ -20,6 +21,7 @@ export class WebsiteFilterDto extends IntersectionType( ResourceFilterDto, FilterByPortDto, FilterByDomainDto, + FilterByHostDto, ) { @IsOptional() @IsString({ each: true }) diff --git a/packages/backend/jobs-manager/service/src/modules/database/reporting/websites/websites-filter-parser.ts b/packages/backend/jobs-manager/service/src/modules/database/reporting/websites/websites-filter-parser.ts new file mode 100644 index 00000000..0c513bd3 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/modules/database/reporting/websites/websites-filter-parser.ts @@ -0,0 +1,271 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { SearchTerms } from '@red-kite/jobs-manager/common-duplicates/search-query'; +import { FilterQuery, Model, Types } from 'mongoose'; +import { Tag } from '../../tags/tag.model'; +import { FilterParserBase } from '../filters-parser/filter-parser-base'; +import { Host } from '../host/host.model'; +import { Project } from '../project.model'; +import { Website, WebsiteDocument } from './website.model'; + +@Injectable() +export class WebsitesFilterParser extends FilterParserBase { + constructor( + @InjectModel('host') private readonly hostModel: Model, + @InjectModel('websites') private readonly portsModel: Model, + @InjectModel('project') projectModel: Model, + @InjectModel('tags') tagModel: Model, + ) { + super(projectModel, tagModel); + } + + protected async buildResourceFilters(terms: SearchTerms) { + return [ + ...(await this.idFilters(terms)), + ...(await this.numberFilters(terms)), + ...(await this.protocolFilters(terms)), + ...(await this.serviceFilters(terms)), + ...(await this.versionFilters(terms)), + ...(await this.productFilters(terms)), + ...(await this.idFilters(terms)), + ...(await this.hostFilters(terms)), + ]; + } + + /** Handles "website.id" search terms. */ + private async idFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'website.id'); + if (t.length) { + const websiteIds = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ + _id: { $in: websiteIds }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.id'); + if (t.length) { + const portIds = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ + _id: { $not: { $in: portIds } }, + }); + } + } + + return filters; + } + + /** Handles "port.number" search terms. */ + private async numberFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.number'); + const ports = t.map((x) => +x.value); + if (t.length) { + filters.push({ + port: { $in: ports }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.number'); + if (t.length) { + const ports = t.map((x) => +x.value); + + filters.push({ + port: { $not: { $in: ports } }, + }); + } + } + + return filters; + } + + /** Handles "port.protocol" search terms. */ + private async protocolFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.protocol'); + if (t.length) { + const protocols = this.toInclusionList(t, { lowercase: true }); + filters.push({ + layer4Protocol: { $in: protocols }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.protocol'); + if (t.length) { + const protocols = this.toInclusionList(t, { lowercase: true }); + filters.push({ + layer4Protocol: { $not: { $in: protocols } }, + }); + } + } + + return filters; + } + + /** Handles "port.service" search terms. */ + private async serviceFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.service'); + if (t.length) { + const service = this.toInclusionList(t, { lowercase: true }); + filters.push({ + service: { $in: service }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.service'); + if (t.length) { + const services = this.toInclusionList(t, { lowercase: true }); + filters.push({ + service: { $not: { $in: services } }, + }); + } + } + + return filters; + } + + /** Handles "port.version" search terms. */ + private async versionFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // Include + { + const t = this.consumeTerms(terms, '', 'port.version'); + if (t.length) { + const version = this.toInclusionList(t, { lowercase: true }); + filters.push({ + service: { $in: version }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.version'); + if (t.length) { + const version = this.toInclusionList(t, { lowercase: true }); + filters.push({ + version: { $not: { $in: version } }, + }); + } + } + + return filters; + } + + /** Handles "port.product" search terms. */ + private async productFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // "port.product" filters + { + // Include + { + const t = this.consumeTerms(terms, '', 'port.product'); + if (t.length) { + const product = this.toInclusionList(t, { lowercase: true }); + filters.push({ + product: { $in: product }, + }); + } + } + + // Exclude + { + const t = this.consumeTerms(terms, '-', 'port.product'); + if (t.length) { + const product = this.toInclusionList(t, { lowercase: true }); + filters.push({ + product: { $not: { $in: product } }, + }); + } + } + } + + return filters; + } + + /** Handles "host.id" and "host.ip" search terms. */ + private async hostFilters(terms: SearchTerms) { + const filters: FilterQuery[] = []; + + // "host.id" filters + { + // Inclusion + { + const t = this.consumeTerms(terms, '', 'host.id'); + if (t.length) { + const hosts = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ 'host.id': { $in: hosts } }); + } + } + + // Exclusion + { + const t = this.consumeTerms(terms, '-', 'host.id'); + if (t.length) { + const notHosts = t.map((x) => new Types.ObjectId(x.value)); + filters.push({ 'host.id': { $not: { $in: notHosts } } }); + } + } + } + + // "host.ip" filters + { + // Inclusion + { + const t = this.consumeTerms(terms, '', 'host.ip'); + if (t.length) { + const hosts = await this.hostModel.find( + { ip: { $in: this.toInclusionList(t) } }, + '_id', + ); + + filters.push({ 'host.id': { $in: hosts.map((x) => x._id) } }); + } + } + + // Exclusion + { + const t = this.consumeTerms(terms, '-', 'host.ip'); + if (t.length) { + const hosts = await this.hostModel.find( + { ip: { $in: this.toInclusionList(t) } }, + '_id', + ); + + filters.push({ + 'host.id': { $not: { $in: hosts.map((x) => x._id) } }, + }); + } + } + } + + return filters; + } +} diff --git a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.module.ts b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.module.ts index a11d7e04..843a48ae 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.module.ts @@ -6,6 +6,7 @@ import { DatalayerModule } from '../../datalayer.module'; import { JobsModule } from '../../jobs/jobs.module'; import { DomainsModule } from '../../reporting/domain/domain.module'; import { HostModule } from '../../reporting/host/host.module'; +import { IpRangeModule } from '../../reporting/ip-ranges/ip-range.module'; import { PortModule } from '../../reporting/port/port.module'; import { ProjectModule } from '../../reporting/project.module'; import { WebsiteModule } from '../../reporting/websites/website.module'; @@ -28,6 +29,7 @@ import { CronSubscriptionsService } from './cron-subscriptions.service'; CustomJobsModule, WebsiteModule, SubscriptionTriggersModule, + IpRangeModule, ], controllers: [CronSubscriptionsController], providers: [CronSubscriptionsService, CustomJobNameExistsRule], diff --git a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.service.ts b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.service.ts index c7c63941..3e54d442 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.service.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.service.ts @@ -26,9 +26,13 @@ import { Domain, DomainDocument } from '../../reporting/domain/domain.model'; import { DomainsService } from '../../reporting/domain/domain.service'; import { HostDocument } from '../../reporting/host/host.model'; import { HostService } from '../../reporting/host/host.service'; +import { + IpRange, + IpRangeDocument, +} from '../../reporting/ip-ranges/ip-range.model'; +import { IpRangeService } from '../../reporting/ip-ranges/ip-range.service'; import { Port } from '../../reporting/port/port.model'; import { PortService } from '../../reporting/port/port.service'; -import { ProjectDocument } from '../../reporting/project.model'; import { ProjectService } from '../../reporting/project.service'; import { WebsiteDocument } from '../../reporting/websites/website.model'; import { WebsiteService } from '../../reporting/websites/website.service'; @@ -53,6 +57,7 @@ export class CronSubscriptionsService { private readonly configService: ConfigService, private readonly customJobsService: CustomJobsService, private readonly jobsService: JobExecutionsService, + private readonly ipRangesService: IpRangeService, private readonly domainsService: DomainsService, private readonly hostsService: HostService, private readonly portsService: PortService, @@ -317,14 +322,17 @@ export class CronSubscriptionsService { } while (ports.length >= pageSize && pageSize !== null); break; case 'ALL_IP_RANGES': - const ranges = await this.projectService.getIpRanges(projectId); - this.publishJobsFromIpRanges( - sub, - ranges, - projectId, - batchEnabled, - pageSize, - ); + let ranges: IpRange[] = []; + do { + ranges = await this.ipRangesService.getAll(page, pageSize, { + query: '', // TODO #319 + detailsLevel: 'summary', + }); + if (ranges.length) { + this.publishJobsFromIpRanges(sub, ranges, projectId, batchEnabled); + } + page++; + } while (ranges.length >= pageSize && pageSize !== null); break; case 'ALL_WEBSITES': let websites: Pick< @@ -427,44 +435,27 @@ export class CronSubscriptionsService { private publishJobsFromIpRanges( sub: CronSubscription, - project: Pick, + ranges: Pick[], projectId: string, batchEnabled: boolean, - batchSize: number, ) { - if (!project.ipRanges) return; + if (!ranges || !ranges.length) return; let batchFinding = new IpRangeBatchFinding(); - let counter = 0; - for (const range of project.ipRanges) { - const ipMask = range.split('/'); - let ip = ''; - let mask = -1; - try { - ip = ipMask[0]; - mask = Number(ipMask[1]); - } catch (err) { - this.logger.error(err); - this.logger.error( - `Error while trying to start a job for ip range ${range}`, - ); - continue; - } - if (!batchEnabled) { + if (!batchEnabled) { + for (const range of ranges) { const finding = new IpRangeFinding(); - finding.ip = ip; - finding.mask = mask; + finding.ip = range.ip; + finding.mask = range.mask; this.publishJobForFinding(sub, finding, projectId); - } else { - counter++; - batchFinding.ipBatch.push(ip); - batchFinding.maskBatch.push(mask); - if (counter % batchSize == 0 || counter === project.ipRanges.length) { - this.publishJobForFinding(sub, batchFinding, projectId); - batchFinding = new IpRangeBatchFinding(); - } } + } else { + for (const range of ranges) { + batchFinding.ipBatch.push(range.ip); + batchFinding.maskBatch.push(range.mask); + } + this.publishJobForFinding(sub, batchFinding, projectId); } } diff --git a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.spec.ts b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.spec.ts index 60b4f41f..3b860fb3 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.spec.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/cron-subscriptions/cron-subscriptions.spec.ts @@ -1,9 +1,14 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { + ipv4RangeValuesToMinMax, + numberToIpv4, +} from '../../../../utils/ip-address.utils'; import { AppModule } from '../../../app.module'; import { DomainDocument } from '../../reporting/domain/domain.model'; import { DomainsService } from '../../reporting/domain/domain.service'; import { HostDocument } from '../../reporting/host/host.model'; import { HostService } from '../../reporting/host/host.service'; +import { IpRangeService } from '../../reporting/ip-ranges/ip-range.service'; import { PortDocument } from '../../reporting/port/port.model'; import { PortService } from '../../reporting/port/port.service'; import { ProjectService } from '../../reporting/project.service'; @@ -22,6 +27,7 @@ describe('Cron Subscriptions Service', () => { let hostsService: HostService; let portsService: PortService; let websiteService: WebsiteService; + let ipRangeService: IpRangeService; const csDto: CronSubscriptionDto = { cronExpression: '*/5 * * * *', @@ -50,6 +56,7 @@ describe('Cron Subscriptions Service', () => { hostsService = moduleFixture.get(HostService); portsService = moduleFixture.get(PortService); websiteService = moduleFixture.get(WebsiteService); + ipRangeService = moduleFixture.get(IpRangeService); }); beforeEach(async () => { @@ -1484,7 +1491,7 @@ describe('Cron Subscriptions Service', () => { { name: 'ports', value: [] }, ]; - await projectService.addIpRangeWithMask(c._id.toString(), ip, mask); + await ipRangeService.addIpRange(ip, mask, c._id.toString()); const spy = jest //@ts-expect-error .spyOn(subscriptionsService, 'publishJob') //@ts-expect-error @@ -1530,27 +1537,11 @@ describe('Cron Subscriptions Service', () => { { name: 'ports', value: [] }, ]; - await projectService.addIpRangeWithMask( - c._id.toString(), - '1.1.1.2', - mask, - ); - await projectService.addIpRangeWithMask( - c._id.toString(), - '1.1.1.3', - mask, - ); - await projectService.addIpRangeWithMask( - c._id.toString(), - '1.1.1.4', - mask, - ); - await projectService.addIpRangeWithMask( - c._id.toString(), - '1.1.1.5', - mask, - ); - await projectService.addIpRangeWithMask(c._id.toString(), ip, mask); + await ipRangeService.addIpRange('1.1.1.2', mask, c._id.toString()); + await ipRangeService.addIpRange('1.1.1.3', mask, c._id.toString()); + await ipRangeService.addIpRange('1.1.1.4', mask, c._id.toString()); + await ipRangeService.addIpRange('1.1.1.5', mask, c._id.toString()); + await ipRangeService.addIpRange(ip, mask, c._id.toString()); const spy = jest //@ts-expect-error .spyOn(subscriptionsService, 'publishJob') //@ts-expect-error @@ -1614,7 +1605,7 @@ describe('Cron Subscriptions Service', () => { }, ]); - await projectService.addIpRangeWithMask(c._id.toString(), ip, mask); + await ipRangeService.addIpRange(ip, mask, c._id.toString()); const spy = jest //@ts-expect-error .spyOn(subscriptionsService, 'publishJob') //@ts-expect-error @@ -1679,27 +1670,11 @@ describe('Cron Subscriptions Service', () => { }, ]); - await projectService.addIpRangeWithMask( - c._id.toString(), - '1.1.1.2', - mask, - ); - await projectService.addIpRangeWithMask( - c._id.toString(), - '1.1.1.3', - mask, - ); - await projectService.addIpRangeWithMask( - c2._id.toString(), - '1.1.1.4', - mask, - ); - await projectService.addIpRangeWithMask( - c2._id.toString(), - '1.1.1.5', - mask, - ); - await projectService.addIpRangeWithMask(c2._id.toString(), ip, mask); + await ipRangeService.addIpRange('1.1.1.2', mask, c._id.toString()); + await ipRangeService.addIpRange('1.1.1.3', mask, c._id.toString()); + await ipRangeService.addIpRange('1.1.1.4', mask, c2._id.toString()); + await ipRangeService.addIpRange('1.1.1.5', mask, c2._id.toString()); + await ipRangeService.addIpRange(ip, mask, c._id.toString()); const spy = jest //@ts-expect-error .spyOn(subscriptionsService, 'publishJobsFromInput') //@ts-expect-error @@ -2419,7 +2394,7 @@ describe('Cron Subscriptions Service', () => { masks: [32, 24, 23], }, ])( - 'Should publish jobs from input ALL_IP_RANGES (one batch)', + 'Should publish jobs from input ALL_IP_RANGES (one batch): %s', async ({ batchEnabled, batchSize, ips, masks }) => { // Arrange const c = await project('Test project'); @@ -2440,11 +2415,8 @@ describe('Cron Subscriptions Service', () => { }; for (let i = 0; i < ips.length; ++i) { - await projectService.addIpRangeWithMask( - c._id.toString(), - ips[i], - masks[i], - ); + await ipRangeService.addIpRange(ips[i], masks[i], c._id.toString()); + ips[i] = numberToIpv4(ipv4RangeValuesToMinMax(ips[i], masks[i]).min); } const spy = jest //@ts-expect-error @@ -2513,11 +2485,7 @@ describe('Cron Subscriptions Service', () => { }; for (let i = 0; i < ips.length; ++i) { - await projectService.addIpRangeWithMask( - c._id.toString(), - ips[i], - masks[i], - ); + await ipRangeService.addIpRange(ips[i], masks[i], c._id.toString()); } const spy = jest //@ts-expect-error diff --git a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.module.ts b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.module.ts index e8faadfc..f6e77f8b 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.module.ts @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common'; import { MongooseModule } from '@nestjs/mongoose'; import { DomainsModule } from '../../reporting/domain/domain.module'; import { HostModule } from '../../reporting/host/host.module'; +import { IpRangeModule } from '../../reporting/ip-ranges/ip-range.module'; import { PortModule } from '../../reporting/port/port.module'; import { WebsiteModule } from '../../reporting/websites/website.module'; import { SubscriptionTriggersController } from './subscription-triggers.controller'; @@ -20,6 +21,7 @@ import { SubscriptionTriggersService } from './subscription-triggers.service'; DomainsModule, PortModule, WebsiteModule, + IpRangeModule, ], controllers: [SubscriptionTriggersController], providers: [SubscriptionTriggersService], diff --git a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.service.ts b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.service.ts index 7c17b7be..a57b2d64 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.service.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.service.ts @@ -5,6 +5,7 @@ import { Model, Types } from 'mongoose'; import { CorrelationKeyUtils } from '../../reporting/correlation.utils'; import { DomainsService } from '../../reporting/domain/domain.service'; import { HostService } from '../../reporting/host/host.service'; +import { IpRangeService } from '../../reporting/ip-ranges/ip-range.service'; import { PortService } from '../../reporting/port/port.service'; import { WebsiteService } from '../../reporting/websites/website.service'; import { @@ -23,6 +24,7 @@ export class SubscriptionTriggersService { private readonly domainsService: DomainsService, private readonly portsService: PortService, private readonly websiteService: WebsiteService, + private readonly ipRangeService: IpRangeService, ) {} public async isTriggerBlocked(correlationKey: string): Promise { @@ -38,6 +40,8 @@ export class SubscriptionTriggersService { return await this.hostsService.keyIsBlocked(correlationKey); case 'WebsiteService': return await this.websiteService.keyIsBlocked(correlationKey); + case 'IpRangeService': + return await this.ipRangeService.keyIsBlocked(correlationKey); default: return false; } diff --git a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.spec.ts b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.spec.ts index 75b2b2a3..9a5cd7d6 100644 --- a/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.spec.ts +++ b/packages/backend/jobs-manager/service/src/modules/database/subscriptions/subscription-triggers/subscription-triggers.spec.ts @@ -5,9 +5,11 @@ import { DomainDocument } from '../../reporting/domain/domain.model'; import { DomainsService } from '../../reporting/domain/domain.service'; import { HostDocument } from '../../reporting/host/host.model'; import { HostService } from '../../reporting/host/host.service'; +import { IpRangeService } from '../../reporting/ip-ranges/ip-range.service'; import { PortService } from '../../reporting/port/port.service'; import { ProjectDocument } from '../../reporting/project.model'; import { ProjectService } from '../../reporting/project.service'; +import { WebsiteService } from '../../reporting/websites/website.service'; import { SubscriptionTriggersService } from './subscription-triggers.service'; describe('Subscriptions Triggers Service', () => { @@ -17,6 +19,8 @@ describe('Subscriptions Triggers Service', () => { let hostService: HostService; let portService: PortService; let projectService: ProjectService; + let ipRangeService: IpRangeService; + let websiteService: WebsiteService; beforeAll(async () => { moduleFixture = await Test.createTestingModule({ @@ -27,6 +31,8 @@ describe('Subscriptions Triggers Service', () => { hostService = moduleFixture.get(HostService); portService = moduleFixture.get(PortService); projectService = moduleFixture.get(ProjectService); + ipRangeService = moduleFixture.get(IpRangeService); + websiteService = moduleFixture.get(WebsiteService); // Without { doNotFake: ['nextTick'] } the tests timeout with fake timers jest.useFakeTimers({ doNotFake: ['nextTick', 'setImmediate'] }); }); @@ -359,6 +365,103 @@ describe('Subscriptions Triggers Service', () => { // Assert expect(triggerSuccess).toStrictEqual(false); }); + + it('Does not trigger a subscription ready to be triggered for a blocked website', async () => { + // Arrange + const subId = '6574f560570cfc954ccf0b42'; + const projectObj = await project('name'); + const projectId = projectObj._id.toString(); + const ip = '1.1.1.1'; + const p = 80; + const d = 'example.com'; + const h = await host(projectId, ip, false); + await domain(projectId, d, false); + await port(projectId, h._id.toString(), p, false); + const path = '/'; + const websiteObj = await websiteService.addWebsite( + projectId, + ip, + p, + d, + path, + true, + ); + await websiteService.batchEdit({ + block: true, + websiteIds: [websiteObj._id], + }); + const subCooldown = 100; + const correlationKey = CorrelationKeyUtils.generateCorrelationKey( + projectId, + d, + ip, + p, + 'tcp', + null, + path, + ); + + await triggersService.attemptTrigger( + subId, + correlationKey, + subCooldown, + null, + ); + jest.setSystemTime(Date.now() + subCooldown * 1000 * 2); + + // Act + const triggerSuccess = await triggersService.attemptTrigger( + subId, + correlationKey, + subCooldown, + null, + ); + + // Assert + expect(triggerSuccess).toStrictEqual(false); + }); + + it('Does not trigger a subscription ready to be triggered for a blocked IP range', async () => { + // Arrange + const subId = '6574f560570cfc954ccf0b42'; + const projectObj = await project('name'); + const projectId = projectObj._id.toString(); + const ip = '1.1.1.1'; + const mask = 23; + const ipRangeObj = await ipRangeService.addIpRange(ip, mask, projectId); + await ipRangeService.batchEdit({ + block: true, + ipRangeIds: [ipRangeObj._id.toString()], + }); + const subCooldown = 100; + const correlationKey = CorrelationKeyUtils.generateCorrelationKey( + projectId, + undefined, + ip, + undefined, + undefined, + mask, + ); + + await triggersService.attemptTrigger( + subId, + correlationKey, + subCooldown, + null, + ); + jest.setSystemTime(Date.now() + subCooldown * 1000 * 2); + + // Act + const triggerSuccess = await triggersService.attemptTrigger( + subId, + correlationKey, + subCooldown, + null, + ); + + // Assert + expect(triggerSuccess).toStrictEqual(false); + }); }); async function project(name: string): Promise { diff --git a/packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ipRange.command.ts b/packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ip-range.command.ts similarity index 100% rename from packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ipRange.command.ts rename to packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ip-range.command.ts diff --git a/packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ipRange.handler.ts b/packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ip-range.handler.ts similarity index 80% rename from packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ipRange.handler.ts rename to packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ip-range.handler.ts index 8d5554da..1ed95951 100644 --- a/packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ipRange.handler.ts +++ b/packages/backend/jobs-manager/service/src/modules/findings/commands/Findings/ip-range.handler.ts @@ -3,20 +3,19 @@ import { CommandHandler } from '@nestjs/cqrs'; import { ConfigService } from '../../../database/admin/config/config.service'; import { CustomJobsService } from '../../../database/custom-jobs/custom-jobs.service'; import { JobExecutionsService } from '../../../database/jobs/job-executions.service'; -import { ProjectService } from '../../../database/reporting/project.service'; +import { IpRangeService } from '../../../database/reporting/ip-ranges/ip-range.service'; import { SecretsService } from '../../../database/secrets/secrets.service'; import { EventSubscriptionsService } from '../../../database/subscriptions/event-subscriptions/event-subscriptions.service'; import { SubscriptionTriggersService } from '../../../database/subscriptions/subscription-triggers/subscription-triggers.service'; import { UserFindingHandlerBase } from '../user-findings-handler-base'; -import { IpCommand } from './ip.command'; -import { IpRangeCommand } from './ipRange.command'; +import { IpRangeCommand } from './ip-range.command'; -@CommandHandler(IpCommand) +@CommandHandler(IpRangeCommand) export class IpRangeHandler extends UserFindingHandlerBase { - protected logger: Logger = new Logger('IpRangeHandler'); + protected logger: Logger = new Logger(IpRangeHandler.name); constructor( - private readonly projectService: ProjectService, + private readonly ipRangeService: IpRangeService, jobService: JobExecutionsService, subscriptionsService: EventSubscriptionsService, customJobsService: CustomJobsService, @@ -37,10 +36,10 @@ export class IpRangeHandler extends UserFindingHandlerBase { protected async executeCore(command: IpRangeCommand) { if (!command.finding.jobId) return; - await this.projectService.addIpRangeWithMask( - command.projectId, + await this.ipRangeService.addIpRange( command.finding.ip, command.finding.mask, + command.projectId, ); } } diff --git a/packages/backend/jobs-manager/service/src/modules/findings/commands/JobFindings/custom.handler.ts b/packages/backend/jobs-manager/service/src/modules/findings/commands/JobFindings/custom.handler.ts index 2b80935c..b79d78ea 100644 --- a/packages/backend/jobs-manager/service/src/modules/findings/commands/JobFindings/custom.handler.ts +++ b/packages/backend/jobs-manager/service/src/modules/findings/commands/JobFindings/custom.handler.ts @@ -42,9 +42,15 @@ export class CustomFindingHandler extends JobFindingHandlerBase { private portService: PortService, private tagService: TagsService, private websiteService: WebsiteService, + private ipRangeService: IpRangeService, jobService: JobExecutionsService, subscriptionsService: EventSubscriptionsService, customJobsService: CustomJobsService, @@ -49,6 +51,7 @@ export class TagHandler extends JobFindingHandlerBase { const service = CorrelationKeyUtils.getResourceServiceName( command.finding.correlationKey, ); + switch (service) { case 'DomainsService': await this.domainService.tagDomainByName( @@ -87,6 +90,16 @@ export class TagHandler extends JobFindingHandlerBase { ); break; + case 'IpRangeService': + await this.ipRangeService.tagIpRangeByIp( + command.finding.ip, + command.finding.mask, + command.projectId, + tag._id.toString(), + true, + ); + break; + default: break; } diff --git a/packages/backend/jobs-manager/service/src/modules/findings/commands/findings-commands.ts b/packages/backend/jobs-manager/service/src/modules/findings/commands/findings-commands.ts index f7a5e120..7c107317 100644 --- a/packages/backend/jobs-manager/service/src/modules/findings/commands/findings-commands.ts +++ b/packages/backend/jobs-manager/service/src/modules/findings/commands/findings-commands.ts @@ -1,5 +1,7 @@ import { HostnameCommand } from './Findings/hostname.command'; import { HostnameHandler } from './Findings/hostname.handler'; +import { IpRangeCommand } from './Findings/ip-range.command'; +import { IpRangeHandler } from './Findings/ip-range.handler'; import { IpCommand } from './Findings/ip.command'; import { IpHandler } from './Findings/ip.handler'; import { CustomFindingCommand } from './JobFindings/custom.command'; @@ -49,6 +51,11 @@ export const FindingsCommandMapping = [ handler: TagHandler, command: TagCommand, }, + { + finding: 'IpRangeFinding', + handler: IpRangeHandler, + command: IpRangeCommand, + }, ]; export const FindingsHandlers = FindingsCommandMapping.map((f) => f.handler); diff --git a/packages/backend/jobs-manager/service/src/modules/findings/finding.dto.ts b/packages/backend/jobs-manager/service/src/modules/findings/finding.dto.ts index 05fc6e0c..82457177 100644 --- a/packages/backend/jobs-manager/service/src/modules/findings/finding.dto.ts +++ b/packages/backend/jobs-manager/service/src/modules/findings/finding.dto.ts @@ -2,6 +2,7 @@ import { IntersectionType } from '@nestjs/swagger'; import { Transform, Type, plainToClass } from 'class-transformer'; import { IsArray, + IsBoolean, IsNotEmpty, IsOptional, IsString, @@ -9,7 +10,9 @@ import { isArray, } from 'class-validator'; import { HttpBadRequestException } from '../../exceptions/http.exceptions'; +import { booleanStringToBoolean } from '../../utils/boolean-string-to-boolean'; import { PagingDto } from '../database/database.dto'; +import { FilterByProjectDto } from '../database/reporting/resource.dto'; export type CustomFindingFieldDto = CustomFindingBaseDto & (CustomFindingImageFieldDto | CustomFindingTextFieldDto); @@ -50,20 +53,20 @@ export class FieldFilterDto { data: unknown; } -export class FindingsFilterDto { +export class FindingsFilterDto extends FilterByProjectDto { @IsString({ each: true }) @IsArray() - targets: string[]; + targets?: string[]; @IsString({ each: true }) @IsArray() @IsOptional() - findingDenyList: string[]; + findingDenyList?: string[]; @IsString({ each: true }) @IsArray() @IsOptional() - findingAllowList: string[]; + findingAllowList?: string[]; @IsArray() @ValidateNested({ each: true }) @@ -86,7 +89,12 @@ export class FindingsFilterDto { { toClassOnly: true }, ) @IsOptional() - fieldFilters: FieldFilterDto[]; + fieldFilters?: FieldFilterDto[]; + + @IsBoolean() + @Transform(booleanStringToBoolean) + @IsOptional() + latestOnly?: boolean; } export class FindingsPagingDto extends IntersectionType( diff --git a/packages/backend/jobs-manager/service/src/modules/findings/findings-filter.type.ts b/packages/backend/jobs-manager/service/src/modules/findings/findings-filter.type.ts deleted file mode 100644 index 16e07b22..00000000 --- a/packages/backend/jobs-manager/service/src/modules/findings/findings-filter.type.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface FieldFilter { - key: string; - data?: unknown; -} - -export interface FindingsFilter { - targets?: string[]; - findingDenyList?: string[]; - findingAllowList?: string[]; - fieldFilters?: FieldFilter[]; -} diff --git a/packages/backend/jobs-manager/service/src/modules/findings/findings.constants.ts b/packages/backend/jobs-manager/service/src/modules/findings/findings.constants.ts index accad2d5..db0483f6 100644 --- a/packages/backend/jobs-manager/service/src/modules/findings/findings.constants.ts +++ b/packages/backend/jobs-manager/service/src/modules/findings/findings.constants.ts @@ -1,6 +1,8 @@ export class CustomFindingsConstants { public static readonly PortServiceFinding = 'PortServiceFinding'; public static readonly ServiceNameFieldKey = 'serviceName'; + public static readonly ServiceProductFieldKey = 'serviceProduct'; + public static readonly ServiceVersionFieldKey = 'serviceVersion'; public static readonly WebsitePathFinding = 'WebsitePathFinding'; public static readonly WebsiteEndpointFieldKey = 'endpoint'; diff --git a/packages/backend/jobs-manager/service/src/modules/findings/findings.module.ts b/packages/backend/jobs-manager/service/src/modules/findings/findings.module.ts index 992784b6..3c4a10f9 100644 --- a/packages/backend/jobs-manager/service/src/modules/findings/findings.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/findings/findings.module.ts @@ -10,6 +10,7 @@ import { JobsModule } from '../database/jobs/jobs.module'; import { DomainsModule } from '../database/reporting/domain/domain.module'; import { FindingDefinitionsModule } from '../database/reporting/finding-definitions/finding-definition.module'; import { HostModule } from '../database/reporting/host/host.module'; +import { IpRangeModule } from '../database/reporting/ip-ranges/ip-range.module'; import { PortModule } from '../database/reporting/port/port.module'; import { ProjectModule } from '../database/reporting/project.module'; import { WebsiteModule } from '../database/reporting/websites/website.module'; @@ -30,6 +31,7 @@ import { JobLogsConsumer } from './job-logs.consumer'; JobsModule, ProjectModule, HostModule, + IpRangeModule, DomainsModule, DatalayerModule, EventSubscriptionsModule, diff --git a/packages/backend/jobs-manager/service/src/modules/findings/findings.service.spec.ts b/packages/backend/jobs-manager/service/src/modules/findings/findings.service.spec.ts index 1d9aba6c..08dd1e13 100644 --- a/packages/backend/jobs-manager/service/src/modules/findings/findings.service.spec.ts +++ b/packages/backend/jobs-manager/service/src/modules/findings/findings.service.spec.ts @@ -137,6 +137,135 @@ describe('Findings Service Spec', () => { expect(firstPage.totalRecords).toBe(4); }); + it('Get all - Should only return from the findings from project', async () => { + // Arrange + const p = await project(); + const p2 = await project(); + const p3 = await project(); + + const correlationKey = CorrelationKeyUtils.generateCorrelationKey( + p._id.toString(), + ); + const correlationKey2 = CorrelationKeyUtils.generateCorrelationKey( + p2._id.toString(), + ); + const correlationKey3 = CorrelationKeyUtils.generateCorrelationKey( + p3._id.toString(), + ); + + await findingsModel.insertMany([ + { + created: new Date(2011, 1, 1), + correlationKey: correlationKey, + name: 'b', + }, + { + created: new Date(2010, 1, 1), + correlationKey: correlationKey, + name: 'a', + }, + { + created: new Date(2022, 1, 1), + correlationKey: correlationKey2, + name: 'should not be returned', + }, + { + created: new Date(2013, 1, 1), + correlationKey: correlationKey3, + name: 'should not be returned', + }, + ]); + + // Act + const firstPage = await findingsService.getAll(0, 5, { + projects: [p2._id.toString(), p3._id.toString()], + }); + + // Assert + expect(firstPage.totalRecords).toBe(2); + expect(firstPage.items.map((f) => f.correlationKey).sort()).toStrictEqual( + [`project:${p2._id.toString()}`, `project:${p3._id.toString()}`].sort(), + ); + }); + + it.each([ + { + page: 0, + pageSize: 5, + filter: { latestOnly: true }, + expectedResult: ['a', 'c'], + }, + { + page: 0, + pageSize: 1, + filter: { latestOnly: true }, + expectedResult: ['c'], + }, + { + page: 1, + pageSize: 1, + filter: { latestOnly: true }, + expectedResult: ['a'], + }, + { + page: 0, + pageSize: 5, + filter: { latestOnly: true, findingAllowList: ['qwerty'] }, + expectedResult: ['c'], + }, + { + page: 0, + pageSize: 5, + filter: { latestOnly: true, findingAllowList: ['returnnothing'] }, + expectedResult: [], + }, + ])( + 'Get all - Should only return from the latest of every finding (latestOnly: true): %s', + async ({ page, pageSize, filter, expectedResult }) => { + // Arrange + const p = await project(); + + const correlationKey = CorrelationKeyUtils.generateCorrelationKey( + p._id.toString(), + ); + + await findingsModel.insertMany([ + { + created: new Date(2011, 1, 1), + key: 'asdf', + correlationKey: correlationKey, + name: 'a', + }, + { + created: new Date(2010, 1, 1), + key: 'asdf', + correlationKey: correlationKey, + name: 'b', + }, + { + created: new Date(2022, 1, 1), + key: 'qwerty', + correlationKey: correlationKey, + name: 'c', + }, + { + created: new Date(2013, 1, 1), + key: 'qwerty', + correlationKey: correlationKey, + name: 'd', + }, + ]); + + // Act + const firstPage = await findingsService.getAll(page, pageSize, filter); + + // Assert + expect(firstPage.items.map((f) => f.name).sort()).toStrictEqual( + expectedResult.sort(), + ); + }, + ); + it('Save - Nonexistent project - Throws', async () => { // Arrange // Act diff --git a/packages/backend/jobs-manager/service/src/modules/findings/findings.service.ts b/packages/backend/jobs-manager/service/src/modules/findings/findings.service.ts index fb354f24..bd1d2a56 100644 --- a/packages/backend/jobs-manager/service/src/modules/findings/findings.service.ts +++ b/packages/backend/jobs-manager/service/src/modules/findings/findings.service.ts @@ -15,15 +15,14 @@ import { FindingDefinitionService } from '../database/reporting/finding-definiti import { CustomFinding } from '../database/reporting/findings/finding.model'; import { ProjectService } from '../database/reporting/project.service'; import { HostnameCommand } from './commands/Findings/hostname.command'; +import { IpRangeCommand } from './commands/Findings/ip-range.command'; import { IpCommand } from './commands/Findings/ip.command'; -import { IpRangeCommand } from './commands/Findings/ipRange.command'; import { CustomFindingCommand } from './commands/JobFindings/custom.command'; import { HostnameIpCommand } from './commands/JobFindings/hostname-ip.command'; import { PortCommand } from './commands/JobFindings/port.command'; import { TagCommand } from './commands/JobFindings/tag.command'; import { WebsiteCommand } from './commands/JobFindings/website.command'; -import { CustomFindingFieldDto } from './finding.dto'; -import { FindingsFilter } from './findings-filter.type'; +import { CustomFindingFieldDto, FindingsFilterDto } from './finding.dto'; export type Finding = | HostnameIpFinding @@ -80,6 +79,7 @@ export class PortBatchFinding extends FindingBase { export class ResourceFinding extends FindingBase { domainName?: string; ip?: string; + mask?: number; port?: number; protocol?: 'tcp' | 'udp'; path?: string; @@ -243,30 +243,119 @@ export class FindingsService { public async getAll( page: number, pageSize: number, - dto: FindingsFilter = undefined, + dto: FindingsFilterDto = undefined, ): Promise> { if (page < 0) throw new HttpBadRequestException('Page starts at 0.'); - const filters: FilterQuery = this.buildFilters(dto); - - const items = await this.findingModel - .find(filters) - .sort({ - created: 'desc', - }) - .skip(page * pageSize) - .limit(pageSize) - .exec(); - const totalRecords = await this.findingModel.countDocuments(filters); - - return { - items, - totalRecords, - }; + return await this.getAllFindings( + this.buildFilters(dto), + !!dto.latestOnly, + page, + pageSize, + ); } - private buildFilters(dto: FindingsFilter): FilterQuery { + private async getAllFindings( + filters: FilterQuery, + latestOnly: boolean, + page: number, + pageSize: number, + ): Promise> { + if (!latestOnly) { + const items = await this.findingModel + .find(filters) + .sort({ + created: 'desc', + }) + .skip(page * pageSize) + .limit(pageSize) + .exec(); + const totalRecords = await this.findingModel.countDocuments(filters); + return { + items, + totalRecords, + }; + } + + return ( + // This query returns only the latest finding by key for every resource, + // in the page format with the count + ( + await this.findingModel.aggregate>( + [ + { $sort: { created: -1 } }, + { + $match: filters, + }, + { + $group: { + _id: { + key: '$key', + correlationKey: '$correlationKey', + }, + name: { $first: '$name' }, + fields: { $first: '$fields' }, + id: { $first: '$_id' }, + created: { $first: '$created' }, + }, + }, + { + $group: { + _id: '$_id.key', + data: { + $addToSet: { + _id: '$id', + key: '$_id.key', + correlationKey: '$_id.correlationKey', + name: '$name', + fields: '$fields', + created: '$created', + }, + }, + }, + }, + { + $unwind: { + path: '$data', + preserveNullAndEmptyArrays: false, + }, + }, + { + $facet: { + counting: [{ $count: 'count' }], + items: [ + { $sort: { 'data.created': -1 } }, + { $skip: page * pageSize }, + { $limit: pageSize }, + { + $project: { + _id: '$data._id', + key: '$data.key', + correlationKey: '$data.correlationKey', + name: '$data.name', + fields: '$data.fields', + created: '$data.created', + }, + }, + ], + }, + }, + { + $project: { + totalRecords: { $first: '$counting.count' }, + items: '$items', + }, + }, + ], + { maxTimeMS: 60000, allowDiskUse: true }, + ) + )[0] + ); + } + + private buildFilters(dto: FindingsFilterDto): FilterQuery { const filters: FilterQuery = {}; + filters.$and = []; if (dto.targets && dto.targets.length > 0) { if (dto.targets.length === 1) { @@ -285,8 +374,6 @@ export class FindingsService { dto.findingAllowList?.length || dto.fieldFilters?.length ) { - filters.$and = []; - if (dto.findingDenyList?.length) { filters.$and.push({ key: { $nin: dto.findingDenyList } }); } @@ -310,6 +397,19 @@ export class FindingsService { } } + if (dto.projects) { + const correlationKeys = []; + for (const id of dto.projects) { + const correlationKey: string = + CorrelationKeyUtils.generateCorrelationKey(id); + correlationKeys.push(new RegExp(`${correlationKey}.*`)); + } + + filters.$and.push({ correlationKey: { $in: correlationKeys } }); + } + + if (!filters.$and.length) delete filters.$and; + return filters; } @@ -345,7 +445,7 @@ export class FindingsService { dto.ip, dto.port, dto.protocol, - null, + dto.mask, dto.path, ); @@ -523,7 +623,7 @@ export class FindingsService { finding.ip, finding.port, finding.protocol, - null, + finding.mask, finding.path, ); this.commandBus.execute( diff --git a/packages/backend/jobs-manager/service/src/modules/queues/finding-queue/kafka-findings-queue.ts b/packages/backend/jobs-manager/service/src/modules/queues/finding-queue/kafka-findings-queue.ts index 03ed7bb4..e55f316f 100644 --- a/packages/backend/jobs-manager/service/src/modules/queues/finding-queue/kafka-findings-queue.ts +++ b/packages/backend/jobs-manager/service/src/modules/queues/finding-queue/kafka-findings-queue.ts @@ -18,6 +18,8 @@ export class KafkaFindingsQueue implements FindingsQueue { jobId?: string, ...findings: Finding[] ): Promise { + if (!findings.length) return; + this.logger.debug( `Publishing ${findings.length} findings to the message queue on topic ${ orchestratorConstants.topics.findings diff --git a/packages/backend/jobs-manager/service/src/modules/queues/queue.module.ts b/packages/backend/jobs-manager/service/src/modules/queues/queue.module.ts index dcedd687..aae93c59 100644 --- a/packages/backend/jobs-manager/service/src/modules/queues/queue.module.ts +++ b/packages/backend/jobs-manager/service/src/modules/queues/queue.module.ts @@ -17,7 +17,7 @@ import { KafkaJobQueue } from './job-queue/kafka-job-queue'; import { NullJobQueue } from './job-queue/null-job-queue'; const certFolder = - isTest() && process.env.TEST_TYPE === 'unit' ? './' : '/certs'; + isTest() && process.env.TEST_TYPE === 'unit' ? '.' : '/certs'; const certTestExtension = isTest() && process.env.TEST_TYPE === 'unit' ? '.test' : ''; @@ -28,16 +28,27 @@ export const kafkaConfig: KafkaConfig = { rejectUnauthorized: true, requestCert: true, ca: [ - readFileSync(`${certFolder}/kafka-ca.crt${certTestExtension}`, 'utf-8'), + isTest() && process.env.TEST_TYPE === 'unit' + ? '' + : readFileSync( + `${certFolder}/kafka-ca.crt${certTestExtension}`, + 'utf-8', + ), ], - cert: readFileSync( - `${certFolder}/kafka-client-signed.crt${certTestExtension}`, - 'utf-8', - ), - key: readFileSync( - `${certFolder}/kafka-client.key${certTestExtension}`, - 'utf-8', - ), + cert: + isTest() && process.env.TEST_TYPE === 'unit' + ? '' + : readFileSync( + `${certFolder}/kafka-client-signed.crt${certTestExtension}`, + 'utf-8', + ), + key: + isTest() && process.env.TEST_TYPE === 'unit' + ? '' + : readFileSync( + `${certFolder}/kafka-client.key${certTestExtension}`, + 'utf-8', + ), passphrase: process.env.JM_KAFKA_KEY_PASSWORD, }, }; diff --git a/packages/backend/jobs-manager/service/src/utils/ip-address.utils.spec.ts b/packages/backend/jobs-manager/service/src/utils/ip-address.utils.spec.ts new file mode 100644 index 00000000..cdfc56ba --- /dev/null +++ b/packages/backend/jobs-manager/service/src/utils/ip-address.utils.spec.ts @@ -0,0 +1,115 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AppController } from '../modules/app.controller'; +import { AppService } from '../modules/app.service'; +import { + cidrStringToipv4Range, + ipv4RangeToMinMax, + ipv4RangeValuesToMinMax, + ipv4ToNumber, + numberToIpv4, +} from './ip-address.utils'; + +const ipAddressRanges = [ + { + ip: '192.168.0.1', + mask: 24, + min: 3232235520, + max: 3232235775, + }, + { + ip: '0.0.0.0', + mask: 32, + min: 0, + max: 0, + }, + { + ip: '0.0.0.0', + mask: 0, + min: 0, + max: 4294967295, + }, + { + ip: '206.189.173.197', + mask: 32, + min: 3468537285, + max: 3468537285, + }, + { + ip: '192.168.0.1', + mask: 32, + min: 3232235520, + max: 3232251903, + }, +]; + +describe('IP address utils', () => { + let moduleFixture: TestingModule; + let appController: AppController; + + beforeEach(async () => { + moduleFixture = await Test.createTestingModule({ + controllers: [AppController], + providers: [AppService], + }).compile(); + + appController = moduleFixture.get(AppController); + }); + + afterAll(async () => { + await moduleFixture.close(); + }); + + describe('IP range calculations', () => { + it.each([ + { ip: '127.0.0.1', value: 2130706433 }, + { ip: '0.0.0.0', value: 0 }, + { ip: '255.255.255.255', value: 4294967295 }, + { ip: '1.2.3.4', value: 16909060 }, + ])(`Should transform an IP to its integer value %s`, ({ ip, value }) => { + // Arrange & Act + const result = ipv4ToNumber(ip); + + // Assert + expect(result).toStrictEqual(value); + }); + + it.each([ + { ip: '127.0.0.1', value: 2130706433 }, + { ip: '0.0.0.0', value: 0 }, + { ip: '255.255.255.255', value: 4294967295 }, + { ip: '1.2.3.4', value: 16909060 }, + ])(`Should transform an IP to its integer value %s`, ({ ip, value }) => { + // Arrange & Act + const result = numberToIpv4(value); + + // Arrange & Act & Assert + expect(result).toStrictEqual(ip); + }); + + it.each([ipAddressRanges])( + `Should find the min and max values for IP range %s`, + ({ ip, mask, min, max }) => { + // Arrange & Act + const minMax = ipv4RangeValuesToMinMax(ip, mask); + + // Assert + expect(minMax.min).toStrictEqual(min); + expect(minMax.max).toStrictEqual(max); + }, + ); + + it.each([ipAddressRanges])( + `Should find the min and max values for IP range in string format %s`, + ({ ip, mask, min, max }) => { + // Arrange & Act + const minMax = ipv4RangeToMinMax( + cidrStringToipv4Range(ip + '/' + mask.toString()), + ); + + // Assert + expect(minMax.min).toStrictEqual(min); + expect(minMax.max).toStrictEqual(max); + }, + ); + }); +}); diff --git a/packages/backend/jobs-manager/service/src/utils/ip-address.utils.ts b/packages/backend/jobs-manager/service/src/utils/ip-address.utils.ts new file mode 100644 index 00000000..cc172b78 --- /dev/null +++ b/packages/backend/jobs-manager/service/src/utils/ip-address.utils.ts @@ -0,0 +1,38 @@ +export function ipv4ToNumber(ip: string): number { + const d = ip.split('.').map(Number); + return ((+d[0] * 256 + +d[1]) * 256 + +d[2]) * 256 + +d[3]; +} + +export function ipv4RangeValuesToMinMax( + ip: string, + mask: number, +): { min: number; max: number } { + const min = (ipv4ToNumber(ip) & (-1 << (32 - mask))) >>> 0; + const max = min + Math.pow(2, 32 - mask) - 1; + return { min, max }; +} + +export function ipv4RangeToMinMax(range: { ip: string; mask: number }): { + min: number; + max: number; +} { + return ipv4RangeValuesToMinMax(range.ip, range.mask); +} + +export function cidrStringToipv4Range(range: string) { + const split = range.split('/'); + if (split.length !== 2) return null; + return { ip: split[0], mask: Number(split[1]) }; +} + +export function numberToIpv4(ipNumber: number) { + return ( + ((ipNumber >>> 24) & 0xff).toString() + + '.' + + ((ipNumber >>> 16) & 0xff).toString() + + '.' + + ((ipNumber >>> 8) & 0xff).toString() + + '.' + + (ipNumber & 0xff).toString() + ); +} diff --git a/packages/backend/jobs-manager/service/src/validators/is-ip-range.validator.ts b/packages/backend/jobs-manager/service/src/validators/is-ip-range.validator.ts new file mode 100644 index 00000000..ff12bb0f --- /dev/null +++ b/packages/backend/jobs-manager/service/src/validators/is-ip-range.validator.ts @@ -0,0 +1,37 @@ +import { + isNumberString, + isString, + registerDecorator, + ValidationArguments, + ValidationOptions, +} from 'class-validator'; +import { isIPv4 } from 'net'; + +export function IsIpRange(validationOptions?: ValidationOptions) { + return function (object: Object, propertyName: string) { + registerDecorator({ + name: 'isIpRange', + target: object.constructor, + propertyName: propertyName, + options: validationOptions, + validator: { + validate(value: any, args: ValidationArguments) { + return isIpRange(value); + }, + }, + }); + }; +} + +export function isIpRange(value: any) { + if (!isString(value)) return false; + if (value !== value.trim()) return false; + + const split = value.split('/'); + if (split.length !== 2) return false; + + if (!isNumberString(split[1])) return false; + const mask = Number(split[1]); + + return isIPv4(split[0]) && mask >= 0 && mask <= 32; +} diff --git a/packages/backend/jobs-manager/service/test/jest.e2e.config.js b/packages/backend/jobs-manager/service/test/jest.e2e.config.js index 975d2885..c85bfd01 100644 --- a/packages/backend/jobs-manager/service/test/jest.e2e.config.js +++ b/packages/backend/jobs-manager/service/test/jest.e2e.config.js @@ -1,3 +1,6 @@ +const { pathsToModuleNameMapper } = require('ts-jest'); +const { compilerOptions } = require('../../../../../tsconfig.base.json'); + module.exports = { moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], modulePathIgnorePatterns: ['/dist/'], @@ -14,4 +17,10 @@ module.exports = { testTimeout: 70000, slowTestThreshold: 30, coverageReporters: ['json', 'lcov'], + rootDir: './', + roots: [''], + modulePaths: [compilerOptions.baseUrl], + moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { + prefix: '/../../../..', + }), }; diff --git a/packages/backend/jobs-manager/service/tsconfig.json b/packages/backend/jobs-manager/service/tsconfig.json index 1bacd9c6..da98af58 100644 --- a/packages/backend/jobs-manager/service/tsconfig.json +++ b/packages/backend/jobs-manager/service/tsconfig.json @@ -1,4 +1,5 @@ { + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "composite": true, "module": "commonjs", @@ -10,7 +11,6 @@ "target": "ESNext", "sourceMap": true, "outDir": "./dist", - "baseUrl": "./", "incremental": true, "skipLibCheck": true, "strictNullChecks": false, @@ -18,7 +18,8 @@ "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, "noFallthroughCasesInSwitch": false, - "esModuleInterop": true + "esModuleInterop": true, + "allowJs": true }, "include": ["src/**/*.ts", "test/**/*.ts"] } diff --git a/packages/common/.dockerignore b/packages/common/.dockerignore new file mode 100644 index 00000000..a79d408c --- /dev/null +++ b/packages/common/.dockerignore @@ -0,0 +1,3 @@ +.husky +dist +node_modules \ No newline at end of file diff --git a/packages/common/.eslintrc.js b/packages/common/.eslintrc.js new file mode 100644 index 00000000..b8a39dec --- /dev/null +++ b/packages/common/.eslintrc.js @@ -0,0 +1,31 @@ +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + sourceType: 'module', + }, + plugins: ['@typescript-eslint/eslint-plugin'], + extends: ['prettier'], + root: true, + env: { + node: true, + jest: true, + }, + ignorePatterns: ['.eslintrc.js'], + rules: { + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/ban-types': [ + 'error', + { + types: { + object: false, + Object: false, + Function: false, + }, + }, + ], + }, +}; diff --git a/packages/common/.gitignore b/packages/common/.gitignore new file mode 100644 index 00000000..1a23fdc5 --- /dev/null +++ b/packages/common/.gitignore @@ -0,0 +1,18 @@ +# compiled output +/dist +/node_modules + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# OS +.DS_Store + +# Tests +/coverage +/.nyc_output \ No newline at end of file diff --git a/packages/common/.husky/pre-commit b/packages/common/.husky/pre-commit new file mode 100644 index 00000000..09129417 --- /dev/null +++ b/packages/common/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh + +npm run generate-search-parser +npm run lint-staged \ No newline at end of file diff --git a/packages/common/.prettierrc b/packages/common/.prettierrc new file mode 100644 index 00000000..dcb72794 --- /dev/null +++ b/packages/common/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} \ No newline at end of file diff --git a/packages/common/global-setup.ts b/packages/common/global-setup.ts new file mode 100644 index 00000000..58caa4c9 --- /dev/null +++ b/packages/common/global-setup.ts @@ -0,0 +1,3 @@ +module.exports = async function () { + // Nothing +}; diff --git a/packages/common/global-teardown.ts b/packages/common/global-teardown.ts new file mode 100644 index 00000000..58caa4c9 --- /dev/null +++ b/packages/common/global-teardown.ts @@ -0,0 +1,3 @@ +module.exports = async function () { + // Nothing +}; diff --git a/packages/common/jest.config.ga.js b/packages/common/jest.config.ga.js new file mode 100644 index 00000000..3fc44f56 --- /dev/null +++ b/packages/common/jest.config.ga.js @@ -0,0 +1,6 @@ +const baseConfig = require('./jest.config'); + +module.exports = { + ...baseConfig, + reporters: [['github-actions', { silent: false }], 'default'], +}; diff --git a/packages/common/jest.config.js b/packages/common/jest.config.js new file mode 100644 index 00000000..b77c6f14 --- /dev/null +++ b/packages/common/jest.config.js @@ -0,0 +1,16 @@ +module.exports = { + moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], + modulePathIgnorePatterns: ['/dist/'], + transform: { + '^.+\\.tsx?$': 'ts-jest', + }, + testRegex: '/src/.*\\.(test|spec).(ts|tsx|js)$', + collectCoverageFrom: [ + 'src/**/*.{js,jsx,tsx,ts}', + '!**/node_modules/**', + '!**/vendor/**', + ], + coverageReporters: ['json', 'lcov'], + globalSetup: './global-setup.ts', + globalTeardown: './global-teardown.ts', +}; diff --git a/packages/common/package.json b/packages/common/package.json new file mode 100644 index 00000000..c0ebbc78 --- /dev/null +++ b/packages/common/package.json @@ -0,0 +1,42 @@ +{ + "name": "@red-kite/common", + "version": "0.0.1", + "description": "", + "author": "", + "private": true, + "license": "UNLICENSED", + "scripts": { + "format:write": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "lint:write": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "lint-staged:run": "npm run lint:write && npm run format:write", + "lint-staged": "lint-staged", + "test": "jest --runInBand", + "test:cicd": "jest --runInBand --json --outputFile=./test/jest-output.json", + "test:watch": "jest --watchAll --runInBand", + "test:cov": "jest --coverage", + "generate-search-parser": "peggy -c src/search-query/peggy.config.mjs; cp -R src/search-query ../backend/jobs-manager/service/src/common-duplicates/search-query" + }, + "dependencies": { + "peggy": "^4.2.0", + "reflect-metadata": "^0.1.13", + "rimraf": "^4.1.2", + "rxjs": "^7.8.0" + }, + "devDependencies": { + "@types/jest": "^29.5.1", + "@typescript-eslint/eslint-plugin": "^5.49.0", + "@typescript-eslint/parser": "^5.49.0", + "eslint": "^8.33.0", + "eslint-config-prettier": "8.6.0", + "eslint-plugin-prettier": "^4.2.1", + "jest": "^29.5.0", + "lint-staged": "^13.1.0", + "prettier": "^2.8.3", + "supertest": "~7.0.0", + "ts-jest": "^29.1.0", + "typescript": "^4.9.4" + }, + "lint-staged": { + "*.ts": "npm run lint-staged:run" + } +} diff --git a/packages/common/src/search-query/generated/search-parser.d.ts b/packages/common/src/search-query/generated/search-parser.d.ts new file mode 100644 index 00000000..e0ce7752 --- /dev/null +++ b/packages/common/src/search-query/generated/search-parser.d.ts @@ -0,0 +1,209 @@ +/** Provides information pointing to a location within a source. */ +export interface Location { + /** Line in the parsed source (1-based). */ + readonly line: number; + /** Column in the parsed source (1-based). */ + readonly column: number; + /** Offset in the parsed source (0-based). */ + readonly offset: number; +} + +/** + * Anything that can successfully be converted to a string with `String()` + * so that it can be used in error messages. + * + * The GrammarLocation class in Peggy is a good example. + */ +export interface GrammarSourceObject { + readonly toString: () => string; + + /** + * If specified, allows the grammar source to be embedded in a larger file + * at some offset. + */ + readonly offset?: undefined | ((loc: Location) => Location); +} + +/** + * Most often, you just use a string with the file name. + */ +export type GrammarSource = string | GrammarSourceObject; + +/** The `start` and `end` position's of an object within the source. */ +export interface LocationRange { + /** + * A string or object that was supplied to the `parse()` call as the + * `grammarSource` option. + */ + readonly source: GrammarSource; + /** Position at the beginning of the expression. */ + readonly start: Location; + /** Position after the end of the expression. */ + readonly end: Location; +} + +/** + * Expected a literal string, like `"foo"i`. + */ +export interface LiteralExpectation { + readonly type: "literal"; + readonly text: string; + readonly ignoreCase: boolean; +} + +/** + * Range of characters, like `a-z` + */ +export type ClassRange = [ + start: string, + end: string, +] + +export interface ClassParts extends Array { +} + +/** + * Expected a class, such as `[^acd-gz]i` + */ +export interface ClassExpectation { + readonly type: "class"; + readonly parts: ClassParts; + readonly inverted: boolean; + readonly ignoreCase: boolean; +} + +/** + * Expected any character, with `.` + */ +export interface AnyExpectation { + readonly type: "any"; +} + +/** + * Expected the end of input. + */ +export interface EndExpectation { + readonly type: "end"; +} + +/** + * Expected some other input. These are specified with a rule's + * "human-readable name", or with the `expected(message, location)` + * function. + */ +export interface OtherExpectation { + readonly type: "other"; + readonly description: string; +} + +export type Expectation = + | AnyExpectation + | ClassExpectation + | EndExpectation + | LiteralExpectation + | OtherExpectation; + +/** + * Pass an array of these into `SyntaxError.prototype.format()` + */ +export interface SourceText { + /** + * Identifier of an input that was used as a grammarSource in parse(). + */ + readonly source: GrammarSource; + /** Source text of the input. */ + readonly text: string; +} + +export declare class SyntaxError extends Error { + /** + * Constructs the human-readable message from the machine representation. + * + * @param expected Array of expected items, generated by the parser + * @param found Any text that will appear as found in the input instead of + * expected + */ + static buildMessage(expected: Expectation[], found?: string | null | undefined): string; + readonly message: string; + readonly expected: Expectation[]; + readonly found: string | null | undefined; + readonly location: LocationRange; + readonly name: string; + constructor( + message: string, + expected: Expectation[], + found: string | null, + location: LocationRange, + ); + + /** + * With good sources, generates a feature-rich error message pointing to the + * error in the input. + * @param sources List of {source, text} objects that map to the input. + */ + format(sources: SourceText[]): string; +} + +/** + * Trace execution of the parser. + */ +export interface ParserTracer { + trace: (event: ParserTracerEvent) => void; +} + +export type ParserTracerEvent + = { + readonly type: "rule.enter"; + readonly rule: string; + readonly location: LocationRange + } + | { + readonly type: "rule.fail"; + readonly rule: string; + readonly location: LocationRange + } + | { + readonly type: "rule.match"; + readonly rule: string; + readonly location: LocationRange + /** Return value from the rule. */ + readonly result: unknown; + }; + +export type StartRuleNames = "start"; +export interface ParseOptions { + /** + * String or object that will be attached to the each `LocationRange` object + * created by the parser. For example, this can be path to the parsed file + * or even the File object. + */ + readonly grammarSource?: GrammarSource; + readonly startRule?: T; + readonly tracer?: ParserTracer; + + // Internal use only: + readonly peg$library?: boolean; + // Internal use only: + peg$currPos?: number; + // Internal use only: + peg$silentFails?: number; + // Internal use only: + peg$maxFailExpected?: Expectation[]; + // Extra application-specific properties + [key: string]: unknown; +} + +export declare const StartRules: StartRuleNames[]; +export declare const parse: typeof ParseFunction; + +// Overload of ParseFunction for each allowedStartRule + +declare function ParseFunction>( + input: string, + options?: Options, +): any; + +declare function ParseFunction>( + input: string, + options?: Options, +): any; diff --git a/packages/common/src/search-query/generated/search-parser.js b/packages/common/src/search-query/generated/search-parser.js new file mode 100644 index 00000000..7f927ff6 --- /dev/null +++ b/packages/common/src/search-query/generated/search-parser.js @@ -0,0 +1,1520 @@ +// @generated by Peggy 4.2.0. +// +// https://peggyjs.org/ + +"use strict"; + + +function peg$subclass(child, parent) { + function C() { this.constructor = child; } + C.prototype = parent.prototype; + child.prototype = new C(); +} + +function peg$SyntaxError(message, expected, found, location) { + var self = Error.call(this, message); + // istanbul ignore next Check is a necessary evil to support older environments + if (Object.setPrototypeOf) { + Object.setPrototypeOf(self, peg$SyntaxError.prototype); + } + self.expected = expected; + self.found = found; + self.location = location; + self.name = "SyntaxError"; + return self; +} + +peg$subclass(peg$SyntaxError, Error); + +function peg$padEnd(str, targetLength, padString) { + padString = padString || " "; + if (str.length > targetLength) { return str; } + targetLength -= str.length; + padString += padString.repeat(targetLength); + return str + padString.slice(0, targetLength); +} + +peg$SyntaxError.prototype.format = function(sources) { + var str = "Error: " + this.message; + if (this.location) { + var src = null; + var k; + for (k = 0; k < sources.length; k++) { + if (sources[k].source === this.location.source) { + src = sources[k].text.split(/\r\n|\n|\r/g); + break; + } + } + var s = this.location.start; + var offset_s = (this.location.source && (typeof this.location.source.offset === "function")) + ? this.location.source.offset(s) + : s; + var loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; + if (src) { + var e = this.location.end; + var filler = peg$padEnd("", offset_s.line.toString().length, ' '); + var line = src[s.line - 1]; + var last = s.line === e.line ? e.column : line.length + 1; + var hatLen = (last - s.column) || 1; + str += "\n --> " + loc + "\n" + + filler + " |\n" + + offset_s.line + " | " + line + "\n" + + filler + " | " + peg$padEnd("", s.column - 1, ' ') + + peg$padEnd("", hatLen, "^"); + } else { + str += "\n at " + loc; + } + } + return str; +}; + +peg$SyntaxError.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + class: function(expectation) { + var escapedParts = expectation.parts.map(function(part) { + return Array.isArray(part) + ? classEscape(part[0]) + "-" + classEscape(part[1]) + : classEscape(part); + }); + + return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]"; + }, + + any: function() { + return "any character"; + }, + + end: function() { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/"/g, "\\\"") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/\]/g, "\\]") + .replace(/\^/g, "\\^") + .replace(/-/g, "\\-") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = expected.map(describeExpectation); + var i, j; + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse(input, options) { + options = options !== undefined ? options : {}; + + var peg$FAILED = {}; + var peg$source = options.grammarSource; + + var peg$startRuleFunctions = { start: peg$parsestart }; + var peg$startRuleFunction = peg$parsestart; + + var peg$c0 = ":"; + var peg$c1 = "-"; + var peg$c2 = "exists"; + var peg$c3 = "finding."; + var peg$c4 = "."; + var peg$c5 = "finding"; + var peg$c6 = "project.name"; + var peg$c7 = "project.id"; + var peg$c8 = "project"; + var peg$c9 = "domain.name"; + var peg$c10 = "domain.id"; + var peg$c11 = "domain"; + var peg$c12 = "host.ip"; + var peg$c13 = "host.id"; + var peg$c14 = "host"; + var peg$c15 = "port.number"; + var peg$c16 = "port.id"; + var peg$c17 = "port.protocol"; + var peg$c18 = "port"; + var peg$c19 = "port.service"; + var peg$c20 = "port.product"; + var peg$c21 = "port.version"; + var peg$c22 = "tag.id"; + var peg$c23 = "tag.name"; + var peg$c24 = "tag"; + var peg$c25 = "mergedIn.id"; + var peg$c26 = "is"; + + var peg$r0 = /^[a-zA-Z._]/; + var peg$r1 = /^[a-zA-Z0-9:_\-:\/.*]/; + var peg$r2 = /^["]/; + var peg$r3 = /^[a-zA-Z0-9._\- :\/*]/; + var peg$r4 = /^[a-zA-Z0-9\-]/; + var peg$r5 = /^[a-zA-Z0-9]/; + var peg$r6 = /^[ \t\n\r]/; + + var peg$e0 = peg$literalExpectation(":", false); + var peg$e1 = peg$classExpectation([["a", "z"], ["A", "Z"], ".", "_"], false, false); + var peg$e2 = peg$literalExpectation("-", false); + var peg$e3 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], ":", "_", "-", ":", "/", ".", "*"], false, false); + var peg$e4 = peg$classExpectation(["\""], false, false); + var peg$e5 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], ".", "_", "-", " ", ":", "/", "*"], false, false); + var peg$e6 = peg$literalExpectation("exists", false); + var peg$e7 = peg$literalExpectation("finding.", false); + var peg$e8 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "-"], false, false); + var peg$e9 = peg$literalExpectation(".", false); + var peg$e10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false); + var peg$e11 = peg$literalExpectation("finding", false); + var peg$e12 = peg$literalExpectation("project.name", false); + var peg$e13 = peg$literalExpectation("project.id", false); + var peg$e14 = peg$literalExpectation("project", false); + var peg$e15 = peg$literalExpectation("domain.name", false); + var peg$e16 = peg$literalExpectation("domain.id", false); + var peg$e17 = peg$literalExpectation("domain", false); + var peg$e18 = peg$literalExpectation("host.ip", false); + var peg$e19 = peg$literalExpectation("host.id", false); + var peg$e20 = peg$literalExpectation("host", false); + var peg$e21 = peg$literalExpectation("port.number", false); + var peg$e22 = peg$literalExpectation("port.id", false); + var peg$e23 = peg$literalExpectation("port.protocol", false); + var peg$e24 = peg$literalExpectation("port", false); + var peg$e25 = peg$literalExpectation("port.service", false); + var peg$e26 = peg$literalExpectation("port.product", false); + var peg$e27 = peg$literalExpectation("port.version", false); + var peg$e28 = peg$literalExpectation("tag.id", false); + var peg$e29 = peg$literalExpectation("tag.name", false); + var peg$e30 = peg$literalExpectation("tag", false); + var peg$e31 = peg$literalExpectation("mergedIn.id", false); + var peg$e32 = peg$literalExpectation("is", false); + var peg$e33 = peg$otherExpectation("whitespace"); + var peg$e34 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false); + + var peg$f0 = function(terms) { + return terms ? [terms[0]].concat(terms[1].map(([_, t]) => t)) : []; + }; + var peg$f1 = function(not, type, value) { + return { not: not ?? false, type, value }; + }; + var peg$f2 = function(not, key) { + return { incomplete: true, not: not ?? false, type: key, value: null } + }; + var peg$f3 = function(not, key) { + return { incomplete: true, not: not ?? false, key, type: "findingField", value: null } + }; + var peg$f4 = function(not, key) { + return { incomplete: true, not: not ?? false, key, type: "finding", value: null } + }; + var peg$f5 = function(not, key) { + return { incomplete: true, not: not ?? false, key, value: null, type: null } + }; + var peg$f6 = function(not, key, value) { + return { not: not ?? false, key, value, type: "findingField" }; + }; + var peg$f7 = function(not, key, value) { + return { not: not ?? false, key, value, type: "finding" }; + }; + var peg$f8 = function() { return true; }; + var peg$f9 = function(value) { + return value; + }; + var peg$f10 = function() { return null; }; + var peg$f11 = function(string) { + return string; + }; + var peg$f12 = function() { return "exists"; }; + var peg$f13 = function(finding_key, field_key) { + return { findingKey: finding_key, fieldKey: field_key }; + }; + var peg$f14 = function(finding_key) { + return { findingKey: finding_key }; + }; + var peg$f15 = function() { return "project.name"; }; + var peg$f16 = function() { return "project.id"; }; + var peg$f17 = function() { return "project.name"; }; + var peg$f18 = function() { return "domain.name"; }; + var peg$f19 = function() { return "domain.id"; }; + var peg$f20 = function() { return "domain.name"; }; + var peg$f21 = function() { return "host.ip"; }; + var peg$f22 = function() { return "host.id"; }; + var peg$f23 = function() { return "host.ip"; }; + var peg$f24 = function() { return "port.number"; }; + var peg$f25 = function() { return "port.id"; }; + var peg$f26 = function() { return "port.protocol"; }; + var peg$f27 = function() { return "port.number"; }; + var peg$f28 = function() { return "port.service"; }; + var peg$f29 = function() { return "port.product"; }; + var peg$f30 = function() { return "port.version"; }; + var peg$f31 = function() { return "tag.id"; }; + var peg$f32 = function() { return "tag.name"; }; + var peg$f33 = function() { return "tag.name"; }; + var peg$f34 = function() { return "mergedIn.id" }; + var peg$f35 = function() { return "is"; }; + var peg$currPos = options.peg$currPos | 0; + var peg$savedPos = peg$currPos; + var peg$posDetailsCache = [{ line: 1, column: 1 }]; + var peg$maxFailPos = peg$currPos; + var peg$maxFailExpected = options.peg$maxFailExpected || []; + var peg$silentFails = options.peg$silentFails | 0; + + var peg$result; + + if (options.startRule) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$savedPos, peg$currPos); + } + + function offset() { + return peg$savedPos; + } + + function range() { + return { + source: peg$source, + start: peg$savedPos, + end: peg$currPos + }; + } + + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); + } + + function expected(description, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildStructuredError( + [peg$otherExpectation(description)], + input.substring(peg$savedPos, peg$currPos), + location + ); + } + + function error(message, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildSimpleError(message, location); + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$otherExpectation(description) { + return { type: "other", description: description }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos]; + var p; + + if (details) { + return details; + } else { + if (pos >= peg$posDetailsCache.length) { + p = peg$posDetailsCache.length - 1; + } else { + p = pos; + while (!peg$posDetailsCache[--p]) {} + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + + return details; + } + } + + function peg$computeLocation(startPos, endPos, offset) { + var startPosDetails = peg$computePosDetails(startPos); + var endPosDetails = peg$computePosDetails(endPos); + + var res = { + source: peg$source, + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + if (offset && peg$source && (typeof peg$source.offset === "function")) { + res.start = peg$source.offset(res.start); + res.end = peg$source.offset(res.end); + } + return res; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildSimpleError(message, location) { + return new peg$SyntaxError(message, null, null, location); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError( + peg$SyntaxError.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parsestart() { + var s0; + + s0 = peg$parseterms(); + + return s0; + } + + function peg$parseterms() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$parseterm(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseterm(); + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseterm(); + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parse_(); + if (s2 === peg$FAILED) { + s2 = null; + } + peg$savedPos = s0; + s0 = peg$f0(s1); + + return s0; + } + + function peg$parseterm() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$parsefinding_field_term(); + if (s0 === peg$FAILED) { + s0 = peg$parsefinding_term(); + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsekey(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f1(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsekey(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f2(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_field_key(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f3(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_key(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f4(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r0.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r0.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f5(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsefinding_field_term() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_field_key(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f6(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefinding_term() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parsenot(); + if (s1 === peg$FAILED) { + s1 = null; + } + s2 = peg$parsefinding_key(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c0; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parsevalue(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f7(s1, s2, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsenot() { + var s0, s1; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s1 = peg$c1; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e2); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f8(); + } + s0 = s1; + + return s0; + } + + function peg$parsevalue() { + var s0; + + s0 = peg$parseraw_value(); + if (s0 === peg$FAILED) { + s0 = peg$parsestring(); + if (s0 === peg$FAILED) { + s0 = peg$parseexists(); + if (s0 === peg$FAILED) { + s0 = peg$parseempty_value(); + } + } + } + + return s0; + } + + function peg$parseraw_value() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = []; + s3 = input.charAt(peg$currPos); + if (peg$r1.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = input.charAt(peg$currPos); + if (peg$r1.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f9(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseempty_value() { + var s0, s1; + + s0 = peg$currPos; + s1 = ''; + peg$savedPos = s0; + s1 = peg$f10(); + s0 = s1; + + return s0; + } + + function peg$parsestring() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = input.charAt(peg$currPos); + if (peg$r2.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r3.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r3.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + s3 = input.charAt(peg$currPos); + if (peg$r2.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f11(s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseexists() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c2) { + s1 = peg$c2; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e6); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f12(); + } + s0 = s1; + + return s0; + } + + function peg$parsefinding_field_key() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c3) { + s1 = peg$c3; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e7); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + s4 = input.charAt(peg$currPos); + if (peg$r4.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = input.charAt(peg$currPos); + if (peg$r4.test(s4)) { + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c4; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + s5 = []; + s6 = input.charAt(peg$currPos); + if (peg$r5.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + s6 = input.charAt(peg$currPos); + if (peg$r5.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + } + s4 = input.substring(s4, peg$currPos); + peg$savedPos = s0; + s0 = peg$f13(s2, s4); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefinding_key() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c5) { + s1 = peg$c5; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e11); } + } + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s2 = peg$c4; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + s3 = peg$currPos; + s4 = []; + s5 = input.charAt(peg$currPos); + if (peg$r4.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = input.charAt(peg$currPos); + if (peg$r4.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + } + s3 = input.substring(s3, peg$currPos); + peg$savedPos = s0; + s0 = peg$f14(s3); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsekey() { + var s0; + + s0 = peg$parseproject(); + if (s0 === peg$FAILED) { + s0 = peg$parsedomain(); + if (s0 === peg$FAILED) { + s0 = peg$parsehost(); + if (s0 === peg$FAILED) { + s0 = peg$parseport(); + if (s0 === peg$FAILED) { + s0 = peg$parsetags(); + if (s0 === peg$FAILED) { + s0 = peg$parseother(); + if (s0 === peg$FAILED) { + s0 = peg$parseis(); + } + } + } + } + } + } + + return s0; + } + + function peg$parseproject() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c6) { + s1 = peg$c6; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e12); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f15(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 10) === peg$c7) { + s1 = peg$c7; + peg$currPos += 10; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e13); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f16(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c8) { + s1 = peg$c8; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f17(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parsedomain() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 11) === peg$c9) { + s1 = peg$c9; + peg$currPos += 11; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e15); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f18(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 9) === peg$c10) { + s1 = peg$c10; + peg$currPos += 9; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e16); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f19(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c11) { + s1 = peg$c11; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e17); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f20(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parsehost() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c12) { + s1 = peg$c12; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e18); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f21(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c13) { + s1 = peg$c13; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e19); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f22(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c14) { + s1 = peg$c14; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e20); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f23(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parseport() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 11) === peg$c15) { + s1 = peg$c15; + peg$currPos += 11; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e21); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f24(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c16) { + s1 = peg$c16; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e22); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f25(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 13) === peg$c17) { + s1 = peg$c17; + peg$currPos += 13; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e23); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f26(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c18) { + s1 = peg$c18; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e24); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f27(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c19) { + s1 = peg$c19; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e25); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f28(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c20) { + s1 = peg$c20; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e26); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f29(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 12) === peg$c21) { + s1 = peg$c21; + peg$currPos += 12; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e27); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f30(); + } + s0 = s1; + } + } + } + } + } + } + + return s0; + } + + function peg$parsetags() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c22) { + s1 = peg$c22; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e28); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f31(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c23) { + s1 = peg$c23; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e29); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f32(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c24) { + s1 = peg$c24; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e30); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f33(); + } + s0 = s1; + } + } + + return s0; + } + + function peg$parseother() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 11) === peg$c25) { + s1 = peg$c25; + peg$currPos += 11; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e31); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f34(); + } + s0 = s1; + + return s0; + } + + function peg$parseis() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c26) { + s1 = peg$c26; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e32); } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f35(); + } + s0 = s1; + + return s0; + } + + function peg$parse_() { + var s0, s1; + + peg$silentFails++; + s0 = []; + s1 = input.charAt(peg$currPos); + if (peg$r6.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e34); } + } + if (s1 !== peg$FAILED) { + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = input.charAt(peg$currPos); + if (peg$r6.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e34); } + } + } + } else { + s0 = peg$FAILED; + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e33); } + } + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (options.peg$library) { + return /** @type {any} */ ({ + peg$result, + peg$currPos, + peg$FAILED, + peg$maxFailExpected, + peg$maxFailPos + }); + } + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +module.exports = { + StartRules: ["start"], + SyntaxError: peg$SyntaxError, + parse: peg$parse +}; diff --git a/packages/common/src/search-query/index.ts b/packages/common/src/search-query/index.ts new file mode 100644 index 00000000..868f886d --- /dev/null +++ b/packages/common/src/search-query/index.ts @@ -0,0 +1,2 @@ +export * from './search-query-parser'; +export * from './search-query-parser.types'; diff --git a/packages/common/src/search-query/peggy.config.mjs b/packages/common/src/search-query/peggy.config.mjs new file mode 100644 index 00000000..ba1e6b4b --- /dev/null +++ b/packages/common/src/search-query/peggy.config.mjs @@ -0,0 +1,6 @@ +// MJS +export default { + input: 'src/search-query/search-grammar.peggy', + output: 'src/search-query/generated/search-parser.js', + dts: true, +}; diff --git a/packages/common/src/search-query/search-grammar.peggy b/packages/common/src/search-query/search-grammar.peggy new file mode 100644 index 00000000..3537bc31 --- /dev/null +++ b/packages/common/src/search-query/search-grammar.peggy @@ -0,0 +1,109 @@ +start + = terms + +terms + = terms:(term (_ term)*)? _? { + return terms ? [terms[0]].concat(terms[1].map(([_, t]) => t)) : []; + } + +term + = finding_field_term + / finding_term + / not:not? type:(key) ":" _? value:value { + return { not: not ?? false, type, value }; + } + / not:not? key:key { + return { incomplete: true, not: not ?? false, type: key, value: null } + } + / not:not? key:finding_field_key { + return { incomplete: true, not: not ?? false, key, type: "findingField", value: null } + } + / not:not? key:finding_key { + return { incomplete: true, not: not ?? false, key, type: "finding", value: null } + } + / not:not? key:$[a-zA-Z._]+ { + return { incomplete: true, not: not ?? false, key, value: null, type: null } + } + +finding_field_term + = not:not? key:finding_field_key ":" _? value:value { + return { not: not ?? false, key, value, type: "findingField" }; + } + +finding_term + = not:not? key:finding_key ":" _? value:value { + return { not: not ?? false, key, value, type: "finding" }; + } + +not + = "-" { return true; } + +value + = raw_value + / string + / exists + / empty_value + +raw_value + = value:$[a-zA-Z0-9:_\-:/.\*]+ { + return value; + } + +empty_value + = "" { return null; } + +string + = [\"] string:$[a-zA-Z0-9._\- :/\*]+ [\"] { + return string; + } + +exists = "exists" { return "exists"; } + +finding_field_key + = "finding." finding_key:$[a-zA-Z0-9-]+ "." field_key:$[a-zA-Z0-9]* { + return { findingKey: finding_key, fieldKey: field_key }; + } + +finding_key + = "finding" "."? finding_key:$[a-zA-Z0-9-]* { + return { findingKey: finding_key }; + } + +key = project / domain / host / port / tags / other / is + +project + = "project.name" { return "project.name"; } + / "project.id" { return "project.id"; } + / "project" { return "project.name"; } + +domain + = "domain.name" { return "domain.name"; } + / "domain.id" { return "domain.id"; } + / "domain" { return "domain.name"; } + +host + = "host.ip" { return "host.ip"; } + / "host.id" { return "host.id"; } + / "host" { return "host.ip"; } + +port + = "port.number" { return "port.number"; } + / "port.id" { return "port.id"; } + / "port.protocol" { return "port.protocol"; } + / "port" { return "port.number"; } + / "port.service" { return "port.service"; } + / "port.product" { return "port.product"; } + / "port.version" { return "port.version"; } + +tags + = "tag.id" { return "tag.id"; } + / "tag.name" { return "tag.name"; } + / "tag" { return "tag.name"; } + +other + = "mergedIn.id" { return "mergedIn.id" } + +is = "is" { return "is"; } + +_ "whitespace" + = [ \t\n\r]+ \ No newline at end of file diff --git a/packages/common/src/search-query/search-query-parser.spec.ts b/packages/common/src/search-query/search-query-parser.spec.ts new file mode 100644 index 00000000..5536722b --- /dev/null +++ b/packages/common/src/search-query/search-query-parser.spec.ts @@ -0,0 +1,391 @@ +import { SearchQueryParser } from './search-query-parser'; +import { + SearchTerm, + SearchTerms, + TermTypes as TermType, +} from './search-query-parser.types'; + +interface HappyTestCase { + input: string; + expected: SearchTerms; +} + +describe('Search Query Parser', () => { + const parser = new SearchQueryParser(); + + const generalUseCases: HappyTestCase[] = [ + { + input: 'domain: "I am confusing: I have spaces and colons"', + expected: [ + term('domain.name', 'I am confusing: I have spaces and colons'), + ], + }, + { + input: 'domain: http://a1b2.ca -is: blocked', + expected: [ + term('domain.name', 'http://a1b2.ca'), + notTerm('is', 'blocked'), + ], + }, + + // Incomplete + { + input: 'dom', + expected: [ + { + not: false, + incomplete: true, + key: 'dom', + value: null, + type: null, + }, + ], + }, + { + input: '-dom', + expected: [ + { + incomplete: true, + not: true, + key: 'dom', + value: null, + type: null, + }, + ], + }, + { + input: 'domain', + expected: [ + { + not: false, + incomplete: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: '-domain', + expected: [ + { + incomplete: true, + not: true, + type: 'domain.name', + value: null, + }, + ], + }, + ]; + + const isTestCases: HappyTestCase[] = [ + { + input: 'is', + expected: [ + { + not: false, + incomplete: true, + type: 'is', + value: null, + }, + ], + }, + { + input: '-is', + expected: [ + { + incomplete: true, + not: true, + type: 'is', + value: null, + }, + ], + }, + { + input: '-is: blocked', + expected: [notTerm('is', 'blocked')], + }, + { + input: 'is: blocked', + expected: [term('is', 'blocked')], + }, + ]; + + const tagsTestCases: HappyTestCase[] = [ + { + input: 'tag.name', + expected: [ + { + not: false, + incomplete: true, + type: 'tag.name', + value: null, + }, + ], + }, + { + input: '-tag.name', + expected: [ + { + incomplete: true, + not: true, + type: 'tag.name', + value: null, + }, + ], + }, + { + input: 'tag: my-tag', + expected: [term('tag.name', 'my-tag')], + }, + { + input: '-tag: my-tag', + expected: [notTerm('tag.name', 'my-tag')], + }, + { + input: 'tag.name: my-tag', + expected: [term('tag.name', 'my-tag')], + }, + { + input: '-tag.name: my-tag', + expected: [notTerm('tag.name', 'my-tag')], + }, + { + input: 'tag.id: my-id', + expected: [term('tag.id', 'my-id')], + }, + { + input: '-tag.id: my-id', + expected: [notTerm('tag.id', 'my-id')], + }, + ]; + + const domainTestCases: HappyTestCase[] = [ + { + input: 'domain.name', + expected: [ + { + not: false, + incomplete: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: '-domain.name', + expected: [ + { + incomplete: true, + not: true, + type: 'domain.name', + value: null, + }, + ], + }, + { + input: 'domain: example.org', + expected: [term('domain.name', 'example.org')], + }, + { + input: '-domain: example.org', + expected: [notTerm('domain.name', 'example.org')], + }, + { + input: 'domain.name: example.org', + expected: [term('domain.name', 'example.org')], + }, + { + input: '-domain.name: example.org', + expected: [notTerm('domain.name', 'example.org')], + }, + { + input: 'domain.id: my-id', + expected: [term('domain.id', 'my-id')], + }, + { + input: '-domain.id: my-id', + expected: [notTerm('domain.id', 'my-id')], + }, + ]; + + const hostTestCases: HappyTestCase[] = [ + { + input: 'host.id', + expected: [ + { + not: false, + incomplete: true, + type: 'host.id', + value: null, + }, + ], + }, + { + input: 'host', + expected: [ + { + not: false, + incomplete: true, + type: 'host.ip', + value: null, + }, + ], + }, + { + input: '-host', + expected: [ + { + incomplete: true, + not: true, + type: 'host.ip', + value: null, + }, + ], + }, + ]; + + const portTestCases: HappyTestCase[] = [ + { + input: 'port', + expected: [ + { + not: false, + incomplete: true, + type: 'port.number', + value: null, + }, + ], + }, + { + input: '-port.number', + expected: [ + { + incomplete: true, + not: true, + type: 'port.number', + value: null, + }, + ], + }, + ]; + + const findingTestCases: HappyTestCase[] = [ + { + input: 'finding', + expected: [ + { + not: false, + incomplete: true, + type: 'finding', + key: { + findingKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.', + expected: [ + { + not: false, + incomplete: true, + type: 'finding', + key: { + findingKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.foo.', + expected: [ + { + not: false, + incomplete: true, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: '', + }, + value: null, + }, + ], + }, + { + input: 'finding.foo.bar: 123', + expected: [ + { + not: false, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: 'bar', + }, + value: '123', + }, + ], + }, + { + input: '-finding.foo.bar: 123', + expected: [ + { + not: true, + type: 'findingField', + key: { + findingKey: 'foo', + fieldKey: 'bar', + }, + value: '123', + }, + ], + }, + { + input: 'finding.foo: exists', + expected: [ + { + not: false, + type: 'finding', + key: { + findingKey: 'foo', + }, + value: 'exists', + }, + ], + }, + ]; + + it.each([ + ...generalUseCases, + ...domainTestCases, + ...hostTestCases, + ...portTestCases, + ...findingTestCases, + ...tagsTestCases, + ...isTestCases, + ])(`Should parse "$input" correctly`, ({ input, expected }) => { + // Arrange + // Act + const parsed = parser.parse(input); + + // Assert + expect(parsed).toEqual(expected); + }); +}); + +function term(type: TermType, value: string): SearchTerm { + return { + not: false, + type, + value, + }; +} + +function notTerm(type: TermType, value: string): SearchTerm { + return { + not: true, + type, + value, + }; +} diff --git a/packages/common/src/search-query/search-query-parser.ts b/packages/common/src/search-query/search-query-parser.ts new file mode 100644 index 00000000..50e5d609 --- /dev/null +++ b/packages/common/src/search-query/search-query-parser.ts @@ -0,0 +1,33 @@ +import * as searchParser from './generated/search-parser'; +import { + isFindingFieldTerm, + isFindingTerm, + SearchTerms, +} from './search-query-parser.types'; + +export class SearchQueryParser { + public parse(query: string): SearchTerms { + return searchParser.parse(query); + } + + public toQueryString(query: string | SearchTerms) { + if (typeof query === 'string') return query; + + return query + .filter((x) => !x.incomplete && x.value != null) + .map((x) => { + if (isFindingTerm(x)) { + return `${x.not ? '-' : ''}finding.${x.key.findingKey}: ${x.value}`; + } + + if (isFindingFieldTerm(x)) { + return `${x.not ? '-' : ''}finding.${x.key.findingKey}.${ + x.key.fieldKey + }: ${x.value}`; + } + + return `${x.not ? '-' : ''}${x.type}: ${x.value}`; + }) + .join(' '); + } +} diff --git a/packages/common/src/search-query/search-query-parser.types.ts b/packages/common/src/search-query/search-query-parser.types.ts new file mode 100644 index 00000000..8ef988b9 --- /dev/null +++ b/packages/common/src/search-query/search-query-parser.types.ts @@ -0,0 +1,98 @@ +/** Base type for a single search term */ +export type SearchTerm = + | NormalTerm + | FindingTerm + | FindingFieldTerm + | IncompleteTerm; + +export interface IncompleteTerm { + /** Indicates if the term is incomplete */ + incomplete?: true; + /** Indicates if the term is negated with "-" */ + not?: boolean; + /** Key for this term. */ + key: string; + /** Type for these terms */ + type: undefined | null; + /** The value for the term */ + value: null; +} + +export type TermTypes = + | 'is' + | 'project.id' + | 'project.name' + | 'domain.id' + | 'domain.name' + | 'host.id' + | 'host.ip' + | 'port.id' + | 'port.number' + | 'port.protocol' + | 'port.service' + | 'port.product' + | 'port.version' + | 'tag.name' + | 'tag.id' + | 'mergedIn.id' + | 'website' + | 'website.id'; + +/** Normal term */ +export interface NormalTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "-" */ + not?: boolean; + /** Type for these terms */ + type: TermTypes; + /** The value for the term */ + value: string | null; +} + +/** Term for finding type */ +export interface FindingTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "!" */ + not?: boolean; + /** Explicit type for finding */ + type: 'finding'; + /** The key for the finding */ + key: { + /** The main key for the finding */ + findingKey: string; + }; + /** The value for the term */ + value: string | null; +} + +/** Term for finding field type */ +export interface FindingFieldTerm { + /** Indicates if the term is incomplete */ + incomplete?: boolean; + /** Indicates if the term is negated with "!" */ + not?: boolean; + /** Explicit type for finding field */ + type: 'findingField'; + /** The key for the finding field */ + key: { + /** The main key for the finding */ + findingKey: string; + /** The field key for the finding */ + fieldKey: string; + }; + /** The value for the term */ + value: string | null; +} + +/** Type for a list of terms */ +export type SearchTerms = SearchTerm[]; + +export function isFindingTerm(term: SearchTerm): term is FindingTerm { + return term.type === 'finding'; +} + +export function isFindingFieldTerm(term: SearchTerm): term is FindingFieldTerm { + return term.type === 'findingField'; +} diff --git a/packages/common/test/jest.e2e.config.ga.js b/packages/common/test/jest.e2e.config.ga.js new file mode 100644 index 00000000..1cb16631 --- /dev/null +++ b/packages/common/test/jest.e2e.config.ga.js @@ -0,0 +1,6 @@ +const baseConfig = require('./jest.e2e.config'); + +module.exports = { + ...baseConfig, + reporters: [['github-actions', { silent: false }], 'default'], +}; diff --git a/packages/common/test/jest.e2e.config.js b/packages/common/test/jest.e2e.config.js new file mode 100644 index 00000000..975d2885 --- /dev/null +++ b/packages/common/test/jest.e2e.config.js @@ -0,0 +1,17 @@ +module.exports = { + moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], + modulePathIgnorePatterns: ['/dist/'], + rootDir: '..', + transform: { + '^.+\\.tsx?$': 'ts-jest', + }, + testRegex: '.e2e-spec.ts$', + collectCoverageFrom: [ + 'src/**/*.{js,jsx,tsx,ts}', + '!**/node_modules/**', + '!**/vendor/**', + ], + testTimeout: 70000, + slowTestThreshold: 30, + coverageReporters: ['json', 'lcov'], +}; diff --git a/packages/common/tsconfig.build.json b/packages/common/tsconfig.build.json new file mode 100644 index 00000000..e875fac2 --- /dev/null +++ b/packages/common/tsconfig.build.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["./src/**/*", "./test/**/*"], + "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] +} diff --git a/packages/common/tsconfig.json b/packages/common/tsconfig.json new file mode 100644 index 00000000..f98446b9 --- /dev/null +++ b/packages/common/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "module": "commonjs", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ESNext", + "sourceMap": true, + "outDir": "./dist", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": false, + "noImplicitAny": false, + "strictBindCallApply": false, + "forceConsistentCasingInFileNames": false, + "noFallthroughCasesInSwitch": false, + "esModuleInterop": true + }, + "include": ["src/**/*.ts", "test/**/*.ts"] +} diff --git a/packages/common/tsconfig.spec.json b/packages/common/tsconfig.spec.json new file mode 100644 index 00000000..d35b94f6 --- /dev/null +++ b/packages/common/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": ["jest"] + }, + "include": ["src/**/*.spec.ts", "src/**/*.d.ts", "test/**/*"], + "exclude": ["node_modules"] +} diff --git a/packages/frontend/stalker-app/src/app/api/domains/domains.service.ts b/packages/frontend/stalker-app/src/app/api/domains/domains.service.ts index bac9d5d8..4192937a 100644 --- a/packages/frontend/stalker-app/src/app/api/domains/domains.service.ts +++ b/packages/frontend/stalker-app/src/app/api/domains/domains.service.ts @@ -1,26 +1,29 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { DateRange } from '@angular/material/datepicker'; +import { SearchQueryParser, SearchTerms } from '@red-kite/common/search-query'; import { firstValueFrom, Observable } from 'rxjs'; import { environment } from '../../../environments/environment'; import { ResourceService } from '../../services/resources/resource.service'; import { Domain } from '../../shared/types/domain/domain.interface'; import { Page } from '../../shared/types/page.type'; -import { filtersToParams } from '../../utils/filters-to-params'; @Injectable({ providedIn: 'root', }) export class DomainsService implements ResourceService { + private searchParser = new SearchQueryParser(); + constructor(private http: HttpClient) {} public getPage( page: number, pageSize: number, - filters: any = undefined, + query: string | SearchTerms, firstSeenDateRange: DateRange = new DateRange(null, null) ): Observable> { - let params = filtersToParams(filters); + let params = new HttpParams(); + params = params.append('query', this.searchParser.toQueryString(query)); params = params.append('page', page); params = params.append('pageSize', pageSize); if (firstSeenDateRange.start) params = params.append('firstSeenStartDate', firstSeenDateRange.start.getTime()); diff --git a/packages/frontend/stalker-app/src/app/api/hosts/hosts.service.ts b/packages/frontend/stalker-app/src/app/api/hosts/hosts.service.ts index f0cc33a2..49d04aad 100644 --- a/packages/frontend/stalker-app/src/app/api/hosts/hosts.service.ts +++ b/packages/frontend/stalker-app/src/app/api/hosts/hosts.service.ts @@ -1,18 +1,20 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { DateRange } from '@angular/material/datepicker'; +import { SearchQueryParser, SearchTerms } from '@red-kite/common/search-query'; import { Observable, firstValueFrom } from 'rxjs'; import { environment } from '../../../environments/environment'; import { ResourceService } from '../../services/resources/resource.service'; import { Host } from '../../shared/types/host/host.interface'; import { Page } from '../../shared/types/page.type'; import { Port } from '../../shared/types/ports/port.interface'; -import { filtersToParams } from '../../utils/filters-to-params'; @Injectable({ providedIn: 'root', }) export class HostsService implements ResourceService { + private searchParser = new SearchQueryParser(); + constructor(private http: HttpClient) {} public get(hostId: string): Observable { @@ -22,10 +24,11 @@ export class HostsService implements ResourceService { public getPage( page: number, pageSize: number, - filters: any = undefined, + query: string | SearchTerms, firstSeenDateRange: DateRange = new DateRange(null, null) ): Observable> { - let params = filtersToParams(filters); + let params = new HttpParams(); + params = params.append('query', this.searchParser.toQueryString(query)); params = params.append('page', page); params = params.append('pageSize', pageSize); if (firstSeenDateRange.start) params = params.append('firstSeenStartDate', firstSeenDateRange.start.getTime()); diff --git a/packages/frontend/stalker-app/src/app/api/ip-ranges/ip-ranges.service.ts b/packages/frontend/stalker-app/src/app/api/ip-ranges/ip-ranges.service.ts new file mode 100644 index 00000000..2eae3412 --- /dev/null +++ b/packages/frontend/stalker-app/src/app/api/ip-ranges/ip-ranges.service.ts @@ -0,0 +1,56 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { DateRange } from '@angular/material/datepicker'; +import { Observable, firstValueFrom } from 'rxjs'; +import { environment } from '../../../environments/environment'; +import { IpRange } from '../../shared/types/ip-range/ip-range.interface'; +import { Page } from '../../shared/types/page.type'; +import { filtersToParams } from '../../utils/filters-to-params'; + +@Injectable({ + providedIn: 'root', +}) +export class IpRangesService { + constructor(private http: HttpClient) {} + private readonly route = `${environment.fmUrl}/ip-ranges`; + + public get(id: string): Observable { + return >this.http.get(`${this.route}/${id}`); + } + + public getPage( + page: number, + pageSize: number, + filters: any = undefined, + firstSeenDateRange: DateRange = new DateRange(null, null), + detailsLevel: 'extended' | 'full' | 'summary' = 'extended' + ): Observable> { + let params = filtersToParams(filters); + params = params.append('page', page); + params = params.append('pageSize', pageSize); + if (firstSeenDateRange.start) params = params.append('firstSeenStartDate', firstSeenDateRange.start.getTime()); + if (firstSeenDateRange.end) params = params.append('firstSeenEndDate', firstSeenDateRange.end.getTime()); + if (detailsLevel) params = params.append('detailsLevel', detailsLevel); + return this.http.get>(`${this.route}`, { params }); + } + + public async tag(id: string, tagId: string, isTagged: boolean) { + return await firstValueFrom(this.http.put(`${this.route}/${id}/tags`, { tagId: tagId, isTagged: isTagged })); + } + + public async add(projectId: string, ranges: Pick[]): Promise { + return await firstValueFrom(this.http.post(`${this.route}`, { ranges, projectId })); + } + + public async delete(hostId: string) { + return await firstValueFrom(this.http.delete(`${this.route}/${hostId}`)); + } + + public async deleteMany(ipRangeIds: string[]) { + return await firstValueFrom(this.http.delete(`${this.route}/`, { body: { ipRangeIds: ipRangeIds } })); + } + + public async block(ipRangeIds: string[], block: boolean) { + return await firstValueFrom(this.http.patch(`${this.route}/`, { ipRangeIds: ipRangeIds, block })); + } +} diff --git a/packages/frontend/stalker-app/src/app/api/jobs/jobs/jobs.service.ts b/packages/frontend/stalker-app/src/app/api/jobs/jobs/jobs.service.ts index 9c66893e..20bca660 100644 --- a/packages/frontend/stalker-app/src/app/api/jobs/jobs/jobs.service.ts +++ b/packages/frontend/stalker-app/src/app/api/jobs/jobs/jobs.service.ts @@ -59,6 +59,6 @@ export class JobsService { private filterJob(job: CustomJob, filters: string[]) { const parts = [job.name, job.findingHandlerLanguage, job.type]; - return filters.some((filter) => normalizeSearchString(parts.join(' ')).includes(filter)); + return filters.some((filter) => normalizeSearchString(parts.join(' ')).includes(normalizeSearchString(filter))); } } diff --git a/packages/frontend/stalker-app/src/app/api/jobs/subscriptions/subscriptions.service.ts b/packages/frontend/stalker-app/src/app/api/jobs/subscriptions/subscriptions.service.ts index 830a7c71..bb044677 100644 --- a/packages/frontend/stalker-app/src/app/api/jobs/subscriptions/subscriptions.service.ts +++ b/packages/frontend/stalker-app/src/app/api/jobs/subscriptions/subscriptions.service.ts @@ -1,13 +1,13 @@ import { Injectable } from '@angular/core'; import { Observable, combineLatest, map } from 'rxjs'; +import { stringify } from 'yaml'; +import { Page } from '../../../shared/types/page.type'; import { CronSubscription, CronSubscriptionData, EventSubscription, EventSubscriptionData, } from '../../../shared/types/subscriptions/subscription.type'; -import { stringify } from 'yaml'; -import { Page } from '../../../shared/types/page.type'; import { normalizeSearchString } from '../../../utils/normalize-search-string'; import { CronSubscriptionsService } from './cron-subscriptions.service'; import { EventSubscriptionsService } from './event-subscriptions.service'; @@ -116,6 +116,6 @@ export class SubscriptionService { cron.cronExpression ? 'cron' : 'event', subscription.isEnabled === false ? 'disabled' : 'enabled', ]; - return filters.some((filter) => normalizeSearchString(parts.join(' ')).includes(filter)); + return filters.some((filter) => normalizeSearchString(parts.join(' ')).includes(normalizeSearchString(filter))); } } diff --git a/packages/frontend/stalker-app/src/app/api/ports/ports.service.ts b/packages/frontend/stalker-app/src/app/api/ports/ports.service.ts index 89b7739e..d1c0c957 100644 --- a/packages/frontend/stalker-app/src/app/api/ports/ports.service.ts +++ b/packages/frontend/stalker-app/src/app/api/ports/ports.service.ts @@ -1,27 +1,29 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { DateRange } from '@angular/material/datepicker'; +import { SearchQueryParser, SearchTerms } from '@red-kite/common/search-query'; import { Observable, firstValueFrom } from 'rxjs'; import { environment } from '../../../environments/environment'; import { ResourceService } from '../../services/resources/resource.service'; import { Page } from '../../shared/types/page.type'; import { ExtendedPort, Port, PortNumber } from '../../shared/types/ports/port.interface'; -import { filtersToParams } from '../../utils/filters-to-params'; @Injectable({ providedIn: 'root', }) export class PortsService implements ResourceService { + private searchParser = new SearchQueryParser(); constructor(private http: HttpClient) {} public getPage( page: number, pageSize: number, - filters: any = undefined, + query: string | SearchTerms, firstSeenDateRange: DateRange = new DateRange(null, null), detailsLevel: 'extended' | 'full' | 'summary' | 'number' = 'full' ): Observable> { - let params = filtersToParams(filters); + let params = new HttpParams(); + params = params.append('query', this.searchParser.toQueryString(query)); params = params.append('page', page); params = params.append('pageSize', pageSize); diff --git a/packages/frontend/stalker-app/src/app/api/tags/tags.service.ts b/packages/frontend/stalker-app/src/app/api/tags/tags.service.ts index c4af8c31..efc88b50 100644 --- a/packages/frontend/stalker-app/src/app/api/tags/tags.service.ts +++ b/packages/frontend/stalker-app/src/app/api/tags/tags.service.ts @@ -36,6 +36,6 @@ export class TagsService { } private filterTags(secret: Tag, filters: string[]) { const parts = [secret?.text, secret.color]; - return filters.some((filter) => normalizeSearchString(parts.join(' ')).includes(filter)); + return filters.some((filter) => normalizeSearchString(parts.join(' ')).includes(normalizeSearchString(filter))); } } diff --git a/packages/frontend/stalker-app/src/app/api/websites/websites.service.ts b/packages/frontend/stalker-app/src/app/api/websites/websites.service.ts index 83794b11..af15aa83 100644 --- a/packages/frontend/stalker-app/src/app/api/websites/websites.service.ts +++ b/packages/frontend/stalker-app/src/app/api/websites/websites.service.ts @@ -1,29 +1,31 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { DateRange } from '@angular/material/datepicker'; +import { SearchQueryParser, SearchTerms } from '@red-kite/common/search-query'; import { Observable, firstValueFrom, map } from 'rxjs'; import { environment } from '../../../environments/environment'; import { ResourceService } from '../../services/resources/resource.service'; import { Page } from '../../shared/types/page.type'; import { Website } from '../../shared/types/websites/website.type'; -import { filtersToParams } from '../../utils/filters-to-params'; @Injectable({ providedIn: 'root', }) export class WebsitesService implements ResourceService { + private searchParser = new SearchQueryParser(); + constructor(private http: HttpClient) {} public getPage( page: number, pageSize: number, - filters: any = undefined, + query: string | SearchTerms, firstSeenDateRange: DateRange = new DateRange(null, null) ): Observable> { - let params = filtersToParams(filters); + let params = new HttpParams(); + params = params.append('query', this.searchParser.toQueryString(query)); params = params.append('page', page); params = params.append('pageSize', pageSize); - if (firstSeenDateRange.start) params = params.append('firstSeenStartDate', firstSeenDateRange.start.getTime()); if (firstSeenDateRange.end) params = params.append('firstSeenEndDate', firstSeenDateRange.end.getTime()); diff --git a/packages/frontend/stalker-app/src/app/app-routing.module.ts b/packages/frontend/stalker-app/src/app/app-routing.module.ts index 6611ad14..b172bbed 100644 --- a/packages/frontend/stalker-app/src/app/app-routing.module.ts +++ b/packages/frontend/stalker-app/src/app/app-routing.module.ts @@ -55,6 +55,11 @@ const routes: Routes = [ canActivate: [authenticationGuard], loadChildren: () => import('./modules/hosts/hosts.module').then((m) => m.HostsListModule), }, + { + path: 'ip-ranges', + canActivate: [authenticationGuard], + loadChildren: () => import('./modules/ip-ranges/ip-ranges.module').then((m) => m.IpRangesListModule), + }, { path: 'ports', canActivate: [authenticationGuard], diff --git a/packages/frontend/stalker-app/src/app/modules/dashboard/number-of-domains-metric/number-of-domains-metric.component.ts b/packages/frontend/stalker-app/src/app/modules/dashboard/number-of-domains-metric/number-of-domains-metric.component.ts index 220bad64..f576c528 100644 --- a/packages/frontend/stalker-app/src/app/modules/dashboard/number-of-domains-metric/number-of-domains-metric.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/dashboard/number-of-domains-metric/number-of-domains-metric.component.ts @@ -1,5 +1,6 @@ import { CommonModule } from '@angular/common'; import { Component } from '@angular/core'; +import { SearchTerms } from '@red-kite/common/search-query'; import { map, switchMap } from 'rxjs'; import { DomainsService } from '../../../api/domains/domains.service'; import { globalProjectFilter$ } from '../../../utils/global-project-filter'; @@ -14,9 +15,13 @@ import { SimpleMetric } from '../simple-metric/simple-metric.component'; export class NumberOfDomainsMetric { public value$ = globalProjectFilter$.pipe( switchMap((project) => { - const projects = []; - if (project) projects.push(project.id); - return this.domainService.getPage(0, 1, { projects }).pipe(map((x) => `${x.totalRecords}`)); + const query: SearchTerms = []; + if (project) + query.push({ + type: 'project.id', + value: project.id, + }); + return this.domainService.getPage(0, 1, query).pipe(map((x) => `${x.totalRecords}`)); }) ); diff --git a/packages/frontend/stalker-app/src/app/modules/dashboard/number-of-hosts-metric/number-of-hosts-metric.component.ts b/packages/frontend/stalker-app/src/app/modules/dashboard/number-of-hosts-metric/number-of-hosts-metric.component.ts index 336666c5..a9baf99e 100644 --- a/packages/frontend/stalker-app/src/app/modules/dashboard/number-of-hosts-metric/number-of-hosts-metric.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/dashboard/number-of-hosts-metric/number-of-hosts-metric.component.ts @@ -1,6 +1,7 @@ import { CommonModule } from '@angular/common'; -import { Component } from '@angular/core'; -import { map, switchMap } from 'rxjs'; +import { Component, Input } from '@angular/core'; +import { SearchTerms } from '@red-kite/common/search-query'; +import { BehaviorSubject, combineLatest, map, switchMap } from 'rxjs'; import { HostsService } from '../../../api/hosts/hosts.service'; import { globalProjectFilter$ } from '../../../utils/global-project-filter'; import { SimpleMetric } from '../simple-metric/simple-metric.component'; @@ -12,17 +13,33 @@ import { SimpleMetric } from '../simple-metric/simple-metric.component'; template: ``, }) export class NumberOfHostsMetric { - public value$ = globalProjectFilter$.pipe( - switchMap((project) => { - const projects = []; - if (project) projects.push(project.id); - return this.hostService.getPage(0, 1, { projects }).pipe(map((x) => `${x.totalRecords}`)); - }) - ); + @Input() public name = $localize`:Number of hosts|:Number of hosts`; - public get name() { - return $localize`:Number of hosts|:Number of hosts`; + private _additionalFilters$: BehaviorSubject<{ [key: string]: string | string[] }> = new BehaviorSubject<{ + [key: string]: string | string[]; + }>({}); + @Input() public set additionalFilters(filters: { [key: string]: string | string[] }) { + this._additionalFilters$.next(filters); } + public value$ = combineLatest([globalProjectFilter$, this._additionalFilters$]).pipe( + switchMap(([project, additionalFilters]) => { + const query: SearchTerms = []; + + if (project) { + query.push({ + type: 'project.id', + value: project.id, + }); + } + + if (additionalFilters) { + // TODO #319 + } + + return this.hostService.getPage(0, 1, query).pipe(map((x) => `${x.totalRecords}`)); + }) + ); + constructor(private hostService: HostsService) {} } diff --git a/packages/frontend/stalker-app/src/app/modules/domains/list-domains/list-domains.component.html b/packages/frontend/stalker-app/src/app/modules/domains/list-domains/list-domains.component.html index 41dff84a..8ca92cb4 100644 --- a/packages/frontend/stalker-app/src/app/modules/domains/list-domains/list-domains.component.html +++ b/packages/frontend/stalker-app/src/app/modules/domains/list-domains/list-domains.component.html @@ -31,6 +31,7 @@ [negatableFilterOptions]="['is']" [dateSearchEnabled]="true" [startDate]="startDate" + [filterType]="'grammar'" > (null, null) ); }), @@ -152,77 +146,6 @@ export class ListDomainsComponent { this.titleService.setTitle($localize`:Domains list page title|:Domains`); } - buildFilters(stringFilters: string[], projects: ProjectSummary[], tags: Tag[]): any { - const SEPARATOR = ':'; - const NEGATING_CHAR = '-'; - const filterObject: any = {}; - const includedTags = []; - const includedDomains = []; - const includedHosts = []; - const includedProjects = []; - let blocked: boolean | null = null; - - for (const filter of stringFilters) { - if (filter.indexOf(SEPARATOR) === -1) continue; - - const keyValuePair = filter.split(SEPARATOR); - - if (keyValuePair.length !== 2) continue; - - let key = keyValuePair[0].trim().toLowerCase(); - const value = keyValuePair[1].trim().toLowerCase(); - const negated = key.length > 0 && key[0] === NEGATING_CHAR; - if (negated) key = key.substring(1); - - if (!key || !value) continue; - - switch (key) { - case 'project': - const project = projects.find((c) => c.name.trim().toLowerCase() === value.trim().toLowerCase()); - if (project) includedProjects.push(project.id); - else - this.toastr.warning( - $localize`:Project does not exist|The given project name is not known to the application:Project name not recognized` - ); - break; - - case 'host': - if (value) includedHosts.push(value.trim().toLowerCase()); - break; - - case 'tags': - const tag = tags.find((t) => t.text.trim().toLowerCase() === value.trim().toLowerCase()); - if (tag) includedTags.push(tag._id); - else - this.toastr.warning( - $localize`:Tag does not exist|The given tag is not known to the application:Tag not recognized` - ); - break; - - case 'domain': - includedDomains.push(value); - break; - - case 'is': - switch (value) { - case 'blocked': - blocked = !negated; - break; - } - break; - } - } - - if (hasGlobalProjectFilter()) includedProjects.push(getGlobalProjectFilter()?.id); - - if (includedTags.length) filterObject['tags'] = includedTags; - if (includedDomains.length) filterObject['domains'] = includedDomains; - if (includedHosts.length) filterObject['hosts'] = includedHosts; - if (includedProjects.length) filterObject['projects'] = includedProjects; - if (blocked !== null) filterObject['blocked'] = blocked; - return filterObject; - } - openNewDomainsDialog(templateRef: TemplateRef) { this.dialog.open(templateRef, { restoreFocus: false, @@ -256,7 +179,7 @@ export class ListDomainsComponent { if (addedDomains.length < newDomains.length) { this.toastr.warning( - $localize`:Domains not added|Some domains were not added to the database:Some domains were not added` + $localize`:Domains duplicates|Some domains were duplicates to the database:Some domains were duplicates` ); } diff --git a/packages/frontend/stalker-app/src/app/modules/domains/view-domain/view-domain.component.ts b/packages/frontend/stalker-app/src/app/modules/domains/view-domain/view-domain.component.ts index 39368714..ccae684f 100644 --- a/packages/frontend/stalker-app/src/app/modules/domains/view-domain/view-domain.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/domains/view-domain/view-domain.component.ts @@ -161,7 +161,13 @@ export class ViewDomainComponent implements OnDestroy { const page$ = new BehaviorSubject(0); return page$.pipe( concatMap((page: number) => { - return this.portsService.getPage(page, pageSize, { hostId: hostId }, undefined, 'number'); + return this.portsService.getPage( + page, + pageSize, + [{ type: 'host.id', value: hostId, not: false }], + undefined, + 'number' + ); }), scan((acc: Page, value: Page) => { return { items: acc.items.concat(value.items), totalRecords: value.totalRecords }; diff --git a/packages/frontend/stalker-app/src/app/modules/findings/finding/finding.component.ts b/packages/frontend/stalker-app/src/app/modules/findings/finding/finding.component.ts index b3ceebd2..690f7a7d 100644 --- a/packages/frontend/stalker-app/src/app/modules/findings/finding/finding.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/findings/finding/finding.component.ts @@ -13,7 +13,7 @@ export class FindingComponent { constructor(private toastr: ToastrService) {} public copyJsonToClipboard() { - navigator.clipboard.writeText(JSON.stringify(this.finding)); + navigator.clipboard.writeText(JSON.stringify(this.finding, undefined, 2)); this.toastr.success( $localize`:Finding copied to clipboard|Finding copied to clipboard:Finding copied to clipboard` ); diff --git a/packages/frontend/stalker-app/src/app/modules/findings/findings-list/finding-list.component.scss b/packages/frontend/stalker-app/src/app/modules/findings/findings-list/finding-list.component.scss index 4aa878b2..4eacc519 100644 --- a/packages/frontend/stalker-app/src/app/modules/findings/findings-list/finding-list.component.scss +++ b/packages/frontend/stalker-app/src/app/modules/findings/findings-list/finding-list.component.scss @@ -34,3 +34,7 @@ width: 100%; justify-content: center; } + +.break-words { + word-break: break-word; +} diff --git a/packages/frontend/stalker-app/src/app/modules/findings/findings-list/findings-list.component.html b/packages/frontend/stalker-app/src/app/modules/findings/findings-list/findings-list.component.html index 2d762efe..c0521704 100644 --- a/packages/frontend/stalker-app/src/app/modules/findings/findings-list/findings-list.component.html +++ b/packages/frontend/stalker-app/src/app/modules/findings/findings-list/findings-list.component.html @@ -3,7 +3,7 @@ @for (finding of findings.items; track finding) {
- + diff --git a/packages/frontend/stalker-app/src/app/modules/hosts/list-hosts/list-hosts.component.html b/packages/frontend/stalker-app/src/app/modules/hosts/list-hosts/list-hosts.component.html index 2cf19e00..478a840d 100644 --- a/packages/frontend/stalker-app/src/app/modules/hosts/list-hosts/list-hosts.component.html +++ b/packages/frontend/stalker-app/src/app/modules/hosts/list-hosts/list-hosts.component.html @@ -30,6 +30,8 @@ [filterOptions]="filterOptions" [negatableFilterOptions]="['is']" [dateSearchEnabled]="true" + [filterType]="'grammar'" + [startDate]="startDate" > { + dataSource$ = combineLatest([this.filtersSource.debouncedFilters$, this.refresh$, globalProjectFilter$]).pipe( + switchMap(([{ dateRange, filters, pagination }]) => { return this.hostsService.getPage( pagination?.page || 0, pagination?.pageSize || 25, - this.buildFilters(filters || [], tags), + appendGlobalFiltersToQuery(filters[0]), dateRange ?? new DateRange(null, null) ); }), @@ -153,73 +143,6 @@ export class ListHostsComponent { this.titleService.setTitle($localize`:Hosts list page title|:Hosts`); } - buildFilters(stringFilters: string[], tags: Tag[]): any { - const SEPARATOR = ':'; - const NEGATING_CHAR = '-'; - const filterObject: any = {}; - const includedTags = []; - const domains = []; - const hosts = []; - const projects = []; - let blocked: boolean | null = null; - - for (const filter of stringFilters) { - if (filter.indexOf(SEPARATOR) === -1) continue; - - const keyValuePair = filter.split(SEPARATOR); - - if (keyValuePair.length !== 2) continue; - - let key = keyValuePair[0].trim().toLowerCase(); - const value = keyValuePair[1].trim().toLowerCase(); - const negated = key.length > 0 && key[0] === NEGATING_CHAR; - if (negated) key = key.substring(1); - - if (!key || !value) continue; - - switch (key) { - case 'project': - const project = this.projects.find((c) => c.name.trim().toLowerCase() === value.trim().toLowerCase()); - if (project) projects.push(project.id); - else - this.toastr.warning( - $localize`:Project does not exist|The given project name is not known to the application:Project name not recognized` - ); - break; - case 'host': - if (value) hosts.push(value.trim().toLowerCase()); - break; - case 'tags': - const tag = tags.find((t) => t.text.trim().toLowerCase() === value.trim().toLowerCase()); - if (tag) includedTags.push(tag._id); - else - this.toastr.warning( - $localize`:Tag does not exist|The given tag is not known to the application:Tag not recognized` - ); - break; - case 'domain': - domains.push(value); - break; - case 'is': - switch (value) { - case 'blocked': - blocked = !negated; - break; - } - break; - } - } - - if (hasGlobalProjectFilter()) projects.push(getGlobalProjectFilter()?.id); - - if (includedTags?.length) filterObject['tags'] = includedTags; - if (domains?.length) filterObject['domains'] = domains; - if (hosts?.length) filterObject['hosts'] = hosts; - if (projects?.length) filterObject['projects'] = projects; - if (blocked !== null) filterObject['blocked'] = blocked; - return filterObject; - } - openNewHostsDialog(templateRef: TemplateRef) { this.dialog.open(templateRef, { restoreFocus: false, @@ -251,7 +174,7 @@ export class ListHostsComponent { if (addedHosts.length < newHosts.length) { this.toastr.warning( - $localize`:Hosts not added|Some hosts were not added to the database:Some hosts were not added` + $localize`:Hosts duplicates|Some hosts were duplicates to the database:Some hosts were duplicates` ); } diff --git a/packages/frontend/stalker-app/src/app/modules/hosts/view-host/view-host.component.ts b/packages/frontend/stalker-app/src/app/modules/hosts/view-host/view-host.component.ts index 332fcd3c..e9709d00 100644 --- a/packages/frontend/stalker-app/src/app/modules/hosts/view-host/view-host.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/hosts/view-host/view-host.component.ts @@ -180,7 +180,13 @@ export class ViewHostComponent implements OnDestroy { const size = page >= 0 ? 100 : 5; page = page < 0 ? 0 : page; - return this.portsService.getPage(page, size, { hostId: host._id }, undefined, 'number'); + return this.portsService.getPage( + page, + size, + [{ type: 'host.id', value: host._id, not: false }], + undefined, + 'number' + ); }), scan((acc: Page, value: Page) => { const found = new Set(); diff --git a/packages/frontend/stalker-app/src/app/modules/ip-ranges/ip-ranges-interactions.service.ts b/packages/frontend/stalker-app/src/app/modules/ip-ranges/ip-ranges-interactions.service.ts new file mode 100644 index 00000000..a404cfba --- /dev/null +++ b/packages/frontend/stalker-app/src/app/modules/ip-ranges/ip-ranges-interactions.service.ts @@ -0,0 +1,160 @@ +import { Injectable } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ToastrService } from 'ngx-toastr'; +import { firstValueFrom } from 'rxjs'; +import { IpRangesService } from '../../api/ip-ranges/ip-ranges.service'; +import { IpRange } from '../../shared/types/ip-range/ip-range.interface'; +import { ProjectSummary } from '../../shared/types/project/project.summary'; +import { ConfirmDialogComponent, ConfirmDialogData } from '../../shared/widget/confirm-dialog/confirm-dialog.component'; + +@Injectable({ providedIn: 'root' }) +export class IpRangesInteractionsService { + constructor( + private ipRangesService: IpRangesService, + private dialog: MatDialog, + private toastr: ToastrService + ) {} + + public deleteBatch(ipRanges: Pick[], projects?: ProjectSummary[]) { + let data: ConfirmDialogData; + if (ipRanges.length > 0) { + data = { + text: $localize`:Confirm delete IP ranges|Confirmation message asking if the user really wants to delete the selected IP ranges:Do you really wish to delete these IP ranges permanently ?`, + title: $localize`:Deleting IP ranges|Title of a page to delete selected IP ranges:Deleting IP ranges`, + primaryButtonText: $localize`:Cancel|Cancel current action:Cancel`, + dangerButtonText: $localize`:Delete permanently|Confirm that the user wants to delete the item permanently:Delete permanently`, + listElements: this.toBulletPoints(ipRanges, projects), + onPrimaryButtonClick: () => { + this.dialog.closeAll(); + }, + onDangerButtonClick: async (close) => { + const ids = ipRanges.map((d) => d._id); + await this.ipRangesService.deleteMany(ids); + this.toastr.success( + $localize`:IP ranges deleted|Confirm the successful deletion of an IP ranges:IP ranges deleted successfully` + ); + close(true); + }, + }; + } else { + data = { + text: $localize`:Select IP ranges again|No IP ranges were selected so there is nothing to delete:Select the IP ranges to delete and try again.`, + title: $localize`:Nothing to delete|Tried to delete something, but there was nothing to delete:Nothing to delete`, + primaryButtonText: $localize`:Ok|Accept or confirm:Ok`, + noDataSelectItem: true, + onPrimaryButtonClick: (close) => { + close(false); + }, + }; + } + + return firstValueFrom( + this.dialog + .open(ConfirmDialogComponent, { + data, + restoreFocus: false, + }) + .afterClosed() + ); + } + + public async blockBatch(ipRanges: Pick[], projects?: ProjectSummary[]) { + let data: ConfirmDialogData; + if (ipRanges.length > 0) { + const block = async (close: (result: boolean) => void, block: boolean) => { + try { + await this.ipRangesService.block( + ipRanges.map((s) => s._id), + block + ); + this.toastr.success( + block + ? $localize`:IP ranges blocked|Blocked an IP range:IP ranges successfully blocked` + : $localize`:IP ranges unblocked|Unblocked an IP range:IP ranges successfully unblocked` + ); + close(true); + } catch { + this.toastr.error($localize`:Error blocking|Error while blocking an IP range:Error blocking IP ranges`); + close(false); + } + }; + + data = { + text: $localize`:Confirm block IP ranges|Confirmation message asking if the user wants to block the selected IP ranges:Do you wish to block or unblock these IP ranges?`, + title: $localize`:Blocking IP ranges|Title of a page to block selected IP ranges:Blocking IP ranges`, + primaryButtonText: $localize`:Unblock|Unblock an item:Unblock`, + dangerButtonText: $localize`:Block|Block an item:Block`, + listElements: this.toBulletPoints(ipRanges, projects), + enableCancelButton: true, + onPrimaryButtonClick: async (close) => await block(close, false), + onDangerButtonClick: async (close) => await block(close, true), + }; + } else { + data = { + text: $localize`:Select IP ranges again|No IP ranges were selected so there is nothing to delete:Select the IP ranges to block and try again.`, + title: $localize`:Nothing to block|Tried to block something, but there was nothing to delete:Nothing to block`, + primaryButtonText: $localize`:Ok|Accept or confirm:Ok`, + noDataSelectItem: true, + onPrimaryButtonClick: (close) => close(false), + }; + } + + return firstValueFrom( + this.dialog + .open(ConfirmDialogComponent, { + data, + restoreFocus: false, + }) + .afterClosed() + ); + } + + public block(ipRangeId: string, block: boolean) { + const errorBlocking = $localize`:Error while blocking|Error while blocking an item:Error while blocking`; + if (!ipRangeId) { + this.toastr.error(errorBlocking); + } + + let data: ConfirmDialogData = { + text: block + ? $localize`:Confirm block IP range|Confirmation message asking if the user wants to block the IP range:Do you really wish to block this IP range?` + : $localize`:Confirm unblock IP range|Confirmation message asking if the user wants to unblock the IP range:Do you really wish to unblock this IP range?`, + title: block + ? $localize`:Blocking IP range|Title of a page to block a IP range:Blocking IP range` + : $localize`:Unblocking IP range|Title of a page to unblock a IP range:Unblocking IP range`, + primaryButtonText: block ? $localize`:Block|Block an item:Block` : $localize`:Unblock|Unblock an item:Unblock`, + enableCancelButton: true, + onPrimaryButtonClick: async (close) => { + try { + await this.ipRangesService.block([ipRangeId], block); + this.toastr.success( + block + ? $localize`:IP range blocked|Blocked an IP range:IP range successfully blocked` + : $localize`:IP range unblocked|Unblocked an IP range:IP range successfully unblocked` + ); + + close(true); + } catch { + this.toastr.error(errorBlocking); + close(false); + } + }, + }; + + return firstValueFrom( + this.dialog + .open(ConfirmDialogComponent, { + data, + restoreFocus: false, + }) + .afterClosed() + ); + } + + private toBulletPoints(ipRanges: Pick[], projects?: ProjectSummary[]) { + return ipRanges.map((x) => { + const projectName = projects?.find((d) => d.id === x.projectId)?.name; + return projectName ? `${x.ip}/${x.mask} (${projectName})` : `${x.ip}/${x.mask}`; + }); + } +} diff --git a/packages/frontend/stalker-app/src/app/modules/ip-ranges/ip-ranges.module.ts b/packages/frontend/stalker-app/src/app/modules/ip-ranges/ip-ranges.module.ts new file mode 100644 index 00000000..fe95b408 --- /dev/null +++ b/packages/frontend/stalker-app/src/app/modules/ip-ranges/ip-ranges.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +const routes: Routes = [ + { + path: ':id', + loadComponent: () => import('./view-ip-range/view-ip-range.component').then((m) => m.ViewIpRangeComponent), + }, + { + path: '', + loadComponent: () => import('./list-ip-ranges/list-ip-ranges.component').then((m) => m.ListIpRangesComponent), + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [], + providers: [], +}) +export class IpRangesListModule {} diff --git a/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.html b/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.html new file mode 100644 index 00000000..61f10f84 --- /dev/null +++ b/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.html @@ -0,0 +1,135 @@ + + +
+ IP Ranges + +
+ + + + + +
+
+
+ + + @if (((projects$ | async) && (tags$ | async)) || true) { + + + + + CIDR + +
+ {{ + element.ip + '/' + element.mask.toString() + }} + + @if (element.blocked) { + + } +
+ +
+ + + + Hosts sample + + @for (host of element.hosts; track host; let i = $index; let last = $last) { + @if (i < maxHostsPerLine || (i === maxHostsPerLine && maxHostsPerLine + 1 === element.hosts.length)) { + {{ host.ip }} + } + @if ( + (!last && i < maxHostsPerLine - 1) || + (i === maxHostsPerLine - 1 && maxHostsPerLine + 1 === element.hosts.length) + ) { + , + } + @if (i === maxHostsPerLine && maxHostsPerLine + 1 !== element.hosts.length) { + ({{ element.hosts.length }} total) + } + @if (i < maxHostsPerLine) { +
+ } + } + +
+ + + + Project + + + + + + + Tags + +
+ @for (tag of element.tags; track tag) { + {{ + (tags$ | async | whereId: [tag])?.text + }} + } + +
+ +
+ +
+
+ } +
+
+ + + +

Add IP ranges

+ + + + + None + @for (project of projects$ | async; track project) { + {{ project.name }} + } + + + + + + + + +
diff --git a/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.scss b/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.scss new file mode 100644 index 00000000..10e761d1 --- /dev/null +++ b/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.scss @@ -0,0 +1,12 @@ +mat-card { + overflow: hidden; +} + +mat-dialog-content { + display: flex; + flex-direction: column; +} + +mat-dialog-actions { + justify-content: center; +} diff --git a/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.ts b/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.ts new file mode 100644 index 00000000..b75d5ee4 --- /dev/null +++ b/packages/frontend/stalker-app/src/app/modules/ip-ranges/list-ip-ranges/list-ip-ranges.component.ts @@ -0,0 +1,320 @@ +import { SelectionModel } from '@angular/cdk/collections'; +import { BreakpointObserver, BreakpointState, Breakpoints } from '@angular/cdk/layout'; +import { CommonModule } from '@angular/common'; +import { Component, Inject, TemplateRef } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { DateRange } from '@angular/material/datepicker'; +import { MatDialog, MatDialogModule } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { Title } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { ToastrService } from 'ngx-toastr'; +import { BehaviorSubject, combineLatest, map, shareReplay, switchMap, tap } from 'rxjs'; +import { IpRangesService } from '../../../api/ip-ranges/ip-ranges.service'; +import { ProjectsService } from '../../../api/projects/projects.service'; +import { TagsService } from '../../../api/tags/tags.service'; +import { IpRangeAccordionComponent } from '../../../shared/components/ip-range-accordion/ip-range-accordion.component'; +import { ProjectCellComponent } from '../../../shared/components/project-cell/project-cell.component'; +import { SharedModule } from '../../../shared/shared.module'; +import { HttpStatus } from '../../../shared/types/http-status.type'; +import { IpRange } from '../../../shared/types/ip-range/ip-range.interface'; +import { Page } from '../../../shared/types/page.type'; +import { ProjectSummary } from '../../../shared/types/project/project.summary'; +import { Tag } from '../../../shared/types/tag.type'; +import { ElementMenuItems } from '../../../shared/widget/dynamic-icons/menu-icon.component'; +import { FilteredPaginatedTableComponent } from '../../../shared/widget/filtered-paginated-table/filtered-paginated-table.component'; +import { + TABLE_FILTERS_SOURCE_INITAL_FILTERS, + TableFilters, + TableFiltersSource, + TableFiltersSourceBase, +} from '../../../shared/widget/filtered-paginated-table/table-filters-source'; +import { TableFormatComponent } from '../../../shared/widget/filtered-paginated-table/table-format/table-format.component'; +import { BlockedPillTagComponent } from '../../../shared/widget/pill-tag/blocked-pill-tag.component'; +import { defaultNewTimeMs } from '../../../shared/widget/pill-tag/new-pill-tag.component'; +import { PillTagComponent } from '../../../shared/widget/pill-tag/pill-tag.component'; +import { + getGlobalProjectFilter, + globalProjectFilter$, + hasGlobalProjectFilter, +} from '../../../utils/global-project-filter'; +import { IpRangesInteractionsService } from '../ip-ranges-interactions.service'; + +@Component({ + standalone: true, + imports: [ + CommonModule, + MatCardModule, + MatIconModule, + MatDialogModule, + MatFormFieldModule, + MatSelectModule, + SharedModule, + FormsModule, + MatButtonModule, + MatTableModule, + ReactiveFormsModule, + MatInputModule, + ProjectCellComponent, + FilteredPaginatedTableComponent, + BlockedPillTagComponent, + RouterModule, + TableFormatComponent, + IpRangeAccordionComponent, + PillTagComponent, + ], + selector: 'app-list-ip-ranges', + templateUrl: './list-ip-ranges.component.html', + styleUrls: ['./list-ip-ranges.component.scss'], + providers: [ + { provide: TableFiltersSourceBase, useClass: TableFiltersSource }, + { + provide: TABLE_FILTERS_SOURCE_INITAL_FILTERS, + useValue: { + filters: ['-is: blocked'], + pagination: { page: 0, pageSize: 25 }, + } as TableFilters, + }, + ], +}) +export class ListIpRangesComponent { + dataLoading = true; + displayedColumns: string[] = ['select', 'cidr', 'hosts', 'project', 'tags', 'menu']; + filterOptions: string[] = ['ip', 'contains', 'project', 'tags', 'is']; + public readonly noDataMessage = $localize`:No ip range found|No ip range was found:No ip range found`; + public newIpRanges: Pick[] = []; + + maxHostsPerLine = 5; + count = 0; + selection = new SelectionModel(true, []); + startDate: Date | null = null; + + tags$ = this.tagsService.getAllTags().pipe(shareReplay(1)); + + private refresh$ = new BehaviorSubject(null); + dataSource$ = combineLatest([ + this.filtersSource.debouncedFilters$, + this.tags$, + this.refresh$, + globalProjectFilter$, + ]).pipe( + switchMap(([{ dateRange, filters, pagination }, tags]) => { + return this.ipRangesService.getPage( + pagination?.page || 0, + pagination?.pageSize || 25, + this.buildFilters(filters || [], tags), + dateRange ?? new DateRange(null, null) + ); + }), + map((data: Page) => { + this.count = data.totalRecords; + this.dataLoading = false; + return new MatTableDataSource(data.items); + }) + ); + + projects: ProjectSummary[] = []; + projects$ = this.projectsService.getAllSummaries().pipe(tap((x) => (this.projects = x))); + + // #addIpRangesDialog template variables + selectedProject = ''; + + private screenSize$ = this.bpObserver.observe([ + Breakpoints.XSmall, + Breakpoints.Small, + Breakpoints.Large, + Breakpoints.XLarge, + ]); + + public displayColumns$ = this.screenSize$.pipe( + map((screen: BreakpointState) => { + if (screen.breakpoints[Breakpoints.XSmall]) return ['select', 'cidr', 'hosts', 'project', 'menu']; + else if (screen.breakpoints[Breakpoints.Small]) return ['select', 'cidr', 'hosts', 'project', 'tags', 'menu']; + else if (screen.breakpoints[Breakpoints.Medium]) return ['select', 'cidr', 'hosts', 'project', 'tags', 'menu']; + return this.displayedColumns; + }) + ); + + constructor( + private bpObserver: BreakpointObserver, + private projectsService: ProjectsService, + private ipRangesService: IpRangesService, + private ipRangesInteractor: IpRangesInteractionsService, + private toastr: ToastrService, + private tagsService: TagsService, + public dialog: MatDialog, + private titleService: Title, + @Inject(TableFiltersSourceBase) private filtersSource: TableFiltersSource + ) { + this.titleService.setTitle($localize`:IP ranges list page title|:IP Ranges`); + } + + buildFilters(stringFilters: string[], tags: Tag[]): any { + const SEPARATOR = ':'; + const NEGATING_CHAR = '-'; + const filterObject: any = {}; + const includedTags = []; + const contains = []; + const ips = []; + const projects = []; + let blocked: boolean | null = null; + + for (const filter of stringFilters) { + if (filter.indexOf(SEPARATOR) === -1) continue; + + const keyValuePair = filter.split(SEPARATOR); + + if (keyValuePair.length !== 2) continue; + + let key = keyValuePair[0].trim().toLowerCase(); + const value = keyValuePair[1].trim().toLowerCase(); + const negated = key.length > 0 && key[0] === NEGATING_CHAR; + if (negated) key = key.substring(1); + + if (!key || !value) continue; + + switch (key) { + case 'project': + const project = this.projects.find((c) => c.name.trim().toLowerCase() === value.trim().toLowerCase()); + if (project) projects.push(project.id); + else + this.toastr.warning( + $localize`:Project does not exist|The given project name is not known to the application:Project name not recognized` + ); + break; + case 'ip': + if (value) ips.push(value.trim().toLowerCase()); + break; + case 'tags': + const tag = tags.find((t) => t.text.trim().toLowerCase() === value.trim().toLowerCase()); + if (tag) includedTags.push(tag._id); + else + this.toastr.warning( + $localize`:Tag does not exist|The given tag is not known to the application:Tag not recognized` + ); + break; + case 'is': + switch (value) { + case 'blocked': + blocked = !negated; + break; + } + break; + case 'contains': + if (value) contains.push(value.trim()); + break; + } + } + + if (hasGlobalProjectFilter()) projects.push(getGlobalProjectFilter()?.id); + + if (includedTags?.length) filterObject['tags'] = includedTags; + if (ips?.length) filterObject['ips'] = ips; + if (contains?.length) filterObject['contains'] = contains; + if (projects?.length) filterObject['projects'] = projects; + if (blocked !== null) filterObject['blocked'] = blocked; + return filterObject; + } + + openNewIpRangesDialog(templateRef: TemplateRef) { + this.dialog.open(templateRef, { + restoreFocus: false, + minWidth: '50%', + }); + } + + async saveNewIpRanges() { + if (!this.selectedProject) { + this.toastr.warning($localize`:Missing project|The data selected is missing the project id:Missing project`); + return; + } + + if (this.newIpRanges.length == 0) { + this.toastr.warning( + $localize`:Add ip range to save|The data selected is missing the new ip ranges:Add IP ranges before saving` + ); + return; + } + + try { + const addedIpRanges = await this.ipRangesService.add(this.selectedProject, this.newIpRanges); + this.toastr.success($localize`:Changes saved|Changes to item saved successfully:Changes saved successfully`); + + if (addedIpRanges.length < this.newIpRanges.length) { + this.toastr.warning( + $localize`:IP ranges duplicates|Some ip ranges were duplicates to the database:Some ip ranges were duplicates` + ); + } + + this.newIpRanges = []; + + this.dialog.closeAll(); + this.refresh$.next(null); + this.selectedProject = ''; + } catch (err: any) { + if (err.status === HttpStatus.BadRequest) { + this.toastr.error( + $localize`:Check ip range format|Error while submitting the new ip ranges to the backend. Most likely an ip range formatting error:Error submitting ip ranges, check formats` + ); + } else { + throw err; + } + } + } + + dateFilter(event: MouseEvent) { + event.stopPropagation(); + this.startDate = new Date(Date.now() - defaultNewTimeMs); + } + + public async deleteBatch(ipRanges: IpRange[]) { + const result = await this.ipRangesInteractor.deleteBatch(ipRanges, this.projects); + if (result) { + this.selection.clear(); + this.refresh$.next(null); + } + } + + public async blockBatch(ipRanges: IpRange[]) { + const result = await this.ipRangesInteractor.blockBatch(ipRanges, this.projects); + if (result) { + this.selection.clear(); + this.refresh$.next(null); + } + } + + public async block(ipRangeId: string, block: boolean) { + const result = await this.ipRangesInteractor.block(ipRangeId, block); + if (result) { + this.selection.clear(); + this.refresh$.next(null); + } + } + + public generateMenuItem = (element: IpRange): ElementMenuItems[] => { + if (!element) return []; + const menuItems: ElementMenuItems[] = []; + + menuItems.push({ + action: () => this.block(element._id, !element.blocked), + icon: element.blocked ? 'thumb_up ' : 'block', + label: element.blocked + ? $localize`:Unblock ip range|Unblock ip range:Unblock` + : $localize`:Block ip range|Block ip range:Block`, + }); + + menuItems.push({ + action: () => this.deleteBatch([element]), + icon: 'delete', + label: $localize`:Delete ip range|Delete ip range:Delete`, + }); + + return menuItems; + }; +} diff --git a/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.html b/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.html new file mode 100644 index 00000000..0addab7e --- /dev/null +++ b/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.html @@ -0,0 +1,147 @@ +@if (ipRange$ | async) { +
+ + + + @if (ipRange.blocked) { + + } +
+ +
+
+
+ + open_in_new + + + + + + +
+
+

IP

+
{{ ipRangeExt.ip }}
+
+
+

Short mask

+
{{ ipRangeExt.shortMask }}
+
+
+

Long mask

+
{{ ipRangeExt.longMask }}
+
+
+

Min IP

+
{{ ipRangeExt.minIp }}
+
+
+

Max IP

+
{{ ipRangeExt.maxIp }}
+
+
+

IP count

+
{{ ipRangeExt.ipCount }}
+
+
+
+
+
+ +
+ +
+
+ +
+ @if (ipRange.blocked) { + + Blocked + + {{ ipRange.blockedAt | timeAgo }} + + + } + + Last seen + + {{ ipRange.lastSeen | timeAgo }} + + + + First seen + + {{ ipRange.createdAt | timeAgo }} + + + + @if ((tagsSelectItems$ | async) && mergedTags$ | async; as ipRangeTags) { + + Tags + + — + + + + +
+ @for (tag of ipRangeTags; track tag) { + {{ + (tagsSelectItems$ | async | whereId: [tag])?.text + }} + } + +
+ + @if (!ipRangeTags.length && !newPillTag.isNew()) { + No tags yet + + } +
+ } + + + + + +
+ + + +
+
+
+
+
+} diff --git a/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.scss b/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.scss new file mode 100644 index 00000000..2694ae09 --- /dev/null +++ b/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.scss @@ -0,0 +1,67 @@ +:host { + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + display: flex; + flex-direction: column; + align-items: stretch; + padding: 16px; + padding-top: 0; +} + +.content-wrapper { + box-sizing: border-box; + display: grid; + grid-template-columns: 1fr 200px; + width: 100%; + gap: var(--normal-gap-size); + align-self: center; +} + +.show-all-button-wrapper { + display: flex; + justify-content: center; + + .show-all-button { + margin-top: 8px; + opacity: 0.6; + } +} + +.context { + display: flex; + flex-direction: column; + gap: var(--normal-gap-size); +} + +panel-section-title { + width: 100%; + display: flex; + .manage-tags-menu { + font-size: 0.9em; + font-style: italic; + display: inline-flex; + width: 100%; + app-text-select-menu { + margin-left: 3px; + width: 100%; + } + } +} + +.metric-title { + opacity: 0.9; + font-size: 0.8rem; +} + +.metric-info { + font-size: 20px; +} + +.host-count:hover { + mat-icon { + opacity: 1; + } +} diff --git a/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.ts b/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.ts new file mode 100644 index 00000000..f3a31579 --- /dev/null +++ b/packages/frontend/stalker-app/src/app/modules/ip-ranges/view-ip-range/view-ip-range.component.ts @@ -0,0 +1,250 @@ +import { CommonModule } from '@angular/common'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnDestroy, ViewChild } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDialog } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatListModule } from '@angular/material/list'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatTableModule } from '@angular/material/table'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { Title } from '@angular/platform-browser'; +import { ActivatedRoute, Router, RouterModule } from '@angular/router'; +import { ToastrService } from 'ngx-toastr'; +import { + BehaviorSubject, + Observable, + Subject, + combineLatest, + firstValueFrom, + map, + merge, + shareReplay, + switchMap, + tap, +} from 'rxjs'; +import { IpRangesService } from '../../../api/ip-ranges/ip-ranges.service'; +import { ProjectsService } from '../../../api/projects/projects.service'; +import { TagsService } from '../../../api/tags/tags.service'; +import { AppHeaderComponent } from '../../../shared/components/page-header/page-header.component'; +import { PanelSectionModule } from '../../../shared/components/panel-section/panel-section.module'; +import { SharedModule } from '../../../shared/shared.module'; +import { Domain } from '../../../shared/types/domain/domain.interface'; +import { DomainSummary } from '../../../shared/types/domain/domain.summary'; +import { IpRange } from '../../../shared/types/ip-range/ip-range.interface'; +import { Ipv4Subnet } from '../../../shared/types/ipv4-subnet'; +import { Port } from '../../../shared/types/ports/port.interface'; +import { ProjectSummary } from '../../../shared/types/project/project.summary'; +import { Tag } from '../../../shared/types/tag.type'; +import { BlockedPillTagComponent } from '../../../shared/widget/pill-tag/blocked-pill-tag.component'; +import { NewPillTagComponent } from '../../../shared/widget/pill-tag/new-pill-tag.component'; +import { PillTagComponent } from '../../../shared/widget/pill-tag/pill-tag.component'; +import { TextMenuComponent } from '../../../shared/widget/text-menu/text-menu.component'; +import { SelectItem } from '../../../shared/widget/text-select-menu/text-select-menu.component'; +import { NumberOfHostsMetric } from '../../dashboard/number-of-hosts-metric/number-of-hosts-metric.component'; +import { FindingsModule } from '../../findings/findings.module'; +import { IpRangesInteractionsService } from '../ip-ranges-interactions.service'; + +@Component({ + standalone: true, + imports: [ + CommonModule, + SharedModule, + MatCardModule, + MatIconModule, + MatListModule, + MatFormFieldModule, + MatTableModule, + MatPaginatorModule, + MatSidenavModule, + MatButtonModule, + MatInputModule, + MatProgressSpinnerModule, + MatMenuModule, + FormsModule, + FindingsModule, + RouterModule, + PanelSectionModule, + AppHeaderComponent, + MatTooltipModule, + BlockedPillTagComponent, + TextMenuComponent, + NumberOfHostsMetric, + PillTagComponent, + ], + selector: 'app-view-ipRange', + templateUrl: './view-ip-range.component.html', + styleUrls: ['./view-ip-range.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ViewIpRangeComponent implements OnDestroy { + public menuResizeObserver$?: ResizeObserver; + public hostFilters: { [key: string]: string | string[] } = {}; + + @ViewChild('newPillTag', { read: ElementRef, static: false }) + newPillTag!: NewPillTagComponent; + + @ViewChild('managementPanelSection', { read: ElementRef, static: false }) + set managementPanelSection(managementPanelSection: ElementRef) { + if (managementPanelSection && !this._managementPanelSection) { + this._managementPanelSection = managementPanelSection; + this.menuResizeObserver$ = new ResizeObserver((resize) => {}); + this.menuResizeObserver$.observe(this._managementPanelSection.nativeElement); + } + } + + _managementPanelSection!: ElementRef; + + public manageTags: string = $localize`:Manage Tags|Manage Tags:Manage Tags`; + public filterTags: string = $localize`:Filter Tags|Filter Tags:Filter Tags`; + public emptyTags: string = $localize`:No Tags|List of tags is empty:No Tags Available`; + public manageIpRangeText: string = $localize`:Manage IP range|Manage the IP range element:Manage IP range`; + + // Drawer + public currentDetailsId: string | null = null; + public selectedDomain: DomainSummary | null = null; + public domainDetails$: Observable | null = null; + public portDetails$: Observable | null = null; + public selectedItemCorrelationKey$ = new Subject(); + + projects: ProjectSummary[] = []; + projects$ = this.projectsService.getAllSummaries().pipe( + map((next: any[]) => { + const comp: ProjectSummary[] = []; + for (const project of next) { + comp.push({ id: project._id, name: project.name }); + } + this.projects = comp; + return this.projects; + }) + ); + + public ipRangeId$ = this.route.params.pipe(map((params) => params['id'] as string)); + public ipRangeId = ''; + public ipRange!: IpRange; + public ipRangeExt!: Ipv4Subnet; + + public ipRangeTagsCache: string[] = []; + + public ipRange$ = this.ipRangeId$.pipe( + switchMap((ipRangeId) => { + this.ipRangeId = ipRangeId; + return this.ipRangesService.get(ipRangeId); + }), + tap((ipRange) => { + this.ipRange = ipRange; + this.ipRangeExt = new Ipv4Subnet(ipRange.ip, ipRange.mask.toString()); + this.hostFilters = { + ranges: [ipRange.ip + '/' + ipRange.mask.toString()], + projects: [ipRange.projectId], + }; + this.titleService.setTitle($localize`:Ip Ranges page title|:IP Ranges · ${ipRange.ip}/${ipRange.mask}`); + this.ipRangeTagsCache = ipRange.tags ?? []; + }) + ); + + public ipRangeTagsSubject$ = new BehaviorSubject([]); + public ipRangeTags$ = this.ipRange$.pipe( + map((ipRange) => { + return ipRange.tags; + }) + ); + + allTags$ = this.tagsService.getAllTags().pipe(shareReplay(1)); + + public tagsSelectItems$ = combineLatest([this.ipRangeTags$, this.allTags$]).pipe( + map(([ipRangeTags, allTags]) => { + const tags: (Tag & SelectItem)[] = []; + for (const tag of allTags) { + if (ipRangeTags && ipRangeTags.includes(tag._id)) { + tags.push({ _id: tag._id, text: tag.text, color: tag.color, isSelected: true }); + } else { + tags.push({ _id: tag._id, text: tag.text, color: tag.color, isSelected: false }); + } + } + return tags; + }) + ); + + public mergedTags$ = merge(this.ipRangeTagsSubject$, this.ipRangeTags$); + + public shownDomainsCount$ = new BehaviorSubject(5); + + /** + * + * @param item A SelectItem, but contains all the attributes of a Tag. + */ + public async itemSelected(item: SelectItem) { + try { + const tagId = item['_id']; + if (!this.ipRangeId) return; + const tagIndex = this.ipRangeTagsCache.findIndex((tag: string) => tag === tagId); + + if (tagIndex === -1 && item.color !== undefined) { + // Tag not found, adding it + await this.ipRangesService.tag(this.ipRangeId, tagId, true); + this.ipRangeTagsCache.push(tagId); + } else { + // Tag was found, removing it + await this.ipRangesService.tag(this.ipRangeId, tagId, false); + this.ipRangeTagsCache.splice(tagIndex, 1); + } + this.ipRangeTagsSubject$.next(this.ipRangeTagsCache); + } catch (err) { + this.toastr.error($localize`:Error while tagging|Error while tagging an item:Error while tagging`); + } + } + + ngOnDestroy(): void { + if (this.menuResizeObserver$) { + this.menuResizeObserver$.unobserve(this._managementPanelSection.nativeElement); + } + } + + public async delete() { + const result = await this.ipRangesInteractor.deleteBatch([this.ipRange], this.projects); + if (result) { + this.router.navigate(['/ip-ranges']); + } + } + + public async block(block: boolean) { + const result = await this.ipRangesInteractor.block(this.ipRangeId, block); + if (result) { + const h = await firstValueFrom(this.ipRangesService.get(this.ipRangeId)); + this.ipRange.blocked = h.blocked; + this.ipRange.blockedAt = h.blockedAt; + this.cdr.markForCheck(); + } + } + + public openHosts() { + const url = this.router.serializeUrl( + this.router.createUrlTree(['/hosts/'], { + queryParams: { + f: `-is: blocked+project: ${this.projects.find((p) => p.id === this.ipRange.projectId)?.name}+range: ${this.ipRange.ip}/${this.ipRange.mask}`, + }, + }) + ); + window.open(url); + } + + constructor( + private route: ActivatedRoute, + private projectsService: ProjectsService, + private ipRangesService: IpRangesService, + private ipRangesInteractor: IpRangesInteractionsService, + private tagsService: TagsService, + private titleService: Title, + private toastr: ToastrService, + private router: Router, + public dialog: MatDialog, + private cdr: ChangeDetectorRef + ) {} +} diff --git a/packages/frontend/stalker-app/src/app/modules/jobs/launch-jobs/launch-jobs.component.ts b/packages/frontend/stalker-app/src/app/modules/jobs/launch-jobs/launch-jobs.component.ts index 9497b6e1..94871f08 100644 --- a/packages/frontend/stalker-app/src/app/modules/jobs/launch-jobs/launch-jobs.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/jobs/launch-jobs/launch-jobs.component.ts @@ -240,6 +240,6 @@ export class LaunchJobsComponent implements AfterViewInit { private filterJob(entry: JobListEntry, filter: string) { const parts = [entry.name]; - return normalizeSearchString(parts.join(' ')).includes(filter); + return normalizeSearchString(parts.join(' ')).includes(normalizeSearchString(filter)); } } diff --git a/packages/frontend/stalker-app/src/app/modules/jobs/subscriptions/list-subscriptions.component.ts b/packages/frontend/stalker-app/src/app/modules/jobs/subscriptions/list-subscriptions.component.ts index 7aba989f..11c90b64 100644 --- a/packages/frontend/stalker-app/src/app/modules/jobs/subscriptions/list-subscriptions.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/jobs/subscriptions/list-subscriptions.component.ts @@ -15,7 +15,6 @@ import { Title } from '@angular/platform-browser'; import { RouterModule } from '@angular/router'; import { BehaviorSubject, combineLatest, map, shareReplay, switchMap, tap } from 'rxjs'; import { SubscriptionService, SubscriptionType } from '../../../api/jobs/subscriptions/subscriptions.service'; -import { AvatarComponent } from '../../../shared/components/avatar/avatar.component'; import { CronSubscription, EventSubscription, @@ -44,7 +43,6 @@ import { subscriptionTypes } from './subscription-templates'; imports: [ CommonModule, RouterModule, - AvatarComponent, MatIconModule, MatTableModule, MatPaginatorModule, diff --git a/packages/frontend/stalker-app/src/app/modules/ports/list-ports/list-ports.component.html b/packages/frontend/stalker-app/src/app/modules/ports/list-ports/list-ports.component.html index bf576480..593fe5f9 100644 --- a/packages/frontend/stalker-app/src/app/modules/ports/list-ports/list-ports.component.html +++ b/packages/frontend/stalker-app/src/app/modules/ports/list-ports/list-ports.component.html @@ -26,6 +26,7 @@ [negatableFilterOptions]="['is']" [dateSearchEnabled]="true" [startDate]="startDate" + [filterType]="'grammar'" > + + + Service + + {{ element.service }} + + + + + + Product + + {{ element.product }} + + + + + + Version + + {{ element.version }} + + + Host diff --git a/packages/frontend/stalker-app/src/app/modules/ports/list-ports/list-ports.component.ts b/packages/frontend/stalker-app/src/app/modules/ports/list-ports/list-ports.component.ts index aa83ff3e..59ab1498 100644 --- a/packages/frontend/stalker-app/src/app/modules/ports/list-ports/list-ports.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/ports/list-ports/list-ports.component.ts @@ -14,17 +14,15 @@ import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { Title } from '@angular/platform-browser'; import { RouterModule } from '@angular/router'; import { ToastrService } from 'ngx-toastr'; -import { BehaviorSubject, combineLatest, map, shareReplay, switchMap, tap } from 'rxjs'; +import { BehaviorSubject, catchError, combineLatest, EMPTY, map, shareReplay, switchMap, tap } from 'rxjs'; import { HostsService } from '../../../api/hosts/hosts.service'; import { PortsService } from '../../../api/ports/ports.service'; import { ProjectsService } from '../../../api/projects/projects.service'; import { TagsService } from '../../../api/tags/tags.service'; import { ProjectCellComponent } from '../../../shared/components/project-cell/project-cell.component'; import { SharedModule } from '../../../shared/shared.module'; -import { DomainSummary } from '../../../shared/types/domain/domain.summary'; -import { ExtendedPort, Port } from '../../../shared/types/ports/port.interface'; +import { Port } from '../../../shared/types/ports/port.interface'; import { ProjectSummary } from '../../../shared/types/project/project.summary'; -import { Tag } from '../../../shared/types/tag.type'; import { ElementMenuItems } from '../../../shared/widget/dynamic-icons/menu-icon.component'; import { FilteredPaginatedTableComponent } from '../../../shared/widget/filtered-paginated-table/filtered-paginated-table.component'; import { @@ -37,11 +35,7 @@ import { TableFormatComponent } from '../../../shared/widget/filtered-paginated- import { BlockedPillTagComponent } from '../../../shared/widget/pill-tag/blocked-pill-tag.component'; import { defaultNewTimeMs } from '../../../shared/widget/pill-tag/new-pill-tag.component'; import { PillTagComponent } from '../../../shared/widget/pill-tag/pill-tag.component'; -import { - getGlobalProjectFilter, - globalProjectFilter$, - hasGlobalProjectFilter, -} from '../../../utils/global-project-filter'; +import { appendGlobalFiltersToQuery, globalProjectFilter$ } from '../../../utils/global-project-filter'; import { PortsInteractionsService } from '../ports-interactions.service'; @Component({ @@ -82,31 +76,39 @@ import { PortsInteractionsService } from '../ports-interactions.service'; }) export class ListPortsComponent { dataLoading = true; - displayedColumns: string[] = ['select', 'port', 'ip', 'domains', 'project', 'tags', 'menu']; - filterOptions: string[] = ['host', 'port', 'project', 'tags', 'is']; + displayedColumns: string[] = [ + 'select', + 'port', + 'service', + 'product', + 'version', + 'ip', + 'domains', + 'project', + 'tags', + 'menu', + ]; + filterOptions: string[] = ['host', 'port', 'service', 'product', 'version', 'project', 'tags', 'is']; public readonly noDataMessage = $localize`:No port found|No port was found:No port found`; - selection = new SelectionModel(true, []); + selection = new SelectionModel(true, []); startDate: Date | null = null; allTags$ = this.tagsService.getAllTags().pipe(shareReplay(1)); private refresh$ = new BehaviorSubject(null); - public ports$ = combineLatest([ - this.filtersSource.debouncedFilters$, - this.allTags$, - this.refresh$, - globalProjectFilter$, - ]).pipe( - switchMap(([{ filters, dateRange, pagination }, tags]) => { - return this.portsService.getPage( - pagination?.page ?? 0, - pagination?.pageSize ?? 25, - this.buildFilters(filters, tags), - dateRange, - 'extended' - ); - }), + public ports$ = combineLatest([this.filtersSource.debouncedFilters$, this.refresh$, globalProjectFilter$]).pipe( + switchMap(([{ filters, dateRange, pagination }]) => + this.portsService + .getPage( + pagination?.page ?? 0, + pagination?.pageSize ?? 25, + appendGlobalFiltersToQuery(filters[0]), + dateRange, + 'extended' + ) + .pipe(catchError(() => EMPTY)) + ), shareReplay(1) ); @@ -156,73 +158,6 @@ export class ListPortsComponent { this.titleService.setTitle($localize`:Ports list page title|:Ports`); } - buildFilters(stringFilters: string[], tags: Tag[]): any { - const SEPARATOR = ':'; - const NEGATING_CHAR = '-'; - const filterObject: any = {}; - const includedTags = []; - const ports = []; - const hosts = []; - const projects = []; - let blocked: boolean | null = null; - - for (const filter of stringFilters) { - if (filter.indexOf(SEPARATOR) === -1) continue; - - const keyValuePair = filter.split(SEPARATOR); - - if (keyValuePair.length !== 2) continue; - - let key = keyValuePair[0].trim().toLowerCase(); - const value = keyValuePair[1].trim().toLowerCase(); - const negated = key.length > 0 && key[0] === NEGATING_CHAR; - if (negated) key = key.substring(1); - - if (!key || !value) continue; - - switch (key) { - case 'project': - const project = this.projects.find((c) => c.name.trim().toLowerCase() === value.trim().toLowerCase()); - if (project) projects.push(project.id); - else - this.toastr.warning( - $localize`:Project does not exist|The given project name is not known to the application:Project name not recognized` - ); - break; - case 'host': - if (value) hosts.push(value.trim().toLowerCase()); - break; - case 'tags': - const tag = tags.find((t) => t.text.trim().toLowerCase() === value.trim().toLowerCase()); - if (tag) includedTags.push(tag._id); - else - this.toastr.warning( - $localize`:Tag does not exist|The given tag is not known to the application:Tag not recognized` - ); - break; - case 'port': - ports.push(value); - break; - case 'is': - switch (value) { - case 'blocked': - blocked = !negated; - break; - } - break; - } - } - - if (hasGlobalProjectFilter()) projects.push(getGlobalProjectFilter()?.id); - - if (includedTags?.length) filterObject['tags'] = includedTags; - if (ports?.length) filterObject['ports'] = ports; - if (hosts?.length) filterObject['hosts'] = hosts; - if (projects?.length) filterObject['projects'] = projects; - if (blocked !== null) filterObject['blocked'] = blocked; - return filterObject; - } - dateFilter(event: MouseEvent) { event.stopPropagation(); this.startDate = new Date(Date.now() - defaultNewTimeMs); diff --git a/packages/frontend/stalker-app/src/app/modules/ports/view-port/view-port.component.html b/packages/frontend/stalker-app/src/app/modules/ports/view-port/view-port.component.html index 5b4ba48a..5d1e676d 100644 --- a/packages/frontend/stalker-app/src/app/modules/ports/view-port/view-port.component.html +++ b/packages/frontend/stalker-app/src/app/modules/ports/view-port/view-port.component.html @@ -78,8 +78,28 @@ Service - @if (port$ | async) { + @if ((port$ | async) && port.service) { {{ port.service }} + } @else { + - + } + + + + Product + @if ((port$ | async) && port.product) { + {{ port.product }} + } @else { + - + } + + + + Version + @if ((port$ | async) && port.version) { + {{ port.version }} + } @else { + - } diff --git a/packages/frontend/stalker-app/src/app/modules/ports/view-port/view-port.component.ts b/packages/frontend/stalker-app/src/app/modules/ports/view-port/view-port.component.ts index 00ebbb55..8a6c12fb 100644 --- a/packages/frontend/stalker-app/src/app/modules/ports/view-port/view-port.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/ports/view-port/view-port.component.ts @@ -142,7 +142,13 @@ export class ViewPortComponent implements OnDestroy { const size = page >= 0 ? 100 : 5; page = page < 0 ? 0 : page; - return this.portsService.getPage(page, size, { hostId: host._id }, undefined, 'number'); + return this.portsService.getPage( + page, + size, + [{ type: 'host.id', value: host._id, not: false }], + undefined, + 'number' + ); }), scan((acc: Page, value: Page) => { const found = new Set(); diff --git a/packages/frontend/stalker-app/src/app/modules/projects/edit-projects/edit-projects.component.html b/packages/frontend/stalker-app/src/app/modules/projects/edit-projects/edit-projects.component.html index 41e889fd..801b1b1f 100644 --- a/packages/frontend/stalker-app/src/app/modules/projects/edit-projects/edit-projects.component.html +++ b/packages/frontend/stalker-app/src/app/modules/projects/edit-projects/edit-projects.component.html @@ -1,4 +1,10 @@ - +
+ + +
@if ((routeSub$ | async) || true) { @@ -26,176 +32,6 @@

Project Informatio

- - - - - add_circle_outline - - -
-
- - IP Address - - - IP Address is invalid - - - - - First IP - - -
- -
- - Short Mask - - The mask is invalid - - - - Last IP - - -
- -
- - Long Mask - - The mask is invalid - - - - IP address count - - -
-
- -
- -
-
- - @for (range of ipRanges.controls; track range; let i = $index) { - - @if (i !== 0) { - - - @if (!range.valid && triedSubmitFailed) { - error_outline - } - - -
-
{{ range.get('minIp')?.value }} – {{ range.get('maxIp')?.value }}
- -
-
-
- } - - @if (i !== 0) { -
-
- - IP Address - - - IP Address is invalid - - - - - First IP - - -
- -
- - Short Mask - - The mask is invalid - - - Last IP - - -
- -
- - Long Mask - - The mask is invalid - - - IP address count - - -
-
- } -
- } -
diff --git a/packages/frontend/stalker-app/src/app/modules/projects/edit-projects/edit-projects.component.ts b/packages/frontend/stalker-app/src/app/modules/projects/edit-projects/edit-projects.component.ts index 47174b0f..c608cd7b 100644 --- a/packages/frontend/stalker-app/src/app/modules/projects/edit-projects/edit-projects.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/projects/edit-projects/edit-projects.component.ts @@ -1,37 +1,27 @@ -import { Component, OnDestroy } from '@angular/core'; -import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormControl, Validators } from '@angular/forms'; +import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core'; +import { UntypedFormBuilder, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { Title } from '@angular/platform-browser'; import { ActivatedRoute, Router } from '@angular/router'; import { ToastrService } from 'ngx-toastr'; -import { Subscription, combineLatest, debounceTime, filter, firstValueFrom, map, merge, switchMap, tap } from 'rxjs'; +import { Subscription, firstValueFrom, map, switchMap, tap } from 'rxjs'; +import { Md5 } from 'ts-md5'; import { ProjectsService } from '../../../api/projects/projects.service'; import { HttpStatus } from '../../../shared/types/http-status.type'; -import { Ipv4Subnet } from '../../../shared/types/ipv4-subnet'; import { Project } from '../../../shared/types/project/project.interface'; import { ConfirmDialogComponent, ConfirmDialogData, } from '../../../shared/widget/confirm-dialog/confirm-dialog.component'; -import { Md5 } from 'ts-md5'; +import { setGlobalProjectFilter } from '../../../utils/global-project-filter'; @Component({ selector: 'app-edit-projects', templateUrl: './edit-projects.component.html', styleUrls: ['./edit-projects.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class EditProjectsComponent implements OnDestroy { - ipRanges = this.fb.array([ - this.fb.group({ - ip: ['', { validators: [this.ipValidator] }], - maxIp: [{ value: '', disabled: true }], - minIp: [{ value: '', disabled: true }], - longMask: ['', { validators: [this.longMaskValidator] }], - shortMask: ['', { validators: [this.shortMaskValidator] }], - ipCount: [{ value: '', disabled: true }], - }), - ]); - form = this.fb.group({ name: [ '', @@ -40,8 +30,6 @@ export class EditProjectsComponent implements OnDestroy { }, ], notes: [''], - ipRanges: this.ipRanges, - frequency: [0, []], }); public fileSelected = false; @@ -54,101 +42,6 @@ export class EditProjectsComponent implements OnDestroy { private md5Logo = ''; - private generateSubnetFormGroup(ipv4Subnet: Ipv4Subnet) { - return this.fb.group({ - ip: [ipv4Subnet.ip, { validators: [this.ipValidator] }], - maxIp: [{ value: ipv4Subnet.maxIp, disabled: true }], - minIp: [{ value: ipv4Subnet.minIp, disabled: true }], - longMask: [ipv4Subnet.longMask, { validators: [this.longMaskValidator] }], - shortMask: [ipv4Subnet.shortMask, { validators: [this.shortMaskValidator] }], - ipCount: [{ value: ipv4Subnet.ipCount, disabled: true }], - }); - } - - private generateSubnetSubscription(subnetControl: AbstractControl, line: number) { - const ip$ = subnetControl.get('ip')?.valueChanges.pipe( - debounceTime(200), - map((a: string) => { - this.triedSubmitFailed = false; - return a ? a.trim() : ''; - }), - filter((x) => { - return x === '' || Ipv4Subnet.isValidIp(x); - }), - map((a) => { - return { ip: a, line: line }; - }) - ); - const shortMask$ = subnetControl.get('shortMask')?.valueChanges.pipe( - debounceTime(200), - map((a: string) => { - this.triedSubmitFailed = false; - return a ? a.trim() : ''; - }), - filter((x: string) => { - return x === '' || Ipv4Subnet.isValidShortMask(x); - }) - ); - - const longMask$ = subnetControl.get('longMask')?.valueChanges.pipe( - debounceTime(200), - map((a: string) => { - this.triedSubmitFailed = false; - return a ? a.trim() : ''; - }), - filter((x: string) => { - return x === '' || Ipv4Subnet.isValidLongMask(x); - }) - ); - - if (ip$ && shortMask$ && longMask$) { - const mask$ = merge(shortMask$, longMask$); - - return combineLatest([ip$, mask$]) - .pipe( - map(([$a, $b]) => { - if (!$a.ip || !$b) { - if ($a.ip) { - return { - subnet: { ip: $a.ip, minIp: '', maxIp: '', ipCount: '', shortMask: '', longMask: '' }, - line: $a.line, - }; - } - if ($b) { - const masks = Ipv4Subnet.createMask($b); - return { - subnet: { - ip: '', - minIp: '', - maxIp: '', - ipCount: '', - shortMask: masks.shortMask, - longMask: masks.longMask, - }, - line: $a.line, - }; - } - return { - subnet: { ip: '', minIp: '', maxIp: '', ipCount: '', shortMask: '', longMask: '' }, - line: $a.line, - }; - } - return { subnet: new Ipv4Subnet($a.ip, $b), line: $a.line }; - }) - ) - .subscribe((subnetData) => { - const fa = this.form.controls['ipRanges'] as UntypedFormArray; - fa.controls[subnetData.line].get('minIp')?.setValue(subnetData.subnet.minIp); - fa.controls[subnetData.line].get('maxIp')?.setValue(subnetData.subnet.maxIp); - fa.controls[subnetData.line].get('ipCount')?.setValue(subnetData.subnet.ipCount); - fa.controls[subnetData.line].get('shortMask')?.setValue(subnetData.subnet.shortMask, { emitEvent: false }); - fa.controls[subnetData.line].get('longMask')?.setValue(subnetData.subnet.longMask, { emitEvent: false }); - }); - } - - return null; - } - public projectId$ = this.route.params.pipe(map((params) => params['id'])); public project$ = this.projectId$.pipe(switchMap((id) => this.projectsService.get(id))); @@ -159,34 +52,6 @@ export class EditProjectsComponent implements OnDestroy { map((project: Project) => { this.form.controls['name'].setValue(project.name); this.form.controls['notes'].setValue(project.notes); - const ranges = []; - - for (const range of project.ipRanges) { - const rangeSplit = range.split('/'); - ranges.push(new Ipv4Subnet(rangeSplit[0], '/' + rangeSplit[1])); - } - - const control = this.form.get('ipRanges') as UntypedFormArray; - - const subnetForm$ = this.generateSubnetSubscription(control.controls[0], 0); - if (subnetForm$) { - this.valueChangeSubscriptions.push(subnetForm$); - } - - ranges.forEach((x) => { - const group = this.generateSubnetFormGroup(x); - control.push(group); - const current = control.controls.length - 1; - const subnet$ = this.generateSubnetSubscription(control.controls[current], current); - if (subnet$) { - this.valueChangeSubscriptions.push(subnet$); - } - - group.controls['ip'].setValue(x.ip); - group.controls['shortMask'].setValue(x.shortMask); - }); - - this.form.controls['frequency'].setValue(project.dataRefreshFrequency); this.fileLoading = false; if (project.logo) { @@ -216,66 +81,6 @@ export class EditProjectsComponent implements OnDestroy { } } - public addSubnet() { - const ipRanges = this.form.controls['ipRanges'] as UntypedFormArray; - const newSubnetForm = ipRanges.controls[0]; - if (!newSubnetForm.valid) { - return; - } - const subnet = new Ipv4Subnet(newSubnetForm.get('ip')?.value, newSubnetForm.get('shortMask')?.value); - const newSubnetGroup = this.generateSubnetFormGroup(subnet); - - ipRanges.push(newSubnetGroup); - const current = ipRanges.controls.length - 1; - const subnet$ = this.generateSubnetSubscription(ipRanges.controls[current], current); - if (subnet$) { - this.valueChangeSubscriptions.push(subnet$); - } - newSubnetGroup.controls['ip'].setValue(newSubnetForm.get('ip')?.value); - newSubnetGroup.controls['shortMask'].setValue(newSubnetForm.get('shortMask')?.value); - - newSubnetForm.reset(); - } - - ipValidator(ip: UntypedFormControl) { - return Ipv4Subnet.isValidIp(ip.value) ? null : { error: 'Ip is not valid' }; - } - - shortMaskValidator(shortMask: UntypedFormControl) { - return Ipv4Subnet.isValidShortMask(shortMask.value) ? null : { error: 'Mask is not valid' }; - } - - longMaskValidator(longMask: UntypedFormControl) { - return Ipv4Subnet.isValidLongMask(longMask.value) ? null : { error: 'Mask is not valid' }; - } - - deleteSubnet($event: Event, line: number) { - $event.stopPropagation(); - const fa = this.form.controls['ipRanges'] as UntypedFormArray; - const subnet = fa.controls[line].get('ip')?.value + fa.controls[line].get('shortMask')?.value; - const list = [subnet]; - - const data: ConfirmDialogData = { - primaryButtonText: $localize`:Cancel|Cancel action:Cancel`, - dangerButtonText: $localize`:Delete|Delete item:Delete`, - title: $localize`:Deleting subnet|Deleting a project subnet:Deleting subnet`, - text: $localize`:Deleting subnet confirm|Confirmation text to delete a subnet:Do you really wish to delete the following subnet ?`, - listElements: list, - onPrimaryButtonClick: () => { - this.dialog.closeAll(); - }, - onDangerButtonClick: () => { - fa.removeAt(line); - this.dialog.closeAll(); - }, - }; - - this.dialog.open(ConfirmDialogComponent, { - data, - restoreFocus: false, - }); - } - async deleteProject() { const projectId = await firstValueFrom(this.projectId$); const data: ConfirmDialogData = { @@ -307,16 +112,6 @@ export class EditProjectsComponent implements OnDestroy { const projectId = await firstValueFrom(this.projectId$); const projectUpdates: Partial = {}; let formValid = this.form.controls['name'].valid; - const fa = this.form.controls['ipRanges'] as UntypedFormArray; - projectUpdates.ipRanges = []; - for (let i = 1; i < fa.length; ++i) { - formValid = formValid && fa.controls[i].valid; - const ip = fa.controls[i].get('ip')?.value; - const sm = fa.controls[i].get('shortMask')?.value; - if (ip && sm) { - projectUpdates.ipRanges.push(ip + sm); - } - } if (!formValid) { this.triedSubmitFailed = true; @@ -369,4 +164,10 @@ export class EditProjectsComponent implements OnDestroy { this.editLoading = false; } } + + public async setGlobalFilter() { + const p = await firstValueFrom(this.project$); + const gpf = { id: p._id, text: p.name }; + setGlobalProjectFilter(gpf); + } } diff --git a/packages/frontend/stalker-app/src/app/modules/websites/list-websites/list-websites.component.html b/packages/frontend/stalker-app/src/app/modules/websites/list-websites/list-websites.component.html index 1d4911b5..fdd6072f 100644 --- a/packages/frontend/stalker-app/src/app/modules/websites/list-websites/list-websites.component.html +++ b/packages/frontend/stalker-app/src/app/modules/websites/list-websites/list-websites.component.html @@ -59,6 +59,7 @@ [negatableFilterOptions]="['is']" [dateSearchEnabled]="true" [startDate]="startDate" + [filterType]="'grammar'" > @if ((viewStyle$ | async) === 'table') { + websites$ = combineLatest([this.filtersSource.debouncedFilters$, this.refresh$, globalProjectFilter$]).pipe( + switchMap(([{ filters, dateRange, pagination }]) => this.websitesService.getPage( pagination?.page ?? 0, pagination?.pageSize ?? 25, - this.buildFilters(filters, tags), + appendGlobalFiltersToQuery(filters[0]), dateRange ) ), @@ -217,83 +207,6 @@ export class ListWebsitesComponent { this.titleService.setTitle($localize`:Websites list page title|:Websites`); } - buildFilters(stringFilters: string[], tags: Tag[]): any { - const SEPARATOR = ':'; - const NEGATING_CHAR = '-'; - const filterObject: any = {}; - const includedTags = []; - const ports = []; - const hosts = []; - const domains = []; - const projects = []; - let blocked: boolean | null = null; - let merged: boolean | null = null; - - for (const filter of stringFilters) { - if (filter.indexOf(SEPARATOR) === -1) continue; - - const keyValuePair = filter.split(SEPARATOR); - - if (keyValuePair.length !== 2) continue; - - let key = keyValuePair[0].trim().toLowerCase(); - const value = keyValuePair[1].trim().toLowerCase(); - const negated = key.length > 0 && key[0] === NEGATING_CHAR; - if (negated) key = key.substring(1); - - if (!key || !value) continue; - - switch (key) { - case 'project': - const project = this.projects.find((c) => c.name.trim().toLowerCase() === value.trim().toLowerCase()); - if (project) projects.push(project.id); - else - this.toastr.warning( - $localize`:Project does not exist|The given project name is not known to the application:Project name not recognized` - ); - break; - case 'host': - if (value) hosts.push(value.trim().toLowerCase()); - break; - case 'domain': - if (value) domains.push(value.trim().toLowerCase()); - break; - case 'tags': - const tag = tags.find((t) => t.text.trim().toLowerCase() === value.trim().toLowerCase()); - if (tag) includedTags.push(tag._id); - else - this.toastr.warning( - $localize`:Tag does not exist|The given tag is not known to the application:Tag not recognized` - ); - break; - case 'port': - ports.push(value); - break; - case 'is': - switch (value) { - case 'blocked': - blocked = !negated; - break; - case 'merged': - merged = !negated; - break; - } - break; - } - } - - if (hasGlobalProjectFilter()) projects.push(getGlobalProjectFilter()?.id); - - if (includedTags?.length) filterObject['tags'] = includedTags; - if (ports?.length) filterObject['ports'] = ports; - if (hosts?.length) filterObject['hosts'] = hosts; - if (domains?.length) filterObject['domains'] = domains; - if (projects?.length) filterObject['projects'] = projects; - if (blocked !== null) filterObject['blocked'] = blocked; - if (merged !== null) filterObject['merged'] = merged; - return filterObject; - } - dateFilter(event: MouseEvent) { event.stopPropagation(); this.startDate = new Date(Date.now() - defaultNewTimeMs); diff --git a/packages/frontend/stalker-app/src/app/modules/websites/view-website/view-website.component.ts b/packages/frontend/stalker-app/src/app/modules/websites/view-website/view-website.component.ts index fd2a6821..58027a9d 100644 --- a/packages/frontend/stalker-app/src/app/modules/websites/view-website/view-website.component.ts +++ b/packages/frontend/stalker-app/src/app/modules/websites/view-website/view-website.component.ts @@ -161,7 +161,7 @@ export class ViewWebsiteComponent implements OnDestroy { return !website.mergedInId; }), switchMap(([website, page]) => { - return this.websitesService.getPage(page, 5, { mergedInId: website._id }); + return this.websitesService.getPage(page, 5, [{ type: 'mergedIn.id', value: website._id }]); }), scan((acc: Page, value: Page) => { acc.items = acc.items.concat(value.items); diff --git a/packages/frontend/stalker-app/src/app/shared/components/header/header.component.ts b/packages/frontend/stalker-app/src/app/shared/components/header/header.component.ts index 0fc7dfbb..c6cd44be 100644 --- a/packages/frontend/stalker-app/src/app/shared/components/header/header.component.ts +++ b/packages/frontend/stalker-app/src/app/shared/components/header/header.component.ts @@ -1,15 +1,19 @@ import { CommonModule } from '@angular/common'; -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { ActivatedRoute, Router } from '@angular/router'; -import { map, Observable } from 'rxjs'; +import { ActivatedRoute, Router, RouterModule } from '@angular/router'; +import { map, Observable, Subscription } from 'rxjs'; import { AuthService } from '../../../api/auth/auth.service'; import { ProjectsService } from '../../../api/projects/projects.service'; import { ThemeService } from '../../../services/theme.service'; -import { getGlobalProjectFilter, setGlobalProjectFilter } from '../../../utils/global-project-filter'; +import { + getGlobalProjectFilter, + globalProjectFilter$, + setGlobalProjectFilter, +} from '../../../utils/global-project-filter'; import { SharedModule } from '../../shared.module'; import { ProjectSummary } from '../../types/project/project.summary'; import { PillTagComponent } from '../../widget/pill-tag/pill-tag.component'; @@ -28,11 +32,12 @@ import { AvatarComponent } from '../avatar/avatar.component'; MatMenuModule, MatButtonModule, PillTagComponent, + RouterModule, ], templateUrl: './header.component.html', styleUrls: ['./header.component.scss'], }) -export class HeaderComponent implements OnInit { +export class HeaderComponent implements OnInit, OnDestroy { public filterProjects: string = $localize`:Filter projects|Filter projects:Filter projects`; public emptyProjects: string = $localize`:No projects yet|List of projects is empty:No projects yet`; @@ -45,6 +50,7 @@ export class HeaderComponent implements OnInit { public currentLanguageLocale = ''; public email = ''; public selectedProject: SelectItem | undefined; + public externalFilterSet$!: Subscription; public readonly languages: { locale: string; @@ -80,9 +86,18 @@ export class HeaderComponent implements OnInit { if (globalProjectFilter) { this.selectedProject = { ...globalProjectFilter, isSelected: true }; } + + this.externalFilterSet$ = globalProjectFilter$.subscribe((filter) => { + this.selectedProject = filter ? { isSelected: true, text: filter.text } : undefined; + this.selectProject(this.selectedProject, false); + }); } } + ngOnDestroy(): void { + if (this.externalFilterSet$) this.externalFilterSet$.unsubscribe(); + } + toggleSideBar() { this.toggleSideBarEvent.emit(); } @@ -112,9 +127,9 @@ export class HeaderComponent implements OnInit { ); } - selectProject(project: SelectItem | undefined) { + selectProject(project: SelectItem | undefined, emit = true) { this.selectedProject = project; - setGlobalProjectFilter(project as SelectItem & ProjectSummary); + if (emit) setGlobalProjectFilter(project as SelectItem & ProjectSummary); } clearProject() { diff --git a/packages/frontend/stalker-app/src/app/shared/components/ip-range-accordion/ip-range-accordion.component.html b/packages/frontend/stalker-app/src/app/shared/components/ip-range-accordion/ip-range-accordion.component.html new file mode 100644 index 00000000..5de65f14 --- /dev/null +++ b/packages/frontend/stalker-app/src/app/shared/components/ip-range-accordion/ip-range-accordion.component.html @@ -0,0 +1,175 @@ +
+ + + + add_circle_outline + + +
+
+ + IP Address + + IP Address is invalid + + + + First IP + + +
+ +
+ + Short Mask + + The mask is invalid + + + + Last IP + + +
+ +
+ + Long Mask + + The mask is invalid + + + + IP address count + + +
+
+ +
+ +
+
+ + @for (range of _ipRangesForm.controls; track range; let i = $index) { + @if (i !== 0) { + + + + @if (!range.valid && inErrorState) { + error_outline + } + + +
+
{{ range.get('minIp')?.value }} – {{ range.get('maxIp')?.value }}
+ +
+
+
+ +
+
+ + IP Address + + + IP Address is invalid + + + + + First IP + + +
+ +
+ + Short Mask + + The mask is invalid + + + Last IP + + +
+ +
+ + Long Mask + + The mask is invalid + + + IP address count + + +
+
+
+ } + } +
+
diff --git a/packages/frontend/stalker-app/src/app/shared/components/ip-range-accordion/ip-range-accordion.component.ts b/packages/frontend/stalker-app/src/app/shared/components/ip-range-accordion/ip-range-accordion.component.ts new file mode 100644 index 00000000..233e7aab --- /dev/null +++ b/packages/frontend/stalker-app/src/app/shared/components/ip-range-accordion/ip-range-accordion.component.ts @@ -0,0 +1,270 @@ +import { CommonModule } from '@angular/common'; +import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, Output, signal } from '@angular/core'; +import { + AbstractControl, + FormBuilder, + FormGroup, + FormsModule, + ReactiveFormsModule, + UntypedFormArray, + UntypedFormControl, +} from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { combineLatest, debounceTime, filter, map, merge, startWith, Subscription, tap } from 'rxjs'; +import { SharedModule } from '../../shared.module'; +import { IpRange } from '../../types/ip-range/ip-range.interface'; +import { Ipv4Subnet } from '../../types/ipv4-subnet'; + +@Component({ + standalone: true, + imports: [ + CommonModule, + MatFormFieldModule, + ReactiveFormsModule, + MatExpansionModule, + MatIconModule, + FormsModule, + SharedModule, + MatInputModule, + MatButtonModule, + MatFormFieldModule, + ], + selector: 'ip-range-accordion', + templateUrl: 'ip-range-accordion.component.html', + styles: ` + .error-bang { + margin-right: 10px; + } + mat-panel-title { + label { + cursor: pointer; + } + } + + mat-panel-description { + margin-right: 0px; + } + + .border { + border-style: solid; + border-color: var(--mdc-outlined-text-field-outline-color); + border-width: 1px 1px 1px 1px; + border-radius: 4px; + margin-top: -1px; + } + + .border-opened { + margin-top: var(--mat-expansion-panel-spacing); + } + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class IpRangeAccordionComponent implements OnDestroy { + @Input() inErrorState: boolean = false; + private _ipRanges: Pick[] = []; + @Input() set ipRanges(ranges: Pick[]) { + this._ipRanges = ranges; + this.clearSubscriptions(); + this._ipRangesForm.controls = this._ipRangesForm.controls.slice(0, 1); + + for (const range of ranges) { + const subnet = new Ipv4Subnet(range.ip, range.mask.toString()); + const newSubnetGroup = this.generateSubnetFormGroup(subnet); + + this._ipRangesForm.push(newSubnetGroup, { emitEvent: false }); + } + + for (let i = 0; i < this._ipRangesForm.controls.length; ++i) { + let subnetForm$ = this.generateSubnetObservable(this._ipRangesForm.controls[i], i); + if (subnetForm$) { + if (i > 0) { + subnetForm$ = subnetForm$.pipe( + tap((subnetData) => { + this._ipRanges[subnetData.line - 1].ip = subnetData.subnet.ip; + this._ipRanges[subnetData.line - 1].mask = Number(subnetData.subnet.shortMask); + }) + ); + } + const subscription$ = subnetForm$.subscribe((subnetData) => { + const fa = this.form.controls['ipRanges'] as UntypedFormArray; + fa.controls[subnetData.line].get('minIp')?.setValue(subnetData.subnet.minIp); + fa.controls[subnetData.line].get('maxIp')?.setValue(subnetData.subnet.maxIp); + fa.controls[subnetData.line].get('ipCount')?.setValue(subnetData.subnet.ipCount); + fa.controls[subnetData.line].get('shortMask')?.setValue(subnetData.subnet.shortMask, { emitEvent: false }); + fa.controls[subnetData.line].get('longMask')?.setValue(subnetData.subnet.longMask, { emitEvent: false }); + }); + this.valueChangeSubscriptions.push(subscription$); + } + } + } + @Output() ipRangesChange = new EventEmitter[]>(); + + readonly openedPanelIndex = signal(0); + readonly closedPanelIndex = signal(undefined); + + public valueChangeSubscriptions: Subscription[] = []; + + _ipRangesForm = this.fb.array([this.generateAddSubnetForm()]); + + form = this.fb.group({ + ipRanges: this._ipRangesForm, + }); + + constructor(private fb: FormBuilder) {} + + private generateAddSubnetForm() { + return this.fb.group({ + ip: ['', { validators: [this.ipValidator] }], + maxIp: [{ value: '', disabled: true }], + minIp: [{ value: '', disabled: true }], + longMask: ['', { validators: [this.longMaskValidator] }], + shortMask: ['', { validators: [this.shortMaskValidator] }], + ipCount: [{ value: '', disabled: true }], + }); + } + + private generateSubnetFormGroup(ipv4Subnet: Ipv4Subnet) { + return this.fb.group({ + ip: [ipv4Subnet.ip, { validators: [this.ipValidator] }], + maxIp: [{ value: ipv4Subnet.maxIp, disabled: true }], + minIp: [{ value: ipv4Subnet.minIp, disabled: true }], + longMask: [ipv4Subnet.longMask, { validators: [this.longMaskValidator] }], + shortMask: [ipv4Subnet.shortMask, { validators: [this.shortMaskValidator] }], + ipCount: [{ value: ipv4Subnet.ipCount.toString(), disabled: true }], + }); + } + + ipValidator(ip: UntypedFormControl) { + return Ipv4Subnet.isValidIp(ip.value) ? null : { error: 'Ip is not valid' }; + } + + shortMaskValidator(shortMask: UntypedFormControl) { + return Ipv4Subnet.isValidShortMask(shortMask.value) ? null : { error: 'Mask is not valid' }; + } + + longMaskValidator(longMask: UntypedFormControl) { + return Ipv4Subnet.isValidLongMask(longMask.value) ? null : { error: 'Mask is not valid' }; + } + + formValueToIpRange(formGroup: FormGroup): Pick { + const ip = formGroup.get('ip')?.value ?? ''; + const mask = formGroup.get('shortMask')?.value ?? ''; + return { ip: ip.toString(), mask: Number(mask.toString()) }; + } + + updateSubnets(includeNew: boolean = true) { + const ipRanges = this.form.controls['ipRanges']; + + const currentRanges: Pick[] = []; + + for (let i = 0; i < ipRanges.length; ++i) { + if (i === 0 && !includeNew) continue; + if (!ipRanges.controls[i].valid) return; + currentRanges.push(this.formValueToIpRange(ipRanges.controls[i])); + } + + this.ipRangesChange.next(currentRanges); + + if (includeNew) { + ipRanges.controls[0].reset(); + } + } + + removeSubnet(index: number) { + this._ipRanges.splice(index - 1, 1); + this._ipRangesForm.controls.splice(index, 1); + } + + private generateSubnetObservable(subnetControl: AbstractControl, line: number) { + const ip$ = subnetControl.get('ip')?.valueChanges.pipe( + startWith(this._ipRangesForm.controls[line].value?.ip ?? ''), + debounceTime(200), + map((a: string) => { + this.inErrorState = false; + return a ? a.trim() : ''; + }), + filter((x) => { + return x === '' || Ipv4Subnet.isValidIp(x); + }), + map((a) => { + return { ip: a, line: line }; + }) + ); + const shortMask$ = subnetControl.get('shortMask')?.valueChanges.pipe( + startWith(this._ipRangesForm.controls[line].value?.shortMask ?? ''), + debounceTime(200), + map((a: string) => { + this.inErrorState = false; + return a ? a.trim() : ''; + }), + filter((x: string) => { + return x === '' || Ipv4Subnet.isValidShortMask(x); + }) + ); + + const longMask$ = subnetControl.get('longMask')?.valueChanges.pipe( + startWith(this._ipRangesForm.controls[line].value?.longMask ?? ''), + debounceTime(200), + map((a: string) => { + this.inErrorState = false; + return a ? a.trim() : ''; + }), + filter((x: string) => { + return x === '' || Ipv4Subnet.isValidLongMask(x); + }) + ); + + if (ip$ && shortMask$ && longMask$) { + const mask$ = merge(shortMask$, longMask$); + + return combineLatest([ip$, mask$]).pipe( + map(([$a, $b]) => { + if (!$a.ip || !$b) { + if ($a.ip) { + return { + subnet: { ip: $a.ip, minIp: '', maxIp: '', ipCount: '', shortMask: '', longMask: '' }, + line: $a.line, + }; + } + if ($b) { + const masks = Ipv4Subnet.createMask($b); + return { + subnet: { + ip: '', + minIp: '', + maxIp: '', + ipCount: '', + shortMask: masks.shortMask, + longMask: masks.longMask, + }, + line: $a.line, + }; + } + return { + subnet: { ip: '', minIp: '', maxIp: '', ipCount: '', shortMask: '', longMask: '' }, + line: $a.line, + }; + } + return { subnet: new Ipv4Subnet($a.ip, $b), line: $a.line }; + }) + ); + } + + return null; + } + + clearSubscriptions() { + for (const s of this.valueChangeSubscriptions) { + s.unsubscribe(); + } + this.valueChangeSubscriptions = []; + } + + ngOnDestroy(): void { + this.clearSubscriptions(); + } +} diff --git a/packages/frontend/stalker-app/src/app/shared/components/sidebar/sidebar.component.html b/packages/frontend/stalker-app/src/app/shared/components/sidebar/sidebar.component.html index ab289192..0066cadf 100644 --- a/packages/frontend/stalker-app/src/app/shared/components/sidebar/sidebar.component.html +++ b/packages/frontend/stalker-app/src/app/shared/components/sidebar/sidebar.component.html @@ -3,6 +3,8 @@ @for (section of sections; track $index) { @if (expanded && section.name) {

{{ section.name }}

+ } @else if (!expanded && $index !== 0) { + } @for (item$ of section.items; track $index) { @@ -17,11 +19,12 @@

{{ section.name }}

[matTooltip]="expanded ? '' : item.name" [matTooltipShowDelay]="700" matTooltipPosition="right" + class="padright" > } @else { -