diff --git a/.eslintrc.json b/.eslintrc.json index 8d20e22..d5d382e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,30 @@ { "extends": "./node_modules/mwts/", - "ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"], + "ignorePatterns": [ + "node_modules", + "dist", + "test", + "jest.config.js", + "typings", + "public/**/**", + "view/**/**", + "packages" + ], "env": { - "jest": true + "jest": true + }, + "rules": { + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/ban-ts-comment": "off", + "node/no-extraneous-import": "off", + "no-empty": "off", + "node/no-extraneous-require": "off", + "node/no-unpublished-import": "off", + "eqeqeq": "off", + "node/no-unsupported-features/node-builtins": "off", + "@typescript-eslint/ban-types": "off", + "no-control-regex": "off", + "prefer-const": "off" } -} +} \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0b909d8 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.js text eol=lf +*.json text eol=lf +*.ts text eol=lf +*.code-snippets text eol=lf \ No newline at end of file diff --git a/.gitignore b/.gitignore index 18ee55a..3022174 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,21 @@ logs/ +cache/ npm-debug.log yarn-error.log node_modules/ +package-lock.json +yarn.lock coverage/ dist/ .idea/ run/ +build/ .DS_Store +launch.json *.sw* *.un~ .tsbuildinfo .tsbuildinfo.* +data/* +pnpm-lock.yaml +public/uploads/* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b68ce7a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ + +FROM node:lts-alpine + +WORKDIR /app + +# 配置alpine国内镜像加速 +RUN sed -i "s@http://dl-cdn.alpinelinux.org/@https://repo.huaweicloud.com/@g" /etc/apk/repositories + +# 安装tzdata,默认的alpine基础镜像不包含时区组件,安装后可通过TZ环境变量配置时区 +RUN apk add --no-cache tzdata + +# 设置时区为中国东八区,这里的配置可以被docker-compose.yml或docker run时指定的时区覆盖 +ENV TZ="Asia/Shanghai" + +# 如果各公司有自己的私有源,可以替换registry地址,如使用官方源注释下一行 +RUN npm config set registry https://registry.npmmirror.com + +# 复制package.json +COPY package.json ./package.json +# 安装依赖 +RUN npm install +# 构建项目 +COPY . . +RUN npm run build +# 删除开发期依赖 +RUN rm -rf node_modules && rm package-lock.json +# 安装生产环境依赖 +RUN npm install + +# 如果端口更换,这边可以更新一下 +EXPOSE 8001 + +CMD ["npm", "run", "start"] \ No newline at end of file diff --git a/build/pkg.log b/build/pkg.log deleted file mode 100644 index fb467e9..0000000 --- a/build/pkg.log +++ /dev/null @@ -1,2 +0,0 @@ -> pkg@5.8.1 -> Fetching base Node.js binaries to PKG_CACHE_PATH diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a296994 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,40 @@ +# 本地数据库环境 +# 数据存放在当前目录下的 data里 +# 推荐使用安装了docker扩展的vscode打开目录 在本文件上右键可以快速启动,停止 +# 如不需要相关容器开机自启动,可注释掉 restart: always +# 如遇端口冲突 可调整ports下 :前面的端口号 +version: "3.1" + +services: + coolDB: + image: mysql + command: + --default-authentication-plugin=mysql_native_password + --sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION + --group_concat_max_len=102400 + restart: always + volumes: + - ./data/mysql/:/var/lib/mysql/ + environment: + TZ: Asia/Shanghai # 指定时区 + MYSQL_ROOT_PASSWORD: "123456" # 配置root用户密码 + MYSQL_DATABASE: "cool" # 业务库名 + MYSQL_USER: "root" # 业务库用户名 + MYSQL_PASSWORD: "123456" # 业务库密码 + networks: + - cool + ports: + - 3306:3306 + + coolRedis: + image: redis + #command: --requirepass "12345678" # redis库密码,不需要密码注释本行 + restart: always + environment: + TZ: Asia/Shanghai # 指定时区 + volumes: + - ./data/redis/:/data/ + networks: + - cool + ports: + - 6379:6379 diff --git a/package.json b/package.json index 453b608..d961694 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,39 @@ { "name": "cool-admin-midway", "version": "8.0.0", - "description": "一个很酷的Ai开发快速框架", + "description": "一个很酷的Ai快速开发框架", "private": true, "dependencies": { "@cool-midway/core": "file:/Users/ap/Documents/src/admin/midway-packages/core", "@midwayjs/bootstrap": "^3.19.3", + "@midwayjs/cache-manager": "^3.19.3", "@midwayjs/core": "^3.19.0", + "@midwayjs/cron": "^3.19.2", + "@midwayjs/cross-domain": "^3.19.3", "@midwayjs/info": "^3.19.2", "@midwayjs/koa": "^3.19.2", "@midwayjs/logger": "^3.4.2", - "@midwayjs/validate": "^3.19.2" + "@midwayjs/static-file": "^3.19.3", + "@midwayjs/typeorm": "^3.19.2", + "@midwayjs/upload": "^3.19.3", + "@midwayjs/validate": "^3.19.2", + "@midwayjs/view-ejs": "^3.19.2", + "jsonwebtoken": "^9.0.2", + "lodash": "^4.17.21", + "md5": "^2.3.0", + "moment": "^2.30.1", + "mysql2": "^3.12.0", + "sharp": "0.32.6", + "svg-captcha": "^1.4.0", + "typeorm": "^0.3.20", + "uuid": "^11.0.5", + "ws": "^8.18.0" }, "devDependencies": { "@midwayjs/bundle-helper": "^1.3.0", "@midwayjs/mock": "^3.19.2", "@types/jest": "^29.5.14", "@types/node": "22", - "@vercel/ncc": "^0.38.3", "cross-env": "^7.0.3", "jest": "^29.7.0", "mwts": "^1.3.0", @@ -31,23 +47,28 @@ }, "scripts": { "start": "NODE_ENV=production node ./bootstrap.js", - "dev": "cool check && cross-env NODE_ENV=local mwtsc --watch --run @midwayjs/mock/app.js", + "entity": "cool entity", + "dev": "cool check entity && bundle && cross-env NODE_ENV=local mwtsc --watch --run @midwayjs/mock/app.js", "test": "cross-env NODE_ENV=unittest jest", "cov": "jest --coverage", "lint": "mwts check", "lint:fix": "mwts fix", "ci": "npm run cov", - "build": "mwtsc --cleanOutDir", - "bundle": "bundle && npm run build && ncc build bootstrap.js -o build", - "bundle_start": "NODE_ENV=production node ./build/index.js", - "pkg": "pkg . -d > build/pkg.log" + "build": "cool entity && bundle && mwtsc --cleanOutDir", + "build:obfuscate": "cool entity && bundle && mwtsc --cleanOutDir && cool obfuscate", + "pkg": "npm run build && pkg . -d > build/pkg.log", + "pm2:start": "pm2 start ./bootstrap.js -i 1 --name cool-admin", + "pm2:stop": "pm2 stop cool-admin & pm2 delete cool-admin" }, "bin": "./bootstrap.js", "pkg": { - "scripts": "dist/**/*.js", - "assets": [], + "scripts": "dist/**/*", + "assets": [ + "public/**/*" + ], "targets": [ - "node18-macos-x64" + "node18-macos-x64", + "node18-win-x64" ], "outputPath": "build" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb75b22..0ce3bd7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,18 @@ importers: '@midwayjs/bootstrap': specifier: ^3.19.3 version: 3.19.3 + '@midwayjs/cache-manager': + specifier: ^3.19.3 + version: 3.19.3 '@midwayjs/core': specifier: ^3.19.0 version: 3.19.0 + '@midwayjs/cron': + specifier: ^3.19.2 + version: 3.19.2 + '@midwayjs/cross-domain': + specifier: ^3.19.3 + version: 3.19.3 '@midwayjs/info': specifier: ^3.19.2 version: 3.19.2 @@ -26,9 +35,51 @@ importers: '@midwayjs/logger': specifier: ^3.4.2 version: 3.4.2 + '@midwayjs/static-file': + specifier: ^3.19.3 + version: 3.19.3 + '@midwayjs/typeorm': + specifier: ^3.19.2 + version: 3.19.2 + '@midwayjs/upload': + specifier: ^3.19.3 + version: 3.19.3 '@midwayjs/validate': specifier: ^3.19.2 version: 3.19.2 + '@midwayjs/view-ejs': + specifier: ^3.19.2 + version: 3.19.2 + jsonwebtoken: + specifier: ^9.0.2 + version: 9.0.2 + lodash: + specifier: ^4.17.21 + version: 4.17.21 + md5: + specifier: ^2.3.0 + version: 2.3.0 + moment: + specifier: ^2.30.1 + version: 2.30.1 + mysql2: + specifier: ^3.12.0 + version: 3.12.0 + sharp: + specifier: 0.32.6 + version: 0.32.6 + svg-captcha: + specifier: ^1.4.0 + version: 1.4.0 + typeorm: + specifier: ^0.3.20 + version: 0.3.20(mysql2@3.12.0) + uuid: + specifier: ^11.0.5 + version: 11.0.5 + ws: + specifier: ^8.18.0 + version: 8.18.0 devDependencies: '@midwayjs/bundle-helper': specifier: ^1.3.0 @@ -42,9 +93,6 @@ importers: '@types/node': specifier: '22' version: 22.10.5 - '@vercel/ncc': - specifier: ^0.38.3 - version: 0.38.3 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -258,6 +306,10 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} + '@cool-midway/cache-manager-fs-hash@7.0.0': + resolution: {integrity: sha512-Bl43bVCUm0V+w1wkfOicRfiHHZtaH1mQCp06baNapG86uC7OiXwMrml5+cvZD+mYSHdP07qUxtqkL8oUhrgAfg==} + engines: {node: '>=8.0.0'} + '@cool-midway/core@file:../midway-packages/core': resolution: {directory: ../midway-packages/core, type: directory} hasBin: true @@ -310,6 +362,14 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} + '@javascript-obfuscator/escodegen@2.3.0': + resolution: {integrity: sha512-QVXwMIKqYMl3KwtTirYIA6gOCiJ0ZDtptXqAv/8KWLG9uQU2fZqTVy7a/A5RvcoZhbDoFfveTxuGxJ5ibzQtkw==} + engines: {node: '>=6.0'} + + '@javascript-obfuscator/estraverse@5.4.0': + resolution: {integrity: sha512-CZFX7UZVN9VopGbjTx4UXaXsi9ewoM1buL0kY7j1ftYdSs7p2spv9opxFjHlQ/QGTgh4UqufYqJJ0WKLml7b6w==} + engines: {node: '>=4.0'} + '@jest/console@29.7.0': resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -411,6 +471,14 @@ packages: engines: {node: '>=12.0.0'} hasBin: true + '@midwayjs/cache-manager@3.19.3': + resolution: {integrity: sha512-aksDyxpFOm9fRCdi3efA9v3NsXlMUm2YxaO/00ZQRAM3pDcNom55WiV3MKsZUDugvYa6+HsYAmL2wJR8PJcu/Q==} + engines: {node: '>=12'} + + '@midwayjs/cache@3.14.0': + resolution: {integrity: sha512-WUDOanpD+vpNnWZ4q91FvlHpNCRSNHKtgVlTZNVmL9VhNt/weqB8VZhDGbGzzg6NM2k9rfwD3TevoolAee4fZw==} + engines: {node: '>=12'} + '@midwayjs/cookies@1.2.0': resolution: {integrity: sha512-gdfAXk3+uL+9qcNo9lNnUFJCUGXXxCitBjyz9QJR08dcZ11mqTbxVNXhea525e3ZwKREy6f4PHAWofFwlPOZzQ==} engines: {node: '>=10'} @@ -419,6 +487,14 @@ packages: resolution: {integrity: sha512-qFoaFeN8c0UcfJKwmXoFmFxhMVMIT+MwUcTt1A9r/7lGmuqTukUICv5dxhTFffIr6YJHhSMOXEK5u9FV/NxGGA==} engines: {node: '>=12'} + '@midwayjs/cron@3.19.2': + resolution: {integrity: sha512-z6W80bs/MD6RQksDiruD+JqDXXO94CL609PseneAGFOrMdhlHHoGUhCDkE9FJ+QbiKItzpuqUZmmVDA3QRwbeA==} + engines: {node: '>=12'} + + '@midwayjs/cross-domain@3.19.3': + resolution: {integrity: sha512-NL5SkiUwJJ+3/MrACvl3zBZ6lMNOFqrGJKVUn5V9qIWmZ+oZz6Rhoi7x/tqrgR686SNH71HDIoYkj9Gey5yTFQ==} + engines: {node: '>=12'} + '@midwayjs/event-bus@1.11.1': resolution: {integrity: sha512-/dm2SnWfGkR5elEnvVKywx1qJrSd01oCryba/dAaWQsOlTJ1zMjBKRLfIXP3kN/SJO5PPESPITo4stLBp3Kxnw==} engines: {node: '>=12.11.0'} @@ -450,10 +526,31 @@ packages: resolution: {integrity: sha512-SRZWFrEw5BPDTIRjOyh0/YoAiafQBbeR+by62kl/s9noy47UlJIRzGcXORbUHpKIbv+7u9jCnZyniXpNNJ53EA==} engines: {node: '>=12'} + '@midwayjs/static-file@3.19.3': + resolution: {integrity: sha512-m2Gr2QIlwMTsb2pXUOMqT5ATCFITReX5U5yZBHrS4yEPg1MpE+ucyFU4DTXtee3IwOLJCgfpMuzVw+wqBXNW2w==} + engines: {node: '>=12'} + + '@midwayjs/typeorm@3.19.2': + resolution: {integrity: sha512-dJnkEZsGr7wON0HkKys51a4iHPzP1gyjyPcbcgqLJdfeJ3iCTOuQ7dDsBz0TTU8V7iYMTgzHcSgtkkl5j9+4jA==} + engines: {node: '>=12'} + hasBin: true + + '@midwayjs/upload@3.19.3': + resolution: {integrity: sha512-DMfO4GuydaNgqkCCZAigwDVP0n2K3dn+qeGbvGBhBA+f89zbo4mWNT7iGp/9kA5KuM3A0RDlppCWAvc77CpAxg==} + engines: {node: '>=12'} + '@midwayjs/validate@3.19.2': resolution: {integrity: sha512-hG/SF8J2o1cvDwErYAXO1oC4a4cvJL+CTbOCaxjRCJRbEamkalCPE82nCQsjkePbcBec15/aSWQzL/fXb2uXKw==} engines: {node: '>=12'} + '@midwayjs/view-ejs@3.19.2': + resolution: {integrity: sha512-sVAXfAO8IJ9uUdPhPZia6eQHmKW2/871gfl6sPyc1enz/Cqizz0YKbe/UEYkLXXms/qGg2PtZvxQ7ehXHqw0zQ==} + engines: {node: '>=12'} + + '@midwayjs/view@3.19.2': + resolution: {integrity: sha512-rmhVUO0s1l48jwlqaYqMyn4oJMsvMV9sL1S6gVWBa05hUH9ByfZuw1NpfFCeDNz/YAt4HOeApm7Rgg+5IOs8pQ==} + engines: {node: '>=12'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -470,6 +567,20 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@pm2/agent@2.0.4': + resolution: {integrity: sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA==} + + '@pm2/io@6.0.1': + resolution: {integrity: sha512-KiA+shC6sULQAr9mGZ1pg+6KVW9MF8NpG99x26Lf/082/Qy8qsTCtnJy+HQReW1A9Rdf0C/404cz0RZGZro+IA==} + engines: {node: '>=6.0'} + + '@pm2/js-api@0.8.0': + resolution: {integrity: sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==} + engines: {node: '>=4.0'} + + '@pm2/pm2-version-check@1.0.4': + resolution: {integrity: sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==} + '@sideway/address@4.1.5': resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} @@ -486,16 +597,29 @@ packages: resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} engines: {node: '>=6'} + '@sindresorhus/is@0.7.0': + resolution: {integrity: sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==} + engines: {node: '>=4'} + '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@sqltools/formatter@1.2.5': + resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} + '@szmarczak/http-timer@1.1.2': resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==} engines: {node: '>=6'} + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@tootallnate/quickjs-emscripten@0.23.0': + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@types/accepts@1.3.7': resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} @@ -568,9 +692,15 @@ packages: '@types/koa@2.15.0': resolution: {integrity: sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==} + '@types/luxon@3.3.8': + resolution: {integrity: sha512-jYvz8UMLDgy3a5SkGJne8H7VA7zPV2Lwohjx0V8V31+SqAjNmurWMkk9cQhfvlcnXWudBpK9xPM1n4rljOcHYQ==} + '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + '@types/minimatch@3.0.5': + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} @@ -607,6 +737,9 @@ packages: '@types/supertest@2.0.16': resolution: {integrity: sha512-6c2ogktZ06tr2ENoZivgm7YnprnhYE4ZoXGMY+oA7IuAf17M8FWvujXZGmxLv8y0PTyts4x5A+erSwVUFA8XSg==} + '@types/validator@13.12.2': + resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -671,10 +804,6 @@ packages: resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@vercel/ncc@0.38.3': - resolution: {integrity: sha512-rnK6hJBS6mwc+Bkab+PGPs9OiS0i/3kdTO+CkI8V0/VrW3vmz7O2Pxjw/owOlmo6PKEIxRSeZKv/kuL9itnpYA==} - hasBin: true - accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -689,16 +818,31 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.8.2: + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + engines: {node: '>= 14'} + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + amp-message@0.1.2: + resolution: {integrity: sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==} + + amp@0.3.1: + resolution: {integrity: sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==} + ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -734,16 +878,31 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + app-root-path@3.1.0: + resolution: {integrity: sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==} + engines: {node: '>= 6.0.0'} + + archive-type@4.0.0: + resolution: {integrity: sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==} + engines: {node: '>=4'} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + array-differ@3.0.0: + resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} + engines: {node: '>=8'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} @@ -752,13 +911,30 @@ packages: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} + arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + assert@2.0.0: + resolution: {integrity: sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==} + + ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} + async@2.6.4: + resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} + + async@3.2.3: + resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==} + async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} @@ -769,6 +945,20 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + aws-ssl-profiles@1.1.2: + resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} + engines: {node: '>= 6.0.0'} + + axios@1.7.9: + resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} + + b4a@1.6.7: + resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} + babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -797,16 +987,46 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} + + bare-fs@2.3.5: + resolution: {integrity: sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==} + + bare-os@2.4.4: + resolution: {integrity: sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==} + + bare-path@2.1.3: + resolution: {integrity: sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==} + + bare-stream@2.6.1: + resolution: {integrity: sha512-eVZbtKM+4uehzrsj49KtCy3Pbg7kO1pJ3SKZ1SFrIH/0pnj9scuGGgUlNDf/7qS8WKtGdiJY5Kyhs/ivYPTB/g==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + basic-ftp@5.0.5: + resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} + engines: {node: '>=10.0.0'} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bl@1.2.3: + resolution: {integrity: sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + blessed@0.1.81: + resolution: {integrity: sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==} + engines: {node: '>= 0.8.0'} + hasBin: true + + bodec@0.1.0: + resolution: {integrity: sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==} + boxen@5.1.2: resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} engines: {node: '>=10'} @@ -833,12 +1053,30 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + buffer-alloc-unsafe@1.1.0: + resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} + + buffer-alloc@1.2.0: + resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer-fill@1.0.0: + resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -847,6 +1085,12 @@ packages: resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} engines: {node: '>= 6.0.0'} + cache-manager@3.6.3: + resolution: {integrity: sha512-dS4DnV6c6cQcVH5OxzIU1XZaACXwvVIiUPkFytnRmLOACuBGv3GQgRQ1RJGRRw4/9DF14ZK2RFlZu1TUgDniMg==} + + cacheable-request@2.1.4: + resolution: {integrity: sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==} + cacheable-request@6.1.0: resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} engines: {node: '>=8'} @@ -855,6 +1099,10 @@ packages: resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} engines: {node: '>= 0.4'} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + call-bound@1.0.3: resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} engines: {node: '>= 0.4'} @@ -882,10 +1130,17 @@ packages: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chance@1.1.9: + resolution: {integrity: sha512-TfxnA/DcZXRTA4OekA2zL9GH8qscbbl6X0ZqU4tXhGveVY/mXWvEQLt5GwZcYXTEyEFflVtj+pG8nc8EwSm1RQ==} + char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} @@ -893,6 +1148,12 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + charm@0.1.2: + resolution: {integrity: sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -917,6 +1178,9 @@ packages: class-transformer@0.5.1: resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + class-validator@0.14.1: + resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==} + cli-boxes@2.2.1: resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} engines: {node: '>=6'} @@ -925,10 +1189,19 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + cli-table3@0.6.5: resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} engines: {node: 10.* || >= 12.*} + cli-tableau@2.0.1: + resolution: {integrity: sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==} + engines: {node: '>=8.10.0'} + cli-width@3.0.0: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} @@ -940,6 +1213,9 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clone-response@1.0.2: + resolution: {integrity: sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==} + clone-response@1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} @@ -967,13 +1243,30 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} + commander@10.0.0: + resolution: {integrity: sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==} + engines: {node: '>=14'} + + commander@13.0.0: + resolution: {integrity: sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==} + engines: {node: '>=18'} + + commander@2.15.1: + resolution: {integrity: sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} commander@9.5.0: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} @@ -985,6 +1278,10 @@ packages: component-emitter@1.3.1: resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1021,6 +1318,12 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true + cron@2.4.4: + resolution: {integrity: sha512-MHlPImXJj3K7x7lyUHjtKEOl69CSlTOWxS89jiFgNkzXfvhVjhMz/nc7/EIfN9vgooZp8XTtXJ1FREdmbyXOiQ==} + + croner@4.1.97: + resolution: {integrity: sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==} + cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} @@ -1030,13 +1333,43 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + crypto-random-string@2.0.0: resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} engines: {node: '>=8'} + culvert@0.1.2: + resolution: {integrity: sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==} + + data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + dayjs@1.8.36: + resolution: {integrity: sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -1054,6 +1387,10 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + decompress-response@3.3.0: resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} engines: {node: '>=4'} @@ -1062,6 +1399,26 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} + decompress-tar@4.1.1: + resolution: {integrity: sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==} + engines: {node: '>=4'} + + decompress-tarbz2@4.1.1: + resolution: {integrity: sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==} + engines: {node: '>=4'} + + decompress-targz@4.1.1: + resolution: {integrity: sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==} + engines: {node: '>=4'} + + decompress-unzip@4.0.1: + resolution: {integrity: sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==} + engines: {node: '>=4'} + + decompress@4.2.1: + resolution: {integrity: sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==} + engines: {node: '>=4'} + dedent@1.5.3: resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: @@ -1087,6 +1444,18 @@ packages: defer-to-connect@1.1.3: resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -1094,6 +1463,10 @@ packages: delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + depd@1.1.2: resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} engines: {node: '>= 0.6'} @@ -1133,6 +1506,14 @@ packages: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + download@8.0.0: + resolution: {integrity: sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==} + engines: {node: '>=10'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -1143,6 +1524,9 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -1171,6 +1555,10 @@ packages: end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -1190,6 +1578,9 @@ packages: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} + es6-object-assign@1.1.0: + resolution: {integrity: sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1213,6 +1604,11 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + eslint-config-prettier@8.10.0: resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} hasBin: true @@ -1246,6 +1642,10 @@ packages: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} + eslint-scope@7.1.1: + resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-utils@2.1.0: resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} engines: {node: '>=6'} @@ -1258,6 +1658,10 @@ packages: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} engines: {node: '>=10'} + eslint-visitor-keys@3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1297,6 +1701,15 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + eventemitter2@0.4.14: + resolution: {integrity: sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==} + + eventemitter2@5.0.1: + resolution: {integrity: sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==} + + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -1313,20 +1726,37 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + ext-list@2.2.2: + resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} + engines: {node: '>=0.10.0'} + + ext-name@5.0.0: + resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} + engines: {node: '>=4'} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} + extrareqp2@1.0.0: + resolution: {integrity: sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-json-patch@3.1.1: + resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==} + fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -1345,6 +1775,12 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fclone@1.0.11: + resolution: {integrity: sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -1353,9 +1789,41 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} + file-type@11.1.0: + resolution: {integrity: sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==} + engines: {node: '>=6'} + + file-type@16.5.4: + resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} + engines: {node: '>=10'} + + file-type@3.9.0: + resolution: {integrity: sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==} + engines: {node: '>=0.10.0'} + + file-type@4.4.0: + resolution: {integrity: sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==} + engines: {node: '>=4'} + + file-type@5.2.0: + resolution: {integrity: sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==} + engines: {node: '>=4'} + + file-type@6.2.0: + resolution: {integrity: sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==} + engines: {node: '>=4'} + filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filename-reserved-regex@2.0.0: + resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} + engines: {node: '>=4'} + + filenamify@3.0.0: + resolution: {integrity: sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==} + engines: {node: '>=6'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1371,6 +1839,18 @@ packages: flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + foreground-child@3.3.0: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} @@ -1396,6 +1876,9 @@ packages: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} + fs-readdir-recursive@1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1410,6 +1893,9 @@ packages: functional-red-black-tree@1.0.1: resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + generate-function@2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1430,6 +1916,14 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@2.3.1: + resolution: {integrity: sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==} + engines: {node: '>=0.10.0'} + + get-stream@3.0.0: + resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} + engines: {node: '>=4'} + get-stream@4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} engines: {node: '>=6'} @@ -1442,6 +1936,21 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-uri@6.0.4: + resolution: {integrity: sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==} + engines: {node: '>= 14'} + + git-node-fs@1.0.0: + resolution: {integrity: sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==} + peerDependencies: + js-git: ^0.7.8 + peerDependenciesMeta: + js-git: + optional: true + + git-sha1@0.1.2: + resolution: {integrity: sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==} + github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} @@ -1453,6 +1962,11 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + glob@11.0.1: + resolution: {integrity: sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==} + engines: {node: 20 || >=22} + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -1477,6 +1991,10 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + got@8.3.2: + resolution: {integrity: sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==} + engines: {node: '>=4'} + got@9.6.0: resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} engines: {node: '>=8.6'} @@ -1499,10 +2017,19 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbol-support-x@1.4.2: + resolution: {integrity: sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} + has-to-string-tag-x@1.4.1: + resolution: {integrity: sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==} + has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} @@ -1523,6 +2050,9 @@ packages: resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} engines: {node: '>=8'} + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -1537,6 +2067,9 @@ packages: resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} engines: {node: '>= 0.8'} + http-cache-semantics@3.8.1: + resolution: {integrity: sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==} + http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} @@ -1548,10 +2081,18 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -1560,6 +2101,10 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1614,17 +2159,42 @@ packages: resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} engines: {node: '>=8.0.0'} + into-stream@3.1.0: + resolution: {integrity: sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==} + engines: {node: '>=4'} + into-stream@6.0.0: resolution: {integrity: sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==} engines: {node: '>=10'} + inversify@6.0.1: + resolution: {integrity: sha512-B3ex30927698TJENHR++8FfEaJGqoWOgI6ZY5Ht/nLUsFCwHn6akbwtnUAPCgUepAnTpe2qHxhDNjoKLyz6rgQ==} + + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + is-ci@2.0.0: resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} hasBin: true @@ -1660,6 +2230,13 @@ packages: resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} engines: {node: '>=10'} + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + + is-natural-number@4.0.1: + resolution: {integrity: sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==} + is-npm@5.0.0: resolution: {integrity: sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==} engines: {node: '>=10'} @@ -1672,6 +2249,9 @@ packages: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} + is-object@1.0.2: + resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} + is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} @@ -1680,14 +2260,29 @@ packages: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} + is-property@1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} + is-retry-allowed@1.2.0: + resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} + engines: {node: '>=0.10.0'} + + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} @@ -1724,14 +2319,27 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} + isurl@1.0.0: + resolution: {integrity: sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==} + engines: {node: '>= 4'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.0.2: + resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} + engines: {node: 20 || >=22} + jake@10.9.2: resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} engines: {node: '>=10'} hasBin: true + javascript-obfuscator@4.1.1: + resolution: {integrity: sha512-gt+KZpIIrrxXHEQGD8xZrL8mTRwRY0U76/xz/YX0gZdPrSqQhT/c7dYLASlLlecT3r+FxE7je/+C0oLnTDCx4A==} + engines: {node: '>=12.22.0'} + hasBin: true + jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1864,6 +2472,13 @@ packages: joi@17.13.3: resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + js-git@0.7.8: + resolution: {integrity: sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==} + + js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1875,6 +2490,9 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} @@ -1903,6 +2521,9 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -1911,10 +2532,23 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonwebtoken@9.0.2: + resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} + engines: {node: '>=12', npm: '>=6'} + + jwa@1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + + jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + keygrip@1.1.0: resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} engines: {node: '>= 0.6'} + keyv@3.0.0: + resolution: {integrity: sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==} + keyv@3.1.0: resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} @@ -1940,6 +2574,14 @@ packages: resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==} engines: {node: '>= 10'} + koa-range@0.3.0: + resolution: {integrity: sha512-Ich3pCz6RhtbajYXRWjIl6O5wtrLs6kE3nkXc9XmaWe+MysJyZO7K4L3oce1Jpg/iMgCbj+5UCiMm/rqVtcDIg==} + engines: {node: '>=7'} + + koa-static-cache@5.1.4: + resolution: {integrity: sha512-abVWOHY6z6qSTvNtapWMAnvHS9SUiUCaQQQubClSAT9ybQPsZ6ioKcRarnownS4fMD0sXQgQ5ey8CYEuwoa1Yg==} + engines: {node: '>= 7.6.0'} + koa@2.15.3: resolution: {integrity: sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} @@ -1948,14 +2590,25 @@ packages: resolution: {integrity: sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==} engines: {node: '>=8'} + lazy@1.0.11: + resolution: {integrity: sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==} + engines: {node: '>=0.2.0'} + leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + libphonenumber-js@1.11.17: + resolution: {integrity: sha512-Jr6v8thd5qRlOlc6CslSTzGzzQW03uiscab7KHQZX1Dfo4R6n6FDhZ0Hri6/X7edLIDv9gl4VMZXhxTjLnl0VQ==} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -1963,18 +2616,52 @@ packages: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} + lockfile@1.0.4: + resolution: {integrity: sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + long@5.2.4: + resolution: {integrity: sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==} + + lowercase-keys@1.0.0: + resolution: {integrity: sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==} + engines: {node: '>=0.10.0'} + lowercase-keys@1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} engines: {node: '>=0.10.0'} @@ -1986,6 +2673,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.0.2: + resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -1993,6 +2684,26 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + lru.min@1.1.1: + resolution: {integrity: sha512-FbAj6lXil6t8z4z3j0E5mfRlPzxkySotzUHwRXjlpRh10vc6AI6WN62ehZj82VG7M20rqogJ0GLwar2Xa05a8Q==} + engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} + + luxon@3.3.0: + resolution: {integrity: sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==} + engines: {node: '>=12'} + + make-dir@1.3.0: + resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} + engines: {node: '>=4'} + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -2019,6 +2730,9 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -2071,6 +2785,10 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2100,14 +2818,39 @@ packages: mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@2.1.3: + resolution: {integrity: sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@2.1.6: + resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==} + engines: {node: '>=10'} + hasBin: true + mkdirp@3.0.1: resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} engines: {node: '>=10'} hasBin: true + module-details-from-path@1.0.3: + resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + multimatch@5.0.0: + resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} + engines: {node: '>=10'} + multistream@4.1.0: resolution: {integrity: sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==} @@ -2130,6 +2873,17 @@ packages: resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==} engines: {node: '>=12.0.0'} + mysql2@3.12.0: + resolution: {integrity: sha512-C8fWhVysZoH63tJbX8d10IAoYCyXy4fdRFz2Ihrt9jtPILYynFEKUUzpp1U7qxzDc3tMbotvaBH+sl6bFnGZiw==} + engines: {node: '>= 8.0'} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + named-placeholders@1.1.3: + resolution: {integrity: sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==} + engines: {node: '>=12.0.0'} + napi-build-utils@1.0.2: resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} @@ -2143,14 +2897,26 @@ packages: resolution: {integrity: sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==} hasBin: true + needle@2.4.0: + resolution: {integrity: sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==} + engines: {node: '>= 4.4.x'} + hasBin: true + negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} + netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + node-abi@3.71.0: resolution: {integrity: sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==} engines: {node: '>=10'} + node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -2177,6 +2943,10 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-url@2.0.1: + resolution: {integrity: sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==} + engines: {node: '>=4'} + normalize-url@4.5.1: resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==} engines: {node: '>=8'} @@ -2185,10 +2955,26 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + nssocket@0.6.0: + resolution: {integrity: sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==} + engines: {node: '>= 0.10.x'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + object-inspect@1.13.3: resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -2203,6 +2989,18 @@ packages: only@0.0.2: resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} + opencollective-postinstall@2.0.3: + resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==} + hasBin: true + + opentype.js@0.7.3: + resolution: {integrity: sha512-Veui5vl2bLonFJ/SjX/WRWJT3SncgiZNnKUyahmXCc2sa1xXW15u3R/3TN5+JFiP7RsjK5ER4HA5eWaEmV9deA==} + hasBin: true + + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2211,10 +3009,26 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + p-cancelable@0.4.1: + resolution: {integrity: sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==} + engines: {node: '>=4'} + p-cancelable@1.1.0: resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} engines: {node: '>=6'} + p-event@2.3.1: + resolution: {integrity: sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==} + engines: {node: '>=6'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-is-promise@1.1.0: + resolution: {integrity: sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==} + engines: {node: '>=4'} + p-is-promise@3.0.0: resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} engines: {node: '>=8'} @@ -2231,10 +3045,22 @@ packages: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} + p-timeout@2.0.1: + resolution: {integrity: sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==} + engines: {node: '>=4'} + p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + pac-proxy-agent@7.1.0: + resolution: {integrity: sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==} + engines: {node: '>= 14'} + + pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -2242,6 +3068,9 @@ packages: resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==} engines: {node: '>=8'} + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2250,6 +3079,15 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -2273,6 +3111,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} @@ -2280,6 +3122,13 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + peek-readable@4.1.0: + resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} + engines: {node: '>=8'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2287,6 +3136,34 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + pidusage@2.0.21: + resolution: {integrity: sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==} + engines: {node: '>=8'} + + pidusage@3.0.2: + resolution: {integrity: sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==} + engines: {node: '>=10'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -2312,11 +3189,42 @@ packages: resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==} engines: {node: '>=12'} + pm2-axon-rpc@0.7.1: + resolution: {integrity: sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==} + engines: {node: '>=5'} + + pm2-axon@4.0.1: + resolution: {integrity: sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==} + engines: {node: '>=5'} + + pm2-deploy@1.0.2: + resolution: {integrity: sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==} + engines: {node: '>=4.0.0'} + + pm2-multimeter@0.1.2: + resolution: {integrity: sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==} + + pm2-sysmonit@1.2.8: + resolution: {integrity: sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==} + + pm2@5.4.3: + resolution: {integrity: sha512-4/I1htIHzZk1Y67UgOCo4F1cJtas1kSds31N8zN0PybO230id1nigyjGuGFzUnGmUFPmrJ0On22fO1ChFlp7VQ==} + engines: {node: '>=12.0.0'} + hasBin: true + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} engines: {node: '>=10'} hasBin: true + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2341,14 +3249,28 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} + promptly@2.2.0: + resolution: {integrity: sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==} + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + proxy-agent@6.3.1: + resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} + engines: {node: '>= 14'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -2367,6 +3289,10 @@ packages: resolution: {integrity: sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==} engines: {node: '>=0.6'} + query-string@5.1.1: + resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} + engines: {node: '>=0.10.0'} + queue-lit@1.5.2: resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==} engines: {node: '>=12'} @@ -2374,6 +3300,9 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} @@ -2397,6 +3326,10 @@ packages: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} + read@1.0.7: + resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} + engines: {node: '>=0.8'} + readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -2404,6 +3337,10 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readable-web-to-node-stream@3.0.2: + resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} + engines: {node: '>=8'} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -2412,6 +3349,9 @@ packages: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + reflect-metadata@0.1.13: + resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -2435,6 +3375,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-in-the-middle@5.2.0: + resolution: {integrity: sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==} + engines: {node: '>=6'} + resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -2483,6 +3427,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + run-series@1.1.9: + resolution: {integrity: sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==} + rxjs@6.6.7: resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} engines: {npm: '>=2.0.0'} @@ -2504,9 +3451,16 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + scmp@2.1.0: resolution: {integrity: sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q==} + seek-bzip@1.0.6: + resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==} + hasBin: true + semver-diff@3.1.1: resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==} engines: {node: '>=8'} @@ -2519,14 +3473,34 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true + seq-queue@0.0.5: + resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + sharp@0.32.6: + resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} + engines: {node: '>=14.15.0'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2535,6 +3509,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shimmer@1.2.1: + resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} + should-send-same-site-none@2.0.5: resolution: {integrity: sha512-7dig49H7sKnv1v/GPoFQChGgJdEX9s2oy9TQBSD5RbUx7M9CCRjHMaFP06v+DZQNM0K+o8dBhvBAd4eEKirqbQ==} @@ -2567,6 +3544,9 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -2578,6 +3558,30 @@ packages: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + sort-keys-length@1.0.1: + resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} + engines: {node: '>=0.10.0'} + + sort-keys@1.1.2: + resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} + engines: {node: '>=0.10.0'} + + sort-keys@2.0.0: + resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} + engines: {node: '>=4'} + source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} @@ -2603,6 +3607,16 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + sprintf-js@1.1.2: + resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + sqlstring@2.3.3: + resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} + engines: {node: '>= 0.6'} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -2618,10 +3632,23 @@ packages: stream-meter@1.0.4: resolution: {integrity: sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==} + stream-slice@0.1.2: + resolution: {integrity: sha512-QzQxpoacatkreL6jsxnVb7X5R/pGw9OUv2qWTYWnmLpg4NdN31snPy/f3TdQE1ZUXaThRvj1Zw4/OGg0ZkaLMA==} + + streamx@2.21.1: + resolution: {integrity: sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==} + + strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} + string-template@1.0.0: + resolution: {integrity: sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2636,6 +3663,9 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringz@2.1.0: + resolution: {integrity: sha512-KlywLT+MZ+v0IRepfMxRtnSvDCMc3nR1qqCs3m/qIbSOWkNZYT8XHQA31rS3TnKp0c5xjZu3M4GY/2aRKSi/6A==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -2648,6 +3678,9 @@ packages: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} + strip-dirs@2.1.0: + resolution: {integrity: sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==} + strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -2664,6 +3697,14 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-outer@1.0.1: + resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} + engines: {node: '>=0.10.0'} + + strtok3@6.3.0: + resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} + engines: {node: '>=10'} + superagent@8.1.2: resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} engines: {node: '>=6.4.0 <13 || >=14'} @@ -2689,6 +3730,16 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svg-captcha@1.4.0: + resolution: {integrity: sha512-/fkkhavXPE57zRRCjNqAP3txRCSncpMx3NnNZL7iEoyAtYwUjPhJxW6FQTQPG5UPEmCrbFoXS10C3YdJlW7PDg==} + engines: {node: '>=4.x'} + + systeminformation@5.25.10: + resolution: {integrity: sha512-7HVNcraf5VUsFHfl/1/bixFidJKrk//BjnPkYdJChqKdHmSyMGYkB6GRWWC3SKClg5D5v5SMpay4oO7hsFhiWg==} + engines: {node: '>=8.0.0'} + os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] + hasBin: true + table@6.9.0: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} @@ -2696,10 +3747,20 @@ packages: tar-fs@2.1.1: resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + tar-fs@3.0.6: + resolution: {integrity: sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==} + + tar-stream@1.6.2: + resolution: {integrity: sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==} + engines: {node: '>= 0.8.0'} + tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + tar@7.4.3: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} @@ -2708,12 +3769,29 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + timed-out@4.0.1: + resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} + engines: {node: '>=0.10.0'} + + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -2721,6 +3799,9 @@ packages: tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + to-buffer@1.1.1: + resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==} + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -2737,6 +3818,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + token-types@4.2.1: + resolution: {integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==} + engines: {node: '>=10'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -2744,6 +3829,10 @@ packages: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} + trim-repeated@1.0.0: + resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==} + engines: {node: '>=0.10.0'} + ts-jest@29.2.5: resolution: {integrity: sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} @@ -2775,6 +3864,15 @@ packages: tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@1.9.3: + resolution: {integrity: sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==} + + tslib@2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsscmp@1.0.6: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} @@ -2788,6 +3886,17 @@ packages: tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + tv4@1.3.0: + resolution: {integrity: sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==} + engines: {node: '>= 0.8.0'} + + tx2@1.0.5: + resolution: {integrity: sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==} + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -2823,11 +3932,72 @@ packages: typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + typeorm@0.3.20: + resolution: {integrity: sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==} + engines: {node: '>=16.13.0'} + hasBin: true + peerDependencies: + '@google-cloud/spanner': ^5.18.0 + '@sap/hana-client': ^2.12.25 + better-sqlite3: ^7.1.2 || ^8.0.0 || ^9.0.0 + hdb-pool: ^0.1.6 + ioredis: ^5.0.4 + mongodb: ^5.8.0 + mssql: ^9.1.1 || ^10.0.1 + mysql2: ^2.2.5 || ^3.0.1 + oracledb: ^6.3.0 + pg: ^8.5.1 + pg-native: ^3.0.0 + pg-query-stream: ^4.0.0 + redis: ^3.1.1 || ^4.0.0 + sql.js: ^1.4.0 + sqlite3: ^5.0.3 + ts-node: ^10.7.0 + typeorm-aurora-data-api-driver: ^2.0.0 + peerDependenciesMeta: + '@google-cloud/spanner': + optional: true + '@sap/hana-client': + optional: true + better-sqlite3: + optional: true + hdb-pool: + optional: true + ioredis: + optional: true + mongodb: + optional: true + mssql: + optional: true + mysql2: + optional: true + oracledb: + optional: true + pg: + optional: true + pg-native: + optional: true + pg-query-stream: + optional: true + redis: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + ts-node: + optional: true + typeorm-aurora-data-api-driver: + optional: true + typescript@5.7.3: resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} engines: {node: '>=14.17'} hasBin: true + unbzip2-stream@1.4.3: + resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} @@ -2860,9 +4030,24 @@ packages: resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} engines: {node: '>=4'} + url-to-options@1.0.1: + resolution: {integrity: sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==} + engines: {node: '>= 4'} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + uuid@11.0.5: + resolution: {integrity: sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + v8-compile-cache@2.4.0: resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} @@ -2873,10 +4058,18 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} + engines: {node: '>= 0.10'} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vizion@2.2.1: + resolution: {integrity: sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==} + engines: {node: '>=4.0'} + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -2886,6 +4079,10 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-typed-array@1.1.18: + resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} + engines: {node: '>= 0.4'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -2917,10 +4114,38 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + 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 + xdg-basedir@4.0.0: resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} engines: {node: '>=8'} + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -2951,6 +4176,9 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + ylru@1.4.0: resolution: {integrity: sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==} engines: {node: '>= 4.0.0'} @@ -3183,9 +4411,34 @@ snapshots: '@colors/colors@1.5.0': optional: true + '@cool-midway/cache-manager-fs-hash@7.0.0': + dependencies: + lockfile: 1.0.4 + '@cool-midway/core@file:../midway-packages/core': dependencies: - commander: 11.1.0 + '@cool-midway/cache-manager-fs-hash': 7.0.0 + '@midwayjs/cache': 3.14.0 + '@midwayjs/cache-manager': 3.19.3 + axios: 1.7.9 + commander: 13.0.0 + decompress: 4.2.1 + download: 8.0.0 + glob: 11.0.1 + javascript-obfuscator: 4.1.1 + jsonwebtoken: 9.0.2 + lodash: 4.17.21 + md5: 2.3.0 + moment: 2.30.1 + pm2: 5.4.3 + sqlstring: 2.3.3 + uuid: 11.0.5 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate '@eslint-community/eslint-utils@4.4.1(eslint@7.32.0)': dependencies: @@ -3249,6 +4502,17 @@ snapshots: '@istanbuljs/schema@0.1.3': {} + '@javascript-obfuscator/escodegen@2.3.0': + dependencies: + '@javascript-obfuscator/estraverse': 5.4.0 + esprima: 4.0.1 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + + '@javascript-obfuscator/estraverse@5.4.0': {} + '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 @@ -3447,6 +4711,15 @@ snapshots: '@midwayjs/bundle-helper@1.3.0': {} + '@midwayjs/cache-manager@3.19.3': + dependencies: + lodash.clonedeep: 4.5.0 + lru-cache: 7.18.3 + + '@midwayjs/cache@3.14.0': + dependencies: + cache-manager: 3.6.3 + '@midwayjs/cookies@1.2.0': dependencies: scmp: 2.1.0 @@ -3459,6 +4732,14 @@ snapshots: picomatch: 2.3.1 reflect-metadata: 0.2.2 + '@midwayjs/cron@3.19.2': + dependencies: + cron: 2.4.4 + + '@midwayjs/cross-domain@3.19.3': + dependencies: + vary: 1.1.2 + '@midwayjs/event-bus@1.11.1': {} '@midwayjs/glob@1.1.1': @@ -3507,11 +4788,33 @@ snapshots: dependencies: '@midwayjs/cookies': 1.2.0 + '@midwayjs/static-file@3.19.3': + dependencies: + koa-range: 0.3.0 + koa-static-cache: 5.1.4 + ylru: 1.4.0 + transitivePeerDependencies: + - supports-color + + '@midwayjs/typeorm@3.19.2': {} + + '@midwayjs/upload@3.19.3': + dependencies: + file-type: 16.5.4 + raw-body: 2.5.2 + '@midwayjs/validate@3.19.2': dependencies: '@midwayjs/i18n': 3.19.2 joi: 17.13.3 + '@midwayjs/view-ejs@3.19.2': + dependencies: + '@midwayjs/view': 3.19.2 + ejs: 3.1.10 + + '@midwayjs/view@3.19.2': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3527,6 +4830,57 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@pm2/agent@2.0.4': + dependencies: + async: 3.2.6 + chalk: 3.0.0 + dayjs: 1.8.36 + debug: 4.3.7 + eventemitter2: 5.0.1 + fast-json-patch: 3.1.1 + fclone: 1.0.11 + nssocket: 0.6.0 + pm2-axon: 4.0.1 + pm2-axon-rpc: 0.7.1 + proxy-agent: 6.3.1 + semver: 7.5.4 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@pm2/io@6.0.1': + dependencies: + async: 2.6.4 + debug: 4.3.7 + eventemitter2: 6.4.9 + require-in-the-middle: 5.2.0 + semver: 7.5.4 + shimmer: 1.2.1 + signal-exit: 3.0.7 + tslib: 1.9.3 + transitivePeerDependencies: + - supports-color + + '@pm2/js-api@0.8.0': + dependencies: + async: 2.6.4 + debug: 4.3.7 + eventemitter2: 6.4.9 + extrareqp2: 1.0.0(debug@4.3.7) + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@pm2/pm2-version-check@1.0.4': + dependencies: + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + '@sideway/address@4.1.5': dependencies: '@hapi/hoek': 9.3.0 @@ -3539,6 +4893,8 @@ snapshots: '@sindresorhus/is@0.14.0': {} + '@sindresorhus/is@0.7.0': {} + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 @@ -3547,10 +4903,16 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 + '@sqltools/formatter@1.2.5': {} + '@szmarczak/http-timer@1.1.2': dependencies: defer-to-connect: 1.1.3 + '@tokenizer/token@0.3.0': {} + + '@tootallnate/quickjs-emscripten@0.23.0': {} + '@types/accepts@1.3.7': dependencies: '@types/node': 22.10.5 @@ -3656,8 +5018,12 @@ snapshots: '@types/koa-compose': 3.2.8 '@types/node': 22.10.5 + '@types/luxon@3.3.8': {} + '@types/mime@1.3.5': {} + '@types/minimatch@3.0.5': {} + '@types/minimist@1.2.5': {} '@types/node@22.10.5': @@ -3698,6 +5064,8 @@ snapshots: dependencies: '@types/superagent': 4.1.14 + '@types/validator@13.12.2': {} + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.33': @@ -3788,8 +5156,6 @@ snapshots: '@typescript-eslint/types': 5.62.0 eslint-visitor-keys: 3.4.3 - '@vercel/ncc@0.38.3': {} - accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -3801,12 +5167,16 @@ snapshots: acorn@7.4.1: {} + acorn@8.8.2: {} + agent-base@6.0.2: dependencies: debug: 4.4.0 transitivePeerDependencies: - supports-color + agent-base@7.1.3: {} + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -3821,6 +5191,12 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + amp-message@0.1.2: + dependencies: + amp: 0.3.1 + + amp@0.3.1: {} + ansi-align@3.0.1: dependencies: string-width: 4.2.3 @@ -3847,31 +5223,76 @@ snapshots: ansi-styles@6.2.1: {} + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 + app-root-path@3.1.0: {} + + archive-type@4.0.0: + dependencies: + file-type: 4.4.0 + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 argparse@2.0.1: {} + array-differ@3.0.0: {} + array-union@2.1.0: {} arrify@1.0.1: {} + arrify@2.0.1: {} + asap@2.0.6: {} + assert@2.0.0: + dependencies: + es6-object-assign: 1.1.0 + is-nan: 1.3.2 + object-is: 1.1.6 + util: 0.12.5 + + ast-types@0.13.4: + dependencies: + tslib: 2.8.1 + astral-regex@2.0.0: {} + async@2.6.4: + dependencies: + lodash: 4.17.21 + + async@3.2.3: {} + async@3.2.6: {} asynckit@0.4.0: {} at-least-node@1.0.0: {} + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + aws-ssl-profiles@1.1.2: {} + + axios@1.7.9: + dependencies: + follow-redirects: 1.15.9(debug@4.3.7) + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + b4a@1.6.7: {} + babel-jest@29.7.0(@babel/core@7.26.0): dependencies: '@babel/core': 7.26.0 @@ -3929,16 +5350,50 @@ snapshots: balanced-match@1.0.2: {} + bare-events@2.5.4: + optional: true + + bare-fs@2.3.5: + dependencies: + bare-events: 2.5.4 + bare-path: 2.1.3 + bare-stream: 2.6.1 + optional: true + + bare-os@2.4.4: + optional: true + + bare-path@2.1.3: + dependencies: + bare-os: 2.4.4 + optional: true + + bare-stream@2.6.1: + dependencies: + streamx: 2.21.1 + optional: true + base64-js@1.5.1: {} + basic-ftp@5.0.5: {} + binary-extensions@2.3.0: {} + bl@1.2.3: + dependencies: + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + bl@4.1.0: dependencies: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 + blessed@0.1.81: {} + + bodec@0.1.0: {} + boxen@5.1.2: dependencies: ansi-align: 3.0.1 @@ -3978,6 +5433,19 @@ snapshots: dependencies: node-int64: 0.4.0 + buffer-alloc-unsafe@1.1.0: {} + + buffer-alloc@1.2.0: + dependencies: + buffer-alloc-unsafe: 1.1.0 + buffer-fill: 1.0.0 + + buffer-crc32@0.2.13: {} + + buffer-equal-constant-time@1.0.1: {} + + buffer-fill@1.0.0: {} + buffer-from@1.1.2: {} buffer@5.7.1: @@ -3985,6 +5453,11 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + bytes@3.1.2: {} cache-content-type@1.0.1: @@ -3992,6 +5465,22 @@ snapshots: mime-types: 2.1.35 ylru: 1.4.0 + cache-manager@3.6.3: + dependencies: + async: 3.2.3 + lodash.clonedeep: 4.5.0 + lru-cache: 6.0.0 + + cacheable-request@2.1.4: + dependencies: + clone-response: 1.0.2 + get-stream: 3.0.0 + http-cache-semantics: 3.8.1 + keyv: 3.0.0 + lowercase-keys: 1.0.0 + normalize-url: 2.0.1 + responselike: 1.0.2 + cacheable-request@6.1.0: dependencies: clone-response: 1.0.3 @@ -4007,6 +5496,13 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-define-property: 1.0.1 + get-intrinsic: 1.2.7 + set-function-length: 1.2.2 + call-bound@1.0.3: dependencies: call-bind-apply-helpers: 1.0.1 @@ -4032,15 +5528,26 @@ snapshots: escape-string-regexp: 1.0.5 supports-color: 5.5.0 + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + chance@1.1.9: {} + char-regex@1.0.2: {} chardet@0.7.0: {} + charenc@0.0.2: {} + + charm@0.1.2: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -4065,18 +5572,37 @@ snapshots: class-transformer@0.5.1: {} + class-validator@0.14.1: + dependencies: + '@types/validator': 13.12.2 + libphonenumber-js: 1.11.17 + validator: 13.12.0 + cli-boxes@2.2.1: {} cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 + cli-highlight@2.1.11: + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + cli-table3@0.6.5: dependencies: string-width: 4.2.3 optionalDependencies: '@colors/colors': 1.5.0 + cli-tableau@2.0.1: + dependencies: + chalk: 3.0.0 + cli-width@3.0.0: {} cliui@7.0.4: @@ -4091,6 +5617,10 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clone-response@1.0.2: + dependencies: + mimic-response: 1.0.1 + clone-response@1.0.3: dependencies: mimic-response: 1.0.1 @@ -4119,11 +5649,27 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - commander@11.1.0: {} + commander@10.0.0: {} + + commander@13.0.0: {} + + commander@2.15.1: {} + + commander@2.20.3: {} commander@9.5.0: {} @@ -4131,6 +5677,10 @@ snapshots: component-emitter@1.3.1: {} + compressible@2.0.18: + dependencies: + mime-db: 1.52.0 + concat-map@0.0.1: {} configstore@5.0.1: @@ -4176,6 +5726,13 @@ snapshots: - supports-color - ts-node + cron@2.4.4: + dependencies: + '@types/luxon': 3.3.8 + luxon: 3.3.0 + + croner@4.1.97: {} + cross-env@7.0.3: dependencies: cross-spawn: 7.0.6 @@ -4186,10 +5743,26 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crypt@0.0.2: {} + crypto-random-string@2.0.0: {} + culvert@0.1.2: {} + + data-uri-to-buffer@6.0.2: {} + dayjs@1.11.13: {} + dayjs@1.8.36: {} + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + debug@4.4.0: dependencies: ms: 2.1.3 @@ -4201,6 +5774,8 @@ snapshots: decamelize@1.2.0: {} + decode-uri-component@0.2.2: {} + decompress-response@3.3.0: dependencies: mimic-response: 1.0.1 @@ -4209,6 +5784,44 @@ snapshots: dependencies: mimic-response: 3.1.0 + decompress-tar@4.1.1: + dependencies: + file-type: 5.2.0 + is-stream: 1.1.0 + tar-stream: 1.6.2 + + decompress-tarbz2@4.1.1: + dependencies: + decompress-tar: 4.1.1 + file-type: 6.2.0 + is-stream: 1.1.0 + seek-bzip: 1.0.6 + unbzip2-stream: 1.4.3 + + decompress-targz@4.1.1: + dependencies: + decompress-tar: 4.1.1 + file-type: 5.2.0 + is-stream: 1.1.0 + + decompress-unzip@4.0.1: + dependencies: + file-type: 3.9.0 + get-stream: 2.3.1 + pify: 2.3.0 + yauzl: 2.10.0 + + decompress@4.2.1: + dependencies: + decompress-tar: 4.1.1 + decompress-tarbz2: 4.1.1 + decompress-targz: 4.1.1 + decompress-unzip: 4.0.1 + graceful-fs: 4.2.11 + make-dir: 1.3.0 + pify: 2.3.0 + strip-dirs: 2.1.0 + dedent@1.5.3: {} deep-equal@1.0.1: {} @@ -4221,10 +5834,30 @@ snapshots: defer-to-connect@1.1.3: {} + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + degenerator@5.0.1: + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + delayed-stream@1.0.0: {} delegates@1.0.0: {} + denque@2.1.0: {} + depd@1.1.2: {} depd@2.0.0: {} @@ -4254,6 +5887,22 @@ snapshots: dependencies: is-obj: 2.0.0 + dotenv@16.4.7: {} + + download@8.0.0: + dependencies: + archive-type: 4.0.0 + content-disposition: 0.5.4 + decompress: 4.2.1 + ext-name: 5.0.0 + file-type: 11.1.0 + filenamify: 3.0.0 + get-stream: 4.1.0 + got: 8.3.2 + make-dir: 2.1.0 + p-event: 2.3.1 + pify: 4.0.1 + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.1 @@ -4264,6 +5913,10 @@ snapshots: eastasianwidth@0.2.0: {} + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + ee-first@1.1.1: {} ejs@3.1.10: @@ -4284,6 +5937,10 @@ snapshots: dependencies: once: 1.4.0 + enquirer@2.3.6: + dependencies: + ansi-colors: 4.1.3 + enquirer@2.4.1: dependencies: ansi-colors: 4.1.3 @@ -4301,6 +5958,8 @@ snapshots: dependencies: es-errors: 1.3.0 + es6-object-assign@1.1.0: {} + escalade@3.2.0: {} escape-goat@2.1.1: {} @@ -4313,6 +5972,14 @@ snapshots: escape-string-regexp@4.0.0: {} + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + eslint-config-prettier@8.10.0(eslint@7.32.0): dependencies: eslint: 7.32.0 @@ -4346,6 +6013,11 @@ snapshots: esrecurse: 4.3.0 estraverse: 4.3.0 + eslint-scope@7.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-utils@2.1.0: dependencies: eslint-visitor-keys: 1.3.0 @@ -4354,6 +6026,8 @@ snapshots: eslint-visitor-keys@2.1.0: {} + eslint-visitor-keys@3.3.0: {} + eslint-visitor-keys@3.4.3: {} eslint@7.32.0: @@ -4423,6 +6097,12 @@ snapshots: esutils@2.0.3: {} + eventemitter2@0.4.14: {} + + eventemitter2@5.0.1: {} + + eventemitter2@6.4.9: {} + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -4447,16 +6127,33 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 + ext-list@2.2.2: + dependencies: + mime-db: 1.52.0 + + ext-name@5.0.0: + dependencies: + ext-list: 2.2.2 + sort-keys-length: 1.0.1 + external-editor@3.1.0: dependencies: chardet: 0.7.0 iconv-lite: 0.4.24 tmp: 0.0.33 + extrareqp2@1.0.0(debug@4.3.7): + dependencies: + follow-redirects: 1.15.9(debug@4.3.7) + transitivePeerDependencies: + - debug + fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} + fast-fifo@1.3.2: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4465,6 +6162,8 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-json-patch@3.1.1: {} + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} @@ -4481,6 +6180,12 @@ snapshots: dependencies: bser: 2.1.1 + fclone@1.0.11: {} + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -4489,10 +6194,34 @@ snapshots: dependencies: flat-cache: 3.2.0 + file-type@11.1.0: {} + + file-type@16.5.4: + dependencies: + readable-web-to-node-stream: 3.0.2 + strtok3: 6.3.0 + token-types: 4.2.1 + + file-type@3.9.0: {} + + file-type@4.4.0: {} + + file-type@5.2.0: {} + + file-type@6.2.0: {} + filelist@1.0.4: dependencies: minimatch: 5.1.6 + filename-reserved-regex@2.0.0: {} + + filenamify@3.0.0: + dependencies: + filename-reserved-regex: 2.0.0 + strip-outer: 1.0.1 + trim-repeated: 1.0.0 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -4510,6 +6239,14 @@ snapshots: flatted@3.3.2: {} + follow-redirects@1.15.9(debug@4.3.7): + optionalDependencies: + debug: 4.3.7 + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + foreground-child@3.3.0: dependencies: cross-spawn: 7.0.6 @@ -4544,6 +6281,8 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 + fs-readdir-recursive@1.1.0: {} + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -4553,6 +6292,10 @@ snapshots: functional-red-black-tree@1.0.1: {} + generate-function@2.3.1: + dependencies: + is-property: 1.0.2 + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -4577,6 +6320,13 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.0.0 + get-stream@2.3.1: + dependencies: + object-assign: 4.1.1 + pinkie-promise: 2.0.1 + + get-stream@3.0.0: {} + get-stream@4.1.0: dependencies: pump: 3.0.2 @@ -4587,6 +6337,20 @@ snapshots: get-stream@6.0.1: {} + get-uri@6.0.4: + dependencies: + basic-ftp: 5.0.5 + data-uri-to-buffer: 6.0.2 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + git-node-fs@1.0.0(js-git@0.7.8): + optionalDependencies: + js-git: 0.7.8 + + git-sha1@0.1.2: {} + github-from-package@0.0.0: {} glob-parent@5.1.2: @@ -4602,6 +6366,15 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@11.0.1: + dependencies: + foreground-child: 3.3.0 + jackspeak: 4.0.2 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -4632,6 +6405,28 @@ snapshots: gopd@1.2.0: {} + got@8.3.2: + dependencies: + '@sindresorhus/is': 0.7.0 + '@types/keyv': 3.1.4 + '@types/responselike': 1.0.3 + cacheable-request: 2.1.4 + decompress-response: 3.3.0 + duplexer3: 0.1.5 + get-stream: 3.0.0 + into-stream: 3.1.0 + is-retry-allowed: 1.2.0 + isurl: 1.0.0 + lowercase-keys: 1.0.1 + mimic-response: 1.0.1 + p-cancelable: 0.4.1 + p-timeout: 2.0.1 + pify: 3.0.0 + safe-buffer: 5.2.1 + timed-out: 4.0.1 + url-parse-lax: 3.0.0 + url-to-options: 1.0.1 + got@9.6.0: dependencies: '@sindresorhus/is': 0.14.0 @@ -4658,8 +6453,18 @@ snapshots: has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbol-support-x@1.4.2: {} + has-symbols@1.1.0: {} + has-to-string-tag-x@1.4.1: + dependencies: + has-symbol-support-x: 1.4.2 + has-tostringtag@1.0.2: dependencies: has-symbols: 1.1.0 @@ -4674,6 +6479,8 @@ snapshots: hexoid@1.0.0: {} + highlight.js@10.7.3: {} + hosted-git-info@2.8.9: {} hosted-git-info@4.1.0: @@ -4687,6 +6494,8 @@ snapshots: deep-equal: 1.0.1 http-errors: 1.8.1 + http-cache-semantics@3.8.1: {} + http-cache-semantics@4.1.1: {} http-errors@1.8.1: @@ -4705,6 +6514,13 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -4712,12 +6528,23 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + human-signals@2.1.0: {} iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} ignore@4.0.6: {} @@ -4769,17 +6596,40 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 + into-stream@3.1.0: + dependencies: + from2: 2.3.0 + p-is-promise: 1.1.0 + into-stream@6.0.0: dependencies: from2: 2.3.0 p-is-promise: 3.0.0 + inversify@6.0.1: {} + + ip-address@9.0.5: + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + is-arrayish@0.2.1: {} + is-arrayish@0.3.2: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 + is-buffer@1.1.6: {} + + is-callable@1.2.7: {} + is-ci@2.0.0: dependencies: ci-info: 2.0.0 @@ -4814,16 +6664,27 @@ snapshots: global-dirs: 3.0.1 is-path-inside: 3.0.3 + is-nan@1.3.2: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + is-natural-number@4.0.1: {} + is-npm@5.0.0: {} is-number@7.0.0: {} is-obj@2.0.0: {} + is-object@1.0.2: {} + is-path-inside@3.0.3: {} is-plain-obj@1.1.0: {} + is-property@1.0.2: {} + is-regex@1.2.1: dependencies: call-bound: 1.0.3 @@ -4831,8 +6692,16 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + is-retry-allowed@1.2.0: {} + + is-stream@1.1.0: {} + is-stream@2.0.1: {} + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.18 + is-typedarray@1.0.0: {} is-yarn-global@0.3.0: {} @@ -4882,12 +6751,21 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + isurl@1.0.0: + dependencies: + has-to-string-tag-x: 1.4.1 + is-object: 1.0.2 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.0.2: + dependencies: + '@isaacs/cliui': 8.0.2 + jake@10.9.2: dependencies: async: 3.2.6 @@ -4895,6 +6773,32 @@ snapshots: filelist: 1.0.4 minimatch: 3.1.2 + javascript-obfuscator@4.1.1: + dependencies: + '@javascript-obfuscator/escodegen': 2.3.0 + '@javascript-obfuscator/estraverse': 5.4.0 + acorn: 8.8.2 + assert: 2.0.0 + chalk: 4.1.2 + chance: 1.1.9 + class-validator: 0.14.1 + commander: 10.0.0 + eslint-scope: 7.1.1 + eslint-visitor-keys: 3.3.0 + fast-deep-equal: 3.1.3 + inversify: 6.0.1 + js-string-escape: 1.0.1 + md5: 2.3.0 + mkdirp: 2.1.3 + multimatch: 5.0.0 + opencollective-postinstall: 2.0.3 + process: 0.11.10 + reflect-metadata: 0.1.13 + source-map-support: 0.5.21 + string-template: 1.0.0 + stringz: 2.1.0 + tslib: 2.5.0 + jest-changed-files@29.7.0: dependencies: execa: 5.1.1 @@ -5211,6 +7115,15 @@ snapshots: '@sideway/formula': 3.0.1 '@sideway/pinpoint': 2.0.0 + js-git@0.7.8: + dependencies: + bodec: 0.1.0 + culvert: 0.1.2 + git-sha1: 0.1.2 + pako: 0.2.9 + + js-string-escape@1.0.1: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -5222,6 +7135,8 @@ snapshots: dependencies: argparse: 2.0.1 + jsbn@1.1.0: {} + jsesc@2.5.2: {} jsesc@3.1.0: {} @@ -5238,6 +7153,9 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json-stringify-safe@5.0.1: + optional: true + json5@2.2.3: {} jsonfile@6.1.0: @@ -5246,10 +7164,38 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonwebtoken@9.0.2: + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.6.3 + + jwa@1.4.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@3.2.2: + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + keygrip@1.1.0: dependencies: tsscmp: 1.0.6 + keyv@3.0.0: + dependencies: + json-buffer: 3.0.0 + keyv@3.1.0: dependencies: json-buffer: 3.0.0 @@ -5275,6 +7221,20 @@ snapshots: co: 4.6.0 koa-compose: 4.1.0 + koa-range@0.3.0: + dependencies: + stream-slice: 0.1.2 + + koa-static-cache@5.1.4: + dependencies: + compressible: 2.0.18 + debug: 3.2.7 + fs-readdir-recursive: 1.1.0 + mime-types: 2.1.35 + mz: 2.7.0 + transitivePeerDependencies: + - supports-color + koa@2.15.3: dependencies: accepts: 1.3.8 @@ -5307,33 +7267,68 @@ snapshots: dependencies: package-json: 6.5.0 + lazy@1.0.11: {} + leven@3.1.0: {} + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 + libphonenumber-js@1.11.17: {} + lines-and-columns@1.2.4: {} locate-path@5.0.0: dependencies: p-locate: 4.1.0 + lockfile@1.0.4: + dependencies: + signal-exit: 3.0.7 + + lodash.clonedeep@4.5.0: {} + + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + lodash.memoize@4.1.2: {} lodash.merge@4.6.2: {} + lodash.once@4.1.1: {} + lodash.truncate@4.4.2: {} lodash@4.17.21: {} + long@5.2.4: {} + + lowercase-keys@1.0.0: {} + lowercase-keys@1.0.1: {} lowercase-keys@2.0.0: {} lru-cache@10.4.3: {} + lru-cache@11.0.2: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -5342,6 +7337,21 @@ snapshots: dependencies: yallist: 4.0.0 + lru-cache@7.18.3: {} + + lru.min@1.1.1: {} + + luxon@3.3.0: {} + + make-dir@1.3.0: + dependencies: + pify: 3.0.0 + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + make-dir@3.1.0: dependencies: semver: 6.3.1 @@ -5362,6 +7372,12 @@ snapshots: math-intrinsics@1.1.0: {} + md5@2.3.0: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + media-typer@0.3.0: {} meow@9.0.0: @@ -5406,6 +7422,10 @@ snapshots: min-indent@1.0.1: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -5435,10 +7455,28 @@ snapshots: mkdirp-classic@0.5.3: {} + mkdirp@1.0.4: {} + + mkdirp@2.1.3: {} + + mkdirp@2.1.6: {} + mkdirp@3.0.1: {} + module-details-from-path@1.0.3: {} + + moment@2.30.1: {} + ms@2.1.3: {} + multimatch@5.0.0: + dependencies: + '@types/minimatch': 3.0.5 + array-differ: 3.0.0 + array-union: 2.1.0 + arrify: 2.0.1 + minimatch: 3.1.2 + multistream@4.1.0: dependencies: once: 1.4.0 @@ -5480,6 +7518,28 @@ snapshots: mylas@2.1.13: {} + mysql2@3.12.0: + dependencies: + aws-ssl-profiles: 1.1.2 + denque: 2.1.0 + generate-function: 2.3.1 + iconv-lite: 0.6.3 + long: 5.2.4 + lru.min: 1.1.1 + named-placeholders: 1.1.3 + seq-queue: 0.0.5 + sqlstring: 2.3.3 + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + named-placeholders@1.1.3: + dependencies: + lru-cache: 7.18.3 + napi-build-utils@1.0.2: {} natural-compare-lite@1.4.0: {} @@ -5488,12 +7548,24 @@ snapshots: ncp@2.0.0: {} + needle@2.4.0: + dependencies: + debug: 3.2.7 + iconv-lite: 0.4.24 + sax: 1.4.1 + transitivePeerDependencies: + - supports-color + negotiator@0.6.3: {} + netmask@2.0.2: {} + node-abi@3.71.0: dependencies: semver: 7.6.3 + node-addon-api@6.1.0: {} + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 @@ -5518,14 +7590,34 @@ snapshots: normalize-path@3.0.0: {} + normalize-url@2.0.1: + dependencies: + prepend-http: 2.0.0 + query-string: 5.1.1 + sort-keys: 2.0.0 + normalize-url@4.5.1: {} npm-run-path@4.0.1: dependencies: path-key: 3.1.1 + nssocket@0.6.0: + dependencies: + eventemitter2: 0.4.14 + lazy: 1.0.11 + + object-assign@4.1.1: {} + object-inspect@1.13.3: {} + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -5540,6 +7632,21 @@ snapshots: only@0.0.2: {} + opencollective-postinstall@2.0.3: {} + + opentype.js@0.7.3: + dependencies: + tiny-inflate: 1.0.3 + + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -5551,8 +7658,18 @@ snapshots: os-tmpdir@1.0.2: {} + p-cancelable@0.4.1: {} + p-cancelable@1.1.0: {} + p-event@2.3.1: + dependencies: + p-timeout: 2.0.1 + + p-finally@1.0.0: {} + + p-is-promise@1.1.0: {} + p-is-promise@3.0.0: {} p-limit@2.3.0: @@ -5567,8 +7684,30 @@ snapshots: dependencies: p-limit: 2.3.0 + p-timeout@2.0.1: + dependencies: + p-finally: 1.0.0 + p-try@2.2.0: {} + pac-proxy-agent@7.1.0: + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.3 + debug: 4.4.0 + get-uri: 6.0.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + pac-resolver: 7.0.1 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + pac-resolver@7.0.1: + dependencies: + degenerator: 5.0.1 + netmask: 2.0.2 + package-json-from-dist@1.0.1: {} package-json@6.5.0: @@ -5578,6 +7717,8 @@ snapshots: registry-url: 5.1.0 semver: 6.3.1 + pako@0.2.9: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -5589,6 +7730,14 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5@5.1.1: {} + + parse5@6.0.1: {} + parseurl@1.3.3: {} path-exists@4.0.0: {} @@ -5604,14 +7753,44 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.0: + dependencies: + lru-cache: 11.0.2 + minipass: 7.1.2 + path-to-regexp@6.3.0: {} path-type@4.0.0: {} + peek-readable@4.1.0: {} + + pend@1.2.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} + pidusage@2.0.21: + dependencies: + safe-buffer: 5.2.1 + optional: true + + pidusage@3.0.2: + dependencies: + safe-buffer: 5.2.1 + + pify@2.3.0: {} + + pify@3.0.0: {} + + pify@4.0.1: {} + + pinkie-promise@2.0.1: + dependencies: + pinkie: 2.0.4 + + pinkie@2.0.4: {} + pirates@4.0.6: {} pkg-dir@4.2.0: @@ -5656,6 +7835,81 @@ snapshots: dependencies: queue-lit: 1.5.2 + pm2-axon-rpc@0.7.1: + dependencies: + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + pm2-axon@4.0.1: + dependencies: + amp: 0.3.1 + amp-message: 0.1.2 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + transitivePeerDependencies: + - supports-color + + pm2-deploy@1.0.2: + dependencies: + run-series: 1.1.9 + tv4: 1.3.0 + + pm2-multimeter@0.1.2: + dependencies: + charm: 0.1.2 + + pm2-sysmonit@1.2.8: + dependencies: + async: 3.2.6 + debug: 4.4.0 + pidusage: 2.0.21 + systeminformation: 5.25.10 + tx2: 1.0.5 + transitivePeerDependencies: + - supports-color + optional: true + + pm2@5.4.3: + dependencies: + '@pm2/agent': 2.0.4 + '@pm2/io': 6.0.1 + '@pm2/js-api': 0.8.0 + '@pm2/pm2-version-check': 1.0.4 + async: 3.2.6 + blessed: 0.1.81 + chalk: 3.0.0 + chokidar: 3.6.0 + cli-tableau: 2.0.1 + commander: 2.15.1 + croner: 4.1.97 + dayjs: 1.11.13 + debug: 4.4.0 + enquirer: 2.3.6 + eventemitter2: 5.0.1 + fclone: 1.0.11 + js-yaml: 4.1.0 + mkdirp: 1.0.4 + needle: 2.4.0 + pidusage: 3.0.2 + pm2-axon: 4.0.1 + pm2-axon-rpc: 0.7.1 + pm2-deploy: 1.0.2 + pm2-multimeter: 0.1.2 + promptly: 2.2.0 + semver: 7.6.3 + source-map-support: 0.5.21 + sprintf-js: 1.1.2 + vizion: 2.2.1 + optionalDependencies: + pm2-sysmonit: 1.2.8 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + possible-typed-array-names@1.0.0: {} + prebuild-install@7.1.1: dependencies: detect-libc: 2.0.3 @@ -5671,6 +7925,8 @@ snapshots: tar-fs: 2.1.1 tunnel-agent: 0.6.0 + prelude-ls@1.1.2: {} + prelude-ls@1.2.1: {} prepend-http@2.0.0: {} @@ -5689,13 +7945,34 @@ snapshots: process-nextick-args@2.0.1: {} + process@0.11.10: {} + progress@2.0.3: {} + promptly@2.2.0: + dependencies: + read: 1.0.7 + prompts@2.4.2: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 + proxy-agent@6.3.1: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 7.18.3 + pac-proxy-agent: 7.1.0 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + proxy-from-env@1.1.0: {} + pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -5713,10 +7990,18 @@ snapshots: dependencies: side-channel: 1.1.0 + query-string@5.1.1: + dependencies: + decode-uri-component: 0.2.2 + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + queue-lit@1.5.2: {} queue-microtask@1.2.3: {} + queue-tick@1.0.1: {} + quick-lru@4.0.1: {} raw-body@2.5.2: @@ -5748,6 +8033,10 @@ snapshots: parse-json: 5.2.0 type-fest: 0.6.0 + read@1.0.7: + dependencies: + mute-stream: 0.0.8 + readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -5764,6 +8053,10 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readable-web-to-node-stream@3.0.2: + dependencies: + readable-stream: 3.6.2 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -5773,6 +8066,8 @@ snapshots: indent-string: 4.0.0 strip-indent: 3.0.0 + reflect-metadata@0.1.13: {} + reflect-metadata@0.2.2: {} regexpp@3.2.0: {} @@ -5789,6 +8084,14 @@ snapshots: require-from-string@2.0.2: {} + require-in-the-middle@5.2.0: + dependencies: + debug: 4.4.0 + module-details-from-path: 1.0.3 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 @@ -5830,6 +8133,8 @@ snapshots: dependencies: queue-microtask: 1.2.3 + run-series@1.1.9: {} + rxjs@6.6.7: dependencies: tslib: 1.14.1 @@ -5848,8 +8153,14 @@ snapshots: safer-buffer@2.1.2: {} + sax@1.4.1: {} + scmp@2.1.0: {} + seek-bzip@1.0.6: + dependencies: + commander: 2.20.3 + semver-diff@3.1.1: dependencies: semver: 6.3.1 @@ -5858,16 +8169,49 @@ snapshots: semver@6.3.1: {} + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + semver@7.6.3: {} + seq-queue@0.0.5: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.7 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + setprototypeof@1.2.0: {} + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + sharp@0.32.6: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + node-addon-api: 6.1.0 + prebuild-install: 7.1.1 + semver: 7.6.3 + simple-get: 4.0.1 + tar-fs: 3.0.6 + tunnel-agent: 0.6.0 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + shimmer@1.2.1: {} + should-send-same-site-none@2.0.5: {} side-channel-list@1.0.0: @@ -5910,6 +8254,10 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + sisteransi@1.0.5: {} slash@3.0.0: {} @@ -5920,6 +8268,33 @@ snapshots: astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 + smart-buffer@4.2.0: {} + + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + socks: 2.8.3 + transitivePeerDependencies: + - supports-color + + socks@2.8.3: + dependencies: + ip-address: 9.0.5 + smart-buffer: 4.2.0 + + sort-keys-length@1.0.1: + dependencies: + sort-keys: 1.1.2 + + sort-keys@1.1.2: + dependencies: + is-plain-obj: 1.1.0 + + sort-keys@2.0.0: + dependencies: + is-plain-obj: 1.1.0 + source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 @@ -5948,6 +8323,12 @@ snapshots: sprintf-js@1.0.3: {} + sprintf-js@1.1.2: {} + + sprintf-js@1.1.3: {} + + sqlstring@2.3.3: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -5960,11 +8341,25 @@ snapshots: dependencies: readable-stream: 2.3.8 + stream-slice@0.1.2: {} + + streamx@2.21.1: + dependencies: + fast-fifo: 1.3.2 + queue-tick: 1.0.1 + text-decoder: 1.2.3 + optionalDependencies: + bare-events: 2.5.4 + + strict-uri-encode@1.1.0: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 strip-ansi: 6.0.1 + string-template@1.0.0: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -5985,6 +8380,10 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringz@2.1.0: + dependencies: + char-regex: 1.0.2 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -5995,6 +8394,10 @@ snapshots: strip-bom@4.0.0: {} + strip-dirs@2.1.0: + dependencies: + is-natural-number: 4.0.1 + strip-final-newline@2.0.0: {} strip-indent@3.0.0: @@ -6005,6 +8408,15 @@ snapshots: strip-json-comments@3.1.1: {} + strip-outer@1.0.1: + dependencies: + escape-string-regexp: 1.0.5 + + strtok3@6.3.0: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 4.1.0 + superagent@8.1.2: dependencies: component-emitter: 1.3.1 @@ -6041,6 +8453,13 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svg-captcha@1.4.0: + dependencies: + opentype.js: 0.7.3 + + systeminformation@5.25.10: + optional: true + table@6.9.0: dependencies: ajv: 8.17.1 @@ -6056,6 +8475,24 @@ snapshots: pump: 3.0.2 tar-stream: 2.2.0 + tar-fs@3.0.6: + dependencies: + pump: 3.0.2 + tar-stream: 3.1.7 + optionalDependencies: + bare-fs: 2.3.5 + bare-path: 2.1.3 + + tar-stream@1.6.2: + dependencies: + bl: 1.2.3 + buffer-alloc: 1.2.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + readable-stream: 2.3.8 + to-buffer: 1.1.1 + xtend: 4.0.2 + tar-stream@2.2.0: dependencies: bl: 4.1.0 @@ -6064,6 +8501,12 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + tar-stream@3.1.7: + dependencies: + b4a: 1.6.7 + fast-fifo: 1.3.2 + streamx: 2.21.1 + tar@7.4.3: dependencies: '@isaacs/fs-minipass': 4.0.1 @@ -6079,16 +8522,34 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 + text-decoder@1.2.3: + dependencies: + b4a: 1.6.7 + text-table@0.2.0: {} + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + through@2.3.8: {} + timed-out@4.0.1: {} + + tiny-inflate@1.0.3: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 tmpl@1.0.5: {} + to-buffer@1.1.1: {} + to-fast-properties@2.0.0: {} to-readable-stream@1.0.0: {} @@ -6099,10 +8560,19 @@ snapshots: toidentifier@1.0.1: {} + token-types@4.2.1: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + tr46@0.0.3: {} trim-newlines@3.0.1: {} + trim-repeated@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.10.5))(typescript@5.7.3): dependencies: bs-logger: 0.2.6 @@ -6133,6 +8603,12 @@ snapshots: tslib@1.14.1: {} + tslib@1.9.3: {} + + tslib@2.5.0: {} + + tslib@2.8.1: {} + tsscmp@1.0.6: {} tsutils@3.21.0(typescript@5.7.3): @@ -6144,6 +8620,17 @@ snapshots: dependencies: safe-buffer: 5.2.1 + tv4@1.3.0: {} + + tx2@1.0.5: + dependencies: + json-stringify-safe: 5.0.1 + optional: true + + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -6169,8 +8656,35 @@ snapshots: dependencies: is-typedarray: 1.0.0 + typeorm@0.3.20(mysql2@3.12.0): + dependencies: + '@sqltools/formatter': 1.2.5 + app-root-path: 3.1.0 + buffer: 6.0.3 + chalk: 4.1.2 + cli-highlight: 2.1.11 + dayjs: 1.11.13 + debug: 4.4.0 + dotenv: 16.4.7 + glob: 10.4.5 + mkdirp: 2.1.6 + reflect-metadata: 0.2.2 + sha.js: 2.4.11 + tslib: 2.8.1 + uuid: 9.0.1 + yargs: 17.7.2 + optionalDependencies: + mysql2: 3.12.0 + transitivePeerDependencies: + - supports-color + typescript@5.7.3: {} + unbzip2-stream@1.4.3: + dependencies: + buffer: 5.7.1 + through: 2.3.8 + undici-types@6.20.0: {} unique-string@2.0.0: @@ -6212,8 +8726,22 @@ snapshots: dependencies: prepend-http: 2.0.0 + url-to-options@1.0.1: {} + util-deprecate@1.0.2: {} + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.0 + is-typed-array: 1.1.15 + which-typed-array: 1.1.18 + + uuid@11.0.5: {} + + uuid@9.0.1: {} + v8-compile-cache@2.4.0: {} v8-to-istanbul@9.3.0: @@ -6227,8 +8755,17 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + validator@13.12.0: {} + vary@1.1.2: {} + vizion@2.2.1: + dependencies: + async: 2.6.4 + git-node-fs: 1.0.0(js-git@0.7.8) + ini: 1.3.8 + js-git: 0.7.8 + walker@1.0.8: dependencies: makeerror: 1.0.12 @@ -6240,6 +8777,15 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + which-typed-array@1.1.18: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + for-each: 0.3.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -6276,8 +8822,14 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 + ws@7.5.10: {} + + ws@8.18.0: {} + xdg-basedir@4.0.0: {} + xtend@4.0.2: {} + y18n@5.0.8: {} yallist@3.1.1: {} @@ -6310,6 +8862,11 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + ylru@1.4.0: {} yocto-queue@0.1.0: {} diff --git a/public/css/welcome.css b/public/css/welcome.css new file mode 100644 index 0000000..10b5800 --- /dev/null +++ b/public/css/welcome.css @@ -0,0 +1,92 @@ +body { + display: flex; + min-height: 100vh; + margin: 0; + justify-content: center; + align-items: center; + text-align: center; + background: #222; + overflow-y: hidden; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.footer-bar { + position: fixed; + bottom: 0; + left: 0; + right: 0; + color: #6ee1f5; + padding: 10px 0 20px 0; + text-align: center; + opacity: 0; + animation: fadeIn 5s forwards; + background: #222; +} + +.link { + color: #6ee1f5; +} + +.reveal { + position: relative; + display: flex; + color: #6ee1f5; + font-size: 2em; + font-family: Raleway, sans-serif; + letter-spacing: 3px; + text-transform: uppercase; + white-space: pre; +} +.reveal span { + opacity: 0; + transform: scale(0); + animation: fadeIn 2.4s forwards; +} +.reveal::before, .reveal::after { + position: absolute; + content: ""; + top: 0; + bottom: 0; + width: 2px; + height: 100%; + background: white; + opacity: 0; + transform: scale(0); +} +.reveal::before { + left: 50%; + animation: slideLeft 1.5s cubic-bezier(0.7, -0.6, 0.3, 1.5) forwards; +} +.reveal::after { + right: 50%; + animation: slideRight 1.5s cubic-bezier(0.7, -0.6, 0.3, 1.5) forwards; +} + +@keyframes fadeIn { + to { + opacity: 1; + transform: scale(1); + } +} +@keyframes slideLeft { + to { + left: -6%; + opacity: 1; + transform: scale(0.9); + } +} +@keyframes slideRight { + to { + right: -6%; + opacity: 1; + transform: scale(0.9); + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..a0c3086 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/js/welcome.js b/public/js/welcome.js new file mode 100644 index 0000000..05054e8 --- /dev/null +++ b/public/js/welcome.js @@ -0,0 +1,14 @@ +const duration = 0.8; +const delay = 0.3; +// eslint-disable-next-line no-undef +const revealText = document.querySelector('.reveal'); +const letters = revealText.textContent.split(''); +revealText.textContent = ''; +const middle = letters.filter(e => e !== ' ').length / 2; +letters.forEach((letter, i) => { + // eslint-disable-next-line no-undef + const span = document.createElement('span'); + span.textContent = letter; + span.style.animationDelay = `${delay + Math.abs(i - middle) * 0.1}s`; + revealText.append(span); +}); diff --git a/public/welcome.html b/public/welcome.html new file mode 100644 index 0000000..063bf0b --- /dev/null +++ b/public/welcome.html @@ -0,0 +1,30 @@ + + + + + + + + COOL-AMIND 一个很酷的后台权限管理系统 + + + + + + +
HELLO COOL-ADMIN AI快速开发框架
+ + + + + + + + diff --git a/src/comm/utils.ts b/src/comm/utils.ts index 1b73aea..a57d1e8 100644 --- a/src/comm/utils.ts +++ b/src/comm/utils.ts @@ -1,6 +1,5 @@ -import { Inject, Provide } from '@midwayjs/decorator'; +import { Inject, Provide } from '@midwayjs/core'; import { Context } from '@midwayjs/koa'; -import * as _ from 'lodash'; import * as moment from 'moment'; /** diff --git a/src/config/config.default.ts b/src/config/config.default.ts index 7edfb03..4216243 100644 --- a/src/config/config.default.ts +++ b/src/config/config.default.ts @@ -1,9 +1,73 @@ +import { CoolConfig } from '@cool-midway/core'; import { MidwayConfig } from '@midwayjs/core'; +import { CoolCacheStore } from '@cool-midway/core'; +import * as path from 'path'; +// redis缓存 +// import { redisStore } from 'cache-manager-ioredis-yet'; export default { // use for cookie sign key, should change to your own and keep security - keys: '1736423310302_5051', + keys: '673dcd50-f95d-4109-b69d-aa80df64098e', koa: { - port: 7001, + port: 8001, }, + // 静态文件配置 + staticFile: { + buffer: true, + dirs: { + default: { + prefix: '/public', + dir: path.join(__dirname, '..', '..', 'public'), + }, + welcome: { + prefix: '/', + dir: path.join(__dirname, '..', '..', 'public'), + alias: { + '/': '/welcome.html', + }, + }, + }, + }, + // 文件上传 + upload: { + fileSize: '200mb', + whitelist: null, + }, + // 缓存 可切换成其他缓存如:redis http://www.midwayjs.org/docs/extensions/caching + cacheManager: { + clients: { + default: { + store: CoolCacheStore, + options: { + path: 'cache', + ttl: 0, + }, + }, + }, + }, + // cacheManager: { + // clients: { + // default: { + // store: redisStore, + // options: { + // port: 6379, + // host: '127.0.0.1', + // password: '', + // ttl: 0, + // db: 0, + // }, + // }, + // }, + // }, + cool: { + // 已经插件化,本地文件上传查看 plugin/config.ts,其他云存储查看对应插件的使用 + file: {}, + // crud配置 + crud: { + // 插入模式,save不会校验字段(允许传入不存在的字段),insert会校验字段 + upsert: 'save', + // 软删除 + softDelete: true, + }, + } as CoolConfig, } as MidwayConfig; diff --git a/src/config/config.local.ts b/src/config/config.local.ts index c137031..c7a38fd 100644 --- a/src/config/config.local.ts +++ b/src/config/config.local.ts @@ -1,3 +1,45 @@ +import { CoolConfig } from '@cool-midway/core'; import { MidwayConfig } from '@midwayjs/core'; +import { entities } from '../entities'; -export default {} as MidwayConfig; +/** + * 本地开发 npm run dev 读取的配置文件 + */ +export default { + typeorm: { + dataSource: { + default: { + type: 'mysql', + host: '192.168.0.119', + port: 3306, + username: 'root', + password: '123456', + database: 'cool', + // 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失 + synchronize: true, + // 打印日志 + logging: false, + // 字符集 + charset: 'utf8mb4', + // 是否开启缓存 + cache: true, + // 实体路径 + entities, + // 扩展配置 + extra: { + keepAliveInitialDelay: 10000, + }, + }, + }, + }, + cool: { + // 实体与路径,跟生成代码、前端请求、swagger文档相关 注意:线上不建议开启,以免暴露敏感信息 + eps: true, + // 是否自动导入模块数据库 + initDB: true, + // 判断是否初始化的方式 + initJudge: 'db', + // 是否自动导入模块菜单 + initMenu: true, + } as CoolConfig, +} as MidwayConfig; diff --git a/src/config/config.prod.ts b/src/config/config.prod.ts new file mode 100644 index 0000000..282c726 --- /dev/null +++ b/src/config/config.prod.ts @@ -0,0 +1,38 @@ +import { CoolConfig } from '@cool-midway/core'; +import { MidwayConfig } from '@midwayjs/core'; +import { entities } from '../entities'; +/** + * 本地开发 npm run prod 读取的配置文件 + */ +export default { + typeorm: { + dataSource: { + default: { + type: 'mysql', + host: '192.168.0.119', + port: 3306, + username: 'root', + password: '123456', + database: 'cool', + // 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失 + synchronize: false, + // 打印日志 + logging: false, + // 字符集 + charset: 'utf8mb4', + // 是否开启缓存 + cache: true, + // 实体路径 + entities, + // 扩展配置 + extra: { + keepAliveInitialDelay: 10000, + }, + }, + }, + }, + cool: { + // 是否自动导入数据库,生产环境不建议开,用本地的数据库手动初始化 + initDB: false, + } as CoolConfig, +} as MidwayConfig; diff --git a/src/configuration.ts b/src/configuration.ts index dca3b5d..b27ea79 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -1,38 +1,60 @@ -import { Configuration, App } from '@midwayjs/core'; +import * as orm from '@midwayjs/typeorm'; +import { + Configuration, + App, + IMidwayApplication, + Inject, + ILogger, +} from '@midwayjs/core'; import * as koa from '@midwayjs/koa'; +// import * as crossDomain from '@midwayjs/cross-domain'; import * as validate from '@midwayjs/validate'; import * as info from '@midwayjs/info'; -import { ReportMiddleware } from './middleware/report.middleware'; +import * as staticFile from '@midwayjs/static-file'; +import * as cron from '@midwayjs/cron'; import * as DefaultConfig from './config/config.default'; import * as LocalConfig from './config/config.local'; +import * as ProdConfig from './config/config.prod'; import * as cool from '@cool-midway/core'; +import * as upload from '@midwayjs/upload'; @Configuration({ imports: [ + // https://koajs.com/ koa, + // 是否开启跨域(注:顺序不能乱放!!!) http://www.midwayjs.org/docs/extensions/cross_domain + // crossDomain, + // 静态文件托管 https://midwayjs.org/docs/extensions/static_file + staticFile, + // orm https://midwayjs.org/docs/extensions/orm + orm, + // 参数验证 https://midwayjs.org/docs/extensions/validate validate, + // 本地任务 http://www.midwayjs.org/docs/extensions/cron + cron, + // 文件上传 + upload, // cool-admin 官方组件 https://cool-js.com cool, { component: info, - enabledEnvironment: ['local'], + enabledEnvironment: ['local', 'prod'], }, ], importConfigs: [ { default: DefaultConfig, local: LocalConfig, + prod: ProdConfig, }, ], }) export class MainConfiguration { - @App('koa') - app: koa.Application; + @App() + app: IMidwayApplication; - async onReady() { - // add middleware - this.app.useMiddleware([ReportMiddleware]); - // add filter - // this.app.useFilter([NotFoundFilter, DefaultErrorFilter]); - } + @Inject() + logger: ILogger; + + async onReady() {} } diff --git a/src/entities.ts b/src/entities.ts new file mode 100644 index 0000000..e02f396 --- /dev/null +++ b/src/entities.ts @@ -0,0 +1,23 @@ +// 自动生成的文件,请勿手动修改 +import * as entity0 from './modules/base/entity/sys/user_role'; +import * as entity1 from './modules/base/entity/sys/user'; +import * as entity2 from './modules/base/entity/sys/role_menu'; +import * as entity3 from './modules/base/entity/sys/role_department'; +import * as entity4 from './modules/base/entity/sys/role'; +import * as entity5 from './modules/base/entity/sys/param'; +import * as entity6 from './modules/base/entity/sys/menu'; +import * as entity7 from './modules/base/entity/sys/log'; +import * as entity8 from './modules/base/entity/sys/department'; +import * as entity9 from './modules/base/entity/sys/conf'; +export const entities = [ + ...Object.values(entity0), + ...Object.values(entity1), + ...Object.values(entity2), + ...Object.values(entity3), + ...Object.values(entity4), + ...Object.values(entity5), + ...Object.values(entity6), + ...Object.values(entity7), + ...Object.values(entity8), + ...Object.values(entity9), +]; diff --git a/src/index.ts b/src/index.ts index bda227b..1dcc7ea 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,44 @@ /** This file generated by @midwayjs/bundle-helper */ - -export { MainConfiguration as Configuration } from './configuration'; + export { MainConfiguration as Configuration } from './configuration'; +export * from './comm/utils'; export * from './config/config.default'; +export * from './modules/base/entity/sys/user_role'; +export * from './modules/base/entity/sys/user'; +export * from './modules/base/entity/sys/role_menu'; +export * from './modules/base/entity/sys/role_department'; +export * from './modules/base/entity/sys/role'; +export * from './modules/base/entity/sys/param'; +export * from './modules/base/entity/sys/menu'; +export * from './modules/base/entity/sys/log'; +export * from './modules/base/entity/sys/department'; +export * from './modules/base/entity/sys/conf'; +export * from './entities'; export * from './config/config.local'; +export * from './config/config.prod'; export * from './interface'; +export * from './modules/base/service/sys/conf'; +export * from './modules/base/service/sys/log'; +export * from './modules/base/middleware/log'; +export * from './modules/base/middleware/authority'; +export * from './modules/base/config'; +export * from './modules/base/dto/login'; +export * from './modules/base/service/sys/data'; +export * from './modules/base/service/sys/menu'; +export * from './modules/base/service/sys/department'; +export * from './modules/base/service/sys/perms'; +export * from './modules/base/service/sys/role'; +export * from './modules/base/service/sys/login'; +export * from './modules/base/service/sys/user'; +export * from './modules/base/controller/admin/comm'; +export * from './modules/base/service/sys/param'; +export * from './modules/base/controller/admin/open'; +export * from './modules/base/controller/admin/sys/department'; +export * from './modules/base/controller/admin/sys/log'; +export * from './modules/base/controller/admin/sys/menu'; +export * from './modules/base/controller/admin/sys/param'; +export * from './modules/base/controller/admin/sys/role'; +export * from './modules/base/controller/admin/sys/user'; +export * from './modules/base/controller/app/comm'; +export * from './modules/base/event/app'; +export * from './modules/base/event/menu'; +export * from './modules/base/job/log'; diff --git a/src/modules/base/config.ts b/src/modules/base/config.ts new file mode 100644 index 0000000..77d851a --- /dev/null +++ b/src/modules/base/config.ts @@ -0,0 +1,35 @@ +import { BaseLogMiddleware } from './middleware/log'; +import { BaseAuthorityMiddleware } from './middleware/authority'; +import { ModuleConfig } from '@cool-midway/core'; + +/** + * 模块的配置 + */ +export default () => { + return { + // 模块名称 + name: '权限管理', + // 模块描述 + description: '基础的权限管理功能,包括登录,权限校验', + // 中间件 + globalMiddlewares: [BaseAuthorityMiddleware, BaseLogMiddleware], + // 模块加载顺序,默认为0,值越大越优先加载 + order: 10, + // app参数配置允许读取的key + allowKeys: [], + // jwt 生成解密token的 + jwt: { + // 单点登录 + sso: false, + // 注意: 最好重新修改,防止破解 + secret: 'e43675a9-0ce5-4d50-8dd0-549dff19334c', + // token + token: { + // 2小时过期,需要用刷新token + expire: 2 * 3600, + // 15天内,如果没操作过就需要重新登录 + refreshExpire: 24 * 3600 * 15, + }, + }, + } as ModuleConfig; +}; diff --git a/src/modules/base/controller/admin/comm.ts b/src/modules/base/controller/admin/comm.ts new file mode 100644 index 0000000..e5dd9e1 --- /dev/null +++ b/src/modules/base/controller/admin/comm.ts @@ -0,0 +1,99 @@ +import { + BaseController, + CoolController, + CoolTag, + CoolUrlTag, + TagTypes, +} from '@cool-midway/core'; +import { ALL, Body, Get, Inject, Post, Provide } from '@midwayjs/core'; +import { Context } from '@midwayjs/koa'; +// import { PluginService } from '../../../plugin/service/info'; +import { BaseSysUserEntity } from '../../entity/sys/user'; +import { BaseSysLoginService } from '../../service/sys/login'; +import { BaseSysPermsService } from '../../service/sys/perms'; +import { BaseSysUserService } from '../../service/sys/user'; + +/** + * Base 通用接口 一般写不需要权限过滤的接口 + */ +@CoolUrlTag() +@Provide() +@CoolController() +export class BaseCommController extends BaseController { + @Inject() + baseSysUserService: BaseSysUserService; + + @Inject() + baseSysPermsService: BaseSysPermsService; + + @Inject() + baseSysLoginService: BaseSysLoginService; + + @Inject() + ctx: Context; + + // @Inject() + // pluginService: PluginService; + + /** + * 获得个人信息 + */ + @Get('/person', { summary: '个人信息' }) + async person() { + return this.ok( + await this.baseSysUserService.person(this.ctx.admin?.userId) + ); + } + + /** + * 修改个人信息 + */ + @Post('/personUpdate', { summary: '修改个人信息' }) + async personUpdate(@Body(ALL) user: BaseSysUserEntity) { + await this.baseSysUserService.personUpdate(user); + return this.ok(); + } + + /** + * 权限菜单 + */ + @Get('/permmenu', { summary: '权限与菜单' }) + async permmenu() { + return this.ok( + await this.baseSysPermsService.permmenu(this.ctx.admin.roleIds) + ); + } + + /** + * 文件上传 + */ + @Post('/upload', { summary: '文件上传' }) + async upload() { + // const file = await this.pluginService.getInstance('upload'); + // return this.ok(await file.upload(this.ctx)); + } + + /** + * 文件上传模式,本地或者云存储 + */ + @Get('/uploadMode', { summary: '文件上传模式' }) + async uploadMode() { + // const file = await this.pluginService.getInstance('upload'); + // return this.ok(await file.getMode()); + } + + /** + * 退出 + */ + @Post('/logout', { summary: '退出' }) + async logout() { + await this.baseSysLoginService.logout(); + return this.ok(); + } + + @CoolTag(TagTypes.IGNORE_TOKEN) + @Get('/program', { summary: '编程' }) + async program() { + return this.ok('Node'); + } +} diff --git a/src/modules/base/controller/admin/open.ts b/src/modules/base/controller/admin/open.ts new file mode 100644 index 0000000..217433b --- /dev/null +++ b/src/modules/base/controller/admin/open.ts @@ -0,0 +1,99 @@ +import { Provide, Body, Inject, Post, Get, Query } from '@midwayjs/core'; +import { + CoolController, + BaseController, + CoolEps, + CoolUrlTag, + CoolTag, + TagTypes, + RESCODE, +} from '@cool-midway/core'; +import { LoginDTO } from '../../dto/login'; +import { BaseSysLoginService } from '../../service/sys/login'; +import { BaseSysParamService } from '../../service/sys/param'; +import { Context } from '@midwayjs/koa'; +import { Validate } from '@midwayjs/validate'; + +/** + * 不需要登录的后台接口 + */ +@Provide() +@CoolController({ description: '开放接口' }) +@CoolUrlTag() +export class BaseOpenController extends BaseController { + @Inject() + baseSysLoginService: BaseSysLoginService; + + @Inject() + baseSysParamService: BaseSysParamService; + + @Inject() + ctx: Context; + + @Inject() + eps: CoolEps; + + /** + * 实体信息与路径 + * @returns + */ + @CoolTag(TagTypes.IGNORE_TOKEN) + @Get('/eps', { summary: '实体信息与路径' }) + public async getEps() { + return this.ok(this.eps.admin); + } + + /** + * 根据配置参数key获得网页内容(富文本) + */ + @CoolTag(TagTypes.IGNORE_TOKEN) + @Get('/html', { summary: '获得网页内容的参数值' }) + async htmlByKey(@Query('key') key: string) { + this.ctx.body = await this.baseSysParamService.htmlByKey(key); + } + + /** + * 登录 + * @param login + */ + @CoolTag(TagTypes.IGNORE_TOKEN) + @Post('/login', { summary: '登录' }) + @Validate() + async login(@Body() login: LoginDTO) { + return this.ok(await this.baseSysLoginService.login(login)); + } + + /** + * 获得验证码 + */ + @CoolTag(TagTypes.IGNORE_TOKEN) + @Get('/captcha', { summary: '验证码' }) + async captcha( + @Query('type') type: string, + @Query('width') width: number, + @Query('height') height: number, + @Query('color') color: string + ) { + return this.ok( + await this.baseSysLoginService.captcha(type, width, height, color) + ); + } + + /** + * 刷新token + */ + @CoolTag(TagTypes.IGNORE_TOKEN) + @Get('/refreshToken', { summary: '刷新token' }) + async refreshToken(@Query('refreshToken') refreshToken: string) { + try { + const token = await this.baseSysLoginService.refreshToken(refreshToken); + return this.ok(token); + } catch (e) { + this.ctx.status = 401; + this.ctx.body = { + code: RESCODE.COMMFAIL, + message: '登录失效~', + }; + } + } +} diff --git a/src/modules/base/controller/admin/sys/department.ts b/src/modules/base/controller/admin/sys/department.ts new file mode 100644 index 0000000..e751134 --- /dev/null +++ b/src/modules/base/controller/admin/sys/department.ts @@ -0,0 +1,27 @@ +import { ALL, Body, Inject, Post, Provide } from '@midwayjs/core'; +import { CoolController, BaseController } from '@cool-midway/core'; +import { BaseSysDepartmentEntity } from '../../../entity/sys/department'; +import { BaseSysDepartmentService } from '../../../service/sys/department'; + +/** + * 部门 + */ +@Provide() +@CoolController({ + api: ['add', 'delete', 'update', 'list'], + entity: BaseSysDepartmentEntity, + service: BaseSysDepartmentService, +}) +export class BaseDepartmentController extends BaseController { + @Inject() + baseDepartmentService: BaseSysDepartmentService; + + /** + * 部门排序 + */ + @Post('/order', { summary: '排序' }) + async order(@Body(ALL) params: any) { + await this.baseDepartmentService.order(params); + return this.ok(); + } +} diff --git a/src/modules/base/controller/admin/sys/log.ts b/src/modules/base/controller/admin/sys/log.ts new file mode 100644 index 0000000..d5381d7 --- /dev/null +++ b/src/modules/base/controller/admin/sys/log.ts @@ -0,0 +1,64 @@ +import { Provide, Post, Inject, Body, Get } from '@midwayjs/core'; +import { CoolController, BaseController } from '@cool-midway/core'; +import { BaseSysLogEntity } from '../../../entity/sys/log'; +import { BaseSysUserEntity } from '../../../entity/sys/user'; +import { BaseSysConfService } from '../../../service/sys/conf'; +import { BaseSysLogService } from '../../../service/sys/log'; + +/** + * 系统日志 + */ +@Provide() +@CoolController({ + api: ['page'], + entity: BaseSysLogEntity, + urlTag: { + name: 'a', + url: ['add'], + }, + pageQueryOp: { + keyWordLikeFields: ['b.name', 'a.action', 'a.ip'], + select: ['a.*', 'b.name'], + join: [ + { + entity: BaseSysUserEntity, + alias: 'b', + condition: 'a.userId = b.id', + type: 'leftJoin', + }, + ], + }, +}) +export class BaseSysLogController extends BaseController { + @Inject() + baseSysLogService: BaseSysLogService; + + @Inject() + baseSysConfService: BaseSysConfService; + + /** + * 清空日志 + */ + @Post('/clear', { summary: '清理' }) + public async clear() { + await this.baseSysLogService.clear(true); + return this.ok(); + } + + /** + * 设置日志保存时间 + */ + @Post('/setKeep', { summary: '日志保存时间' }) + public async setKeep(@Body('value') value: number) { + await this.baseSysConfService.updateVaule('logKeep', value); + return this.ok(); + } + + /** + * 获得日志保存时间 + */ + @Get('/getKeep', { summary: '获得日志保存时间' }) + public async getKeep() { + return this.ok(await this.baseSysConfService.getValue('logKeep')); + } +} diff --git a/src/modules/base/controller/admin/sys/menu.ts b/src/modules/base/controller/admin/sys/menu.ts new file mode 100644 index 0000000..d31c692 --- /dev/null +++ b/src/modules/base/controller/admin/sys/menu.ts @@ -0,0 +1,46 @@ +import { Body, Inject, Post, Provide } from '@midwayjs/core'; +import { CoolController, BaseController } from '@cool-midway/core'; +import { BaseSysMenuEntity } from '../../../entity/sys/menu'; +import { BaseSysMenuService } from '../../../service/sys/menu'; + +/** + * 菜单 + */ +@Provide() +@CoolController({ + api: ['add', 'delete', 'update', 'info', 'list', 'page'], + entity: BaseSysMenuEntity, + service: BaseSysMenuService, +}) +export class BaseSysMenuController extends BaseController { + @Inject() + baseSysMenuService: BaseSysMenuService; + + @Post('/parse', { summary: '解析' }) + async parse( + @Body('entity') entity: string, + @Body('controller') controller: string, + @Body('module') module: string + ) { + return this.ok( + await this.baseSysMenuService.parse(entity, controller, module) + ); + } + + @Post('/create', { summary: '创建代码' }) + async create(@Body() body) { + await this.baseSysMenuService.create(body); + return this.ok(); + } + + @Post('/export', { summary: '导出' }) + async export(@Body('ids') ids: number[]) { + return this.ok(await this.baseSysMenuService.export(ids)); + } + + @Post('/import', { summary: '导入' }) + async import(@Body('menus') menus: any[]) { + await this.baseSysMenuService.import(menus); + return this.ok(); + } +} diff --git a/src/modules/base/controller/admin/sys/param.ts b/src/modules/base/controller/admin/sys/param.ts new file mode 100644 index 0000000..304a97b --- /dev/null +++ b/src/modules/base/controller/admin/sys/param.ts @@ -0,0 +1,34 @@ +import { Get, Inject, Provide, Query } from '@midwayjs/core'; +import { CoolController, BaseController } from '@cool-midway/core'; +import { BaseSysParamEntity } from '../../../entity/sys/param'; +import { BaseSysParamService } from '../../../service/sys/param'; +import { Context } from '@midwayjs/koa'; + +/** + * 参数配置 + */ +@Provide() +@CoolController({ + api: ['add', 'delete', 'update', 'info', 'page'], + entity: BaseSysParamEntity, + service: BaseSysParamService, + pageQueryOp: { + keyWordLikeFields: ['name', 'keyName'], + fieldEq: ['dataType'], + }, +}) +export class BaseSysParamController extends BaseController { + @Inject() + baseSysParamService: BaseSysParamService; + + @Inject() + ctx: Context; + + /** + * 根据配置参数key获得网页内容(富文本) + */ + @Get('/html', { summary: '获得网页内容的参数值' }) + async htmlByKey(@Query('key') key: string) { + this.ctx.body = await this.baseSysParamService.htmlByKey(key); + } +} diff --git a/src/modules/base/controller/admin/sys/role.ts b/src/modules/base/controller/admin/sys/role.ts new file mode 100644 index 0000000..4a462dc --- /dev/null +++ b/src/modules/base/controller/admin/sys/role.ts @@ -0,0 +1,38 @@ +import { Provide } from '@midwayjs/core'; +import { CoolController, BaseController } from '@cool-midway/core'; +import { Context } from 'vm'; +import { BaseSysRoleEntity } from '../../../entity/sys/role'; +import { BaseSysRoleService } from '../../../service/sys/role'; + +/** + * 系统角色 + */ +@Provide() +@CoolController({ + api: ['add', 'delete', 'update', 'info', 'list', 'page'], + entity: BaseSysRoleEntity, + service: BaseSysRoleService, + // 新增的时候插入当前用户ID + insertParam: async (ctx: Context) => { + return { + userId: ctx.admin.userId, + }; + }, + pageQueryOp: { + keyWordLikeFields: ['a.name', 'a.label'], + where: async (ctx: Context) => { + const { userId, roleIds, username } = ctx.admin; + return [ + // 超级管理员的角色不展示 + ['label != :label', { label: 'admin' }], + // 如果不是超管,只能看到自己新建的或者自己有的角色 + [ + `(userId=:userId or id in (${roleIds.join(',')}))`, + { userId }, + username !== 'admin', + ], + ]; + }, + }, +}) +export class BaseSysRoleController extends BaseController {} diff --git a/src/modules/base/controller/admin/sys/user.ts b/src/modules/base/controller/admin/sys/user.ts new file mode 100644 index 0000000..ba8961e --- /dev/null +++ b/src/modules/base/controller/admin/sys/user.ts @@ -0,0 +1,30 @@ +import { Body, Inject, Post, Provide } from '@midwayjs/core'; +import { CoolController, BaseController } from '@cool-midway/core'; +import { BaseSysUserEntity } from '../../../entity/sys/user'; +import { BaseSysUserService } from '../../../service/sys/user'; + +/** + * 系统用户 + */ +@Provide() +@CoolController({ + api: ['add', 'delete', 'update', 'info', 'list', 'page'], + entity: BaseSysUserEntity, + service: BaseSysUserService, +}) +export class BaseSysUserController extends BaseController { + @Inject() + baseSysUserService: BaseSysUserService; + + /** + * 移动部门 + */ + @Post('/move', { summary: '移动部门' }) + async move( + @Body('departmentId') departmentId: number, + @Body('userIds') userIds: [] + ) { + await this.baseSysUserService.move(departmentId, userIds); + return this.ok(); + } +} diff --git a/src/modules/base/controller/app/README.md b/src/modules/base/controller/app/README.md new file mode 100644 index 0000000..df64e76 --- /dev/null +++ b/src/modules/base/controller/app/README.md @@ -0,0 +1 @@ +这里写对外的api接口 \ No newline at end of file diff --git a/src/modules/base/controller/app/comm.ts b/src/modules/base/controller/app/comm.ts new file mode 100644 index 0000000..53e01b9 --- /dev/null +++ b/src/modules/base/controller/app/comm.ts @@ -0,0 +1,72 @@ +import { Provide, Inject, Get, Post, Query, Config } from '@midwayjs/core'; +import { + CoolController, + BaseController, + CoolEps, + TagTypes, + CoolUrlTag, + CoolTag, +} from '@cool-midway/core'; +import { Context } from '@midwayjs/koa'; +import { BaseSysParamService } from '../../service/sys/param'; +// import { PluginService } from '../../../plugin/service/info'; + +/** + * 不需要登录的后台接口 + */ +@CoolUrlTag() +@Provide() +@CoolController() +export class BaseAppCommController extends BaseController { + // @Inject() + // pluginService: PluginService; + + @Inject() + ctx: Context; + + @Config('module.base.allowKeys') + allowKeys: string[]; + + @Inject() + eps: CoolEps; + + @Inject() + baseSysParamService: BaseSysParamService; + + @CoolTag(TagTypes.IGNORE_TOKEN) + @Get('/param', { summary: '参数配置' }) + async param(@Query('key') key: string) { + if (!this.allowKeys.includes(key)) { + return this.fail('非法操作'); + } + return this.ok(await this.baseSysParamService.dataByKey(key)); + } + + /** + * 实体信息与路径 + * @returns + */ + @CoolTag(TagTypes.IGNORE_TOKEN) + @Get('/eps', { summary: '实体信息与路径' }) + public async getEps() { + return this.ok(this.eps.app); + } + + /** + * 文件上传 + */ + @Post('/upload', { summary: '文件上传' }) + async upload() { + // const file = await this.pluginService.getInstance('upload'); + // return this.ok(await file.upload(this.ctx)); + } + + /** + * 文件上传模式,本地或者云存储 + */ + @Get('/uploadMode', { summary: '文件上传模式' }) + async uploadMode() { + // const file = await this.pluginService.getInstance('upload'); + // return this.ok(await file.getMode()); + } +} diff --git a/src/modules/base/db.json b/src/modules/base/db.json new file mode 100644 index 0000000..81ffd6f --- /dev/null +++ b/src/modules/base/db.json @@ -0,0 +1,103 @@ +{ + "base_sys_param": [ + { + "keyName": "rich", + "name": "富文本参数", + "data": "

这是一个富文本

xxx

xxxxxxxxxx


", + "dataType": 1, + "remark": null + }, + { + "keyName": "json", + "name": "JSON参数", + "data": "{\n \"code\": 111233\n}", + "dataType": 0, + "remark": null + }, + { + "keyName": "file", + "name": "文件", + "data": "", + "dataType": 2, + "remark": null + }, + { + "keyName": "text", + "name": "测试", + "data": "这是一段字符串", + "dataType": 0, + "remark": null + } + ], + "base_sys_conf": [ + { + "cKey": "logKeep", + "cValue": "31" + }, + { + "cKey": "recycleKeep", + "cValue": "31" + } + ], + "base_sys_department": [ + { + "id": 1, + "name": "COOL", + "parentId": null, + "orderNum": 0 + }, + { + "id": 11, + "name": "开发", + "parentId": 12, + "orderNum": 2 + }, + { + "id": 12, + "name": "测试", + "parentId": 1, + "orderNum": 1 + }, + { + "id": 13, + "name": "游客", + "parentId": 1, + "orderNum": 3 + } + ], + "base_sys_role": [ + { + "id": 1, + "userId": "1", + "name": "超管", + "label": "admin", + "remark": "最高权限的角色", + "relevance": 1, + "menuIdList": "null", + "departmentIdList": "null" + } + ], + "base_sys_user": [ + { + "id": 1, + "departmentId": 1, + "name": "超级管理员", + "username": "admin", + "password": "e10adc3949ba59abbe56e057f20f883e", + "passwordV": 7, + "nickName": "管理员", + "headImg": "https://cool-js.com/admin/headimg.jpg", + "phone": "18000000000", + "email": "team@cool-js.com", + "status": 1, + "remark": "拥有最高权限的用户", + "socketId": null + } + ], + "base_sys_user_role": [ + { + "userId": 1, + "roleId": 1 + } + ] +} \ No newline at end of file diff --git a/src/modules/base/dto/login.ts b/src/modules/base/dto/login.ts new file mode 100644 index 0000000..5b4b30c --- /dev/null +++ b/src/modules/base/dto/login.ts @@ -0,0 +1,21 @@ +import { Rule, RuleType } from '@midwayjs/validate'; +/** + * 登录参数校验 + */ +export class LoginDTO { + // 用户名 + @Rule(RuleType.string().required()) + username: string; + + // 密码 + @Rule(RuleType.string().required()) + password: string; + + // 验证码ID + @Rule(RuleType.string().required()) + captchaId: string; + + // 验证码 + @Rule(RuleType.required()) + verifyCode: number; +} diff --git a/src/modules/base/entity/sys/conf.ts b/src/modules/base/entity/sys/conf.ts new file mode 100644 index 0000000..fcfc5e1 --- /dev/null +++ b/src/modules/base/entity/sys/conf.ts @@ -0,0 +1,15 @@ +import { Column, Index, Entity } from 'typeorm'; +import { BaseEntity } from '@cool-midway/core'; + +/** + * 系统配置 + */ +@Entity('base_sys_conf') +export class BaseSysConfEntity extends BaseEntity { + @Index({ unique: true }) + @Column({ comment: '配置键' }) + cKey: string; + + @Column({ comment: '配置值' }) + cValue: string; +} diff --git a/src/modules/base/entity/sys/department.ts b/src/modules/base/entity/sys/department.ts new file mode 100644 index 0000000..f340ecc --- /dev/null +++ b/src/modules/base/entity/sys/department.ts @@ -0,0 +1,19 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Entity } from 'typeorm'; + +/** + * 部门 + */ +@Entity('base_sys_department') +export class BaseSysDepartmentEntity extends BaseEntity { + @Column({ comment: '部门名称' }) + name: string; + + @Column({ comment: '上级部门ID', nullable: true }) + parentId: number; + + @Column({ comment: '排序', default: 0 }) + orderNum: number; + // 父菜单名称 + parentName: string; +} diff --git a/src/modules/base/entity/sys/log.ts b/src/modules/base/entity/sys/log.ts new file mode 100644 index 0000000..c5fb13d --- /dev/null +++ b/src/modules/base/entity/sys/log.ts @@ -0,0 +1,23 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Index, Entity } from 'typeorm'; + +/** + * 系统日志 + */ +@Entity('base_sys_log') +export class BaseSysLogEntity extends BaseEntity { + @Index() + @Column({ comment: '用户ID', nullable: true }) + userId: number; + + @Index() + @Column({ comment: '行为' }) + action: string; + + @Index() + @Column({ comment: 'ip', nullable: true }) + ip: string; + + @Column({ comment: '参数', nullable: true, type: 'json' }) + params: string; +} diff --git a/src/modules/base/entity/sys/menu.ts b/src/modules/base/entity/sys/menu.ts new file mode 100644 index 0000000..d816713 --- /dev/null +++ b/src/modules/base/entity/sys/menu.ts @@ -0,0 +1,47 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Entity } from 'typeorm'; + +/** + * 菜单 + */ +@Entity('base_sys_menu') +export class BaseSysMenuEntity extends BaseEntity { + @Column({ comment: '父菜单ID', nullable: true }) + parentId: number; + + @Column({ comment: '菜单名称' }) + name: string; + + @Column({ comment: '菜单地址', nullable: true }) + router: string; + + @Column({ comment: '权限标识', type: 'text', nullable: true }) + perms: string; + + @Column({ + comment: '类型 0-目录 1-菜单 2-按钮', + default: 0, + }) + type: number; + + @Column({ comment: '图标', nullable: true }) + icon: string; + + @Column({ comment: '排序', default: 0 }) + orderNum: number; + + @Column({ comment: '视图地址', nullable: true }) + viewPath: string; + + @Column({ comment: '路由缓存', default: true }) + keepAlive: boolean; + + @Column({ comment: '是否显示', default: true }) + isShow: boolean; + + // 父菜单名称 + parentName: string; + + // 子菜单 + childMenus: any; +} diff --git a/src/modules/base/entity/sys/param.ts b/src/modules/base/entity/sys/param.ts new file mode 100644 index 0000000..f147f89 --- /dev/null +++ b/src/modules/base/entity/sys/param.ts @@ -0,0 +1,27 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Index, Entity } from 'typeorm'; + +/** + * 参数配置 + */ +@Entity('base_sys_param') +export class BaseSysParamEntity extends BaseEntity { + @Index({ unique: true }) + @Column({ comment: '键' }) + keyName: string; + + @Column({ comment: '名称' }) + name: string; + + @Column({ comment: '数据', type: 'text' }) + data: string; + + @Column({ + comment: '数据类型 0-字符串 1-富文本 2-文件 ', + default: 0, + }) + dataType: number; + + @Column({ comment: '备注', nullable: true }) + remark: string; +} diff --git a/src/modules/base/entity/sys/role.ts b/src/modules/base/entity/sys/role.ts new file mode 100644 index 0000000..c1498d1 --- /dev/null +++ b/src/modules/base/entity/sys/role.ts @@ -0,0 +1,31 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Index, Entity } from 'typeorm'; + +/** + * 角色 + */ +@Entity('base_sys_role') +export class BaseSysRoleEntity extends BaseEntity { + @Column({ comment: '用户ID' }) + userId: string; + + @Index({ unique: true }) + @Column({ comment: '名称' }) + name: string; + + @Index({ unique: true }) + @Column({ comment: '角色标签', nullable: true, length: 50 }) + label: string; + + @Column({ comment: '备注', nullable: true }) + remark: string; + + @Column({ comment: '数据权限是否关联上下级', default: false }) + relevance: boolean; + + @Column({ comment: '菜单权限', type: 'json' }) + menuIdList: number[]; + + @Column({ comment: '部门权限', type: 'json' }) + departmentIdList: number[]; +} diff --git a/src/modules/base/entity/sys/role_department.ts b/src/modules/base/entity/sys/role_department.ts new file mode 100644 index 0000000..e0a52a8 --- /dev/null +++ b/src/modules/base/entity/sys/role_department.ts @@ -0,0 +1,14 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Entity } from 'typeorm'; + +/** + * 角色部门 + */ +@Entity('base_sys_role_department') +export class BaseSysRoleDepartmentEntity extends BaseEntity { + @Column({ comment: '角色ID' }) + roleId: number; + + @Column({ comment: '部门ID' }) + departmentId: number; +} diff --git a/src/modules/base/entity/sys/role_menu.ts b/src/modules/base/entity/sys/role_menu.ts new file mode 100644 index 0000000..667e312 --- /dev/null +++ b/src/modules/base/entity/sys/role_menu.ts @@ -0,0 +1,14 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Entity } from 'typeorm'; + +/** + * 角色菜单 + */ +@Entity('base_sys_role_menu') +export class BaseSysRoleMenuEntity extends BaseEntity { + @Column({ comment: '角色ID' }) + roleId: number; + + @Column({ comment: '菜单ID' }) + menuId: number; +} diff --git a/src/modules/base/entity/sys/user.ts b/src/modules/base/entity/sys/user.ts new file mode 100644 index 0000000..a97e7c9 --- /dev/null +++ b/src/modules/base/entity/sys/user.ts @@ -0,0 +1,54 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Index, Entity } from 'typeorm'; + +/** + * 系统用户 + */ +@Entity('base_sys_user') +export class BaseSysUserEntity extends BaseEntity { + @Index() + @Column({ comment: '部门ID', nullable: true }) + departmentId: number; + + @Column({ comment: '姓名', nullable: true }) + name: string; + + @Index({ unique: true }) + @Column({ comment: '用户名', length: 100 }) + username: string; + + @Column({ comment: '密码' }) + password: string; + + @Column({ + comment: '密码版本, 作用是改完密码,让原来的token失效', + default: 1, + }) + passwordV: number; + + @Column({ comment: '昵称', nullable: true }) + nickName: string; + + @Column({ comment: '头像', nullable: true }) + headImg: string; + + @Index() + @Column({ comment: '手机', nullable: true, length: 20 }) + phone: string; + + @Column({ comment: '邮箱', nullable: true }) + email: string; + + @Column({ comment: '备注', nullable: true }) + remark: string; + + @Column({ comment: '状态 0-禁用 1-启用', default: 1 }) + status: number; + // 部门名称 + departmentName: string; + // 角色ID列表 + roleIdList: number[]; + + @Column({ comment: 'socketId', nullable: true }) + socketId: string; +} diff --git a/src/modules/base/entity/sys/user_role.ts b/src/modules/base/entity/sys/user_role.ts new file mode 100644 index 0000000..c15f00c --- /dev/null +++ b/src/modules/base/entity/sys/user_role.ts @@ -0,0 +1,14 @@ +import { BaseEntity } from '@cool-midway/core'; +import { Column, Entity } from 'typeorm'; + +/** + * 用户角色 + */ +@Entity('base_sys_user_role') +export class BaseSysUserRoleEntity extends BaseEntity { + @Column({ comment: '用户ID' }) + userId: number; + + @Column({ comment: '角色ID' }) + roleId: number; +} diff --git a/src/modules/base/event/app.ts b/src/modules/base/event/app.ts new file mode 100644 index 0000000..508b79b --- /dev/null +++ b/src/modules/base/event/app.ts @@ -0,0 +1,102 @@ +import { CoolEvent, Event } from '@cool-midway/core'; +import { App, Config, ILogger, Logger } from '@midwayjs/core'; +import { IMidwayKoaApplication } from '@midwayjs/koa'; +import * as fs from 'fs'; +import * as path from 'path'; +import { v1 as uuid } from 'uuid'; + +/** + * 修改jwt.secret + */ +@CoolEvent() +export class BaseAppEvent { + @Logger() + coreLogger: ILogger; + + @Config('module') + config; + + @Config('keys') + configKeys; + + @Config('koa.port') + port; + + @App() + app: IMidwayKoaApplication; + + @Event('onMenuInit') + async onMenuInit() { + if (this.app.getEnv() != 'local') return; + this.checkConfig(); + this.checkKeys(); + } + + @Event('onServerReady') + async onServerReady() { + this.coreLogger.info(`服务启动成功,端口:${this.port}`); + } + + /** + * 检查配置 + */ + async checkConfig() { + if (this.config.base.jwt.secret == 'cool-admin-xxxxxx') { + this.coreLogger.warn( + '\x1B[36m 检测到模块[base] jwt.secret 配置是默认值,请不要关闭!即将自动修改... \x1B[0m' + ); + setTimeout(() => { + const filePath = path.join( + this.app.getBaseDir(), + '..', + 'src', + 'modules', + 'base', + 'config.ts' + ); + // 替换文件内容 + let fileData = fs.readFileSync(filePath, 'utf8'); + const secret = uuid().replace(/-/g, ''); + this.config.base.jwt.secret = secret; + fs.writeFileSync( + filePath, + fileData.replace('cool-admin-xxxxxx', secret) + ); + this.coreLogger.info( + '\x1B[36m [cool:module:base] midwayjs cool module base auto modify jwt.secret\x1B[0m' + ); + }, 6000); + } + } + + /** + * 检查keys + */ + async checkKeys() { + if (this.configKeys == 'cool-admin-keys-xxxxxx') { + this.coreLogger.warn( + '\x1B[36m 检测到基础配置[Keys] 是默认值,请不要关闭!即将自动修改... \x1B[0m' + ); + setTimeout(() => { + const filePath = path.join( + this.app.getBaseDir(), + '..', + 'src', + 'config', + 'config.default.ts' + ); + // 替换文件内容 + let fileData = fs.readFileSync(filePath, 'utf8'); + const secret = uuid().replace(/-/g, ''); + this.config.base.jwt.secret = secret; + fs.writeFileSync( + filePath, + fileData.replace('cool-admin-keys-xxxxxx', secret) + ); + this.coreLogger.info( + '\x1B[36m [cool:module:base] midwayjs cool keys auto modify \x1B[0m' + ); + }, 6000); + } + } +} diff --git a/src/modules/base/event/menu.ts b/src/modules/base/event/menu.ts new file mode 100644 index 0000000..3257b43 --- /dev/null +++ b/src/modules/base/event/menu.ts @@ -0,0 +1,40 @@ +import { CoolEvent, CoolEventManager, Event } from '@cool-midway/core'; +import { BaseSysMenuService } from '../service/sys/menu'; +import { + App, + ILogger, + IMidwayApplication, + Inject, + Logger, +} from '@midwayjs/core'; + +/** + * 导入菜单 + */ +@CoolEvent() +export class BaseMenuEvent { + @Logger() + coreLogger: ILogger; + + @Inject() + baseSysMenuService: BaseSysMenuService; + + @App() + app: IMidwayApplication; + + @Inject() + coolEventManager: CoolEventManager; + + @Event('onMenuImport') + async onMenuImport(datas) { + for (const module in datas) { + await this.baseSysMenuService.import(datas[module]); + this.coreLogger.info( + '\x1B[36m [cool:module:base] midwayjs cool module base import [' + + module + + '] module menu success \x1B[0m' + ); + } + this.coolEventManager.emit('onMenuInit', {}); + } +} diff --git a/src/modules/base/job/log.ts b/src/modules/base/job/log.ts new file mode 100644 index 0000000..0e35727 --- /dev/null +++ b/src/modules/base/job/log.ts @@ -0,0 +1,25 @@ +import { Job, IJob } from '@midwayjs/cron'; +import { FORMAT, ILogger, Inject } from '@midwayjs/core'; +import { BaseSysLogService } from '../service/sys/log'; + +/** + * 日志定时任务 + */ +@Job({ + cronTime: FORMAT.CRONTAB.EVERY_DAY, + start: true, +}) +export class BaseLogJob implements IJob { + @Inject() + baseSysLogService: BaseSysLogService; + + @Inject() + logger: ILogger; + + async onTick() { + this.logger.info('清除日志定时任务开始执行'); + const startTime = Date.now(); + await this.baseSysLogService.clear(); + this.logger.info(`清除日志定时任务结束,耗时:${Date.now() - startTime}ms`); + } +} diff --git a/src/modules/base/menu.json b/src/modules/base/menu.json new file mode 100644 index 0000000..c0e0cfb --- /dev/null +++ b/src/modules/base/menu.json @@ -0,0 +1,875 @@ +[ + { + "name": "系统管理", + "router": "/sys", + "perms": null, + "type": 0, + "icon": "icon-system", + "orderNum": 2, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "权限管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-auth", + "orderNum": 1, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [ + { + "name": "菜单列表", + "router": "/sys/menu", + "perms": null, + "type": 1, + "icon": "icon-menu", + "orderNum": 2, + "viewPath": "modules/base/views/menu/index.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "新增", + "router": null, + "perms": "base:sys:menu:add", + "type": 2, + "icon": null, + "orderNum": 1, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [] + }, + { + "name": "删除", + "router": null, + "perms": "base:sys:menu:delete", + "type": 2, + "icon": null, + "orderNum": 2, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [] + }, + { + "name": "查询", + "router": null, + "perms": "base:sys:menu:page,base:sys:menu:list,base:sys:menu:info", + "type": 2, + "icon": null, + "orderNum": 4, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [] + }, + { + "name": "参数", + "router": "/test/aa", + "perms": null, + "type": 1, + "icon": "icon-goods", + "orderNum": 0, + "viewPath": "modules/base/views/info.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "编辑", + "router": null, + "perms": "base:sys:menu:info,base:sys:menu:update", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "角色列表", + "router": "/sys/role", + "perms": null, + "type": 1, + "icon": "icon-dept", + "orderNum": 3, + "viewPath": "cool/modules/base/views/role.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "新增", + "router": null, + "perms": "base:sys:role:add", + "type": 2, + "icon": null, + "orderNum": 1, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [] + }, + { + "name": "删除", + "router": null, + "perms": "base:sys:role:delete", + "type": 2, + "icon": null, + "orderNum": 2, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "base:sys:role:update", + "type": 2, + "icon": null, + "orderNum": 3, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [] + }, + { + "name": "查询", + "router": null, + "perms": "base:sys:role:page,base:sys:role:list,base:sys:role:info", + "type": 2, + "icon": null, + "orderNum": 4, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "用户列表", + "router": "/sys/user", + "perms": null, + "type": 1, + "icon": "icon-user", + "orderNum": 0, + "viewPath": "modules/base/views/user/index.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "部门列表", + "router": null, + "perms": "base:sys:department:list", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增部门", + "router": null, + "perms": "base:sys:department:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "更新部门", + "router": null, + "perms": "base:sys:department:update", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "删除部门", + "router": null, + "perms": "base:sys:department:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "部门排序", + "router": null, + "perms": "base:sys:department:order", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "用户转移", + "router": null, + "perms": "base:sys:user:move", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增", + "router": null, + "perms": "base:sys:user:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "删除", + "router": null, + "perms": "base:sys:user:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "base:sys:user:delete,base:sys:user:update", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "查询", + "router": null, + "perms": "base:sys:user:page,base:sys:user:list,base:sys:user:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "参数配置", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-params", + "orderNum": 3, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "参数列表", + "router": "/sys/param", + "perms": null, + "type": 1, + "icon": "icon-menu", + "orderNum": 0, + "viewPath": "cool/modules/base/views/param.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "新增", + "router": null, + "perms": "base:sys:param:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "base:sys:param:info,base:sys:param:update", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "删除", + "router": null, + "perms": "base:sys:param:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "查看", + "router": null, + "perms": "base:sys:param:page,base:sys:param:list,base:sys:param:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "监控管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-monitor", + "orderNum": 9, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "请求日志", + "router": "/sys/log", + "perms": null, + "type": 1, + "icon": "icon-log", + "orderNum": 1, + "viewPath": "cool/modules/base/views/log.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "权限", + "router": null, + "perms": "base:sys:log:page,base:sys:log:clear,base:sys:log:getKeep,base:sys:log:setKeep", + "type": 2, + "icon": null, + "orderNum": 1, + "viewPath": null, + "keepAlive": false, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "任务管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-activity", + "orderNum": 9, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "任务列表", + "router": "/task/list", + "perms": null, + "type": 1, + "icon": "icon-menu", + "orderNum": 0, + "viewPath": "modules/task/views/list.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "权限", + "router": null, + "perms": "task:info:page,task:info:list,task:info:info,task:info:add,task:info:delete,task:info:update,task:info:stop,task:info:start,task:info:once,task:info:log", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + } + ] + }, + { + "name": "框架教程", + "router": "/tutorial", + "perms": null, + "type": 0, + "icon": "icon-task", + "orderNum": 98, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "文档官网", + "router": "/tutorial/doc", + "perms": null, + "type": 1, + "icon": "icon-log", + "orderNum": 0, + "viewPath": "https://admin.cool-js.com", + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "crud 示例", + "router": "/demo/crud", + "perms": null, + "type": 1, + "icon": "icon-favor", + "orderNum": 1, + "viewPath": "modules/demo/views/crud/index.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "通用", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-radioboxfill", + "orderNum": 99, + "viewPath": null, + "keepAlive": true, + "isShow": false, + "childMenus": [ + { + "name": "图片上传", + "router": null, + "perms": "space:info:page,space:info:list,space:info:info,space:info:add,space:info:delete,space:info:update,space:type:page,space:type:list,space:type:info,space:type:add,space:type:delete,space:type:update", + "type": 2, + "icon": null, + "orderNum": 1, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "首页", + "router": "/", + "perms": null, + "type": 1, + "icon": null, + "orderNum": 0, + "viewPath": "modules/demo/views/home/index.vue", + "keepAlive": true, + "isShow": false, + "childMenus": [] + }, + { + "name": "数据管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-data", + "orderNum": 7, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "字典管理", + "router": "/dict/list", + "perms": null, + "type": 1, + "icon": "icon-dict", + "orderNum": 3, + "viewPath": "modules/dict/views/list.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "删除", + "router": null, + "perms": "dict:info:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "dict:info:update,dict:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "获得字典数据", + "router": null, + "perms": "dict:info:data", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "dict:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "列表查询", + "router": null, + "perms": "dict:info:list", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "dict:info:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增", + "router": null, + "perms": "dict:info:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "组权限", + "router": null, + "perms": "dict:type:list,dict:type:update,dict:type:delete,dict:type:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "字典类型", + "router": null, + "perms": "dict:type:delete,dict:type:update,dict:type:info,dict:type:list,dict:type:page,dict:type:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "数据回收站", + "router": "/recycle/data", + "perms": null, + "type": 1, + "icon": "icon-delete", + "orderNum": 6, + "viewPath": "modules/recycle/views/data.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "恢复数据", + "router": null, + "perms": "recycle:data:restore", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "recycle:data:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "recycle:data:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "文件管理", + "router": "/upload/list", + "perms": null, + "type": 1, + "icon": "icon-log", + "orderNum": 5, + "viewPath": "modules/space/views/list.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "权限", + "router": null, + "perms": "space:type:delete,space:type:update,space:type:info,space:type:list,space:type:page,space:type:add,space:info:getConfig,space:info:delete,space:info:update,space:info:info,space:info:list,space:info:page,space:info:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "用户管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-user", + "orderNum": 11, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "用户列表", + "router": "/user/list", + "perms": null, + "type": 1, + "icon": "icon-menu", + "orderNum": 1, + "viewPath": "modules/user/views/list.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "删除", + "router": null, + "perms": "user:info:delete", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "修改", + "router": null, + "perms": "user:info:update,user:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "单个信息", + "router": null, + "perms": "user:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "列表查询", + "router": null, + "perms": "user:info:list", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "分页查询", + "router": null, + "perms": "user:info:page", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + }, + { + "name": "新增", + "router": null, + "perms": "user:info:add", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } + ] + }, + { + "name": "扩展管理", + "router": null, + "perms": null, + "type": 0, + "icon": "icon-favor", + "orderNum": 8, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "后端插件", + "router": "/helper/plugins/serve", + "perms": null, + "type": 1, + "icon": "icon-component", + "orderNum": 2, + "viewPath": "modules/helper/views/plugins/serve.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [ + { + "name": "权限", + "router": null, + "perms": "plugin:info:install,plugin:info:delete,plugin:info:update,plugin:info:page,plugin:info:info", + "type": 2, + "icon": null, + "orderNum": 0, + "viewPath": null, + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + }, + { + "name": "前端插件", + "router": "/helper/plugins/vue", + "perms": null, + "type": 1, + "icon": "icon-vue", + "orderNum": 1, + "viewPath": "modules/helper/views/plugins/vue.vue", + "keepAlive": true, + "isShow": true, + "childMenus": [] + } + ] + } +] \ No newline at end of file diff --git a/src/modules/base/middleware/authority.ts b/src/modules/base/middleware/authority.ts new file mode 100644 index 0000000..939dca0 --- /dev/null +++ b/src/modules/base/middleware/authority.ts @@ -0,0 +1,185 @@ +import { App, Config, Inject, Middleware } from '@midwayjs/core'; +import * as _ from 'lodash'; +import { CoolUrlTagData, RESCODE, TagTypes } from '@cool-midway/core'; +import * as jwt from 'jsonwebtoken'; +import { NextFunction, Context } from '@midwayjs/koa'; +import { + IMiddleware, + IMidwayApplication, + Init, + InjectClient, +} from '@midwayjs/core'; +import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager'; + +/** + * 权限校验 + */ +@Middleware() +export class BaseAuthorityMiddleware + implements IMiddleware +{ + @Config('koa.globalPrefix') + prefix; + + @Config('module.base') + jwtConfig; + + @InjectClient(CachingFactory, 'default') + midwayCache: MidwayCache; + + @Inject() + coolUrlTagData: CoolUrlTagData; + + @App() + app: IMidwayApplication; + + ignoreUrls: string[] = []; + + @Init() + async init() { + this.ignoreUrls = this.coolUrlTagData.byKey(TagTypes.IGNORE_TOKEN, 'admin'); + } + + resolve() { + return async (ctx: Context, next: NextFunction) => { + let statusCode = 200; + let { url } = ctx; + url = url.replace(this.prefix, '').split('?')[0]; + const token = ctx.get('Authorization'); + const adminUrl = '/admin/'; + // 路由地址为 admin前缀的 需要权限校验 + if (_.startsWith(url, adminUrl)) { + try { + ctx.admin = jwt.verify(token, this.jwtConfig.jwt.secret); + if (ctx.admin.isRefresh) { + ctx.status = 401; + ctx.body = { + code: RESCODE.COMMFAIL, + message: '登录失效~', + }; + return; + } + } catch (error) {} + // 使用matchUrl方法来检查URL是否应该被忽略 + const isIgnored = this.ignoreUrls.some(pattern => + this.matchUrl(pattern, url) + ); + if (isIgnored) { + await next(); + return; + } + if (ctx.admin) { + const rToken = await this.midwayCache.get( + `admin:token:${ctx.admin.userId}` + ); + // 判断密码版本是否正确 + const passwordV = await this.midwayCache.get( + `admin:passwordVersion:${ctx.admin.userId}` + ); + if (passwordV != ctx.admin.passwordVersion) { + ctx.status = 401; + ctx.body = { + code: RESCODE.COMMFAIL, + message: '登录失效~', + }; + return; + } + // 超管拥有所有权限 + if (ctx.admin.username == 'admin' && !ctx.admin.isRefresh) { + if (rToken !== token && this.jwtConfig.jwt.sso) { + ctx.status = 401; + ctx.body = { + code: RESCODE.COMMFAIL, + message: '登录失效~', + }; + return; + } else { + await next(); + return; + } + } + // 要登录每个人都有权限的接口 + if ( + new RegExp(`^${adminUrl}?.*/comm/`).test(url) || + // 字典接口 + url == '/admin/dict/info/data' + ) { + await next(); + return; + } + // 如果传的token是refreshToken则校验失败 + if (ctx.admin.isRefresh) { + ctx.status = 401; + ctx.body = { + code: RESCODE.COMMFAIL, + message: '登录失效~', + }; + return; + } + if (!rToken) { + ctx.status = 401; + ctx.body = { + code: RESCODE.COMMFAIL, + message: '登录失效或无权限访问~', + }; + return; + } + if (rToken !== token && this.jwtConfig.jwt.sso) { + statusCode = 401; + } else { + let perms: string[] = await this.midwayCache.get( + `admin:perms:${ctx.admin.userId}` + ); + if (!_.isEmpty(perms)) { + perms = perms.map(e => { + return e.replace(/:/g, '/'); + }); + if (!perms.includes(url.split('?')[0].replace('/admin/', ''))) { + statusCode = 403; + } + } else { + statusCode = 403; + } + } + } else { + statusCode = 401; + } + if (statusCode > 200) { + ctx.status = statusCode; + ctx.body = { + code: RESCODE.COMMFAIL, + message: '登录失效或无权限访问~', + }; + return; + } + } + await next(); + }; + } + + // 匹配URL的方法 + matchUrl(pattern, url) { + const patternSegments = pattern.split('/').filter(Boolean); + const urlSegments = url.split('/').filter(Boolean); + + // 如果段的数量不同,则无法匹配 + if (patternSegments.length !== urlSegments.length) { + return false; + } + + // 逐段进行匹配 + for (let i = 0; i < patternSegments.length; i++) { + if (patternSegments[i].startsWith(':')) { + // 如果模式段以':'开始,我们认为它是一个参数,可以匹配任何内容 + continue; + } + // 如果两个段不相同,则不匹配 + if (patternSegments[i] !== urlSegments[i]) { + return false; + } + } + + // 所有段都匹配 + return true; + } +} diff --git a/src/modules/base/middleware/log.ts b/src/modules/base/middleware/log.ts new file mode 100644 index 0000000..4c92ec6 --- /dev/null +++ b/src/modules/base/middleware/log.ts @@ -0,0 +1,26 @@ +import { Middleware } from '@midwayjs/core'; +import * as _ from 'lodash'; +import { NextFunction, Context } from '@midwayjs/koa'; +import { IMiddleware } from '@midwayjs/core'; +import { BaseSysLogService } from '../service/sys/log'; + +/** + * 日志中间件 + */ +@Middleware() +export class BaseLogMiddleware implements IMiddleware { + resolve() { + return async (ctx: Context, next: NextFunction) => { + const baseSysLogService = await ctx.requestContext.getAsync( + BaseSysLogService + ); + baseSysLogService.record( + ctx, + ctx.url, + ctx.req.method === 'GET' ? ctx.request.query : ctx.request.body, + ctx.admin ? ctx.admin.userId : null + ); + await next(); + }; + } +} diff --git a/src/modules/base/service/sys/conf.ts b/src/modules/base/service/sys/conf.ts new file mode 100644 index 0000000..1208158 --- /dev/null +++ b/src/modules/base/service/sys/conf.ts @@ -0,0 +1,39 @@ +import { Provide } from '@midwayjs/core'; +import { BaseService } from '@cool-midway/core'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { Repository } from 'typeorm'; +import { BaseSysConfEntity } from '../../entity/sys/conf'; + +/** + * 系统配置 + */ +@Provide() +export class BaseSysConfService extends BaseService { + @InjectEntityModel(BaseSysConfEntity) + baseSysConfEntity: Repository; + + /** + * 获得配置参数值 + * @param key + */ + async getValue(key) { + const conf = await this.baseSysConfEntity.findOneBy({ cKey: key }); + if (conf) { + return conf.cValue; + } + } + + /** + * 更新配置参数 + * @param cKey + * @param cValue + */ + async updateVaule(cKey, cValue) { + await this.baseSysConfEntity + .createQueryBuilder() + .update() + .where({ cKey }) + .set({ cKey, cValue }) + .execute(); + } +} diff --git a/src/modules/base/service/sys/data.ts b/src/modules/base/service/sys/data.ts new file mode 100644 index 0000000..42b03c9 --- /dev/null +++ b/src/modules/base/service/sys/data.ts @@ -0,0 +1,10 @@ +import { DataSource } from 'typeorm'; + +export class TempDataSource extends DataSource { + /** + * 重新构造元数据 + */ + async buildMetadatas() { + await super.buildMetadatas(); + } +} diff --git a/src/modules/base/service/sys/department.ts b/src/modules/base/service/sys/department.ts new file mode 100644 index 0000000..8037852 --- /dev/null +++ b/src/modules/base/service/sys/department.ts @@ -0,0 +1,124 @@ +import { Inject, Provide } from '@midwayjs/core'; +import { BaseService } from '@cool-midway/core'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { In, Repository } from 'typeorm'; +import { BaseSysDepartmentEntity } from '../../entity/sys/department'; +import * as _ from 'lodash'; +import { BaseSysRoleDepartmentEntity } from '../../entity/sys/role_department'; +import { BaseSysPermsService } from './perms'; +import { BaseSysUserEntity } from '../../entity/sys/user'; + +/** + * 描述 + */ +@Provide() +export class BaseSysDepartmentService extends BaseService { + @InjectEntityModel(BaseSysDepartmentEntity) + baseSysDepartmentEntity: Repository; + + @InjectEntityModel(BaseSysUserEntity) + baseSysUserEntity: Repository; + + @InjectEntityModel(BaseSysRoleDepartmentEntity) + baseSysRoleDepartmentEntity: Repository; + + @Inject() + baseSysPermsService: BaseSysPermsService; + + @Inject() + ctx; + + /** + * 获得部门菜单 + */ + async list() { + // 部门权限 + const permsDepartmentArr = await this.baseSysPermsService.departmentIds( + this.ctx.admin.userId + ); + + // 过滤部门权限 + const find = this.baseSysDepartmentEntity.createQueryBuilder('a'); + if (this.ctx.admin.username !== 'admin') + find.andWhere('a.id in (:...ids)', { + ids: !_.isEmpty(permsDepartmentArr) ? permsDepartmentArr : [null], + }); + find.addOrderBy('a.orderNum', 'ASC'); + const departments: BaseSysDepartmentEntity[] = await find.getMany(); + + if (!_.isEmpty(departments)) { + departments.forEach(e => { + const parentMenu = departments.filter(m => { + e.parentId = parseInt(e.parentId + ''); + if (e.parentId == m.id) { + return m.name; + } + }); + if (!_.isEmpty(parentMenu)) { + e.parentName = parentMenu[0].name; + } + }); + } + return departments; + } + + /** + * 根据多个ID获得部门权限信息 + * @param {[]} roleIds 数组 + * @param isAdmin 是否超管 + */ + async getByRoleIds(roleIds: number[], isAdmin) { + if (!_.isEmpty(roleIds)) { + if (isAdmin) { + const result = await this.baseSysDepartmentEntity.find(); + return result.map(e => { + return e.id; + }); + } + const result = await this.baseSysRoleDepartmentEntity + .createQueryBuilder('a') + .where('a.roleId in (:...roleIds)', { roleIds }) + .getMany(); + if (!_.isEmpty(result)) { + return _.uniq( + result.map(e => { + return e.departmentId; + }) + ); + } + } + return []; + } + + /** + * 部门排序 + * @param params + */ + async order(params) { + for (const e of params) { + await this.baseSysDepartmentEntity.update(e.id, e); + } + } + + /** + * 删除 + */ + async delete(ids: number[]) { + const { deleteUser } = this.ctx.request.body; + await super.delete(ids); + if (deleteUser) { + await this.baseSysUserEntity.delete({ departmentId: In(ids) }); + } else { + const topDepartment = await this.baseSysDepartmentEntity + .createQueryBuilder('a') + .where('a.parentId is null') + .getOne(); + if (topDepartment) { + await this.baseSysUserEntity.update( + { departmentId: In(ids) }, + { departmentId: topDepartment.id } + ); + } + } + } +} diff --git a/src/modules/base/service/sys/log.ts b/src/modules/base/service/sys/log.ts new file mode 100644 index 0000000..8695c92 --- /dev/null +++ b/src/modules/base/service/sys/log.ts @@ -0,0 +1,62 @@ +import { Inject, Provide } from '@midwayjs/core'; +import { BaseService } from '@cool-midway/core'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { LessThan, Repository } from 'typeorm'; +import * as _ from 'lodash'; +import { BaseSysLogEntity } from '../../entity/sys/log'; +import * as moment from 'moment'; +import { Utils } from '../../../../comm/utils'; +import { BaseSysConfService } from './conf'; +import { Context } from '@midwayjs/koa'; + +/** + * 描述 + */ +@Provide() +export class BaseSysLogService extends BaseService { + @Inject() + ctx; + + @Inject() + utils: Utils; + + @InjectEntityModel(BaseSysLogEntity) + baseSysLogEntity: Repository; + + @Inject() + baseSysConfService: BaseSysConfService; + + /** + * 记录 + * @param url URL地址 + * @param params 参数 + * @param userId 用户ID + */ + async record(context: Context, url, params, userId) { + const ip = await this.utils.getReqIP(context); + const sysLog = new BaseSysLogEntity(); + sysLog.userId = userId; + sysLog.ip = typeof ip === 'string' ? ip : ip.join(','); + sysLog.action = url.split('?')[0]; + sysLog.params = params; + await this.baseSysLogEntity.insert(sysLog); + } + + /** + * 日志 + * @param isAll 是否清除全部 + */ + async clear(isAll?) { + if (isAll) { + await this.baseSysLogEntity.clear(); + return; + } + const keepDay = await this.baseSysConfService.getValue('logKeep'); + if (keepDay) { + const beforeDate = moment().add(-keepDay, 'days').startOf('day').toDate(); + await this.baseSysLogEntity.delete({ createTime: LessThan(beforeDate) }); + } else { + await this.baseSysLogEntity.clear(); + } + } +} diff --git a/src/modules/base/service/sys/login.ts b/src/modules/base/service/sys/login.ts new file mode 100644 index 0000000..bc3dfae --- /dev/null +++ b/src/modules/base/service/sys/login.ts @@ -0,0 +1,272 @@ +import { Inject, Provide, Config, InjectClient } from '@midwayjs/core'; +import { BaseService, CoolCommException } from '@cool-midway/core'; +import { LoginDTO } from '../../dto/login'; +import * as svgCaptcha from 'svg-captcha'; +import { v1 as uuid } from 'uuid'; +import { BaseSysUserEntity } from '../../entity/sys/user'; +import { Repository } from 'typeorm'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import * as md5 from 'md5'; +import { BaseSysRoleService } from './role'; +import * as _ from 'lodash'; +import { BaseSysMenuService } from './menu'; +import { BaseSysDepartmentService } from './department'; +import * as jwt from 'jsonwebtoken'; +import { Context } from '@midwayjs/koa'; +import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager'; +// import * as sharp from 'sharp'; + +/** + * 登录 + */ +@Provide() +export class BaseSysLoginService extends BaseService { + @InjectClient(CachingFactory, 'default') + midwayCache: MidwayCache; + + @InjectEntityModel(BaseSysUserEntity) + baseSysUserEntity: Repository; + + @Inject() + baseSysRoleService: BaseSysRoleService; + + @Inject() + baseSysMenuService: BaseSysMenuService; + + @Inject() + baseSysDepartmentService: BaseSysDepartmentService; + + @Inject() + ctx: Context; + + @Config('module.base') + coolConfig; + + /** + * 登录 + * @param login + */ + async login(login: LoginDTO) { + const { username, captchaId, verifyCode, password } = login; + // 校验验证码 + const checkV = await this.captchaCheck(captchaId, verifyCode); + if (checkV) { + const user = await this.baseSysUserEntity.findOneBy({ username }); + // 校验用户 + if (user) { + // 校验用户状态及密码 + if (user.status === 0 || user.password !== md5(password)) { + throw new CoolCommException('账户或密码不正确~'); + } + } else { + throw new CoolCommException('账户或密码不正确~'); + } + // 校验角色 + const roleIds = await this.baseSysRoleService.getByUser(user.id); + if (_.isEmpty(roleIds)) { + throw new CoolCommException('该用户未设置任何角色,无法登录~'); + } + + // 生成token + const { expire, refreshExpire } = this.coolConfig.jwt.token; + const result = { + expire, + token: await this.generateToken(user, roleIds, expire), + refreshExpire, + refreshToken: await this.generateToken( + user, + roleIds, + refreshExpire, + true + ), + }; + + // 将用户相关信息保存到缓存 + const perms = await this.baseSysMenuService.getPerms(roleIds); + const departments = await this.baseSysDepartmentService.getByRoleIds( + roleIds, + user.username === 'admin' + ); + await this.midwayCache.set(`admin:department:${user.id}`, departments); + await this.midwayCache.set(`admin:perms:${user.id}`, perms); + await this.midwayCache.set(`admin:token:${user.id}`, result.token); + await this.midwayCache.set( + `admin:token:refresh:${user.id}`, + result.token + ); + + return result; + } else { + throw new CoolCommException('验证码不正确'); + } + } + + /** + * 验证码 + * @param type 图片验证码类型 svg + * @param width 宽 + * @param height 高 + */ + async captcha(type: string, width = 150, height = 50, color = '#fff') { + const svg = svgCaptcha.create({ + ignoreChars: 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM', + width, + height, + }); + const result = { + captchaId: uuid(), + data: svg.data.replace(/"/g, "'"), + }; + // 文字变白 + const rpList = [ + '#111', + '#222', + '#333', + '#444', + '#555', + '#666', + '#777', + '#888', + '#999', + ]; + rpList.forEach(rp => { + result.data = result.data['replaceAll'](rp, color); + }); + if (type === 'png' || type === 'base64') { + result.data = await this.svgToBase64Png(result.data, { + width, + height, + }); + } + // 半小时过期 + await this.midwayCache.set( + `verify:img:${result.captchaId}`, + svg.text.toLowerCase(), + 1800 * 1000 + ); + return result; + } + + /** + * svg转base64 + * @param svgBuffer + * @param options + */ + async svgToBase64Png(svgBuffer: string, options = {} as any) { + try { + // const svgBufferData = Buffer.from(svgBuffer); + + // // 处理图片 + // const pngBuffer = await sharp(svgBufferData) + // .png({ + // quality: options.quality || 100, + // compressionLevel: options.compression || 6, + // }) + // .resize(options.width, options.height, { + // fit: 'contain', + // background: { r: 255, g: 255, b: 255, alpha: 1 }, + // }) + // .toBuffer(); + + // // 转换为base64 + // const base64String = `data:image/png;base64,${pngBuffer.toString( + // 'base64' + // )}`; + return ''; + } catch (error) { + console.error('转换失败:', error); + throw error; + } + } + + /** + * 退出登录 + */ + async logout() { + if (!this.coolConfig.jwt.sso) return; + const { userId } = this.ctx.admin; + await this.midwayCache.del(`admin:department:${userId}`); + await this.midwayCache.del(`admin:perms:${userId}`); + await this.midwayCache.del(`admin:token:${userId}`); + await this.midwayCache.del(`admin:token:refresh:${userId}`); + await this.midwayCache.del(`admin:passwordVersion:${userId}`); + } + + /** + * 检验图片验证码 + * @param captchaId 验证码ID + * @param value 验证码 + */ + async captchaCheck(captchaId, value) { + const rv = await this.midwayCache.get(`verify:img:${captchaId}`); + if (!rv || !value || value.toLowerCase() !== rv) { + return false; + } else { + this.midwayCache.del(`verify:img:${captchaId}`); + return true; + } + } + + /** + * 生成token + * @param user 用户对象 + * @param roleIds 角色集合 + * @param expire 过期 + * @param isRefresh 是否是刷新 + */ + async generateToken(user, roleIds, expire, isRefresh?) { + await this.midwayCache.set( + `admin:passwordVersion:${user.id}`, + user.passwordV + ); + const tokenInfo = { + isRefresh: false, + roleIds, + username: user.username, + userId: user.id, + passwordVersion: user.passwordV, + }; + if (isRefresh) { + tokenInfo.isRefresh = true; + } + return jwt.sign(tokenInfo, this.coolConfig.jwt.secret, { + expiresIn: expire, + }); + } + + /** + * 刷新token + * @param token + */ + async refreshToken(token: string) { + const decoded = jwt.verify(token, this.coolConfig.jwt.secret); + if (decoded && decoded['isRefresh']) { + delete decoded['exp']; + delete decoded['iat']; + + const { expire, refreshExpire } = this.coolConfig.jwt.token; + decoded['isRefresh'] = false; + const result = { + expire, + token: jwt.sign(decoded, this.coolConfig.jwt.secret, { + expiresIn: expire, + }), + refreshExpire, + refreshToken: '', + }; + decoded['isRefresh'] = true; + result.refreshToken = jwt.sign(decoded, this.coolConfig.jwt.secret, { + expiresIn: refreshExpire, + }); + await this.midwayCache.set( + `admin:passwordVersion:${decoded['userId']}`, + decoded['passwordVersion'] + ); + await this.midwayCache.set( + `admin:token:${decoded['userId']}`, + result.token + ); + return result; + } + } +} diff --git a/src/modules/base/service/sys/menu.ts b/src/modules/base/service/sys/menu.ts new file mode 100644 index 0000000..261d5a7 --- /dev/null +++ b/src/modules/base/service/sys/menu.ts @@ -0,0 +1,463 @@ +import { App, IMidwayApplication, Scope, ScopeEnum } from '@midwayjs/core'; +import { ALL, Config, Inject, Provide } from '@midwayjs/core'; +import { BaseService, CoolCommException } from '@cool-midway/core'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { In, Repository } from 'typeorm'; +import { BaseSysMenuEntity } from '../../entity/sys/menu'; +import * as _ from 'lodash'; +import { BaseSysPermsService } from './perms'; +import { Context } from '@midwayjs/koa'; +import { TempDataSource } from './data'; +// eslint-disable-next-line node/no-unpublished-import +import * as ts from 'typescript'; +import * as fs from 'fs'; +import * as pathUtil from 'path'; +import { BaseSysRoleMenuEntity } from '../../entity/sys/role_menu'; +import { BaseSysUserRoleEntity } from '../../entity/sys/user_role'; + +/** + * 菜单 + */ +@Scope(ScopeEnum.Request, { allowDowngrade: true }) +@Provide() +export class BaseSysMenuService extends BaseService { + @Inject() + ctx: Context; + + @InjectEntityModel(BaseSysMenuEntity) + baseSysMenuEntity: Repository; + + @InjectEntityModel(BaseSysRoleMenuEntity) + baseSysRoleMenuEntity: Repository; + + @Inject() + baseSysPermsService: BaseSysPermsService; + + @Config(ALL) + config; + + @App() + app: IMidwayApplication; + + /** + * 获得所有菜单 + */ + async list() { + const menus = await this.getMenus( + this.ctx.admin.roleIds, + this.ctx.admin.username === 'admin' + ); + if (!_.isEmpty(menus)) { + menus.forEach((e: any) => { + const parentMenu = menus.filter(m => { + e.parentId = parseInt(e.parentId); + if (e.parentId == m.id) { + return m.name; + } + }); + if (!_.isEmpty(parentMenu)) { + e.parentName = parentMenu[0].name; + } + }); + } + return menus; + } + + /** + * 修改之后 + * @param param + */ + async modifyAfter(param) { + if (param.id) { + await this.refreshPerms(param.id); + } + } + + /** + * 根据角色获得权限信息 + * @param {[]} roleIds 数组 + */ + async getPerms(roleIds) { + let perms = []; + if (!_.isEmpty(roleIds)) { + const find = await this.baseSysMenuEntity.createQueryBuilder('a'); + if (!roleIds.includes(1)) { + find.innerJoinAndSelect( + BaseSysRoleMenuEntity, + 'b', + 'a.id = b.menuId AND b.roleId in (:...roleIds)', + { roleIds } + ); + } + find.where('a.perms is not NULL'); + const result = await find.getMany(); + if (result) { + result.forEach(d => { + if (d.perms) { + perms = perms.concat(d.perms.split(',')); + } + }); + } + perms = _.uniq(perms); + perms = _.remove(perms, n => { + return !_.isEmpty(n); + }); + } + return _.uniq(perms); + } + + /** + * 获得用户菜单信息 + * @param roleIds + * @param isAdmin 是否是超管 + */ + async getMenus(roleIds, isAdmin) { + const find = this.baseSysMenuEntity.createQueryBuilder('a'); + if (!isAdmin) { + find.innerJoinAndSelect( + BaseSysRoleMenuEntity, + 'b', + 'a.id = b.menuId AND b.roleId in (:...roleIds)', + { roleIds } + ); + } + find.orderBy('a.orderNum', 'ASC'); + const list = await find.getMany(); + return _.uniqBy(list, 'id'); + } + + /** + * 删除 + * @param ids + */ + async delete(ids) { + let idArr; + if (ids instanceof Array) { + idArr = ids; + } else { + idArr = ids.split(','); + } + for (const id of idArr) { + await this.baseSysMenuEntity.delete({ id }); + await this.delChildMenu(id); + } + } + + /** + * 删除子菜单 + * @param id + */ + private async delChildMenu(id) { + await this.refreshPerms(id); + const delMenu = await this.baseSysMenuEntity.findBy({ parentId: id }); + if (_.isEmpty(delMenu)) { + return; + } + const delMenuIds = delMenu.map(e => { + return e.id; + }); + await this.baseSysMenuEntity.delete(delMenuIds); + for (const menuId of delMenuIds) { + await this.delChildMenu(menuId); + } + } + + /** + * 更新权限 + * @param menuId + */ + async refreshPerms(menuId) { + const find = this.baseSysRoleMenuEntity.createQueryBuilder('a'); + find.leftJoinAndSelect(BaseSysUserRoleEntity, 'b', 'a.roleId = b.roleId'); + find.where('a.menuId = :menuId', { menuId: menuId }); + find.select('b.userId', 'userId'); + const users = await find.getRawMany(); + // 刷新admin权限 + await this.baseSysPermsService.refreshPerms(1); + if (!_.isEmpty(users)) { + // 刷新其他权限 + for (const user of _.uniqBy(users, 'userId')) { + await this.baseSysPermsService.refreshPerms(user.userId); + } + } + } + + /** + * 解析实体和Controller + * @param entityString + * @param controller + * @param module + */ + async parse(entityString: string, controller: string, module: string) { + const tempDataSource = new TempDataSource({ + ...this.config.typeorm.dataSource.default, + entities: [], + }); + // 连接数据库 + await tempDataSource.initialize(); + const { newCode, className, oldTableName } = this.parseCode(entityString); + const code = ts.transpile( + `${newCode} + tempDataSource.options.entities.push(${className}) + `, + { + emitDecoratorMetadata: true, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES2018, + removeComments: true, + experimentalDecorators: true, + noImplicitThis: true, + noUnusedLocals: true, + stripInternal: true, + skipLibCheck: true, + pretty: true, + declaration: true, + noImplicitAny: false, + } + ); + eval(code); + await tempDataSource.buildMetadatas(); + const meta = tempDataSource.getMetadata(className); + const columnArr = meta.columns; + await tempDataSource.destroy(); + + const commColums = []; + const columns = _.filter( + columnArr.map(e => { + return { + propertyName: e.propertyName, + type: typeof e.type == 'string' ? e.type : e.type.name.toLowerCase(), + length: e.length, + comment: e.comment, + nullable: e.isNullable, + }; + }), + o => { + if (['createTime', 'updateTime'].includes(o.propertyName)) { + commColums.push(o); + } + return o && !['createTime', 'updateTime'].includes(o.propertyName); + } + ).concat(commColums); + if (!controller) { + const tableNames = oldTableName.split('_'); + const fileName = tableNames[tableNames.length - 1]; + return { + columns, + className: className.replace('TEMP', ''), + tableName: oldTableName, + fileName, + path: `/admin/${module}/${fileName}`, + }; + } + const fileName = await this.fileName(controller); + return { + columns, + path: `/admin/${module}/${fileName}`, + }; + } + + /** + * 解析Entity类名 + * @param code + * @returns + */ + parseCode(code: string) { + try { + const oldClassName = code + .match('class(.*)extends')[1] + .replace(/\s*/g, ''); + const oldTableStart = code.indexOf('@Entity('); + const oldTableEnd = code.indexOf(')'); + + const oldTableName = code + .substring(oldTableStart + 9, oldTableEnd - 1) + .replace(/\s*/g, '') + // eslint-disable-next-line no-useless-escape + .replace(/\"/g, '') + // eslint-disable-next-line no-useless-escape + .replace(/\'/g, ''); + const className = `${oldClassName}TEMP`; + return { + newCode: code + .replace(oldClassName, className) + .replace(oldTableName, `func_${oldTableName}`), + className, + tableName: `func_${oldTableName}`, + oldTableName, + }; + } catch (err) { + throw new CoolCommException('代码结构不正确,请检查'); + } + } + + /** + * 创建代码 + * @param body body + */ + async create(body) { + const { module, entity, controller, service, fileName } = body; + const basePath = this.app.getBaseDir(); + const modulePath = pathUtil.join(basePath, '..', 'src', 'modules', module); + // 生成Entity + const entityPath = pathUtil.join(modulePath, 'entity', `${fileName}.ts`); + // 生成Controller + const controllerPath = pathUtil.join( + modulePath, + 'controller', + 'admin', + `${fileName}.ts` + ); + // 生成Service + const servicePath = pathUtil.join(modulePath, 'service', `${fileName}.ts`); + this.createConfigFile(module); + this.createFile(entityPath, entity); + this.createFile(controllerPath, controller); + this.createFile(servicePath, service); + } + + /** + * 创建配置文件 + * @param module + */ + async createConfigFile(module: string) { + const basePath = this.app.getBaseDir(); + const configFilePath = pathUtil.join( + basePath, + '..', + 'src', + 'modules', + module, + 'config.ts' + ); + if (!fs.existsSync(configFilePath)) { + const data = `import { ModuleConfig } from '@cool-midway/core'; + +/** + * 模块配置 + */ +export default () => { + return { + // 模块名称 + name: 'xxx', + // 模块描述 + description: 'xxx', + // 中间件,只对本模块有效 + middlewares: [], + // 中间件,全局有效 + globalMiddlewares: [], + // 模块加载顺序,默认为0,值越大越优先加载 + order: 0, + } as ModuleConfig; +}; +`; + await this.createFile(configFilePath, data); + } + } + + /** + * 找到文件名 + * @param controller + * @returns + */ + async fileName(controller: string) { + const regex = /import\s*{\s*\w+\s*}\s*from\s*'[^']*\/([\w-]+)';/; + const match = regex.exec(controller); + + if (match && match.length > 1) { + return match[1]; + } + + return null; + } + + /** + * 创建文件 + * @param filePath + * @param content + */ + async createFile(filePath: string, content: string) { + const folderPath = pathUtil.dirname(filePath); + if (!fs.existsSync(folderPath)) { + fs.mkdirSync(folderPath, { recursive: true }); + } + fs.writeFileSync(filePath, content); + } + + /** + * 导出菜单 + * @param ids + * @returns + */ + async export(ids: number[]) { + const result: any[] = []; + const menus = await this.baseSysMenuEntity.findBy({ id: In(ids) }); + + // 递归取出子菜单 + const getChildMenus = (parentId: number): any[] => { + const children = _.remove(menus, e => e.parentId == parentId); + children.forEach(child => { + child.childMenus = getChildMenus(child.id); + // 删除不需要的字段 + delete child.id; + delete child.createTime; + delete child.updateTime; + delete child.parentId; + }); + return children; + }; + + // lodash取出父级菜单(parentId为 null), 并从menus 删除 + const parentMenus = _.remove(menus, e => { + return e.parentId == null; + }); + + // 对于每个父级菜单,获取它的子菜单 + parentMenus.forEach(parent => { + parent.childMenus = getChildMenus(parent.id); + // 删除不需要的字段 + delete parent.id; + delete parent.createTime; + delete parent.updateTime; + delete parent.parentId; + + result.push(parent); + }); + + return result; + } + + /** + * 导入 + * @param menus + */ + async import(menus: any[]) { + // 递归保存子菜单 + const saveChildMenus = async (parentMenu: any, parentId: number | null) => { + const children = parentMenu.childMenus || []; + for (let child of children) { + const childData = { ...child, parentId: parentId }; // 保持与数据库的parentId字段的一致性 + delete childData.childMenus; // 删除childMenus属性,因为我们不想将它保存到数据库中 + + // 保存子菜单并获取其ID,以便为其子菜单设置parentId + const savedChild = await this.baseSysMenuEntity.save(childData); + + if (!_.isEmpty(child.childMenus)) { + await saveChildMenus(child, savedChild.id); + } + } + }; + + for (let menu of menus) { + const menuData = { ...menu }; + delete menuData.childMenus; // 删除childMenus属性,因为我们不想将它保存到数据库中 + + // 保存主菜单并获取其ID + const savedMenu = await this.baseSysMenuEntity.save(menuData); + + if (menu.childMenus && menu.childMenus.length > 0) { + await saveChildMenus(menu, savedMenu.id); + } + } + } +} diff --git a/src/modules/base/service/sys/param.ts b/src/modules/base/service/sys/param.ts new file mode 100644 index 0000000..77ecf8e --- /dev/null +++ b/src/modules/base/service/sys/param.ts @@ -0,0 +1,91 @@ +import { Inject, InjectClient, Provide } from '@midwayjs/core'; +import { BaseService, CoolCommException } from '@cool-midway/core'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { Not, Repository } from 'typeorm'; +import { BaseSysParamEntity } from '../../entity/sys/param'; +import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager'; + +/** + * 参数配置 + */ +@Provide() +export class BaseSysParamService extends BaseService { + @InjectEntityModel(BaseSysParamEntity) + baseSysParamEntity: Repository; + + @InjectClient(CachingFactory, 'default') + midwayCache: MidwayCache; + + /** + * 根据key获得对应的参数 + * @param key + */ + async dataByKey(key) { + let result: any = await this.midwayCache.get(`param:${key}`); + if (!result) { + result = await this.baseSysParamEntity.findOneBy({ keyName: key }); + this.midwayCache.set(`param:${key}`, result); + } + if (result) { + if (result.dataType == 0) { + try { + return JSON.parse(result.data); + } catch (error) { + return result.data; + } + } + if (result.dataType == 1) { + return result.data; + } + if (result.dataType == 2) { + return result.data.split(','); + } + } + return; + } + + /** + * 根据key获得对应的网页数据 + * @param key + */ + async htmlByKey(key) { + let html = '@title@content'; + let result: any = await this.midwayCache.get(`param:${key}`); + if (result) { + html = html + .replace('@content', result.data) + .replace('@title', result.name); + } else { + html = html.replace('@content', 'key notfound'); + } + return html; + } + + /** + * 添加或者修改 + * @param param + */ + async addOrUpdate(param: any, type): Promise { + const find = { + keyName: param.keyName, + }; + if (param.id) { + find['id'] = Not(param.id); + } + const check = await this.baseSysParamEntity.findOneBy(find); + if (check) { + throw new CoolCommException('存在相同的keyName'); + } + await super.addOrUpdate(param, type); + } + + /** + * 重新初始化缓存 + */ + async modifyAfter() { + const params = await this.baseSysParamEntity.find(); + for (const param of params) { + await this.midwayCache.set(`param:${param.keyName}`, param); + } + } +} diff --git a/src/modules/base/service/sys/perms.ts b/src/modules/base/service/sys/perms.ts new file mode 100644 index 0000000..ca4b029 --- /dev/null +++ b/src/modules/base/service/sys/perms.ts @@ -0,0 +1,90 @@ +import { Inject, InjectClient, Provide } from '@midwayjs/core'; +import { BaseService } from '@cool-midway/core'; +import { BaseSysMenuService } from './menu'; +import { BaseSysRoleService } from './role'; +import { BaseSysDepartmentService } from './department'; +import { Context } from '@midwayjs/koa'; +import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager'; +import { BaseSysRoleEntity } from '../../entity/sys/role'; +import { In, Repository } from 'typeorm'; +import { InjectEntityModel } from '@midwayjs/typeorm'; + +/** + * 权限 + */ +@Provide() +export class BaseSysPermsService extends BaseService { + @InjectClient(CachingFactory, 'default') + midwayCache: MidwayCache; + + @Inject() + baseSysMenuService: BaseSysMenuService; + + @Inject() + baseSysRoleService: BaseSysRoleService; + + @Inject() + baseSysDepartmentService: BaseSysDepartmentService; + + @InjectEntityModel(BaseSysRoleEntity) + baseSysRoleEntity: Repository; + + @Inject() + ctx: Context; + base: any; + + /** + * 刷新权限 + * @param userId 用户ID + */ + async refreshPerms(userId) { + const roleIds = await this.baseSysRoleService.getByUser(userId); + const perms = await this.baseSysMenuService.getPerms(roleIds); + await this.midwayCache.set(`admin:perms:${userId}`, perms); + // 更新部门权限 + const departments = await this.baseSysDepartmentService.getByRoleIds( + roleIds, + await this.isAdmin(roleIds) + ); + await this.midwayCache.set(`admin:department:${userId}`, departments); + } + + /** + * 根据角色判断是不是超管 + * @param roleIds + */ + async isAdmin(roleIds: number[]) { + const roles = await this.baseSysRoleEntity.findBy({ id: In(roleIds) }); + const roleLabels = roles.map(item => item.label); + return roleLabels.includes('admin'); + } + + /** + * 获得权限菜单 + * @param roleIds + */ + async permmenu(roleIds: number[]) { + const perms = await this.baseSysMenuService.getPerms(roleIds); + const menus = await this.baseSysMenuService.getMenus( + roleIds, + this.ctx.admin.username === 'admin' + ); + return { perms, menus }; + } + + /** + * 根据用户ID获得部门权限 + * @param userId + * @return 部门ID数组 + */ + async departmentIds(userId: number) { + const department: any = await this.midwayCache.get( + `admin:department:${userId}` + ); + if (department) { + return department; + } else { + return []; + } + } +} diff --git a/src/modules/base/service/sys/role.ts b/src/modules/base/service/sys/role.ts new file mode 100644 index 0000000..932ebc9 --- /dev/null +++ b/src/modules/base/service/sys/role.ts @@ -0,0 +1,136 @@ +import { Inject, Provide } from '@midwayjs/core'; +import { BaseService } from '@cool-midway/core'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { Repository } from 'typeorm'; +import { BaseSysRoleEntity } from '../../entity/sys/role'; +import { BaseSysUserRoleEntity } from '../../entity/sys/user_role'; +import * as _ from 'lodash'; +import { BaseSysRoleMenuEntity } from '../../entity/sys/role_menu'; +import { BaseSysRoleDepartmentEntity } from '../../entity/sys/role_department'; +import { BaseSysPermsService } from './perms'; +import { Brackets } from 'typeorm'; + +/** + * 角色 + */ +@Provide() +export class BaseSysRoleService extends BaseService { + @InjectEntityModel(BaseSysRoleEntity) + baseSysRoleEntity: Repository; + + @InjectEntityModel(BaseSysUserRoleEntity) + baseSysUserRoleEntity: Repository; + + @InjectEntityModel(BaseSysRoleMenuEntity) + baseSysRoleMenuEntity: Repository; + + @InjectEntityModel(BaseSysRoleDepartmentEntity) + baseSysRoleDepartmentEntity: Repository; + + @Inject() + baseSysPermsService: BaseSysPermsService; + + @Inject() + ctx; + + /** + * 根据用户ID获得所有用户角色 + * @param userId + */ + async getByUser(userId: number): Promise { + const userRole = await this.baseSysUserRoleEntity.findBy({ userId }); + if (!_.isEmpty(userRole)) { + return userRole.map(e => { + return e.roleId; + }); + } + return []; + } + + /** + * + * @param param + */ + async modifyAfter(param) { + if (param.id) { + this.updatePerms(param.id, param.menuIdList, param.departmentIdList); + } + } + + /** + * 更新权限 + * @param roleId + * @param menuIdList + * @param departmentIds + */ + async updatePerms(roleId, menuIdList?, departmentIds = []) { + // 更新菜单权限 + await this.baseSysRoleMenuEntity.delete({ roleId }); + await Promise.all( + menuIdList.map(async e => { + return await this.baseSysRoleMenuEntity.save({ roleId, menuId: e }); + }) + ); + // 更新部门权限 + await this.baseSysRoleDepartmentEntity.delete({ roleId }); + await Promise.all( + departmentIds.map(async e => { + return await this.baseSysRoleDepartmentEntity.save({ + roleId, + departmentId: e, + }); + }) + ); + // 刷新权限 + const userRoles = await this.baseSysUserRoleEntity.findBy({ roleId }); + for (const userRole of userRoles) { + await this.baseSysPermsService.refreshPerms(userRole.userId); + } + } + + /** + * 角色信息 + * @param id + */ + async info(id) { + const info = await this.baseSysRoleEntity.findOneBy({ id }); + if (info) { + const menus = await this.baseSysRoleMenuEntity.findBy( + id !== 1 ? { roleId: id } : {} + ); + const menuIdList = menus.map(e => { + return parseInt(e.menuId + ''); + }); + const departments = await this.baseSysRoleDepartmentEntity.findBy( + id !== 1 ? { roleId: id } : {} + ); + const departmentIdList = departments.map(e => { + return parseInt(e.departmentId + ''); + }); + return { + ...info, + menuIdList, + departmentIdList, + }; + } + return {}; + } + + async list() { + return this.baseSysRoleEntity + .createQueryBuilder('a') + .where( + new Brackets(qb => { + qb.where('a.id !=:id', { id: 1 }); // 超级管理员的角色不展示 + // 如果不是超管,只能看到自己新建的或者自己有的角色 + if (this.ctx.admin.username !== 'admin') { + qb.andWhere('(a.userId=:userId or a.id in (:...roleId))', { + userId: this.ctx.admin.userId, + roleId: this.ctx.admin.roleIds, + }); + } + }) + ) + .getMany(); + } +} diff --git a/src/modules/base/service/sys/user.ts b/src/modules/base/service/sys/user.ts new file mode 100644 index 0000000..28e5809 --- /dev/null +++ b/src/modules/base/service/sys/user.ts @@ -0,0 +1,235 @@ +import { Inject, InjectClient, Provide } from '@midwayjs/core'; +import { BaseService, CoolCommException } from '@cool-midway/core'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { Equal, In, Repository } from 'typeorm'; +import { BaseSysUserEntity } from '../../entity/sys/user'; +import { BaseSysPermsService } from './perms'; +import * as _ from 'lodash'; +import { BaseSysUserRoleEntity } from '../../entity/sys/user_role'; +import * as md5 from 'md5'; +import { BaseSysDepartmentEntity } from '../../entity/sys/department'; +import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager'; + +/** + * 系统用户 + */ +@Provide() +export class BaseSysUserService extends BaseService { + @InjectEntityModel(BaseSysUserEntity) + baseSysUserEntity: Repository; + + @InjectEntityModel(BaseSysUserRoleEntity) + baseSysUserRoleEntity: Repository; + + @InjectEntityModel(BaseSysDepartmentEntity) + baseSysDepartmentEntity: Repository; + + @InjectClient(CachingFactory, 'default') + midwayCache: MidwayCache; + + @Inject() + baseSysPermsService: BaseSysPermsService; + + @Inject() + ctx; + + /** + * 分页查询 + * @param query + */ + async page(query) { + const { keyWord, status, departmentIds = [] } = query; + const permsDepartmentArr = await this.baseSysPermsService.departmentIds( + this.ctx.admin.userId + ); // 部门权限 + const sql = ` + SELECT + a.id,a.name,a.nickName,a.headImg,a.email,a.remark,a.status,a.createTime,a.updateTime,a.username,a.phone,a.departmentId, + b.name as "departmentName" + FROM + base_sys_user a + LEFT JOIN base_sys_department b on a.departmentId = b.id + WHERE 1 = 1 + ${this.setSql( + !_.isEmpty(departmentIds), + 'and a.departmentId in (?)', + [departmentIds] + )} + ${this.setSql(status, 'and a.status = ?', [status])} + ${this.setSql(keyWord, 'and (a.name LIKE ? or a.username LIKE ?)', [ + `%${keyWord}%`, + `%${keyWord}%`, + ])} + ${this.setSql(true, 'and a.username != ?', ['admin'])} + ${this.setSql( + this.ctx.admin.username !== 'admin', + 'and a.departmentId in (?)', + [!_.isEmpty(permsDepartmentArr) ? permsDepartmentArr : [null]] + )} `; + const result = await this.sqlRenderPage(sql, query); + // 匹配角色 + if (!_.isEmpty(result.list)) { + const userIds = result.list.map(e => e.id); + const roles = await this.nativeQuery( + 'SELECT b.name, a.userId FROM base_sys_user_role a LEFT JOIN base_sys_role b ON a.roleId = b.id WHERE a.userId in (?) ', + [userIds] + ); + result.list.forEach(e => { + e['roleName'] = roles + .filter(role => role.userId == e.id) + .map(role => role.name) + .join(','); + }); + } + return result; + } + + /** + * 移动部门 + * @param departmentId + * @param userIds + */ + async move(departmentId, userIds) { + await this.baseSysUserEntity.update({ id: In(userIds) }, { departmentId }); + } + + /** + * 获得个人信息 + */ + async person(userId) { + const info = await this.baseSysUserEntity.findOneBy({ + id: Equal(userId), + }); + delete info?.password; + return info; + } + + /** + * 更新用户角色关系 + * @param user + */ + async updateUserRole(user) { + if (_.isEmpty(user.roleIdList)) { + return; + } + if (user.username === 'admin') { + throw new CoolCommException('非法操作~'); + } + await this.baseSysUserRoleEntity.delete({ userId: user.id }); + if (user.roleIdList) { + for (const roleId of user.roleIdList) { + await this.baseSysUserRoleEntity.save({ userId: user.id, roleId }); + } + } + await this.baseSysPermsService.refreshPerms(user.id); + } + + /** + * 新增 + * @param param + */ + async add(param) { + const exists = await this.baseSysUserEntity.findOneBy({ + username: param.username, + }); + if (!_.isEmpty(exists)) { + throw new CoolCommException('用户名已经存在~'); + } + param.password = md5(param.password); + await this.baseSysUserEntity.save(param); + await this.updateUserRole(param); + return param.id; + } + + /** + * 根据ID获得信息 + * @param id + */ + public async info(id) { + const info = await this.baseSysUserEntity.findOneBy({ id }); + const userRoles = await this.nativeQuery( + 'select a.roleId from base_sys_user_role a where a.userId = ?', + [id] + ); + const department = await this.baseSysDepartmentEntity.findOneBy({ + id: info.departmentId, + }); + if (info) { + delete info.password; + if (userRoles) { + info.roleIdList = userRoles.map(e => { + return parseInt(e.roleId); + }); + } + } + delete info.password; + if (department) { + info.departmentName = department.name; + } + return info; + } + + /** + * 修改个人信息 + * @param param + */ + public async personUpdate(param) { + param.id = this.ctx.admin.userId; + if (!_.isEmpty(param.password)) { + param.password = md5(param.password); + const oldPassword = md5(param.oldPassword); + const userInfo = await this.baseSysUserEntity.findOneBy({ id: param.id }); + if (!userInfo) { + throw new CoolCommException('用户不存在'); + } + if (oldPassword !== userInfo.password) { + throw new CoolCommException('原密码错误'); + } + param.passwordV = userInfo.passwordV + 1; + await this.midwayCache.set( + `admin:passwordVersion:${param.id}`, + param.passwordV + ); + } else { + delete param.password; + } + await this.baseSysUserEntity.save(param); + } + + /** + * 修改 + * @param param 数据 + */ + async update(param) { + if (param.id && param.username === 'admin') { + throw new CoolCommException('非法操作~'); + } + if (!_.isEmpty(param.password)) { + param.password = md5(param.password); + const userInfo = await this.baseSysUserEntity.findOneBy({ id: param.id }); + if (!userInfo) { + throw new CoolCommException('用户不存在'); + } + param.passwordV = userInfo.passwordV + 1; + await this.midwayCache.set( + `admin:passwordVersion:${param.id}`, + param.passwordV + ); + } else { + delete param.password; + } + if (param.status === 0) { + await this.forbidden(param.id); + } + await this.baseSysUserEntity.save(param); + await this.updateUserRole(param); + } + + /** + * 禁用用户 + * @param userId + */ + async forbidden(userId) { + await this.midwayCache.del(`admin:token:${userId}`); + } +} diff --git a/tsconfig.json b/tsconfig.json index 8f2598d..9e88494 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,23 +6,25 @@ "moduleResolution": "node", "experimentalDecorators": true, "emitDecoratorMetadata": true, - "inlineSourceMap":true, + "inlineSourceMap": true, "noImplicitThis": true, - "noUnusedLocals": true, + "noUnusedLocals": false, "stripInternal": true, "skipLibCheck": true, + "resolveJsonModule": true, "pretty": true, - "declaration": true, - "forceConsistentCasingInFileNames": true, - "typeRoots": [ "./typings", "./node_modules/@types"], + "declaration": false, + "noImplicitAny": false, + "typeRoots": [ + "typings", + "./node_modules/@types" + ], "outDir": "dist", "rootDir": "src" }, "exclude": [ - "*.js", - "*.ts", "dist", "node_modules", "test" ] -} +} \ No newline at end of file