diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index faf5130..0000000 --- a/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -/**/*.js -node_modules -lib -.eslintrc.json -__tests__ -servers diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 99c9a49..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,386 +0,0 @@ -{ - "globals": { - "NodeJS": true - }, - "env": { - "browser": false, - "es6": true, - "node": true - }, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": "./tsconfig.json", - "sourceType": "module", - "ecmaVersion": "latest" - }, - "plugins": [ - "import", - "check-file", - "@typescript-eslint", - "eslint-plugin-prettier", - "@typescript-eslint/eslint-plugin", - "sort-class-members" - ], - "extends": [ - "eslint-config-prettier", - "plugin:import/recommended", - "plugin:import/typescript", - "plugin:prettier/recommended", - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking", - "plugin:@typescript-eslint/strict", - "prettier" - ], - "settings": { - "import/resolver": { - "node": { - "extensions": [ - ".ts", - ".d.ts" - ] - } - }, - "import/parsers": { - "@typescript-eslint/parser": [ - ".ts" - ] - } - }, - "rules": { - "array-callback-return": 2, - "class-methods-use-this": 0, - "check-file/folder-match-with-fex": [ - 2, - { - "*.test.{js,ts}": "**/__tests__/**" - } - ], - "check-file/filename-naming-convention": [ - 2, - { - "**/!{migrations}**/!(*.d).{js,ts}": "CAMEL_CASE", - "**/*.d.{ts}": "CAMEL_CASE" - } - ], - "check-file/folder-naming-convention": [ - 2, - { - "src/**/": "CAMEL_CASE" - } - ], - "consistent-return": 2, - "default-case": 2, - "default-case-last": 2, - "default-param-last": 2, - "dot-notation": 2, - "eqeqeq": 2, - "import/no-cycle": 2, - "import/prefer-default-export": 2, - "import/no-absolute-path": 2, - "import/no-extraneous-dependencies": 2, - "import/no-unresolved": 0, - "import/order": [ - "error", - { - "groups": [ - [ - "external" - ], - [ - "index", - "sibling", - "parent" - ], - "type" - ], - "newlines-between": "ignore", - "alphabetize": { - "caseInsensitive": true, - "order": "asc" - }, - "pathGroups": [ - { - "group": "external", - "pattern": "react", - "position": "before" - }, - { - "group": "external", - "pattern": "@my_org/**", - "position": "after" - } - ], - "pathGroupsExcludedImportTypes": [ - "builtin" - ] - } - ], - "max-classes-per-file": 2, - "no-await-in-loop": 2, - "no-bitwise": 2, - "no-class-assign": 2, - "no-cond-assign": 2, - "no-else-return": 2, - "no-empty": 2, - "no-empty-function": 2, - "no-eq-null": 2, - "no-eval": 2, - "no-confusing-arrow": 2, - "no-constant-condition": 2, - "no-constructor-return": 0, - "no-empty-pattern": 2, - "no-func-assign": 2, - "no-implicit-coercion": 0, - "no-implicit-globals": 2, - "no-implied-eval": 2, - "no-import-assign": 2, - "no-lone-blocks": 2, - "no-invalid-this": 2, - "no-magic-numbers": 0, - "no-multi-str": 2, - "no-new-func": 2, - "no-new-wrappers": 2, - "no-non-null-assertion": 0, - "no-unused-vars": 0, - "no-param-reassign": 2, - "no-plusplus": 0, - "no-restricted-modules": 2, - "no-return-await": 2, - "no-setter-return": 2, - "no-shadow": 0, - "no-this-before-super": 2, - "no-throw-literal": 2, - "no-trailing-spaces": 2, - "no-underscore-dangle": 0, - "no-unexpected-multiline": 2, - "no-unreachable": 2, - "no-unsafe-negation": 2, - "no-use-before-define": 2, - "no-octal": 2, - "no-redeclare": 2, - "no-regex-spaces": 2, - "no-return-assign": 2, - "no-script-url": 2, - "no-self-compare": 2, - "no-sequences": 2, - "no-shadow-restricted-names": 2, - "no-unused-expressions": 0, - "no-unused-labels": 2, - "no-useless-call": 2, - "no-useless-concat": 2, - "no-useless-constructor": 2, - "no-useless-escape": 2, - "no-useless-rename": 2, - "no-useless-return": 2, - "no-void": 2, - "no-var": 2, - "object-curly-newline": [ - 2, - { - "consistent": true - } - ], - "object-shorthand": 2, - "prefer-const": 2, - "prefer-arrow-callback": 2, - "prefer-destructuring": [ - 2, - { - "object": true, - "array": false - } - ], - "prefer-exponentiation-operator": 2, - "prefer-numeric-literals": 2, - "prefer-object-spread": 2, - "prefer-promise-reject-errors": 2, - "prefer-regex-literals": 2, - "prefer-rest-params": 2, - "prefer-spread": 2, - "prefer-template": 2, - "prettier/prettier": 2, - "require-atomic-updates": 0, - "require-jsdoc": 2, - "require-unicode-regexp": 2, - "require-yield": 2, - "sort-class-members/sort-class-members": [ - 2, - { - "order": [ - "[public-static-property]", - "[protected-static-property]", - "[private-static-property]", - - "[public-property]", - "[protected-property]", - "[private-property]", - - "constructor", - - { - "type": "method", - "name": "/^get.+$/", - "sort": "alphabetical" - }, - { - "type": "method", - "name": "/^set.+$/", - "sort": "alphabetical" - }, - - "[public-method]", - "[protected-method]", - "[private-method]" - ], - "groups": { - "getterSetterPair": [ - { - "type": "method", - "name": "/^get.+$/" - }, - { - "type": "method", - "name": "/^set.+$/" - } - ] - }, - "accessorPairPositioning": "getThenSet" - } - ], - "spaced-comment": 2, - "strict": 2, - "semi": 2, - "use-isnan": 2, - "valid-typeof": 2, - "quotes": [ - 2, - "single", - { - "avoidEscape": true - } - ], - "@typescript-eslint/consistent-type-assertions": [ - 2, - { - "assertionStyle": "as" - } - ], - "@typescript-eslint/consistent-type-definitions": [ - "error", - "interface" - ], - "@typescript-eslint/consistent-type-imports": [ - 2, - { - "prefer": "type-imports", - "disallowTypeAnnotations": false - } - ], - "@typescript-eslint/explicit-function-return-type": 2, - "@typescript-eslint/explicit-module-boundary-types": 2, - "@typescript-eslint/naming-convention": [ - 2, - { - "selector": "interface", - "format": [ - "PascalCase" - ], - "custom": { - "regex": "^I[A-Z]", - "match": true - } - }, - { - "selector": "enum", - "format": [ - "PascalCase" - ], - "custom": { - "regex": "^E[A-Z]", - "match": true - } - }, - { - "selector": "variable", - "format": [ - "camelCase", - "PascalCase" - ] - }, - { - "selector": "variable", - "modifiers": [ - "destructured" - ], - "format": null - }, - { - "selector": "classProperty", - "modifiers": [ - "private" - ], - "format": [ - "camelCase" - ], - "leadingUnderscore": "require" - }, - { - "selector": "typeLike", - "format": [ - "PascalCase" - ] - }, - { - "selector": "variable", - "format": [ - "camelCase" - ] - } - ], - "@typescript-eslint/no-dynamic-delete": 0, - "@typescript-eslint/no-empty-interface": 2, - "@typescript-eslint/no-empty-function": 0, - "@typescript-eslint/no-explicit-any": 2, - "@typescript-eslint/no-extraneous-class": 0, - "@typescript-eslint/no-non-null-assertion": 0, - "@typescript-eslint/no-shadow": 2, - "@typescript-eslint/no-unnecessary-condition": 0, - "@typescript-eslint/no-unsafe-member-access": 2, - "@typescript-eslint/no-unused-expressions": 0, - "@typescript-eslint/no-unused-vars": [ - 2, - { - "argsIgnorePattern": "^_", - "varsIgnorePattern": "^_" - } - ], - "@typescript-eslint/no-misused-promises": [ - "error", - { - "checksVoidReturn": false - } - ], - "@typescript-eslint/no-this-alias": [ - 2, - { - "allowedNames": [ - "self" - ] - } - ], - "@typescript-eslint/no-var-requires": 2, - "@typescript-eslint/prefer-nullish-coalescing": 2, - "@typescript-eslint/semi": [ - "error" - ], - "@typescript-eslint/typedef": 2, - "@typescript-eslint/unbound-method": [ - 2, - { - "ignoreStatic": true - } - ] - } -} diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 6642ba4..da57879 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -7,14 +7,6 @@ body: attributes: value: Before submitting new issue, please make sure similar problem/idea hasn't been already submitted by someone else. - - type: textarea - id: timeWhenOccurred - attributes: - label: Time when occurred - placeholder: Try to provide time and date. For example '15.02.2024 ~08:00' - validations: - required: true - - type: textarea id: reproducibility attributes: @@ -23,24 +15,6 @@ body: validations: required: true - - type: dropdown - attributes: - multiple: false - label: Does this problem occurs while you are logged in ? - options: - - "Yes" - - "No" - validations: - required: true - - - type: textarea - id: client - attributes: - label: Client - description: What did you use when this problem occurred ? Web client from our repo ? Custom client ? API utility like postman ? - validations: - required: true - - type: textarea id: stepsToReproduce attributes: diff --git a/.github/workflows/actions.yaml b/.github/workflows/actions.yaml index 459be1d..a5de276 100644 --- a/.github/workflows/actions.yaml +++ b/.github/workflows/actions.yaml @@ -30,8 +30,8 @@ jobs: - name: Install dependencies run: npm install - test: - needs: [] + lint: + needs: [install] runs-on: ubuntu-latest container: @@ -52,11 +52,12 @@ jobs: restore-keys: | ${{ runner.OS }}-node- - - name: Run tests - run: npm run test + - name: Lint + run: npm run lint + + build: + needs: [lint] - lint: - needs: [] runs-on: ubuntu-latest container: @@ -77,13 +78,14 @@ jobs: restore-keys: | ${{ runner.OS }}-node- - - name: Lint - run: npm run lint + - name: Build + run: npm run build - build: - needs: [test, lint] + audit: + needs: [lint] runs-on: ubuntu-latest + continue-on-error: true container: image: node:18 @@ -92,9 +94,6 @@ jobs: - name: Checkout code uses: actions/checkout@v2 - - name: Install dependencies - run: npm install - - name: Cache node modules uses: actions/cache@v2 with: @@ -103,5 +102,5 @@ jobs: restore-keys: | ${{ runner.OS }}-node- - - name: Build - run: npm run build + - name: Audit + run: npm install && npm audit diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index da167ee..faf78ce --- a/.gitignore +++ b/.gitignore @@ -1,42 +1,30 @@ -# Logs -logs -*.log -npm-debug.log* - -# Dependencies -node_modules/ - -# Coverage -coverage - -# VS Code -.vscode - -# JetBrains IDEs -.idea/ - -# Optional npm cache directory -.npm -yarn.lock -package-lock.json - -# Optional eslint cache -.eslintcache - -# Misc -.env.local -.env.development.local -.env.test.local -.env.production.local - -yarn-debug.log* -yarn-error.log* -/.temp_img/* -/.temp_audio/* -/.VSCodeCounter - -tsconfig.tsbuildinfo -.DS_Store - -# Production -lib +# Dependencies +node_modules/ + +# VS Code +.vscode +!.vscode/tasks.js + +# JetBrains IDEs +.idea/ + +# Optional npm cache directory +.npm +yarn.lock +tsconfig.tsbuildinfo + +# Optional eslint cache +.eslintcache + +# Misc +.DS_Store + +yarn-debug.log* +yarn-error.log* + +# Compiled code +lib + +# Tsconfig cache +tsconfig.tsbuildinfo +tsconfig.release.tsbuildinfo diff --git a/.prettierrc b/.prettierrc old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md old mode 100644 new mode 100755 index f93be8c..5f9fb4b --- a/README.md +++ b/README.md @@ -534,4 +534,4 @@ await client.connect({ } }) await client.connect() -``` +``` \ No newline at end of file diff --git a/__tests__/application/index.test.ts b/__tests__/application/index.test.ts deleted file mode 100644 index 34dd2b0..0000000 --- a/__tests__/application/index.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { describe, expect, it } from '@jest/globals'; -import Websocket from 'ws'; -import MocSocket, { type IClient } from '../../src'; -import { ClientNotOpen, NoServer } from '../../src/errors'; -import { WsServer } from '../../src/modules/servers'; - -describe('Tests', () => { - describe('Should throw', () => { - describe('No data passed', () => { - it(`Missing server`, async () => { - let error: Error | undefined = undefined - let mock: WsServer | undefined; - - try { - // @ts-ignore - mock = MocSocket.createWsClient(); - } catch (err) { - error = err as Error - } - - expect(error!.message).toEqual(new NoServer().message); - expect(mock).toEqual(undefined); - }); - - it(`Client not open`, async () => { - let error: Error = new Error(); - - const server = new Websocket.Server({ - noServer: true, - }); - const mock = MocSocket.createWsClient(server); - const client = mock.createClient(); - - try { - client.sendMessage('test'); - } catch (err) { - error = err as Error; - } - - expect(error.message).toEqual(new ClientNotOpen().message); - }); - }); - }); - - describe('Should pass', () => { - let server: Websocket.Server; - let mock: WsServer; - let client: IClient; - - beforeEach(() => { - server = new Websocket.Server({ - noServer: true, - }); - mock = MocSocket.createWsClient(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect, send message and receive 1 back`, async () => { - server.on('connection', (ws) => { - ws.on('message', () => ws.send(JSON.stringify({ userId: 1 }))); - }); - - await client.connect(); - const callback = await client.sendAsyncMessage('Test'); - - expect(callback).toEqual({ userId: 1 }); - }); - }); -}); diff --git a/__tests__/jest.config.default.ts b/__tests__/jest.config.default.ts deleted file mode 100644 index a94ef3e..0000000 --- a/__tests__/jest.config.default.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { defaults } from 'jest-config'; -import type { Config } from 'jest'; - -const config: Config = { - verbose: true, - moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'], - testPathIgnorePatterns: ['build'], - preset: 'ts-jest', - testMatch: ['**/*.test.ts'], - testEnvironment: 'node', - forceExit: true, - clearMocks: true, - testTimeout: 10000 -}; - -export default config; diff --git a/__tests__/socketIo/basicServer/client.test.ts b/__tests__/socketIo/basicServer/client.test.ts deleted file mode 100644 index 94c34cd..0000000 --- a/__tests__/socketIo/basicServer/client.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import MocSocket from '../../../src'; -import { SocketIoServer } from '../../../src/modules/servers'; -import { Server as IoServer } from 'socket.io' -import Server from '../../../servers/io/basicServer' -import { IIoClient } from '../../../types'; -import { sleep } from '../../utils' - -describe('SocketIo - Basic server - client', () => { - describe('Should pass', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: IIoClient; - const options = { - transports: ['websocket'], - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let closed: boolean = false - await client.connect({ options }); - - client.onClose(() => { - closed = true - }) - - await client.disconnect() - - expect(closed).toBeTruthy() - }); - - it(`Connect, generate listeners and get message`, async () => { - const messages: unknown[] = [] - - await client.connect({ options }); - client.on('messages', (m: unknown) => { - messages.push(m) - }) - client.sendMessage('message', 'test') - await sleep(500) - - expect(messages.length).toBeGreaterThan(0) - }); - - it(`Connect, generate listeners and wait for response`, async () => { - await client.connect({ options }); - const callback = await client.sendAsyncMessage('message', 'test', 'messages') - - expect(callback).not.toBeUndefined() - }); - }); -}); diff --git a/__tests__/socketIo/basicServer/simpleClient.test.ts b/__tests__/socketIo/basicServer/simpleClient.test.ts deleted file mode 100644 index fdb0cbc..0000000 --- a/__tests__/socketIo/basicServer/simpleClient.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import MocSocket from '../../../src'; -import { SocketIoServer } from '../../../src/modules/servers'; -import { Server as IoServer } from 'socket.io' -import Server from '../../../servers/io/basicServer' -import { ISimpleIoClient } from '../../../types'; -import { sleep } from '../../utils' - -describe('SocketIo - Basic server - simple client', () => { - describe('Should pass', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: ISimpleIoClient; - const options = { - transports: ['websocket'], - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createSimpleClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let closed: boolean = false - - client.connect(options); - client.onOpen(() => { - client.disconnect() - }) - client.onClose(() => { - closed = true - }) - - await sleep(200) - - expect(closed).toBeTruthy() - }); - - it(`Connect, generate listeners and get message`, async () => { - const messages: unknown[] = [] - client.connect(options); - - client.onOpen(() => { - client.sendMessage('message', 'test') - }) - client.on('messages', (m: unknown) => { - messages.push(m) - }) - await sleep(500) - - expect(messages.length).toBeGreaterThan(0) - }); - }); -}); diff --git a/__tests__/socketIo/cookieAuth/client.test.ts b/__tests__/socketIo/cookieAuth/client.test.ts deleted file mode 100644 index 7f48562..0000000 --- a/__tests__/socketIo/cookieAuth/client.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import MocSocket from '../../../src'; -import { SocketIoServer } from '../../../src/modules/servers'; -import { Server as IoServer } from 'socket.io' -import Server from '../../../servers/io/serverWithCookieAuth' -import { IIoClient } from '../../../types'; - -describe('SocketIo - Cookie auth server - client', () => { - describe('Should fail', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: IIoClient; - const options = { - transports: ['websocket'], - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let error: Error | undefined = undefined - - try { - await client.connect({ options }); - } catch (err) { - error = err as Error - } - - expect(error).not.toBeUndefined() - }); - }) - - describe('Should pass', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: IIoClient; - const options = { - transports: ['websocket'], - extraHeaders: { - cookie: 'randomId=123;' - } - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let closed: boolean = false - await client.connect({ options }); - - client.onClose(() => { - closed = true - }) - - await client.disconnect() - - expect(closed).toBeTruthy() - }); - }); -}); diff --git a/__tests__/socketIo/cookieAuth/simpleClient.test.ts b/__tests__/socketIo/cookieAuth/simpleClient.test.ts deleted file mode 100644 index 7fdfdab..0000000 --- a/__tests__/socketIo/cookieAuth/simpleClient.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import MocSocket from '../../../src'; -import { SocketIoServer } from '../../../src/modules/servers'; -import { Server as IoServer } from 'socket.io' -import Server from '../../../servers/io/serverWithCookieAuth' -import { ISimpleIoClient } from '../../../types'; -import { sleep } from '../../utils' - -describe('SocketIo - Cookie auth server - simple client', () => { - describe('Should fail', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: ISimpleIoClient; - const options = { - transports: ['websocket'], - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createSimpleClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - const errors: Error[] = [] - client.connect(options); - - client.onError((e) => { - errors.push(e) - }) - - await sleep(200) - - expect(errors.length).toBeGreaterThan(0) - }); - }); - - describe('Should pass', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: ISimpleIoClient; - const options = { - transports: ['websocket'], - Headers: { - Cookie: 'randomId=123;' - } - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createSimpleClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let closed: boolean = false - client.connect(options); - - client.onOpen(async () => { - await sleep(200) - client.disconnect() - }) - client.onClose(() => { - closed = true - }) - - await sleep(1000) - - expect(closed).toBeTruthy() - }); - }); -}); diff --git a/__tests__/socketIo/headersAuth/client.test.ts b/__tests__/socketIo/headersAuth/client.test.ts deleted file mode 100644 index 4a73e93..0000000 --- a/__tests__/socketIo/headersAuth/client.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import MocSocket from '../../../src'; -import { SocketIoServer } from '../../../src/modules/servers'; -import { Server as IoServer } from 'socket.io' -import Server from '../../../servers/io/serverWithHeadersAuth' -import { IIoClient } from '../../../types'; - -describe('SocketIo - Headers auth server - client', () => { - describe('Should fail', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: IIoClient; - const options = { - transports: ['websocket'], - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let error: Error | undefined = undefined - - try { - await client.connect({ options }); - } catch (err) { - error = err as Error - } - - expect(error).not.toBeUndefined() - }); - }) - - describe('Should pass', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: IIoClient; - const options = { - transports: ['websocket'], - extraHeaders: { - Authorization: "Bearer varyLegitApiKey" - } - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let closed: boolean = false - const errors: Error[] = [] - await client.connect({ options }); - - client.onClose(() => { - closed = true - }) - client.onError(e => { - errors.push(e) - }) - - await client.disconnect() - - expect(errors.length).toEqual(0) - expect(closed).toBeTruthy() - }); - }); -}); diff --git a/__tests__/socketIo/headersAuth/simpleClient.test.ts b/__tests__/socketIo/headersAuth/simpleClient.test.ts deleted file mode 100644 index 1c308b9..0000000 --- a/__tests__/socketIo/headersAuth/simpleClient.test.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import MocSocket from '../../../src'; -import { SocketIoServer } from '../../../src/modules/servers'; -import { Server as IoServer } from 'socket.io' -import Server from '../../../servers/io/serverWithHeadersAuth' -import { ISimpleIoClient } from '../../../types'; -import { sleep } from '../../utils' - -describe('SocketIo - Headers auth server - simple client', () => { - describe('Should fail', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: ISimpleIoClient; - const options = { - transports: ['websocket'], - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createSimpleClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - const errors: Error[] = [] - client.connect(options); - - client.onError((e) => { - errors.push(e) - }) - - await sleep(200) - - expect(errors.length).toBeGreaterThan(0) - }); - }); - - describe('Should pass', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: ISimpleIoClient; - const options = { - transports: ['websocket'], - extraHeaders: { - Authorization: "Bearer varyLegitApiKey" - } - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createSimpleClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let closed: boolean = false - const errors: Error[] = [] - client.connect(options); - - client.onOpen(async () => { - await sleep(200) - client.disconnect() - }) - client.onError(e => { - errors.push(e) - }) - client.onClose(() => { - closed = true - }) - - await sleep(1000) - - expect(errors.length).toEqual(0) - expect(closed).toBeTruthy() - }); - }); -}); diff --git a/__tests__/socketIo/queryParams/client.test.ts b/__tests__/socketIo/queryParams/client.test.ts deleted file mode 100644 index e46ab4e..0000000 --- a/__tests__/socketIo/queryParams/client.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import MocSocket from '../../../src'; -import { SocketIoServer } from '../../../src/modules/servers'; -import { Server as IoServer } from 'socket.io' -import Server from '../../../servers/io/serverWithQueryParams' -import { IIoClient } from '../../../types'; - -describe('SocketIo - Query auth server - client', () => { - describe('Should fail', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: IIoClient; - const options = { - transports: ['websocket'] - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let error: Error | undefined = undefined - - try { - await client.connect({ options }); - } catch (err) { - error = err as Error - } - - expect(error).not.toBeUndefined() - }); - }) - - describe('Should pass', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: IIoClient; - const options = { - transports: ['websocket'], - query: { - "key": "abc" - } - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let closed: boolean = false - await client.connect({ options }); - - client.onClose(() => { - closed = true - }) - - await client.disconnect() - - expect(closed).toBeTruthy() - }); - }); -}); diff --git a/__tests__/socketIo/queryParams/simpleClient.test.ts b/__tests__/socketIo/queryParams/simpleClient.test.ts deleted file mode 100644 index 4b512da..0000000 --- a/__tests__/socketIo/queryParams/simpleClient.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { describe, it, expect } from '@jest/globals'; -import MocSocket from '../../../src'; -import { SocketIoServer } from '../../../src/modules/servers'; -import { Server as IoServer } from 'socket.io' -import Server from '../../../servers/io/serverWithQueryParams' -import { ISimpleIoClient } from '../../../types'; -import { sleep } from '../../utils' - -describe('SocketIo - Query auth server - simple client', () => { - describe('Should fail', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: ISimpleIoClient; - const options = { - transports: ['websocket'], - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createSimpleClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let err: Error | undefined = undefined - client.connect(options); - client.on('error', (e => { - console.log("Got err") - err = e as Error - })) - client.onError((e) => { - console.log("Got er 2") - err = e as Error - }) - - await sleep(200) - - expect(err).not.toBeUndefined() - }); - }); - - describe('Should pass', () => { - let server: IoServer; - let mock: SocketIoServer; - let client: ISimpleIoClient; - const options = { - transports: ['websocket'], - Headers: { - Authorization: "Bearer varyLegitApiKey" - } - } - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createSocketIoServer(server); - client = mock.createSimpleClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect and disconnect`, async () => { - let closed: boolean = false - client.connect(options); - - client.onOpen(async () => { - await sleep(200) - client.disconnect() - }) - client.onClose(() => { - closed = true - }) - - await sleep(1000) - - expect(closed).toBeTruthy() - }); - }); -}); diff --git a/__tests__/utils/index.ts b/__tests__/utils/index.ts deleted file mode 100644 index a0830da..0000000 --- a/__tests__/utils/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const sleep = async (amount: number = 2000): Promise => { - return new Promise(resolve => { - setTimeout(() => { - resolve() - }, amount) - }) -} diff --git a/__tests__/ws/basicServer/client.test.ts b/__tests__/ws/basicServer/client.test.ts deleted file mode 100644 index d4bfec7..0000000 --- a/__tests__/ws/basicServer/client.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { describe, expect, it } from '@jest/globals'; -import MocSocket, { type IClient } from '../../../src'; -import { WsServer } from '../../../src/modules/servers'; -import Server from '../../../servers/ws/basicServer' -import WebSocket from 'ws'; - -describe('WS - Basic server - client', () => { - describe('Should pass', () => { - let server: WebSocket.Server; - let mock: WsServer; - let client: IClient; - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createWsClient(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect, send message and receive information about connection`, async () => { - await client.connect(); - await client.sendAsyncMessage('test') - - expect(client.getLastMessages(1).length).toBeGreaterThan(0) - }); - - it(`Connect, send message and disconnect`, async () => { - await client.connect(); - await client.sendAsyncMessage('test') - client.disconnect() - - expect(client.getLastMessages(1).length).toBeGreaterThan(0) - }); - }); -}); diff --git a/__tests__/ws/cookieAuth/client.test.ts b/__tests__/ws/cookieAuth/client.test.ts deleted file mode 100644 index c995e37..0000000 --- a/__tests__/ws/cookieAuth/client.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { describe, expect, it } from '@jest/globals'; -import MocSocket, { type IClient } from '../../../src'; -import { WsServer } from '../../../src/modules/servers'; -import Server from '../../../servers/ws/serverWithCookieAuth' -import WebSocket from 'ws'; - -describe('WS - Cookie auth server - client', () => { - describe('Should pass', () => { - let server: WebSocket.Server; - let mock: WsServer; - let client: IClient; - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createWsClient(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect, send message and receive information about connection`, async () => { - await client.connect({ headers: { cookie: "randomId=VaryLegitAuthKey;" } }); - await client.sendAsyncMessage('test') - - expect(client.getLastMessages(1).length).toBeGreaterThan(0) - }); - - it(`Connect, send message and disconnect`, async () => { - await client.connect({ headers: { cookie: "randomId=VaryLegitAuthKey;" } }); - await client.sendAsyncMessage('test') - client.disconnect() - - expect(client.getLastMessages(1).length).toBeGreaterThan(0) - }); - }); -}); diff --git a/__tests__/ws/headersAuth/client.test.ts b/__tests__/ws/headersAuth/client.test.ts deleted file mode 100644 index 1119f13..0000000 --- a/__tests__/ws/headersAuth/client.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { describe, expect, it } from '@jest/globals'; -import MocSocket, { type IClient } from '../../../src'; -import { WsServer } from '../../../src/modules/servers'; -import Server from '../../../servers/ws/serverWithHeadersAuth' -import WebSocket from 'ws'; - -describe('WS - Headers auth server - client', () => { - describe('Should pass', () => { - let server: WebSocket.Server; - let mock: WsServer; - let client: IClient; - - beforeEach(() => { - const wsServer = new Server() - wsServer.init() - server = wsServer.getServer() - - mock = MocSocket.createWsClient(server); - client = mock.createClient(); - }); - - afterEach(() => { - mock.close(); - }); - - it(`Connect, send message and receive information about connection`, async () => { - await client.connect({ headers: { Authorization: `Bearer VaryRealisticAuthKey` } }); - await client.sendAsyncMessage('test') - - expect(client.getLastMessages(1).length).toBeGreaterThan(0) - }); - - it(`Connect, send message and disconnect`, async () => { - await client.connect({ headers: { Authorization: `Bearer VaryRealisticAuthKey` } }); - await client.sendAsyncMessage('test') - client.disconnect() - - expect(client.getLastMessages(1).length).toBeGreaterThan(0) - }); - }); -}); diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..5a50229 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,405 @@ +import { fixupConfigRules, fixupPluginRules } from "@eslint/compat"; +import _import from "eslint-plugin-import"; +import checkFile from "eslint-plugin-check-file"; +import typescriptEslint from '@typescript-eslint/eslint-plugin'; +import typescriptEslint_eslintPlugin from "@typescript-eslint/eslint-plugin"; +import prettier from "eslint-plugin-prettier"; +import sortClassMembers from "eslint-plugin-sort-class-members"; +import jsdoc from "eslint-plugin-jsdoc"; +import globals from "globals"; +import tsParser from "@typescript-eslint/parser"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import js from "@eslint/js"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all +}); + +export default [...fixupConfigRules(compat.extends( + "eslint-config-prettier", + "plugin:import/recommended", + "plugin:import/typescript", + "plugin:prettier/recommended", + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:@typescript-eslint/strict", + "prettier", +)).map(config => ({ + ...config, + files: ["src/**/*.ts", "src/**/**.*.json"], +})), { + files: ["src/**/*.ts", "ssrc/**/**.*.json"], + + plugins: { + import: fixupPluginRules(_import), + "check-file": checkFile, + "@typescript-eslint": fixupPluginRules(typescriptEslint), + prettier: fixupPluginRules(prettier), + "@typescript-eslint": fixupPluginRules(typescriptEslint_eslintPlugin), + "sort-class-members": sortClassMembers, + jsdoc, + }, + + languageOptions: { + globals: { + ...Object.fromEntries(Object.entries(globals.browser).map(([key]) => [key, "off"])), + ...globals.node, + NodeJS: true, + }, + + parser: tsParser, + ecmaVersion: "latest", + sourceType: "module", + + parserOptions: { + project: "./tsconfig.json", + parser: "@typescript-eslint/parser" + }, + }, + + settings: { + "import/resolver": { + node: { + extensions: [".ts", ".d.ts"], + }, + }, + + "import/parsers": { + espree: [".js", ".cjs", ".mjs", ".jsx"], + "@typescript-eslint/parser": [".ts"], + }, + }, + + rules: { + "array-callback-return": 2, + "class-methods-use-this": 0, + + "check-file/folder-match-with-fex": [2, { + "*.test.{js,ts}": "**/__tests__/**", + }], + + "check-file/filename-naming-convention": [2, { + "**/!{migrations}**/!(*.d).{js,ts}": "CAMEL_CASE", + "**/*.d.{ts}": "CAMEL_CASE", + }], + + "check-file/folder-naming-convention": [2, { + "src/**/": "CAMEL_CASE", + }], + + "consistent-return": 2, + "default-case": 2, + "default-case-last": 2, + "default-param-last": 2, + "dot-notation": 2, + eqeqeq: 2, + "import/extensions": [0, "ignorePackages"], + "import/default": 0, + "import/namespace": 0, + "import/no-named-as-default": 0, + "import/no-named-as-default-member": 0, + "import/no-cycle": 2, + "import/prefer-default-export": 2, + "import/no-absolute-path": 2, + "import/no-extraneous-dependencies": 2, + "import/no-unresolved": 0, + + "import/order": ["error", { + groups: [["external"], ["index", "sibling", "parent"], "type"], + "newlines-between": "ignore", + + alphabetize: { + caseInsensitive: true, + order: "asc", + }, + + pathGroups: [{ + group: "external", + pattern: "react", + position: "before", + }, { + group: "external", + pattern: "@my_org/**", + position: "after", + }], + + pathGroupsExcludedImportTypes: ["builtin"], + }], + + "jsdoc/check-access": 1, + "jsdoc/check-alignment": 1, + "jsdoc/check-indentation": 0, + "jsdoc/check-line-alignment": 1, + "jsdoc/check-param-names": 1, + "jsdoc/check-property-names": 1, + "jsdoc/check-tag-names": [1, + { + "definedTags": ["openapi"] + } + ], + "jsdoc/check-types": 1, + "jsdoc/check-values": 1, + "jsdoc/empty-tags": 1, + "jsdoc/implements-on-classes": 1, + "jsdoc/informative-docs": 1, + "jsdoc/no-bad-blocks": 1, + "jsdoc/no-blank-block-descriptions": 1, + "jsdoc/no-defaults": 1, + "jsdoc/no-multi-asterisks": 1, + "jsdoc/require-asterisk-prefix": 1, + "jsdoc/require-description": 1, + "jsdoc/require-description-complete-sentence": 1, + "jsdoc/require-jsdoc": 1, + "jsdoc/require-param": 1, + "jsdoc/require-param-description": 1, + "jsdoc/require-param-name": 1, + "jsdoc/require-property": 1, + "jsdoc/require-property-description": 1, + "jsdoc/require-property-name": 1, + "jsdoc/require-returns": 1, + "jsdoc/require-returns-check": 0, + "jsdoc/require-returns-description": 1, + "jsdoc/require-throws": 1, + "jsdoc/sort-tags": 1, + "jsdoc/tag-lines": 1, + "jsdoc/valid-types": 1, + "max-classes-per-file": 2, + "no-await-in-loop": 2, + "no-bitwise": 2, + "no-class-assign": 2, + "no-cond-assign": 2, + "no-else-return": 2, + "no-empty": 2, + "no-empty-function": 2, + "no-eq-null": 2, + "no-eval": 2, + "no-confusing-arrow": 2, + "no-constant-binary-expression": 0, + "no-constant-condition": 2, + "no-console": 0, + "no-constructor-return": 0, + "no-empty-pattern": 2, + "no-func-assign": 2, + "no-implicit-coercion": 0, + "no-implicit-globals": 2, + "no-implied-eval": 2, + "no-import-assign": 2, + "no-lone-blocks": 2, + "no-invalid-this": 0, + "no-magic-numbers": 0, + "no-multi-str": 2, + "no-new-func": 2, + "no-new-wrappers": 2, + "no-non-null-assertion": 0, + "no-param-reassign": 2, + "no-plusplus": 0, + "no-restricted-modules": 2, + "no-return-await": 2, + "no-setter-return": 2, + "no-shadow": 0, + "no-this-before-super": 2, + "no-throw-literal": 2, + "no-trailing-spaces": 2, + "no-underscore-dangle": 0, + "no-unexpected-multiline": 2, + "no-unreachable": 2, + "no-unsafe-negation": 2, + "no-use-before-define": 2, + "no-octal": 2, + "no-redeclare": 2, + "no-regex-spaces": 2, + "no-return-assign": 2, + "no-script-url": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-shadow-restricted-names": 2, + "no-unused-expressions": 0, + "no-unused-labels": 2, + "no-useless-call": 2, + "no-useless-concat": 2, + "no-useless-constructor": 2, + "no-useless-escape": 2, + "no-useless-rename": 2, + "no-useless-return": 2, + "no-void": 2, + "no-var": 2, + + "object-curly-newline": [2, { + consistent: true, + }], + + "object-shorthand": 2, + "prefer-const": 2, + "prefer-arrow-callback": 2, + + "prefer-destructuring": [2, { + object: true, + array: false, + }], + + "prefer-exponentiation-operator": 2, + "prefer-numeric-literals": 2, + "prefer-object-spread": 2, + "prefer-promise-reject-errors": 2, + "prefer-regex-literals": 2, + "prefer-rest-params": 2, + "prefer-spread": 2, + "prefer-template": 2, + "prettier/prettier": 2, + "require-atomic-updates": 0, + "require-unicode-regexp": 2, + "require-yield": 2, + "sort-class-members/sort-class-members": [ + 2, + { + "order": [ + "[protected-static-property]", + "[private-static-property]", + "[public-static-property]", + + "[conventional-private-properties]", + "[private-property]", + "[protected-property]", + "[public-property]", + "[properties]", + + "constructor", + + "[accessor-pairs]", + "[getters]", + "[setters]", + + { + type: "method", + name: "/^get.+$/", + sort: "alphabetical", + }, + { + type: "method", + name: "/^set.+$/", + sort: "alphabetical", + }, + + "[static-properties]", + "[static-methods]", + + "[methods]", + "[protected-method]", + "[conventional-private-methods]", + { + type: "method", + private: true, + sort: "alphabetical", + }, + "[private-methods]" + ], + "accessorPairPositioning": "getThenSet", + + accessorPairPositioning: "getThenSet", + stopAfterFirstProblem: false + }, + ], + + "spaced-comment": 2, + strict: 2, + semi: 2, + "use-isnan": 2, + "valid-typeof": 2, + + quotes: [2, "single", { + avoidEscape: true, + }], + + "@typescript-eslint/consistent-type-assertions": [2, { + assertionStyle: "as", + }], + + "@typescript-eslint/consistent-type-definitions": ["error", "interface"], + + "@typescript-eslint/consistent-type-imports": [2, { + prefer: "type-imports", + disallowTypeAnnotations: false, + }], + + "@typescript-eslint/explicit-function-return-type": 2, + "@typescript-eslint/explicit-module-boundary-types": 2, + + "@typescript-eslint/naming-convention": [2, { + selector: "interface", + format: ["PascalCase"], + + custom: { + regex: "^I[A-Z]", + match: true, + }, + }, { + selector: "enum", + format: ["PascalCase"], + + custom: { + regex: "^E[A-Z]", + match: true, + }, + }, { + selector: "variable", + format: ["camelCase", "PascalCase"], + }, { + selector: "variable", + modifiers: ["destructured"], + format: null, + }, { + selector: "classProperty", + modifiers: ["private"], + format: ["camelCase"], + leadingUnderscore: "require", + }, { + selector: "typeLike", + format: ["PascalCase"], + }, { + selector: "variable", + format: ["camelCase"], + }], + + "@typescript-eslint/no-dynamic-delete": 0, + "@typescript-eslint/no-empty-interface": 2, + "@typescript-eslint/no-empty-function": 0, + "@typescript-eslint/no-explicit-any": 2, + "@typescript-eslint/no-extraneous-class": 0, + "@typescript-eslint/no-non-null-assertion": 0, + "@typescript-eslint/no-shadow": 2, + "@typescript-eslint/no-unnecessary-condition": 0, + "@typescript-eslint/no-unsafe-member-access": 2, + "@typescript-eslint/no-unused-expressions": 0, + + "@typescript-eslint/no-unused-vars": [2, { + argsIgnorePattern: "^_", + caughtErrorsIgnorePattern: "^_", + varsIgnorePattern: "^_", + }], + + "@typescript-eslint/no-misused-promises": [2, { + checksVoidReturn: false, + }], + + "@typescript-eslint/no-this-alias": [2, { + allowedNames: ["self"], + }], + + "@typescript-eslint/no-var-requires": 2, + "@typescript-eslint/unified-signatures": 0, + "@typescript-eslint/prefer-nullish-coalescing": 2, + "@typescript-eslint/typedef": 2, + + "@typescript-eslint/unbound-method": [2, { + ignoreStatic: true, + }], + }, +}]; diff --git a/licence.md b/licence.md new file mode 100644 index 0000000..89f6547 --- /dev/null +++ b/licence.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2024 Jakub Kiszczyc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..ca18bfa --- /dev/null +++ b/makefile @@ -0,0 +1,4 @@ +clean: + rm -rf ./lib \ + rm tsconfig.tsbuildinfo \ + rm tsconfig.release.tsbuildinfo diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4554331 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4425 @@ +{ + "name": "moc-socket", + "version": "0.2.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "moc-socket", + "version": "0.2.0", + "license": "Apache-2.0", + "dependencies": { + "socket.io-client": "4.8.1", + "ws": "8.18.0" + }, + "devDependencies": { + "@eslint/compat": "^1.1.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.9.0", + "@rollup/plugin-commonjs": "^28.0.0", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@types/node": "22.9.0", + "@types/ws": "^8.5.13", + "@typescript-eslint/eslint-plugin": "8.13.0", + "@typescript-eslint/parser": "8.13.0", + "cross-env": "7.0.3", + "eslint": "9.14.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-check-file": "2.8.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-jest": "28.9.0", + "eslint-plugin-jsdoc": "^50.0.0", + "eslint-plugin-prettier": "5.2.1", + "eslint-plugin-sort-class-members": "1.21.0", + "prettier": "3.3.3", + "rollup": "^4.22.5", + "socket.io": "^4.8.1", + "typescript": "5.6.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", + "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/compat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.2.3.tgz", + "integrity": "sha512-wlZhwlDFxkxIZ571aH0FoK4h4Vwx7P3HJx62Gp8hTc10bfpwT2x0nULuAHmQSJBOWPgPeVf+9YtnD4j50zVHmA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.10.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.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": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", + "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "28.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz", + "integrity": "sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", + "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", + "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.0.tgz", + "integrity": "sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.0.tgz", + "integrity": "sha512-eiNkznlo0dLmVG/6wf+Ifi/v78G4d4QxRhuUl+s8EWZpDewgk7PX3ZyECUXU0Zq/Ca+8nU8cQpNC4Xgn2gFNDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.0.tgz", + "integrity": "sha512-lmKx9yHsppblnLQZOGxdO66gT77bvdBtr/0P+TPOseowE7D9AJoBw8ZDULRasXRWf1Z86/gcOdpBrV6VDUY36Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.0.tgz", + "integrity": "sha512-8hxgfReVs7k9Js1uAIhS6zq3I+wKQETInnWQtgzt8JfGx51R1N6DRVy3F4o0lQwumbErRz52YqwjfvuwRxGv1w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.0.tgz", + "integrity": "sha512-lA1zZB3bFx5oxu9fYud4+g1mt+lYXCoch0M0V/xhqLoGatbzVse0wlSQ1UYOWKpuSu3gyN4qEc0Dxf/DII1bhQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.0.tgz", + "integrity": "sha512-aI2plavbUDjCQB/sRbeUZWX9qp12GfYkYSJOrdYTL/C5D53bsE2/nBPuoiJKoWp5SN78v2Vr8ZPnB+/VbQ2pFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.0.tgz", + "integrity": "sha512-WXveUPKtfqtaNvpf0iOb0M6xC64GzUX/OowbqfiCSXTdi/jLlOmH0Ba94/OkiY2yTGTwteo4/dsHRfh5bDCZ+w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.0.tgz", + "integrity": "sha512-yLc3O2NtOQR67lI79zsSc7lk31xjwcaocvdD1twL64PK1yNaIqCeWI9L5B4MFPAVGEVjH5k1oWSGuYX1Wutxpg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.0.tgz", + "integrity": "sha512-+P9G9hjEpHucHRXqesY+3X9hD2wh0iNnJXX/QhS/J5vTdG6VhNYMxJ2rJkQOxRUd17u5mbMLHM7yWGZdAASfcg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.0.tgz", + "integrity": "sha512-1xsm2rCKSTpKzi5/ypT5wfc+4bOGa/9yI/eaOLW0oMs7qpC542APWhl4A37AENGZ6St6GBMWhCCMM6tXgTIplw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.0.tgz", + "integrity": "sha512-zgWxMq8neVQeXL+ouSf6S7DoNeo6EPgi1eeqHXVKQxqPy1B2NvTbaOUWPn/7CfMKL7xvhV0/+fq/Z/J69g1WAQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.0.tgz", + "integrity": "sha512-VEdVYacLniRxbRJLNtzwGt5vwS0ycYshofI7cWAfj7Vg5asqj+pt+Q6x4n+AONSZW/kVm+5nklde0qs2EUwU2g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.0.tgz", + "integrity": "sha512-LQlP5t2hcDJh8HV8RELD9/xlYtEzJkm/aWGsauvdO2ulfl3QYRjqrKW+mGAIWP5kdNCBheqqqYIGElSRCaXfpw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.0.tgz", + "integrity": "sha512-Nl4KIzteVEKE9BdAvYoTkW19pa7LR/RBrT6F1dJCV/3pbjwDcaOq+edkP0LXuJ9kflW/xOK414X78r+K84+msw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.0.tgz", + "integrity": "sha512-eKpJr4vBDOi4goT75MvW+0dXcNUqisK4jvibY9vDdlgLx+yekxSm55StsHbxUsRxSTt3JEQvlr3cGDkzcSP8bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.0.tgz", + "integrity": "sha512-Vi+WR62xWGsE/Oj+mD0FNAPY2MEox3cfyG0zLpotZdehPFXwz6lypkGs5y38Jd/NVSbOD02aVad6q6QYF7i8Bg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.0.tgz", + "integrity": "sha512-kN/Vpip8emMLn/eOza+4JwqDZBL6MPNpkdaEsgUtW1NYN3DZvZqSQrbKzJcTL6hd8YNmFTn7XGWMwccOcJBL0A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.0.tgz", + "integrity": "sha512-Bvno2/aZT6usSa7lRDL2+hMjVAGjuqaymF1ApZm31JXzniR/hvr14jpU+/z4X6Gt5BPlzosscyJZGUvguXIqeQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz", + "integrity": "sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.13.0", + "@typescript-eslint/type-utils": "8.13.0", + "@typescript-eslint/utils": "8.13.0", + "@typescript-eslint/visitor-keys": "8.13.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.13.0.tgz", + "integrity": "sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "8.13.0", + "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/typescript-estree": "8.13.0", + "@typescript-eslint/visitor-keys": "8.13.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.13.0.tgz", + "integrity": "sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/visitor-keys": "8.13.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.13.0.tgz", + "integrity": "sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.13.0", + "@typescript-eslint/utils": "8.13.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.13.0.tgz", + "integrity": "sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.13.0.tgz", + "integrity": "sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/visitor-keys": "8.13.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.13.0.tgz", + "integrity": "sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.13.0", + "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/typescript-estree": "8.13.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.13.0.tgz", + "integrity": "sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.13.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "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, + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=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==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "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/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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", + "dev": true, + "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.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.2.tgz", + "integrity": "sha512-TAr+NKeoVTjEVW8P3iHguO1LO6RlUz9O5Y8o7EY0fU+gY1NYqas7NN3slpFtbXEsLMHk0h90fJMfKjRkQ0qUIw==", + "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.1.1" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "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 + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "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 + } + } + }, + "node_modules/es-abstract": { + "version": "1.23.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz", + "integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", + "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.14.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.0", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-check-file": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-check-file/-/eslint-plugin-check-file-2.8.0.tgz", + "integrity": "sha512-FvvafMTam2WJYH9uj+FuMxQ1y+7jY3Z6P9T4j2214cH0FBxNzTcmeCiGTj1Lxp3mI6kbbgsXvmgewvf+llKYyw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "is-glob": "^4.0.3", + "micromatch": "^4.0.5" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "ko_fi", + "url": "https://ko-fi.com/huanluo" + }, + "peerDependencies": { + "eslint": ">=7.28.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/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, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "28.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.9.0.tgz", + "integrity": "sha512-rLu1s1Wf96TgUUxSw6loVIkNtUjq1Re7A9QdCCHSohnvXEBAjuL420h0T/fMmkQlNsQP2GhQzEUpYHPfxBkvYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "engines": { + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "50.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.0.tgz", + "integrity": "sha512-tCNp4fR79Le3dYTPB0dKEv7yFyvGkUCa+Z3yuTrrNGGOxBlXo9Pn0PEgroOZikUQOGjxoGMVKNjrOHcYEdfszg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.49.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.6", + "escape-string-regexp": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "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 + } + } + }, + "node_modules/eslint-plugin-sort-class-members": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sort-class-members/-/eslint-plugin-sort-class-members-1.21.0.tgz", + "integrity": "sha512-QKV4jvGMu/ge1l4s1TUBC6rqqV/fbABWY7q2EeNpV3FRikoX6KuLhiNvS8UuMi+EERe0hKGrNU9e6ukFDxNnZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + }, + "peerDependencies": { + "eslint": ">=0.8.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", + "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "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" + } + }, + "node_modules/fast-glob/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==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "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" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.1.0.tgz", + "integrity": "sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.1.0.tgz", + "integrity": "sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "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, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.0.tgz", + "integrity": "sha512-kR5g0+dXf/+kXnqI+lu0URKYPKgICtHGGNCDSB10AaUFj3o/HkB3u7WfpRBJGFopxxY0oH3ux7ZsDjLtK7xqvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz", + "integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.0.tgz", + "integrity": "sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.0.tgz", + "integrity": "sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "gopd": "^1.1.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.0.tgz", + "integrity": "sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.0.tgz", + "integrity": "sha512-qS8KkNNXUZ/I+nX6QT8ZS1/Yx0A444yhzdTKxCzKkNjQ9sHErBxJnJAgh+f5YhusYECEcjo4XcyH87hn6+ks0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "has-symbols": "^1.0.3", + "safe-regex-test": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "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, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.14", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.14.tgz", + "integrity": "sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "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==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "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" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-imports": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", + "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", + "dev": true, + "license": "Apache-2.0 AND MIT", + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.7.tgz", + "integrity": "sha512-bMvFGIUKlc/eSfXNX+aZ+EL95/EgZzuwA0OBPTbZZDEJw/0AkentjMuM1oiRfwHrshqk4RzdgiTg5CcDalXN5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "which-builtin-type": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "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" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.0.tgz", + "integrity": "sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.28.0", + "@rollup/rollup-android-arm64": "4.28.0", + "@rollup/rollup-darwin-arm64": "4.28.0", + "@rollup/rollup-darwin-x64": "4.28.0", + "@rollup/rollup-freebsd-arm64": "4.28.0", + "@rollup/rollup-freebsd-x64": "4.28.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.28.0", + "@rollup/rollup-linux-arm-musleabihf": "4.28.0", + "@rollup/rollup-linux-arm64-gnu": "4.28.0", + "@rollup/rollup-linux-arm64-musl": "4.28.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.28.0", + "@rollup/rollup-linux-riscv64-gnu": "4.28.0", + "@rollup/rollup-linux-s390x-gnu": "4.28.0", + "@rollup/rollup-linux-x64-gnu": "4.28.0", + "@rollup/rollup-linux-x64-musl": "4.28.0", + "@rollup/rollup-win32-arm64-msvc": "4.28.0", + "@rollup/rollup-win32-ia32-msvc": "4.28.0", + "@rollup/rollup-win32-x64-msvc": "4.28.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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/slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true, + "license": "ISC" + }, + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "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 + } + } + }, + "node_modules/socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "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" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz", + "integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.0.tgz", + "integrity": "sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.0", + "is-number-object": "^1.1.0", + "is-string": "^1.1.0", + "is-symbol": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.0.tgz", + "integrity": "sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz", + "integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "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 + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index 68f5ccd..4c7eecb 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,22 @@ { "name": "moc-socket", - "version": "0.2.0", + "version": "0.2.1", "description": "Websocket mocking utility", "productName": "MocSocket", + "author": "https://github.com/Virus288", + "license": "Apache-2.0", + "private": false, + "type": "module", "main": "lib/index.js", "types": "lib/index.d.ts", + "exports": { + "import": "./lib/index.js", + "require": "./lib/commonIndex.cjs" + }, "files": [ "/lib", "/types" ], - "author": "https://github.com/Virus288", - "license": "Apache-2.0", - "scripts": { - "build": "tsc -p tsconfig.json", - "build:watch": "tsc -w -p tsconfig.json", - "lint": "cross-env NODE_ENV=development eslint . --ext .ts --fix", - "listErrors": "node_modules/.bin/tsc --skipLibCheck", - "lintStaged": "npx lint-staged", - "test": "jest --config __tests__/jest.config.default.ts" - }, "repository": { "type": "git", "url": "https://github.com/Virus288/MocSocket" @@ -32,32 +30,46 @@ "testing", "mocSocket" ], + "scripts": { + "build": "tsc -p tsconfig.json", + "build:common": "rollup --config", + "build:watch": "tsc -w -p tsconfig.json", + "lint": "cross-env NODE_ENV=development eslint -c eslint.config.mjs . --fix", + "listErrors": "node_modules/.bin/tsc --skipLibCheck -p tsconfig.json", + "lintStaged": "npx lint-staged", + "test": "jest --config __tests__/jest.config.default.ts" + }, "dependencies": { - "socket.io-client": "^4.7.5", - "ws": "^8.18.0" + "socket.io-client": "4.8.1", + "ws": "8.18.0" }, "devDependencies": { - "@jest/globals": "29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "22.5.0", - "@types/ws": "^8.5.11", - "@typescript-eslint/eslint-plugin": "8.2.0", - "@typescript-eslint/parser": "8.2.0", - "cross-env": "^7.0.3", - "eslint": "9.9.1", + "@eslint/compat": "^1.1.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.9.0", + "@rollup/plugin-commonjs": "^28.0.0", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@types/node": "22.9.0", + "@types/ws": "^8.5.13", + "@typescript-eslint/eslint-plugin": "8.13.0", + "@typescript-eslint/parser": "8.13.0", + "cross-env": "7.0.3", + "eslint": "9.14.0", "eslint-config-prettier": "9.1.0", - "eslint-plugin-check-file": "^2.8.0", - "eslint-plugin-import": "2.29.1", - "eslint-plugin-jest": "28.8.0", + "eslint-plugin-check-file": "2.8.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-jest": "28.9.0", + "eslint-plugin-jsdoc": "^50.0.0", "eslint-plugin-prettier": "5.2.1", - "eslint-plugin-sort-class-members": "^1.20.0", - "jest": "29.7.0", - "jest-config": "29.7.0", + "eslint-plugin-sort-class-members": "1.21.0", "prettier": "3.3.3", - "socket.io": "^4.7.5", - "ts-jest": "29.2.5", - "ts-node": "^10.9.2", - "typescript": "5.5.4" + "rollup": "^4.22.5", + "socket.io": "^4.8.1", + "typescript": "5.6.3" + }, + "engines": { + "node": ">=16" }, "lint-staged": { "*.ts": [ diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..8abe614 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,17 @@ +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json' +import resolve from '@rollup/plugin-node-resolve'; + +export default { + input: 'lib/index.js', + output: { + file: 'lib/commonIndex.cjs', + format: 'cjs' + }, + plugins: [ + resolve({ preferBuiltins: true }), + commonjs(), + json() + ] +}; + diff --git a/servers/io/basicServer.ts b/servers/io/basicServer.ts deleted file mode 100644 index facf024..0000000 --- a/servers/io/basicServer.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Server } from 'socket.io'; -import type { Socket } from 'socket.io'; -import http from 'http' - -export default class SocketIoServer { - private _server: Server | undefined; - private _httpServer: http.Server | undefined; - private _users: Socket[] = []; - - private get users(): Socket[] { - return this._users; - } - - private get server(): Server { - return this._server!; - } - - private set server(value: Server) { - this._server = value; - } - - private get httpServer(): http.Server { - return this._httpServer! - } - - private set httpServer(val: http.Server) { - this._httpServer = val - } - - init(): void { - this.httpServer = http.createServer(); - this.server = new Server(this.httpServer, { - transports: ['websocket'], - cors: { origin: '*' }, - }); - - this.listen() - } - - close(): void { - if (this.server) { - this.server.close(); - } - this.users.forEach((u) => { - u.disconnect(true); - this.userDisconnected(u); - }); - } - - - getServer(): Server { - return this.server; - } - - private listen(): void { - this.server.on('connection', (ws) => { - console.log('Socket:', `User ${ws.id} connected`); - this.onUserConnected(ws); - }); - } - - sendToUser(message: unknown): void { - const target = this.users[0]! - - if (target) target.emit('messages', JSON.stringify(message)); - } - - private userDisconnected(ws: Socket): void { - console.log(`User disconnected ${ws.id}`) - } - - private onUserConnected(ws: Socket): void { - this.users.push(ws) - - ws.on('message', (message: string) => this.errorWrapper(() => this.handleUserMessage(message))); - ws.on('disconnect', () => this.userDisconnected(ws)); - } - - private errorWrapper(callback: () => void): void { - try { - callback(); - } catch (err) { - this.sendToUser(err) - } - } - - private handleUserMessage(mess: string): void { - let message: { payload: unknown | undefined, target: unknown | undefined } = { payload: undefined, target: undefined! }; - - try { - message = JSON.parse(mess) as { payload: unknown, target: string }; - } catch (err) { - return this.sendToUser(err) - } - - console.log("got new message", message) - this.sendToUser(JSON.stringify({ key: "value" })) - } -} diff --git a/servers/io/serverWithCookieAuth.ts b/servers/io/serverWithCookieAuth.ts deleted file mode 100644 index d764678..0000000 --- a/servers/io/serverWithCookieAuth.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Server } from 'socket.io'; -import type { Socket } from 'socket.io'; -import http from 'http' - -export default class SocketIoServer { - private _server: Server | undefined; - private _httpServer: http.Server | undefined; - private _users: Socket[] = []; - - private get users(): Socket[] { - return this._users; - } - - private get server(): Server { - return this._server!; - } - - private set server(value: Server) { - this._server = value; - } - - private get httpServer(): http.Server { - return this._httpServer! - } - - private set httpServer(val: http.Server) { - this._httpServer = val - } - - init(): void { - this.httpServer = http.createServer(); - this.server = new Server(this.httpServer, { - transports: ['websocket'], - cors: { origin: '*' }, - }); - - this.listen() - } - - close(): void { - if (this.server) { - this.server.close(); - } - this.users.forEach((u) => { - u.disconnect(true); - this.userDisconnected(u); - }); - } - - - getServer(): Server { - return this.server; - } - - private listen(): void { - this.server.on('connection', (ws) => { - console.log('Socket:', `User ${ws.id} connected`); - this.onUserConnected(ws); - }); - } - - sendToUser(message: unknown): void { - const target = this.users[0]! - - if (target) target.emit('messages', JSON.stringify(message)); - } - - private userDisconnected(ws: Socket): void { - console.log(`User disconnected ${ws.id}`) - } - - private onUserConnected(ws: Socket): void { - this.users.push(ws) - this.validateUser(ws) - - ws.on('message', (message: string) => this.errorWrapper(() => this.handleUserMessage(message))); - ws.on('disconnect', () => this.userDisconnected(ws)); - } - - private validateUser(ws: Socket): string | undefined { - const err = new Error('Missing cookies') - - if (!ws.request.headers.cookie) { - ws.emit("error", { message: err.message, name: err.name }) - ws.disconnect() - - return undefined - } - - const cookie = ws.request.headers.cookie.split(';') - .map((e) => e.split('=')) - .find((e) => e[0]!.trim() === 'randomId'); - - if (!cookie || cookie.length === 0) { - ws.emit("error", { message: err.message, name: err.name }) - ws.disconnect() - - return undefined - } - - return cookie[0] - } - - private errorWrapper(callback: () => void): void { - try { - callback(); - } catch (err) { - this.sendToUser(err) - } - } - - private handleUserMessage(mess: string): void { - let message: { payload: unknown | undefined, target: unknown | undefined } = { payload: undefined, target: undefined! }; - - try { - message = JSON.parse(mess) as { payload: unknown, target: string }; - } catch (err) { - return this.sendToUser(err) - } - - console.log("got new message", message) - this.sendToUser(JSON.stringify({ key: "value" })) - } -} diff --git a/servers/io/serverWithHeadersAuth.ts b/servers/io/serverWithHeadersAuth.ts deleted file mode 100644 index 6297ea6..0000000 --- a/servers/io/serverWithHeadersAuth.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Server } from 'socket.io'; -import type { Socket } from 'socket.io'; -import http from 'http' - -export default class SocketIoServer { - private _server: Server | undefined; - private _httpServer: http.Server | undefined; - private _users: Socket[] = []; - - private get users(): Socket[] { - return this._users; - } - - private get server(): Server { - return this._server!; - } - - private set server(value: Server) { - this._server = value; - } - - private get httpServer(): http.Server { - return this._httpServer! - } - - private set httpServer(val: http.Server) { - this._httpServer = val - } - - init(): void { - this.httpServer = http.createServer(); - this.server = new Server(this.httpServer, { - transports: ['websocket'], - cors: { origin: '*' }, - }); - - this.listen() - } - - close(): void { - if (this.server) { - this.server.close(); - } - this.users.forEach((u) => { - u.disconnect(true); - this.userDisconnected(u); - }); - } - - - getServer(): Server { - return this.server; - } - - private listen(): void { - this.server.on('connection', (ws) => { - console.log('Socket:', `User ${ws.id} connected`); - this.onUserConnected(ws); - }); - } - - sendToUser(message: unknown): void { - const target = this.users[0]! - - if (target) target.emit('messages', JSON.stringify(message)); - } - - private userDisconnected(ws: Socket): void { - console.log(`User disconnected ${ws.id}`) - } - - private onUserConnected(ws: Socket): void { - this.users.push(ws) - this.validateUser(ws) - - ws.on('message', (message: string) => this.errorWrapper(() => this.handleUserMessage(message))); - ws.on('disconnect', () => this.userDisconnected(ws)); - } - - private validateUser(ws: Socket): string | undefined { - const err = new Error("Missing token") - - if (!ws.handshake.headers.authorization) { - ws.emit("error", { nessage: err.message, name: err.name }) - ws.disconnect() - - return undefined - } - - const token = (ws.handshake.headers.authorization as string).split('Bearer')![1] - if (!token || token.length === 0) { - ws.emit("error", { message: err.message, name: err.name }) - ws.disconnect() - - return undefined - } - - return token - } - - private errorWrapper(callback: () => void): void { - try { - callback(); - } catch (err) { - this.sendToUser(err) - } - } - - private handleUserMessage(mess: string): void { - let message: { payload: unknown | undefined, target: unknown | undefined } = { payload: undefined, target: undefined! }; - - try { - message = JSON.parse(mess) as { payload: unknown, target: string }; - } catch (err) { - return this.sendToUser(err) - } - - console.log("got new message", message) - this.sendToUser(JSON.stringify({ key: "value" })) - } -} diff --git a/servers/io/serverWithQueryParams.ts b/servers/io/serverWithQueryParams.ts deleted file mode 100644 index 5f33f07..0000000 --- a/servers/io/serverWithQueryParams.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Server } from 'socket.io'; -import type { Socket } from 'socket.io'; -import http from 'http' - -export default class SocketIoServer { - private _server: Server | undefined; - private _httpServer: http.Server | undefined; - private _users: Socket[] = []; - - private get users(): Socket[] { - return this._users; - } - - private get server(): Server { - return this._server!; - } - - private set server(value: Server) { - this._server = value; - } - - private get httpServer(): http.Server { - return this._httpServer! - } - - private set httpServer(val: http.Server) { - this._httpServer = val - } - - init(): void { - this.httpServer = http.createServer(); - this.server = new Server(this.httpServer, { - transports: ['websocket'], - cors: { origin: '*' }, - }); - - this.listen() - } - - close(): void { - if (this.server) { - this.server.close(); - } - this.users.forEach((u) => { - u.disconnect(true); - this.userDisconnected(u); - }); - } - - - getServer(): Server { - return this.server; - } - - private listen(): void { - this.server.on('connection', (ws) => { - console.log('Socket:', `User ${ws.id} connected`); - this.onUserConnected(ws); - }); - } - - sendToUser(message: unknown): void { - const target = this.users[0]! - - if (target) target.emit('messages', JSON.stringify(message)); - } - - private userDisconnected(ws: Socket): void { - console.log(`User disconnected ${ws.id}`) - } - - private onUserConnected(ws: Socket): void { - this.users.push(ws) - this.validateUser(ws) - - ws.on('message', (message: string) => this.errorWrapper(() => this.handleUserMessage(message))); - ws.on('disconnect', () => this.userDisconnected(ws)); - } - - private validateUser(ws: Socket): string | undefined { - const err = new Error('Missing token') - - if (!ws.handshake.query.key) { - ws.emit("error", { message: err.message, name: err.name }) - ws.disconnect() - - return undefined - } - - const token = (ws.handshake.query.key as string) - if (!token || token.length === 0) { - ws.emit("error", { message: err.message, name: err.name }) - ws.disconnect() - - return undefined - } - - return token - } - - private errorWrapper(callback: () => void): void { - try { - callback(); - } catch (err) { - this.sendToUser(err) - } - } - - private handleUserMessage(mess: string): void { - let message: { payload: unknown | undefined, target: unknown | undefined } = { payload: undefined, target: undefined! }; - - try { - message = JSON.parse(mess) as { payload: unknown, target: string }; - } catch (err) { - return this.sendToUser(err) - } - - console.log("got new message", message) - this.sendToUser(JSON.stringify({ key: "value" })) - } -} diff --git a/servers/ws/basicServer.ts b/servers/ws/basicServer.ts deleted file mode 100644 index 846afc4..0000000 --- a/servers/ws/basicServer.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { WebSocketServer, WebSocket } from 'ws'; - -export default class BasicWebsocketServer { - private _server: WebSocketServer | null = null; - private _users: WebSocket[] = []; - - private get users(): WebSocket[] { - return this._users; - } - - private get server(): WebSocketServer { - return this._server!; - } - - private set server(value: WebSocketServer) { - this._server = value; - } - - init(): void { - this._server = new WebSocketServer({ - noServer: true - }); - console.log('Socket:', `Started socket`); - this.startListeners(); - } - - close(): void { - if (this.server) { - this.server.close(); - } - this.users.forEach((u) => { - u.close(1000, JSON.stringify(new Error('Closing server'))); - this.userDisconnected(); - }); - } - - getServer(): WebSocketServer { - return this.server; - } - - startListeners(): void { - this.server.on('connection', (ws: WebSocket) => { - this.errorWrapper(() => this.onUserConnected(ws)); - }); - this.server.on('error', (err) => this.handleServerError(err)); - this.server.on('close', () => console.log('Websocket', 'Server closed')); - } - - sendToUser(message: unknown): void { - const target = this.users[0]! - - if (target) target.send(JSON.stringify(message)); - } - - private userDisconnected(): void { - console.log("User disconnected") - } - - private onUserConnected(ws: WebSocket): void { - this.users.push(ws) - - ws.on('message', (message: string) => this.errorWrapper(() => this.handleUserMessage(message))); - ws.on('ping', () => this.errorWrapper(() => this.ping(ws))); - ws.on('close', () => this.userDisconnected()); - } - - private errorWrapper(callback: () => void): void { - try { - callback(); - } catch (err) { - this.sendToUser(err) - } - } - - private handleUserMessage(mess: string): void { - let message: { payload: unknown | undefined, target: unknown | undefined } = { payload: undefined, target: undefined! }; - - try { - message = JSON.parse(mess) as { payload: unknown, target: string }; - } catch (err) { - return this.sendToUser(err) - } - - console.log("got new message", message) - this.sendToUser(JSON.stringify({ key: "value" })) - } - - private ping(ws: WebSocket): void { - ws.pong(); - } - - private handleServerError(err: Error): void { - console.error('Socket', err.message, err.stack); - this.close(); - } -} diff --git a/servers/ws/serverWithCookieAuth.ts b/servers/ws/serverWithCookieAuth.ts deleted file mode 100644 index 93bfee2..0000000 --- a/servers/ws/serverWithCookieAuth.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { WebSocketServer, WebSocket } from 'ws'; - -export default class WebsocketServer { - private _server: WebSocketServer | null = null; - private _users: WebSocket[] = []; - - private get users(): WebSocket[] { - return this._users; - } - - private get server(): WebSocketServer { - return this._server!; - } - - private set server(value: WebSocketServer) { - this._server = value; - } - - init(): void { - this._server = new WebSocketServer({ - noServer: true - }); - console.log('Socket:', `Started socket`); - this.startListeners(); - } - - close(): void { - if (this.server) { - this.server.close(); - } - this.users.forEach((u) => { - u.close(1000, JSON.stringify(new Error('Closing server'))); - this.userDisconnected(); - }); - } - - getServer(): WebSocketServer { - return this.server; - } - - startListeners(): void { - this.server.on('connection', (ws: WebSocket, req) => { - this.errorWrapper(() => this.onUserConnected(ws, req.headers.cookie)); - }); - this.server.on('error', (err) => this.handleServerError(err)); - this.server.on('close', () => console.log('Websocket', 'Server closed')); - } - - sendToUser(message: unknown): void { - const target = this.users[0]! - - if (target) target.send(JSON.stringify(message)); - } - - private userDisconnected(): void { - console.log("User disconnected") - } - - private onUserConnected(ws: WebSocket, cookies: string | undefined): void { - this.validateUser(ws, cookies) - this.users.push(ws) - - ws.on('message', (message: string) => this.errorWrapper(() => this.handleUserMessage(message))); - ws.on('ping', () => this.errorWrapper(() => this.ping(ws))); - ws.on('close', () => this.userDisconnected()); - } - - private validateUser(ws: WebSocket, cookies: string | undefined) { - if (!cookies) throw new Error('No token provided') - - const preparedCookie = cookies - .split(';') - .map((e) => e.split('=')) - .find((e) => e[0]!.trim() === 'randomId'); - - if (!preparedCookie || preparedCookie.length === 0) { - ws.close(1000, 'No token provided'); - return; - } - } - - private errorWrapper(callback: () => void): void { - try { - callback(); - } catch (err) { - this.sendToUser(err) - } - } - - private handleUserMessage(mess: string): void { - let message: { payload: unknown | undefined, target: unknown | undefined } = { payload: undefined, target: undefined! }; - - try { - message = JSON.parse(mess) as { payload: unknown, target: string }; - } catch (err) { - return this.sendToUser(err) - } - - console.log("got new message", message) - this.sendToUser(JSON.stringify({ key: "value" })) - } - - private ping(ws: WebSocket): void { - ws.pong(); - } - - private handleServerError(err: Error): void { - console.error('Socket', err.message, err.stack); - this.close(); - } -} diff --git a/servers/ws/serverWithHeadersAuth.ts b/servers/ws/serverWithHeadersAuth.ts deleted file mode 100644 index 3017fb5..0000000 --- a/servers/ws/serverWithHeadersAuth.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { WebSocketServer, WebSocket } from 'ws'; - -export default class WebsocketServer { - private _server: WebSocketServer | null = null; - private _users: WebSocket[] = []; - - private get users(): WebSocket[] { - return this._users; - } - - private get server(): WebSocketServer { - return this._server!; - } - - private set server(value: WebSocketServer) { - this._server = value; - } - - init(): void { - this._server = new WebSocketServer({ - noServer: true - }); - console.log('Socket:', `Started socket`); - this.startListeners(); - } - - close(): void { - if (this.server) { - this.server.close(); - } - this.users.forEach((u) => { - u.close(1000, JSON.stringify(new Error('Closing server'))); - this.userDisconnected(); - }); - } - - getServer(): WebSocketServer { - return this.server; - } - - startListeners(): void { - this.server.on('connection', (ws: WebSocket, req) => { - this.errorWrapper(() => this.onUserConnected(ws, req.headers.authorization)); - }); - this.server.on('error', (err) => this.handleServerError(err)); - this.server.on('close', () => console.log('Websocket', 'Server closed')); - } - - sendToUser(message: unknown): void { - const target = this.users[0]! - - if (target) target.send(JSON.stringify(message)); - } - - private userDisconnected(): void { - console.log("User disconnected") - } - - private onUserConnected(ws: WebSocket, headers: string | undefined): void { - this.validateUser(ws, headers) - this.users.push(ws) - - ws.on('message', (message: string) => this.errorWrapper(() => this.handleUserMessage(message))); - ws.on('ping', () => this.errorWrapper(() => this.ping(ws))); - ws.on('close', () => this.userDisconnected()); - } - - private validateUser(ws: WebSocket, headers: string | undefined) { - if (!headers) throw new Error('No token provided') - let access: string | undefined - - if (headers.includes('Bearer')) { - access = headers.split('Bearer')[1]!.trim(); - } - - if (!access || access.length === 0) { - ws.close(1000, 'No token provided'); - return; - } - } - - private errorWrapper(callback: () => void): void { - try { - callback(); - } catch (err) { - this.sendToUser(err) - } - } - - private handleUserMessage(mess: string): void { - let message: { payload: unknown | undefined, target: unknown | undefined } = { payload: undefined, target: undefined! }; - - try { - message = JSON.parse(mess) as { payload: unknown, target: string }; - } catch (err) { - return this.sendToUser(err) - } - - console.log("got new message", message) - this.sendToUser(JSON.stringify({ key: "value" })) - } - - private ping(ws: WebSocket): void { - ws.pong(); - } - - private handleServerError(err: Error): void { - console.error('Socket', err.message, err.stack); - this.close(); - } -} diff --git a/src/enums/index.ts b/src/enums/index.ts index f522859..a2f15a2 100644 --- a/src/enums/index.ts +++ b/src/enums/index.ts @@ -1,4 +1,5 @@ export enum ESocketEvents { + Connect = 'connect', Open = 'open', Message = 'message', Error = 'error', diff --git a/src/errors/index.ts b/src/errors/index.ts index d41ffa1..5b7c718 100644 --- a/src/errors/index.ts +++ b/src/errors/index.ts @@ -1,4 +1,8 @@ -// eslint-disable-next-line max-classes-per-file +/* eslint-disable max-classes-per-file */ + +/** + * Error thrown, whenever incorrect element was provided as server, or server does not exist. + */ export class NoServer extends Error { constructor() { super('NoServer'); @@ -6,6 +10,9 @@ export class NoServer extends Error { } } +/** + * Error thrown, whenever action is triggered on client, but client is not connected. + */ export class ClientNotOpen extends Error { constructor() { super('ClientNotOpen'); diff --git a/src/index.ts b/src/index.ts index f691a44..5c0f1b5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -import MocSocket from './mocSocket'; +import MocSocket from './mocSocket.js'; -export type { IClient, ISimpleClient, ISendMessageConfig, ISendAsyncMessageConfig } from '../types'; +export type { IClient, ISimpleClient, ISendMessageConfig, ISendAsyncMessageConfig } from '../types/index.js'; -export { ESocketEvents } from './enums'; +export { ESocketEvents } from './enums/index.js'; export default MocSocket; diff --git a/src/mocSocket.ts b/src/mocSocket.ts index 2c6c877..9fb8d58 100644 --- a/src/mocSocket.ts +++ b/src/mocSocket.ts @@ -1,11 +1,21 @@ -import { WsServer, SocketIoServer } from './modules/servers'; -import type { ISocketIoServer, IWebsocketServer } from '../types'; +import { WsServer, SocketIoServer } from './modules/servers/index.js'; +import type { ISocketIoServer, IWebsocketServer } from '../types/index.js'; -export default abstract class MocSocket { +export default class MocSocket { + /** + * Create a mocked server client for websocket server. + * @param server Initialized websocket server. + * @returns Wrapped instance of websocket server. + */ static createWsClient(server: IWebsocketServer): WsServer { return new WsServer(server); } + /** + * Create a mocked server client for socket.io server. + * @param server Initialized socket.io server. + * @returns Wrapped instance of socket server. + */ static createSocketIoServer(server: ISocketIoServer): SocketIoServer { return new SocketIoServer(server); } diff --git a/src/modules/clients/abstracts/io.ts b/src/modules/clients/abstracts/io.ts new file mode 100644 index 0000000..4284981 --- /dev/null +++ b/src/modules/clients/abstracts/io.ts @@ -0,0 +1,66 @@ +import { ESocketEvents } from '../../../enums/index.js'; +import { ClientNotOpen } from '../../../errors/index.js'; +import type { IBaseIoClient } from '../../../../types/index.js'; +import type { Socket } from 'socket.io-client'; + +export default abstract class AbstractIoClient implements IBaseIoClient { + protected readonly _port: number; + private _client: Socket | undefined; + + constructor(port: number) { + this._port = port; + return new Proxy(this, this.createHandler()); + } + + protected get client(): Socket | undefined { + return this._client; + } + + protected set client(value: Socket | undefined) { + this._client = value; + } + + protected get port(): number { + return this._port; + } + + disableEvent(event: ESocketEvents | string, action: (...params: unknown[]) => void | Promise): void { + this.client!.off(event, action); + } + + onError(action: (e: Error) => void | Promise): void { + this.client!.on(ESocketEvents.Error, (e) => action(e as Error)); + } + + onConnectionError(action: (e: Error) => void | Promise): void { + this.client!.on(ESocketEvents.ConnectionError, (e) => action(e as Error)); + } + + on(event: string, action: (...params: unknown[]) => void | Promise): void { + this.client!.on(event, (...params) => action(params)); + } + + sendMessage(event: string, message: unknown): void { + this.client?.emit(event, message); + } + + private createHandler(): ProxyHandler { + return { + get: (target: this, prop: string, receiver): (() => void) => { + const value = target[prop as keyof this]; + + if (value instanceof Function) { + const allowedActions = ['connect', 'close']; + if (!allowedActions.includes(prop)) { + if (!this.client) throw new ClientNotOpen(); + } + + return (...args) => { + return value.apply(this === receiver ? target : this, args) as unknown; + }; + } + return value as () => void; + }, + }; + } +} diff --git a/src/modules/clients/abstract.ts b/src/modules/clients/abstracts/ws.ts similarity index 55% rename from src/modules/clients/abstract.ts rename to src/modules/clients/abstracts/ws.ts index 7dc4e64..34a155c 100644 --- a/src/modules/clients/abstract.ts +++ b/src/modules/clients/abstracts/ws.ts @@ -1,11 +1,9 @@ -// eslint-disable-next-line max-classes-per-file -import { ESocketEvents } from '../../enums'; -import { ClientNotOpen } from '../../errors'; -import type { IBaseClient, IBaseIoClient, ISendAsyncMessageConfig, ISendMessageConfig } from '../../../types'; -import type { Socket } from 'socket.io-client'; +import { ESocketEvents } from '../../../enums/index.js'; +import { ClientNotOpen } from '../../../errors/index.js'; +import type { IBaseClient, ISendAsyncMessageConfig, ISendMessageConfig } from '../../../../types/index.js'; import type WebSocket from 'ws'; -export abstract class AbstractClient implements IBaseClient { +export default abstract class AbstractClient implements IBaseClient { protected readonly _port: number; private _client: WebSocket | undefined; @@ -14,10 +12,6 @@ export abstract class AbstractClient implements IBaseClient { return new Proxy(this, this.createHandler()); } - protected get port(): number { - return this._port; - } - protected get client(): WebSocket | undefined { return this._client; } @@ -26,6 +20,10 @@ export abstract class AbstractClient implements IBaseClient { this._client = value; } + protected get port(): number { + return this._port; + } + disableEvent(event: ESocketEvents | string, action: (...params: unknown[]) => void | Promise): void { this.client!.off(event, action); } @@ -63,17 +61,14 @@ export abstract class AbstractClient implements IBaseClient { this.client!.ping(data, mask, action); } - /** - * Create new client - */ - async sendAsyncMessage(message: unknown, options?: ISendAsyncMessageConfig): Promise { + async sendAsyncMessage(message: unknown, options?: ISendAsyncMessageConfig): Promise { return new Promise((resolve) => { const delayed: NodeJS.Timeout | undefined = undefined; const timeout = setTimeout( () => { if (delayed) clearTimeout(delayed); - return resolve(undefined); + return resolve(undefined as T); }, (options?.timeout ?? 2000) + (options?.delayed ?? 0), ); @@ -88,10 +83,10 @@ export abstract class AbstractClient implements IBaseClient { this.client!.once(ESocketEvents.Message, (m: WebSocket.RawData | string) => { try { clearTimeout(timeout); - resolve(JSON.parse(m as string)); - } catch (err) { + resolve(JSON.parse(m as string) as T); + } catch (_err) { clearTimeout(timeout); - resolve(m as string); + resolve(m as T); } }); }); @@ -121,65 +116,3 @@ export abstract class AbstractClient implements IBaseClient { }; } } - -export abstract class AbstractIoClient implements IBaseIoClient { - protected readonly _port: number; - private _client: Socket | undefined; - - constructor(port: number) { - this._port = port; - return new Proxy(this, this.createHandler()); - } - - protected get port(): number { - return this._port; - } - - protected get client(): Socket | undefined { - return this._client; - } - - protected set client(value: Socket | undefined) { - this._client = value; - } - - disableEvent(event: ESocketEvents | string, action: (...params: unknown[]) => void | Promise): void { - this.client!.off(event, action); - } - - onError(action: (e: Error) => void | Promise): void { - this.client!.on(ESocketEvents.Error, (e) => action(e as Error)); - } - - onConnectionError(action: (e: Error) => void | Promise): void { - this.client!.on(ESocketEvents.ConnectionError, (e) => action(e as Error)); - } - - on(event: string, action: (...params: unknown[]) => void | Promise): void { - this.client!.on(event, (...params) => action(params)); - } - - sendMessage(event: string, message: unknown): void { - this.client?.emit(event, message); - } - - private createHandler(): ProxyHandler { - return { - get: (target: this, prop: string, receiver): (() => void) => { - const value = target[prop as keyof this]; - - if (value instanceof Function) { - const allowedActions = ['connect', 'close']; - if (!allowedActions.includes(prop)) { - if (!this.client) throw new ClientNotOpen(); - } - - return (...args) => { - return value.apply(this === receiver ? target : this, args) as unknown; - }; - } - return value as () => void; - }, - }; - } -} diff --git a/src/modules/clients/index.ts b/src/modules/clients/index.ts index fc8eb2f..3148725 100644 --- a/src/modules/clients/index.ts +++ b/src/modules/clients/index.ts @@ -1,6 +1,6 @@ -import Client from './client'; -import IoClient from './ioClient'; -import SimpleClient from './simpleClient'; -import SimpleIoClient from './simpleIoClient'; +import IoClient from './io/client.js'; +import SimpleIoClient from './io/simpleClient.js'; +import Client from './ws/client'; +import SimpleClient from './ws/simpleClient.js'; export { Client, SimpleClient, SimpleIoClient, IoClient }; diff --git a/src/modules/clients/io/client.ts b/src/modules/clients/io/client.ts new file mode 100644 index 0000000..2bf89b1 --- /dev/null +++ b/src/modules/clients/io/client.ts @@ -0,0 +1,169 @@ +import { io } from 'socket.io-client'; +import { ESocketEvents } from '../../../enums/index.js'; +import AbstractIoClient from '../abstracts/io.js'; +import type { IIoClient } from '../../../../types/index.js'; +import type { SocketOptions } from 'dgram'; +import type { ManagerOptions } from 'socket.io-client'; + +export default class IoClient extends AbstractIoClient implements IIoClient { + private _messages: unknown[] = []; + private _onCloseActions: ((...params: unknown[]) => void | Promise)[] = []; + private _onOpenActions: ((...params: unknown[]) => void | Promise)[] = []; + private _onOpenEvent: string | null = null; + + private get onOpenEvent(): string | null { + return this._onOpenEvent; + } + + private set onOpenEvent(value: string | null) { + this._onOpenEvent = value; + } + + private get onOpenActions(): ((...params: unknown[]) => void | Promise)[] { + return this._onOpenActions; + } + + private set onOpenActions(val: ((...params: unknown[]) => void | Promise)[]) { + this._onOpenActions = val; + } + + private get onCloseActions(): ((...params: unknown[]) => void | Promise)[] { + return this._onCloseActions; + } + + private set onCloseActions(val: ((...params: unknown[]) => void | Promise)[]) { + this._onCloseActions = val; + } + + private get messages(): unknown[] { + return this._messages; + } + + /** + * Get last x messages that client received. + * @param amount Amount of messages to received. + * @param remove Should remove fetched messages from client. + * @returns List of received messages. + */ + getLastMessages(amount = 1, remove = true): T[] { + const startIndex = Math.max(0, this.messages.length - amount); + const messages = this.messages.slice(startIndex); + + if (remove) this.messages.splice(startIndex); + return messages as T[]; + } + + /** + * Connect client to server. + * @param params Optional connection parameters. + * @param params.eventName Name of event, on that server will send callback. Default 'connect'. + * @param params.options Additional connection options. + * @async + */ + async connect(params?: { eventName?: string; options?: Partial }): Promise { + await new Promise((resolve, reject) => { + this.client = io(`http://localhost:${this.port}`, params?.options); + + this.onOpen(params?.eventName ? params?.eventName : 'connect', () => { + setTimeout(() => { + // Timeout is here to handle post-connection errors, which occur if some async action is triggered on server's side + this.disableEvent( + params?.eventName ? params?.eventName : 'connect', + resolve as (...params: unknown[]) => void | Promise, + ); + resolve(); + }, 200); + }); + this.onClose(() => console.log('Client disconnected')); + this.onError(reject); + this.onConnectionError((e) => { + console.log('Cannot connect to server'); + reject(e); + }); + }); + } + + /** + * Send message to server and wait for callback. + * @param event Event, to which message should be send. + * @param message Message, which should be send. + * @param options Optional additional params related to sender. + * @param options.callbackEvent Optional callback event, if server will respond to another event. + * @param options.shouldThrow Optional check, if function should throw an error after some time, if no callback was received. + * @param options.timeout Optional wait time, which will cooperate with options.shouldThrow and wait for callback. + * @returns Callback message. + * @async + */ + async sendAsyncMessage( + event: string, + message: unknown, + options?: { callbackEvent?: string; shouldThrow?: boolean; timeout?: number }, + ): Promise { + return new Promise((resolve, reject) => { + this.client!.emit(event, message); + + let timeout: NodeJS.Timeout | undefined = undefined; + if (options?.shouldThrow) { + timeout = setTimeout(() => { + reject(new Error('Did not receive callback in selected time')); + }, options?.timeout ?? 2000); + } + this.client!.once(options?.callbackEvent ? options?.callbackEvent : event, (e) => { + clearTimeout(timeout); + resolve(e as T); + }); + }); + } + + onOpen(event: string, action: ((...params: unknown[]) => void | Promise)[]): void; + onOpen(event: string, action: (...params: unknown[]) => void | Promise): void; + + /** + * Change default on open action and event. + * This function is used by default opOpen handler, which listens to 'connect' event. + * @param event Event to listen to. + * @param action Single action or list of actions to trigger on open event. + */ + onOpen( + event: string, + action: ((...params: unknown[]) => void | Promise) | ((...params: unknown[]) => void | Promise)[], + ): void { + Array.isArray(action) ? this.onOpenActions.push(...action) : this.onOpenActions.push(action); + if (this.onOpenEvent) return; + + this.onOpenEvent = event; + this.client!.on(event, async () => { + await Promise.allSettled(this.onOpenActions.map((a) => a)); + }); + } + + /** + * Disconnect client from server. + * @async + */ + async disconnect(): Promise { + return new Promise((resolve) => { + this.client?.close(); + resolve(); + }); + } + + onClose(action: ((...params: unknown[]) => void | Promise)[]): void; + onClose(action: (...params: unknown[]) => void | Promise): void; + + /** + * Change default on close action. + * This function is used by default opClose handler. + * @param action Single action or list of actions to trigger on close event. + */ + onClose( + action: ((...params: unknown[]) => void | Promise) | ((...params: unknown[]) => void | Promise)[], + ): void { + Array.isArray(action) ? this.onCloseActions.push(...action) : this.onCloseActions.push(action); + if (this.onCloseActions.length > 0) return; + + this.client!.on(ESocketEvents.Disconnect, async () => { + await Promise.allSettled(this.onOpenActions.map((a) => a)); + }); + } +} diff --git a/src/modules/clients/io/simpleClient.ts b/src/modules/clients/io/simpleClient.ts new file mode 100644 index 0000000..2bdd872 --- /dev/null +++ b/src/modules/clients/io/simpleClient.ts @@ -0,0 +1,59 @@ +import { io } from 'socket.io-client'; +import { ESocketEvents } from '../../../enums/index.js'; +import AbstractIoClient from '../abstracts/io.js'; +import type { ISimpleIoClient } from '../../../../types/index.js'; +import type { SocketOptions } from 'dgram'; +import type { ManagerOptions } from 'socket.io-client'; + +export default class SimpleIoClient extends AbstractIoClient implements ISimpleIoClient { + onOpen(action: ((...params: unknown[]) => void | Promise)[]): void; + onOpen(action: (...params: unknown[]) => void | Promise): void; + + /** + * Change default on open action and event. + * You can still use client.on() method. This is just a proxy. + * @param action Single action or list of actions to trigger on open event. + */ + onOpen( + action: ((...params: unknown[]) => void | Promise) | ((...params: unknown[]) => void | Promise)[], + ): void { + const toRun = Array.isArray(action) ? action : [action]; + + this.client!.on(ESocketEvents.Connect, async () => { + await Promise.allSettled(toRun.map((a) => a)); + }); + } + + onClose(action: ((...params: unknown[]) => void | Promise)[]): void; + onClose(action: (...params: unknown[]) => void | Promise): void; + + /** + * Action to trigger on connection close. + * This is just a proxy. You can still call client.on("disconnect"). + * @param action Action or list of actions to run on connection close. + */ + onClose( + action: ((...params: unknown[]) => void | Promise) | ((...params: unknown[]) => void | Promise)[], + ): void { + const toRun = Array.isArray(action) ? action : [action]; + + this.client!.on(ESocketEvents.Disconnect, async () => { + await Promise.allSettled(toRun.map((a) => a)); + }); + } + + /** + * Create new client. + * @param options Additional connection options. + */ + connect(options: Partial = {}): void { + this.client = io(`http://localhost:${this.port}`, options); + } + + /** + * Disconnect client from server. + */ + disconnect(): void { + this.client?.disconnect(); + } +} diff --git a/src/modules/clients/ioClient.ts b/src/modules/clients/ioClient.ts deleted file mode 100644 index d151bca..0000000 --- a/src/modules/clients/ioClient.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { io } from 'socket.io-client'; -import { AbstractIoClient } from './abstract'; -import { ESocketEvents } from '../../enums'; -import type { IIoClient } from '../../../types'; -import type { SocketOptions } from 'dgram'; -import type { ManagerOptions } from 'socket.io-client'; - -export default class IoClient extends AbstractIoClient implements IIoClient { - private _messages: unknown[] = []; - - private get messages(): unknown[] { - return this._messages; - } - - /** - * Get last x messages that client received - */ - getLastMessages(amount = 1, remove = true): unknown[] { - const startIndex = Math.max(0, this.messages.length - amount); - const messages = this.messages.slice(startIndex); - - if (remove) this.messages.splice(startIndex); - return messages; - } - - /** - * Create new client - */ - async connect(params?: { eventName?: string; options?: Partial }): Promise { - await new Promise((resolve, reject) => { - this.client = io(`http://localhost:${this.port}`, params?.options); - - this.onOpen(params?.eventName ? params?.eventName : 'connect', () => { - setTimeout(() => { - // Timeout is here to handle post-connection errors, which occur with strage times - this.disableEvent( - params?.eventName ? params?.eventName : 'connect', - resolve as (...params: unknown[]) => void | Promise, - ); - resolve(); - }, 200); - }); - this.onClose(() => console.log('Client disconnected')); - this.onError((err) => { - reject(err); - }); - this.onConnectionError((e) => { - console.log('Cannot connect'); - reject(e); - }); - }); - } - - sendAsyncMessage(event: string, message: unknown, callbackEvent?: string): Promise { - return new Promise((resolve) => { - this.client!.emit(event, message); - this.client!.once(callbackEvent ? callbackEvent : event, (e) => resolve(e)); - }); - } - - onOpen(event: string, action: (...params: unknown[]) => void | Promise): void { - this.client!.on(event, action); - } - - /* - * Disconnect user - */ - disconnect(): Promise { - return new Promise((resolve) => { - this.onClose(resolve as () => void | Promise); - this.client?.close(); - }); - } - - onClose(action: () => void | Promise): void { - this.client!.on(ESocketEvents.Disconnect, () => action()); - } -} diff --git a/src/modules/clients/simpleClient.ts b/src/modules/clients/simpleClient.ts deleted file mode 100644 index 1fe8d3a..0000000 --- a/src/modules/clients/simpleClient.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Websocket from 'ws'; -import { AbstractClient } from './abstract'; -import type { ISimpleClient } from '../../../types'; - -export default class SimpleClient extends AbstractClient implements ISimpleClient { - onOpen(action: (...params: unknown[]) => void | Promise): void { - this.client!.on('open', action); - } - - /** - * Create new client - */ - connect(options: Websocket.ClientOptions = {}): void { - this.client = new Websocket(`ws://localhost:${this.port}`, options); - } -} diff --git a/src/modules/clients/simpleIoClient.ts b/src/modules/clients/simpleIoClient.ts deleted file mode 100644 index dd95f6c..0000000 --- a/src/modules/clients/simpleIoClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { io } from 'socket.io-client'; -import { AbstractIoClient } from './abstract'; -import { ESocketEvents } from '../../enums'; -import type { ISimpleIoClient } from '../../../types'; -import type { SocketOptions } from 'dgram'; -import type { ManagerOptions } from 'socket.io-client'; - -export default class SimpleIoClient extends AbstractIoClient implements ISimpleIoClient { - onOpen(action: (...params: unknown[]) => void | Promise): void { - this.client!.on('connect', action); - } - - onClose(action: (...params: unknown[]) => void | Promise): void { - this.client!.on(ESocketEvents.Disconnect, action); - } - - /** - * Create new client - */ - connect(options: Partial = {}): void { - this.client = io(`http://localhost:${this.port}`, options); - } - - disconnect(): void { - this.client?.disconnect(); - } -} diff --git a/src/modules/clients/client.ts b/src/modules/clients/ws/client.ts similarity index 72% rename from src/modules/clients/client.ts rename to src/modules/clients/ws/client.ts index adcdb58..09efd8b 100644 --- a/src/modules/clients/client.ts +++ b/src/modules/clients/ws/client.ts @@ -1,6 +1,6 @@ import Websocket from 'ws'; -import { AbstractClient } from './abstract'; -import type { IClient } from '../../../types'; +import AbstractClient from '../abstracts/ws.js'; +import type { IClient } from '../../../../types/index.js'; export default class Client extends AbstractClient implements IClient { private _messages: unknown[] = []; @@ -10,18 +10,22 @@ export default class Client extends AbstractClient implements IClient { } /** - * Get last x messages that client received + * Get last x messages that client received. + * @param amount Amount of messages to get. + * @param remove Should remove fetched messages from client. + * @returns Last x messages. */ - getLastMessages(amount = 1, remove = true): unknown[] { + getLastMessages(amount = 1, remove = true): T[] { const startIndex = Math.max(0, this.messages.length - amount); const messages = this.messages.slice(startIndex); if (remove) this.messages.splice(startIndex); - return messages; + return messages as T[]; } /** - * Create new client + * Create new client. + * @param options Additional connection options. */ async connect(options: Websocket.ClientOptions = {}): Promise { await new Promise((resolve, reject) => { @@ -33,14 +37,14 @@ export default class Client extends AbstractClient implements IClient { this.onMessage((m) => { try { this.messages.push(JSON.parse((m as string).toString())); - } catch (err) { + } catch (_err) { this.messages.push((m as string).toString()); } }); this.onClose((_code, m) => { try { this.messages.push(JSON.parse(m.toString())); - } catch (err) { + } catch (_err) { this.messages.push(m.toString()); } }); diff --git a/src/modules/clients/ws/simpleClient.ts b/src/modules/clients/ws/simpleClient.ts new file mode 100644 index 0000000..2f3bfcb --- /dev/null +++ b/src/modules/clients/ws/simpleClient.ts @@ -0,0 +1,32 @@ +import Websocket from 'ws'; +import { ESocketEvents } from '../../../enums/index.js'; +import AbstractClient from '../abstracts/ws.js'; +import type { ISimpleClient } from '../../../../types/index.js'; + +export default class SimpleClient extends AbstractClient implements ISimpleClient { + onOpen(action: ((...params: unknown[]) => void | Promise)[]): void; + onOpen(action: (...params: unknown[]) => void | Promise): void; + + /** + * Change default on open action. Event "open". + * You can still use client.on() method. This is just a proxy. + * @param action Single action or list of actions to trigger on open event. + */ + onOpen( + action: ((...params: unknown[]) => void | Promise) | ((...params: unknown[]) => void | Promise)[], + ): void { + const toRun = Array.isArray(action) ? action : [action]; + + this.client!.on(ESocketEvents.Open, async () => { + await Promise.allSettled(toRun.map((a) => a)); + }); + } + + /** + * Create new client. + * @param options Client's options, for sending message. + */ + connect(options: Websocket.ClientOptions = {}): void { + this.client = new Websocket(`ws://localhost:${this.port}`, options); + } +} diff --git a/src/modules/servers/abstract.ts b/src/modules/servers/abstract/index.ts similarity index 75% rename from src/modules/servers/abstract.ts rename to src/modules/servers/abstract/index.ts index da62309..bf1257b 100644 --- a/src/modules/servers/abstract.ts +++ b/src/modules/servers/abstract/index.ts @@ -1,6 +1,6 @@ -import { NoServer } from '../../errors'; -import type { ISocketServer, ISocketSimpleClients, ISocketClients } from '../../../types'; -import type { ESocketType } from '../../enums'; +import { NoServer } from '../../../errors/index.js'; +import type { ISocketServer, ISocketSimpleClients, ISocketClients } from '../../../../types/index.js'; +import type { ESocketType } from '../../../enums/index.js'; import http from 'http'; export default abstract class SocketClient { @@ -8,20 +8,11 @@ export default abstract class SocketClient { protected _httpServer: http.Server | null = null; private _clients: (ISocketClients[T] | ISocketSimpleClients[T])[] = []; - protected get clients(): (ISocketClients[T] | ISocketSimpleClients[T])[] { - return this._clients; - } - constructor(server: ISocketServer[T]) { if (!server) throw new NoServer(); this._server = server; this.init(); } - - protected get server(): ISocketServer[T] { - return this._server; - } - protected get httpServer(): http.Server { return this._httpServer!; } @@ -30,31 +21,42 @@ export default abstract class SocketClient { this._httpServer = val; } + protected get clients(): (ISocketClients[T] | ISocketSimpleClients[T])[] { + return this._clients; + } + + protected get server(): ISocketServer[T] { + return this._server; + } + /** - * Create connection + * Create connection. + * @async */ - close(): void { + async close(): Promise { this.httpServer.close(); - this.server.close(); + await this.server.close(); this.clients.forEach((c) => c.disconnect()); } /** - * Create new client + * Create new simple client. + * @returns Instance of client. */ createSimpleClient(): ISocketSimpleClients[T] { return this.clients[0] as ISocketSimpleClients[T]; } /** - * Create new client + * Create new client. + * @returns Instance of client. */ createClient(): ISocketClients[T] { return this.clients[0] as ISocketClients[T]; } /** - * Initialize app + * Initialize app. */ protected init(): void { this.httpServer = http.createServer(); diff --git a/src/modules/servers/index.ts b/src/modules/servers/index.ts index f44c85d..780bd3c 100644 --- a/src/modules/servers/index.ts +++ b/src/modules/servers/index.ts @@ -1,4 +1,4 @@ -import SocketIoServer from './socketIo'; -import WsServer from './ws'; +import SocketIoServer from './socketIo.js'; +import WsServer from './ws.js'; export { WsServer, SocketIoServer }; diff --git a/src/modules/servers/socketIo.ts b/src/modules/servers/socketIo.ts index 785986f..bb8f84f 100644 --- a/src/modules/servers/socketIo.ts +++ b/src/modules/servers/socketIo.ts @@ -1,7 +1,7 @@ -import AbstractSocketClient from './abstract'; -import * as clients from '../clients'; -import type { ISimpleIoClient, IIoClient } from '../../../types'; -import type { ESocketType } from '../../enums'; +import AbstractSocketClient from './abstract/index.js'; +import * as clients from '../clients/index.js'; +import type { ISimpleIoClient, IIoClient } from '../../../types/index.js'; +import type { ESocketType } from '../../enums/index.js'; import type { AddressInfo } from 'net'; import http from 'http'; @@ -14,7 +14,8 @@ export default class SocketIoProvider extends AbstractSocketClient { } /** - * Create new client + * Create new client. + * @returns Instance of client. */ override createSimpleClient(): ISimpleClient { const client = new clients.SimpleClient((this.httpServer.address() as AddressInfo).port); @@ -27,7 +28,8 @@ export default class WsProvider extends AbstractSocketClient { } /** - * Create new client + * Create new client. + * @returns Instance of client. */ override createClient(): IClient { const client = new clients.Client((this.httpServer.address() as AddressInfo).port); diff --git a/tsconfig.json b/tsconfig.json old mode 100644 new mode 100755 index 1c22de7..43f9481 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,65 +1,74 @@ { - "compilerOptions": { - "target": "ES6", - "module": "NodeNext", - "types": [ - "node", - "jest" - ], - "lib": [ - "ES6", - "ESNext" - ], - "allowJs": false, - "allowSyntheticDefaultImports": true, - "allowUmdGlobalAccess": true, - "alwaysStrict": true, - "baseUrl": "./src", - "checkJs": false, - "declaration": true, - "declarationMap": false, - "downlevelIteration": true, - "emitDecoratorMetadata": true, - "esModuleInterop": true, - "exactOptionalPropertyTypes": false, - "experimentalDecorators": true, - "forceConsistentCasingInFileNames": true, - "importHelpers": true, - "incremental": true, - "inlineSources": true, - "inlineSourceMap": true, - "isolatedModules": true, - "moduleResolution": "NodeNext", - "noEmit": false, - "noEmitOnError": false, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noImplicitOverride": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "outDir": "./lib", - "rootDir": "./src", - "preserveSymlinks": true, - "pretty": true, - "preserveConstEnums": true, - "removeComments": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "strict": true, - "strictBindCallApply": true, - "strictFunctionTypes": true, - "strictNullChecks": true, - "strictPropertyInitialization": true, - "sourceMap": false, - "useDefineForClassFields": true - }, - "include": [ - "src" - ], - "exclude": [ - "__tests__", "servers" - ] + "compilerOptions": { + "allowImportingTsExtensions": false, + "allowJs": false, + "allowSyntheticDefaultImports": true, + "allowUmdGlobalAccess": false, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "alwaysStrict": true, + "baseUrl": "./src", + "checkJs": false, + "declaration": true, + "declarationMap": false, + "disableReferencedProjectLoad": true, + "disableSolutionSearching": false, + "downlevelIteration": true, + "emitDecoratorMetadata": false, + "esModuleInterop": true, + "exactOptionalPropertyTypes": false, + "experimentalDecorators": false, + "forceConsistentCasingInFileNames": true, + "importHelpers": true, + "incremental": true, + "inlineSources": false, + "inlineSourceMap": false, + "isolatedDeclarations": false, + "isolatedModules": true, + "lib": [ + "ES6", + "ESNext" + ], + "module": "ES2022", + "moduleResolution": "Node", + "newLine": "lf", + "noEmit": false, + "noEmitHelpers": false, + "noEmitOnError": false, + "noErrorTruncation": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitOverride": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noPropertyAccessFromIndexSignature": false, + "noStrictGenericChecks": false, + "outDir": "./lib", + "preserveSymlinks": true, + "pretty": true, + "preserveConstEnums": true, + "removeComments": false, + "resolveJsonModule": true, + "rootDir": "./src", + "skipLibCheck": true, + "suppressExcessPropertyErrors": false, + "suppressImplicitAnyIndexErrors": false, + "strict": true, + "strictBindCallApply": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "sourceMap": false, + "target": "ES2022", + "types": ["node"], + "useDefineForClassFields": true, + "useUnknownInCatchVariables": true, + "verbatimModuleSyntax": false + }, + "exclude": ["node_modules", "lib", "eslint.config.mjs"], + "include": [ "src/**/*.ts" ] } diff --git a/types/clients.d.ts b/types/clients.d.ts index 45a10db..dc4664b 100644 --- a/types/clients.d.ts +++ b/types/clients.d.ts @@ -1,6 +1,6 @@ -import type { ISendAsyncMessageConfig, ISendMessageConfig } from './messages'; -import type { ESocketEvents } from '../src'; -import type { ESocketType } from '../src/enums'; +import type { ISendAsyncMessageConfig, ISendMessageConfig } from './messages.js'; +import type { ESocketEvents } from '../src/index.js'; +import type { ESocketType } from '../src/enums/index.js'; import type { SocketOptions } from 'dgram'; import type { ManagerOptions, Socket } from 'socket.io-client'; import type { WebSocket } from 'ws'; @@ -8,7 +8,7 @@ import type Websocket from 'ws'; export interface IBaseClient { /** - * Disalbe enabled event. Alternative for 'off' + * Disable enabled event. Alternative for 'off' */ disableEvent(event: ESocketEvents | string, action: (...params: unknown[]) => void | Promise): void; @@ -75,7 +75,7 @@ export interface IBaseClient { * @returns {Promise} message * @async */ - sendAsyncMessage(message: unknown, options?: ISendAsyncMessageConfig): Promise; + sendAsyncMessage(message: unknown, options?: ISendAsyncMessageConfig): Promise; /** * Close connectio @@ -93,7 +93,7 @@ export interface IClient extends IBaseClient { * @param [remove=true] Should they be removed from list * @returns {unknown[]} List of last x messages */ - getLastMessages(amount = 1, remove = true): unknown[]; + getLastMessages(amount: number, remove: boolean): unknown[]; /** * Create new client @@ -102,7 +102,7 @@ export interface IClient extends IBaseClient { * @returns {Promise} void * @async */ - connect(options: Websocket.ClientOptions = {}): Promise; + connect(options: Websocket.ClientOptions): Promise; } export interface ISimpleClient extends IBaseClient { @@ -123,7 +123,7 @@ export interface ISimpleClient extends IBaseClient { export interface IBaseIoClient { /** - * Disalbe enabled event. Alternative for 'off' + * Disable enabled event. Alternative for 'off' */ disableEvent(event: ESocketEvents | string, action: (...params: unknown[]) => void | Promise): void; @@ -149,7 +149,7 @@ export interface IBaseIoClient { * @param action action to trigger on event * @returns {void} void */ - on(event: string, action: (...params: unknown[]) => void | Promise); + on(event: string, action: (...params: unknown[]) => void | Promise): void /** * Send message on event @@ -167,7 +167,7 @@ export interface ISimpleIoClient extends IBaseIoClient { * @returns {Promise} void * @async */ - connect(options: Partial = {}): void; + connect(options: Partial): void; /** * Disconnect client from server @@ -181,8 +181,8 @@ export interface ISimpleIoClient extends IBaseIoClient { * @description ping server to check if it still working * @returns {void} void */ - onClose(action: (...params: unknown[]) => void | Promise): void; - onOpen(action: (...params: unknown[]) => void | Promise): void; + onClose(action: ((...params: unknown[]) => void | Promise) | ((...params: unknown[]) => void | Promise)[]): void; + onOpen(action: ((...params: unknown[]) => void | Promise) | ((...params: unknown[]) => void | Promise)[]): void; } export interface IIoClient extends IBaseIoClient { @@ -214,14 +214,20 @@ export interface IIoClient extends IBaseIoClient { onClose(action: (...params: unknown[]) => void | Promise): void; /** - * Send message on event and wait for message back - * @param {string} event Event target - * @message {unknown} Message to send - * @callbackEvent {string} Optional param, which defines, on what event client should wait for response + * Send message to server and wait for callback. + * @param event Event, to which message should be send. + * @param message Message, which should be send. + * @param options Optional additional params related to sender. + * @param options.callbackEvent Optional callback event, if server will respond to another event. + * @param options.shouldThrow Optional check, if function should throw an error after some time, if no callback was received. + * @param options.timeout Optional wait time, which will cooperate with options.shouldThrow and wait for callback. + * @returns Callback message. * @async - * @returns {unknown} callback from server */ - sendAsyncMessage(event: string, message: unknown, callbackEvent?: string): Promise; + + sendAsyncMessage(event: string, + message: unknown, + options?: { callbackEvent?: string; shouldThrow?: boolean; timeout?: number },): Promise; } export interface ISocketSimpleClients { diff --git a/types/index.d.ts b/types/index.d.ts index 9616781..7e4d90e 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,3 +1,3 @@ -export * from './servers'; -export * from './clients'; -export * from './messages'; +export * from './servers.js'; +export * from './clients.js'; +export * from './messages.js'; diff --git a/types/servers.d.ts b/types/servers.d.ts index 3239f63..e748d8e 100644 --- a/types/servers.d.ts +++ b/types/servers.d.ts @@ -1,6 +1,6 @@ -import type * as enums from '../src/enums'; +import type * as enums from '../src/enums/index.js'; +import type { DefaultEventsMap, Server } from 'socket.io' import type { IncomingMessage } from 'http'; -import type { Server } from 'socket.io'; import type { Duplex, EventEmitter } from 'stream'; export interface IWebsocketServer extends EventEmitter { @@ -14,7 +14,9 @@ export interface IWebsocketServer extends EventEmitter { close(cb?: (err?: Error) => void): void; } -export type ISocketIoServer = Server<*, *, *, *>; +export type ISocketData = Record + +export type ISocketIoServer = Server; export interface ISocketServer { [enums.ESocketType.Io]: ISocketIoServer;