wyling007 2 anni fa
commit
6a212b5527

+ 17 - 0
.eslintrc.js

@@ -0,0 +1,17 @@
+module.exports = {
+	env: {
+		es2021: true,
+		node: true,
+	},
+	extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
+	parser: '@typescript-eslint/parser',
+	parserOptions: {
+		ecmaVersion: 'latest',
+		sourceType: 'module',
+	},
+	plugins: ['@typescript-eslint'],
+	rules: {
+		'no-console': 0,
+		'@typescript-eslint/no-namespace': 0,
+	},
+};

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+node_modules/
+bin/
+dist/

+ 3050 - 0
package-lock.json

@@ -0,0 +1,3050 @@
+{
+	"name": "wyling-nest-demo",
+	"version": "1.0.0",
+	"lockfileVersion": 2,
+	"requires": true,
+	"packages": {
+		"": {
+			"name": "wyling-nest-demo",
+			"version": "1.0.0",
+			"license": "ISC",
+			"dependencies": {
+				"@nestjs/common": "^8.4.5",
+				"@nestjs/core": "^8.4.5",
+				"@nestjs/platform-express": "^8.4.5",
+				"reflect-metadata": "^0.1.13",
+				"rxjs": "^7.5.5"
+			},
+			"devDependencies": {
+				"@typescript-eslint/eslint-plugin": "^5.26.0",
+				"@typescript-eslint/parser": "^5.26.0",
+				"eslint": "^8.16.0",
+				"nodemon": "^2.0.16",
+				"typescript": "^4.6.4"
+			}
+		},
+		"../../node_modules/.pnpm/@[email protected]_e7ea248743279784063e3708d703abc5/node_modules/@nestjs/common": {
+			"version": "8.4.5",
+			"license": "MIT",
+			"dependencies": {
+				"axios": "0.27.2",
+				"iterare": "1.2.1",
+				"tslib": "2.4.0",
+				"uuid": "8.3.2"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/nest"
+			},
+			"peerDependencies": {
+				"cache-manager": "*",
+				"class-transformer": "*",
+				"class-validator": "*",
+				"reflect-metadata": "^0.1.12",
+				"rxjs": "^7.1.0"
+			},
+			"peerDependenciesMeta": {
+				"cache-manager": {
+					"optional": true
+				},
+				"class-transformer": {
+					"optional": true
+				},
+				"class-validator": {
+					"optional": true
+				}
+			}
+		},
+		"../../node_modules/.pnpm/@[email protected]_9530c9e4e8c33b27551732908d05d2fb/node_modules/@nestjs/core": {
+			"version": "8.4.5",
+			"hasInstallScript": true,
+			"license": "MIT",
+			"dependencies": {
+				"@nuxtjs/opencollective": "0.3.2",
+				"fast-safe-stringify": "2.1.1",
+				"iterare": "1.2.1",
+				"object-hash": "3.0.0",
+				"path-to-regexp": "3.2.0",
+				"tslib": "2.4.0",
+				"uuid": "8.3.2"
+			},
+			"devDependencies": {
+				"@nestjs/common": "8.4.5"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/nest"
+			},
+			"peerDependencies": {
+				"@nestjs/common": "^8.0.0",
+				"@nestjs/microservices": "^8.0.0",
+				"@nestjs/platform-express": "^8.0.0",
+				"@nestjs/websockets": "^8.0.0",
+				"reflect-metadata": "^0.1.12",
+				"rxjs": "^7.1.0"
+			},
+			"peerDependenciesMeta": {
+				"@nestjs/microservices": {
+					"optional": true
+				},
+				"@nestjs/platform-express": {
+					"optional": true
+				},
+				"@nestjs/websockets": {
+					"optional": true
+				}
+			}
+		},
+		"../../node_modules/.pnpm/@[email protected]_c0c9651cd01c4e2d3bda397a5c438062/node_modules/@nestjs/platform-express": {
+			"version": "8.4.5",
+			"license": "MIT",
+			"dependencies": {
+				"body-parser": "1.20.0",
+				"cors": "2.8.5",
+				"express": "4.18.1",
+				"multer": "1.4.4",
+				"tslib": "2.4.0"
+			},
+			"devDependencies": {
+				"@nestjs/common": "8.4.5",
+				"@nestjs/core": "8.4.5"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/nest"
+			},
+			"peerDependencies": {
+				"@nestjs/common": "^8.0.0",
+				"@nestjs/core": "^8.0.0"
+			}
+		},
+		"../../node_modules/.pnpm/[email protected]/node_modules/nodemon": {
+			"version": "2.0.16",
+			"dev": true,
+			"hasInstallScript": true,
+			"license": "MIT",
+			"dependencies": {
+				"chokidar": "^3.5.2",
+				"debug": "^3.2.7",
+				"ignore-by-default": "^1.0.1",
+				"minimatch": "^3.0.4",
+				"pstree.remy": "^1.1.8",
+				"semver": "^5.7.1",
+				"supports-color": "^5.5.0",
+				"touch": "^3.1.0",
+				"undefsafe": "^2.0.5",
+				"update-notifier": "^5.1.0"
+			},
+			"bin": {
+				"nodemon": "bin/nodemon.js"
+			},
+			"devDependencies": {
+				"@commitlint/cli": "^11.0.0",
+				"@commitlint/config-conventional": "^11.0.0",
+				"async": "1.4.2",
+				"coffee-script": "~1.7.1",
+				"eslint": "^7.32.0",
+				"husky": "^7.0.4",
+				"mocha": "^2.5.3",
+				"nyc": "^15.1.0",
+				"proxyquire": "^1.8.0",
+				"semantic-release": "^18.0.0",
+				"should": "~4.0.0"
+			},
+			"engines": {
+				"node": ">=8.10.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/nodemon"
+			}
+		},
+		"../../node_modules/.pnpm/[email protected]/node_modules/reflect-metadata": {
+			"version": "0.1.13",
+			"license": "Apache-2.0",
+			"devDependencies": {
+				"@types/chai": "^3.4.34",
+				"@types/mocha": "^2.2.34",
+				"@types/node": "^6.0.52",
+				"chai": "^3.5.0",
+				"del": "^2.2.2",
+				"ecmarkup": "^3.9.3",
+				"gulp": "^3.9.1",
+				"gulp-emu": "^1.1.0",
+				"gulp-live-server": "0.0.30",
+				"gulp-mocha": "^3.0.1",
+				"gulp-rename": "^1.2.2",
+				"gulp-sequence": "^0.4.6",
+				"gulp-tsb": "^2.0.3",
+				"mocha": "^3.2.0",
+				"typescript": "^2.1.4"
+			}
+		},
+		"../../node_modules/.pnpm/[email protected]/node_modules/rxjs": {
+			"version": "7.5.5",
+			"license": "Apache-2.0",
+			"dependencies": {
+				"tslib": "^2.1.0"
+			},
+			"devDependencies": {
+				"@angular-devkit/build-optimizer": "0.4.6",
+				"@angular-devkit/schematics": "^11.0.7",
+				"@swc/core": "^1.2.128",
+				"@swc/helpers": "^0.3.2",
+				"@types/chai": "^4.2.11",
+				"@types/lodash": "4.14.102",
+				"@types/mocha": "^7.0.2",
+				"@types/node": "^14.14.6",
+				"@types/shelljs": "^0.8.8",
+				"@types/sinon": "4.1.3",
+				"@types/sinon-chai": "2.7.29",
+				"@types/source-map": "^0.5.2",
+				"@typescript-eslint/eslint-plugin": "^4.29.1",
+				"@typescript-eslint/parser": "^4.29.1",
+				"babel-polyfill": "6.26.0",
+				"chai": "^4.2.0",
+				"check-side-effects": "0.0.23",
+				"color": "3.0.0",
+				"colors": "1.1.2",
+				"cross-env": "5.1.3",
+				"cz-conventional-changelog": "1.2.0",
+				"dependency-cruiser": "^9.12.0",
+				"escape-string-regexp": "1.0.5",
+				"eslint": "^7.8.1",
+				"eslint-plugin-jasmine": "^2.10.1",
+				"form-data": "^3.0.0",
+				"fs-extra": "^8.1.0",
+				"glob": "7.1.2",
+				"google-closure-compiler-js": "20170218.0.0",
+				"husky": "^4.2.5",
+				"klaw-sync": "3.0.2",
+				"lint-staged": "^10.2.11",
+				"lodash": "^4.17.15",
+				"minimist": "^1.2.5",
+				"mocha": "^8.1.3",
+				"nodemon": "^1.9.2",
+				"npm-run-all": "4.1.2",
+				"opn-cli": "3.1.0",
+				"platform": "1.3.5",
+				"prettier": "^2.5.1",
+				"promise": "8.0.1",
+				"rollup": "0.66.6",
+				"rollup-plugin-alias": "1.4.0",
+				"rollup-plugin-inject": "2.0.0",
+				"rollup-plugin-node-resolve": "2.0.0",
+				"shelljs": "^0.8.4",
+				"shx": "^0.3.2",
+				"sinon": "4.3.0",
+				"sinon-chai": "2.14.0",
+				"source-map-support": "0.5.3",
+				"systemjs": "^0.21.0",
+				"ts-api-guardian": "^0.5.0",
+				"ts-node": "^9.1.1",
+				"tslint": "^5.20.1",
+				"tslint-config-prettier": "^1.18.0",
+				"tslint-etc": "1.13.10",
+				"tslint-no-toplevel-property-access": "0.0.2",
+				"tslint-no-unused-expression-chai": "0.0.3",
+				"typescript": "~4.2.0",
+				"validate-commit-msg": "2.14.0",
+				"web-streams-polyfill": "^3.0.2",
+				"webpack": "^4.31.0"
+			}
+		},
+		"../../node_modules/.pnpm/[email protected]/node_modules/typescript": {
+			"version": "4.6.4",
+			"dev": true,
+			"license": "Apache-2.0",
+			"bin": {
+				"tsc": "bin/tsc",
+				"tsserver": "bin/tsserver"
+			},
+			"devDependencies": {
+				"@octokit/rest": "latest",
+				"@types/browserify": "latest",
+				"@types/chai": "latest",
+				"@types/convert-source-map": "latest",
+				"@types/glob": "latest",
+				"@types/gulp": "^4.0.9",
+				"@types/gulp-concat": "latest",
+				"@types/gulp-newer": "latest",
+				"@types/gulp-rename": "0.0.33",
+				"@types/gulp-sourcemaps": "0.0.32",
+				"@types/jake": "latest",
+				"@types/merge2": "latest",
+				"@types/microsoft__typescript-etw": "latest",
+				"@types/minimatch": "latest",
+				"@types/minimist": "latest",
+				"@types/mkdirp": "latest",
+				"@types/mocha": "latest",
+				"@types/ms": "latest",
+				"@types/node": "latest",
+				"@types/node-fetch": "^2.3.4",
+				"@types/q": "latest",
+				"@types/source-map-support": "latest",
+				"@types/through2": "latest",
+				"@types/xml2js": "^0.4.0",
+				"@typescript-eslint/eslint-plugin": "^4.28.0",
+				"@typescript-eslint/experimental-utils": "^4.28.0",
+				"@typescript-eslint/parser": "^4.28.0",
+				"async": "latest",
+				"azure-devops-node-api": "^11.0.1",
+				"browser-resolve": "^1.11.2",
+				"browserify": "latest",
+				"chai": "latest",
+				"chalk": "^4.1.2",
+				"convert-source-map": "latest",
+				"del": "5.1.0",
+				"diff": "^4.0.2",
+				"eslint": "7.12.1",
+				"eslint-formatter-autolinkable-stylish": "1.1.4",
+				"eslint-plugin-import": "2.22.1",
+				"eslint-plugin-jsdoc": "30.7.6",
+				"eslint-plugin-no-null": "1.0.2",
+				"fancy-log": "latest",
+				"fs-extra": "^9.0.0",
+				"glob": "latest",
+				"gulp": "^4.0.0",
+				"gulp-concat": "latest",
+				"gulp-insert": "latest",
+				"gulp-newer": "latest",
+				"gulp-rename": "latest",
+				"gulp-sourcemaps": "latest",
+				"merge2": "latest",
+				"minimist": "latest",
+				"mkdirp": "latest",
+				"mocha": "latest",
+				"mocha-fivemat-progress-reporter": "latest",
+				"ms": "^2.1.3",
+				"node-fetch": "^2.6.1",
+				"plugin-error": "latest",
+				"pretty-hrtime": "^1.0.3",
+				"prex": "^0.4.3",
+				"q": "latest",
+				"source-map-support": "latest",
+				"through2": "latest",
+				"typescript": "^4.5.5",
+				"vinyl": "latest",
+				"vinyl-sourcemaps-apply": "latest",
+				"xml2js": "^0.4.19"
+			},
+			"engines": {
+				"node": ">=4.2.0"
+			}
+		},
+		"node_modules/@eslint/eslintrc": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
+			"integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==",
+			"dev": true,
+			"dependencies": {
+				"ajv": "^6.12.4",
+				"debug": "^4.3.2",
+				"espree": "^9.3.2",
+				"globals": "^13.15.0",
+				"ignore": "^5.2.0",
+				"import-fresh": "^3.2.1",
+				"js-yaml": "^4.1.0",
+				"minimatch": "^3.1.2",
+				"strip-json-comments": "^3.1.1"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			}
+		},
+		"node_modules/@humanwhocodes/config-array": {
+			"version": "0.9.5",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
+			"integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+			"dev": true,
+			"dependencies": {
+				"@humanwhocodes/object-schema": "^1.2.1",
+				"debug": "^4.1.1",
+				"minimatch": "^3.0.4"
+			},
+			"engines": {
+				"node": ">=10.10.0"
+			}
+		},
+		"node_modules/@humanwhocodes/object-schema": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+			"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+			"dev": true
+		},
+		"node_modules/@nestjs/common": {
+			"resolved": "../../node_modules/.pnpm/@[email protected]_e7ea248743279784063e3708d703abc5/node_modules/@nestjs/common",
+			"link": true
+		},
+		"node_modules/@nestjs/core": {
+			"resolved": "../../node_modules/.pnpm/@[email protected]_9530c9e4e8c33b27551732908d05d2fb/node_modules/@nestjs/core",
+			"link": true
+		},
+		"node_modules/@nestjs/platform-express": {
+			"resolved": "../../node_modules/.pnpm/@[email protected]_c0c9651cd01c4e2d3bda397a5c438062/node_modules/@nestjs/platform-express",
+			"link": true
+		},
+		"node_modules/@nodelib/fs.scandir": {
+			"version": "2.1.5",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+			"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+			"dev": true,
+			"dependencies": {
+				"@nodelib/fs.stat": "2.0.5",
+				"run-parallel": "^1.1.9"
+			},
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/@nodelib/fs.stat": {
+			"version": "2.0.5",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+			"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+			"dev": true,
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/@nodelib/fs.walk": {
+			"version": "1.2.8",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+			"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+			"dev": true,
+			"dependencies": {
+				"@nodelib/fs.scandir": "2.1.5",
+				"fastq": "^1.6.0"
+			},
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/@types/json-schema": {
+			"version": "7.0.11",
+			"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+			"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+			"dev": true
+		},
+		"node_modules/@typescript-eslint/eslint-plugin": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.26.0.tgz",
+			"integrity": "sha512-oGCmo0PqnRZZndr+KwvvAUvD3kNE4AfyoGCwOZpoCncSh4MVD06JTE8XQa2u9u+NX5CsyZMBTEc2C72zx38eYA==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/scope-manager": "5.26.0",
+				"@typescript-eslint/type-utils": "5.26.0",
+				"@typescript-eslint/utils": "5.26.0",
+				"debug": "^4.3.4",
+				"functional-red-black-tree": "^1.0.1",
+				"ignore": "^5.2.0",
+				"regexpp": "^3.2.0",
+				"semver": "^7.3.7",
+				"tsutils": "^3.21.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"@typescript-eslint/parser": "^5.0.0",
+				"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+			},
+			"peerDependenciesMeta": {
+				"typescript": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/@typescript-eslint/parser": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.26.0.tgz",
+			"integrity": "sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/scope-manager": "5.26.0",
+				"@typescript-eslint/types": "5.26.0",
+				"@typescript-eslint/typescript-estree": "5.26.0",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+			},
+			"peerDependenciesMeta": {
+				"typescript": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/@typescript-eslint/scope-manager": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.26.0.tgz",
+			"integrity": "sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.26.0",
+				"@typescript-eslint/visitor-keys": "5.26.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/type-utils": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.26.0.tgz",
+			"integrity": "sha512-7ccbUVWGLmcRDSA1+ADkDBl5fP87EJt0fnijsMFTVHXKGduYMgienC/i3QwoVhDADUAPoytgjbZbCOMj4TY55A==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/utils": "5.26.0",
+				"debug": "^4.3.4",
+				"tsutils": "^3.21.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "*"
+			},
+			"peerDependenciesMeta": {
+				"typescript": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/@typescript-eslint/types": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.26.0.tgz",
+			"integrity": "sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==",
+			"dev": true,
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/typescript-estree": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.26.0.tgz",
+			"integrity": "sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.26.0",
+				"@typescript-eslint/visitor-keys": "5.26.0",
+				"debug": "^4.3.4",
+				"globby": "^11.1.0",
+				"is-glob": "^4.0.3",
+				"semver": "^7.3.7",
+				"tsutils": "^3.21.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependenciesMeta": {
+				"typescript": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/@typescript-eslint/utils": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.26.0.tgz",
+			"integrity": "sha512-PJFwcTq2Pt4AMOKfe3zQOdez6InIDOjUJJD3v3LyEtxHGVVRK3Vo7Dd923t/4M9hSH2q2CLvcTdxlLPjcIk3eg==",
+			"dev": true,
+			"dependencies": {
+				"@types/json-schema": "^7.0.9",
+				"@typescript-eslint/scope-manager": "5.26.0",
+				"@typescript-eslint/types": "5.26.0",
+				"@typescript-eslint/typescript-estree": "5.26.0",
+				"eslint-scope": "^5.1.1",
+				"eslint-utils": "^3.0.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+			}
+		},
+		"node_modules/@typescript-eslint/visitor-keys": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz",
+			"integrity": "sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.26.0",
+				"eslint-visitor-keys": "^3.3.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/acorn": {
+			"version": "8.7.1",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
+			"integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+			"dev": true,
+			"bin": {
+				"acorn": "bin/acorn"
+			},
+			"engines": {
+				"node": ">=0.4.0"
+			}
+		},
+		"node_modules/acorn-jsx": {
+			"version": "5.3.2",
+			"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+			"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+			"dev": true,
+			"peerDependencies": {
+				"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+			}
+		},
+		"node_modules/ajv": {
+			"version": "6.12.6",
+			"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+			"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+			"dev": true,
+			"dependencies": {
+				"fast-deep-equal": "^3.1.1",
+				"fast-json-stable-stringify": "^2.0.0",
+				"json-schema-traverse": "^0.4.1",
+				"uri-js": "^4.2.2"
+			},
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/epoberezkin"
+			}
+		},
+		"node_modules/ansi-regex": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/ansi-styles": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+			"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+			"dev": true,
+			"dependencies": {
+				"color-convert": "^2.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
+		},
+		"node_modules/argparse": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+			"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+			"dev": true
+		},
+		"node_modules/array-union": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+			"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/balanced-match": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+			"dev": true
+		},
+		"node_modules/brace-expansion": {
+			"version": "1.1.11",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+			"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+			"dev": true,
+			"dependencies": {
+				"balanced-match": "^1.0.0",
+				"concat-map": "0.0.1"
+			}
+		},
+		"node_modules/braces": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+			"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+			"dev": true,
+			"dependencies": {
+				"fill-range": "^7.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/callsites": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+			"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/chalk": {
+			"version": "4.1.2",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+			"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+			"dev": true,
+			"dependencies": {
+				"ansi-styles": "^4.1.0",
+				"supports-color": "^7.1.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/chalk?sponsor=1"
+			}
+		},
+		"node_modules/color-convert": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+			"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+			"dev": true,
+			"dependencies": {
+				"color-name": "~1.1.4"
+			},
+			"engines": {
+				"node": ">=7.0.0"
+			}
+		},
+		"node_modules/color-name": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+			"dev": true
+		},
+		"node_modules/concat-map": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+			"dev": true
+		},
+		"node_modules/cross-spawn": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+			"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+			"dev": true,
+			"dependencies": {
+				"path-key": "^3.1.0",
+				"shebang-command": "^2.0.0",
+				"which": "^2.0.1"
+			},
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/debug": {
+			"version": "4.3.4",
+			"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+			"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+			"dev": true,
+			"dependencies": {
+				"ms": "2.1.2"
+			},
+			"engines": {
+				"node": ">=6.0"
+			},
+			"peerDependenciesMeta": {
+				"supports-color": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/deep-is": {
+			"version": "0.1.4",
+			"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+			"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+			"dev": true
+		},
+		"node_modules/dir-glob": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+			"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+			"dev": true,
+			"dependencies": {
+				"path-type": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/doctrine": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+			"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+			"dev": true,
+			"dependencies": {
+				"esutils": "^2.0.2"
+			},
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/escape-string-regexp": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+			"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+			"dev": true,
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/eslint": {
+			"version": "8.16.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz",
+			"integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==",
+			"dev": true,
+			"dependencies": {
+				"@eslint/eslintrc": "^1.3.0",
+				"@humanwhocodes/config-array": "^0.9.2",
+				"ajv": "^6.10.0",
+				"chalk": "^4.0.0",
+				"cross-spawn": "^7.0.2",
+				"debug": "^4.3.2",
+				"doctrine": "^3.0.0",
+				"escape-string-regexp": "^4.0.0",
+				"eslint-scope": "^7.1.1",
+				"eslint-utils": "^3.0.0",
+				"eslint-visitor-keys": "^3.3.0",
+				"espree": "^9.3.2",
+				"esquery": "^1.4.0",
+				"esutils": "^2.0.2",
+				"fast-deep-equal": "^3.1.3",
+				"file-entry-cache": "^6.0.1",
+				"functional-red-black-tree": "^1.0.1",
+				"glob-parent": "^6.0.1",
+				"globals": "^13.15.0",
+				"ignore": "^5.2.0",
+				"import-fresh": "^3.0.0",
+				"imurmurhash": "^0.1.4",
+				"is-glob": "^4.0.0",
+				"js-yaml": "^4.1.0",
+				"json-stable-stringify-without-jsonify": "^1.0.1",
+				"levn": "^0.4.1",
+				"lodash.merge": "^4.6.2",
+				"minimatch": "^3.1.2",
+				"natural-compare": "^1.4.0",
+				"optionator": "^0.9.1",
+				"regexpp": "^3.2.0",
+				"strip-ansi": "^6.0.1",
+				"strip-json-comments": "^3.1.0",
+				"text-table": "^0.2.0",
+				"v8-compile-cache": "^2.0.3"
+			},
+			"bin": {
+				"eslint": "bin/eslint.js"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"url": "https://opencollective.com/eslint"
+			}
+		},
+		"node_modules/eslint-scope": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+			"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+			"dev": true,
+			"dependencies": {
+				"esrecurse": "^4.3.0",
+				"estraverse": "^4.1.1"
+			},
+			"engines": {
+				"node": ">=8.0.0"
+			}
+		},
+		"node_modules/eslint-utils": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+			"dev": true,
+			"dependencies": {
+				"eslint-visitor-keys": "^2.0.0"
+			},
+			"engines": {
+				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/mysticatea"
+			},
+			"peerDependencies": {
+				"eslint": ">=5"
+			}
+		},
+		"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+			"dev": true,
+			"engines": {
+				"node": ">=10"
+			}
+		},
+		"node_modules/eslint-visitor-keys": {
+			"version": "3.3.0",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+			"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+			"dev": true,
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			}
+		},
+		"node_modules/eslint/node_modules/eslint-scope": {
+			"version": "7.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
+			"integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+			"dev": true,
+			"dependencies": {
+				"esrecurse": "^4.3.0",
+				"estraverse": "^5.2.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			}
+		},
+		"node_modules/eslint/node_modules/estraverse": {
+			"version": "5.3.0",
+			"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+			"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+			"dev": true,
+			"engines": {
+				"node": ">=4.0"
+			}
+		},
+		"node_modules/espree": {
+			"version": "9.3.2",
+			"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
+			"integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+			"dev": true,
+			"dependencies": {
+				"acorn": "^8.7.1",
+				"acorn-jsx": "^5.3.2",
+				"eslint-visitor-keys": "^3.3.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			}
+		},
+		"node_modules/esquery": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+			"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+			"dev": true,
+			"dependencies": {
+				"estraverse": "^5.1.0"
+			},
+			"engines": {
+				"node": ">=0.10"
+			}
+		},
+		"node_modules/esquery/node_modules/estraverse": {
+			"version": "5.3.0",
+			"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+			"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+			"dev": true,
+			"engines": {
+				"node": ">=4.0"
+			}
+		},
+		"node_modules/esrecurse": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+			"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+			"dev": true,
+			"dependencies": {
+				"estraverse": "^5.2.0"
+			},
+			"engines": {
+				"node": ">=4.0"
+			}
+		},
+		"node_modules/esrecurse/node_modules/estraverse": {
+			"version": "5.3.0",
+			"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+			"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+			"dev": true,
+			"engines": {
+				"node": ">=4.0"
+			}
+		},
+		"node_modules/estraverse": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+			"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+			"dev": true,
+			"engines": {
+				"node": ">=4.0"
+			}
+		},
+		"node_modules/esutils": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+			"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+			"dev": true,
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/fast-deep-equal": {
+			"version": "3.1.3",
+			"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+			"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+			"dev": true
+		},
+		"node_modules/fast-glob": {
+			"version": "3.2.11",
+			"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
+			"integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+			"dev": true,
+			"dependencies": {
+				"@nodelib/fs.stat": "^2.0.2",
+				"@nodelib/fs.walk": "^1.2.3",
+				"glob-parent": "^5.1.2",
+				"merge2": "^1.3.0",
+				"micromatch": "^4.0.4"
+			},
+			"engines": {
+				"node": ">=8.6.0"
+			}
+		},
+		"node_modules/fast-glob/node_modules/glob-parent": {
+			"version": "5.1.2",
+			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+			"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+			"dev": true,
+			"dependencies": {
+				"is-glob": "^4.0.1"
+			},
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"node_modules/fast-json-stable-stringify": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+			"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+			"dev": true
+		},
+		"node_modules/fast-levenshtein": {
+			"version": "2.0.6",
+			"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+			"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+			"dev": true
+		},
+		"node_modules/fastq": {
+			"version": "1.13.0",
+			"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+			"integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+			"dev": true,
+			"dependencies": {
+				"reusify": "^1.0.4"
+			}
+		},
+		"node_modules/file-entry-cache": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+			"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+			"dev": true,
+			"dependencies": {
+				"flat-cache": "^3.0.4"
+			},
+			"engines": {
+				"node": "^10.12.0 || >=12.0.0"
+			}
+		},
+		"node_modules/fill-range": {
+			"version": "7.0.1",
+			"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+			"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+			"dev": true,
+			"dependencies": {
+				"to-regex-range": "^5.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/flat-cache": {
+			"version": "3.0.4",
+			"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+			"integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+			"dev": true,
+			"dependencies": {
+				"flatted": "^3.1.0",
+				"rimraf": "^3.0.2"
+			},
+			"engines": {
+				"node": "^10.12.0 || >=12.0.0"
+			}
+		},
+		"node_modules/flatted": {
+			"version": "3.2.5",
+			"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
+			"integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
+			"dev": true
+		},
+		"node_modules/fs.realpath": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+			"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+			"dev": true
+		},
+		"node_modules/functional-red-black-tree": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+			"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+			"dev": true
+		},
+		"node_modules/glob": {
+			"version": "7.2.3",
+			"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+			"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+			"dev": true,
+			"dependencies": {
+				"fs.realpath": "^1.0.0",
+				"inflight": "^1.0.4",
+				"inherits": "2",
+				"minimatch": "^3.1.1",
+				"once": "^1.3.0",
+				"path-is-absolute": "^1.0.0"
+			},
+			"engines": {
+				"node": "*"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/isaacs"
+			}
+		},
+		"node_modules/glob-parent": {
+			"version": "6.0.2",
+			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+			"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+			"dev": true,
+			"dependencies": {
+				"is-glob": "^4.0.3"
+			},
+			"engines": {
+				"node": ">=10.13.0"
+			}
+		},
+		"node_modules/globals": {
+			"version": "13.15.0",
+			"resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz",
+			"integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==",
+			"dev": true,
+			"dependencies": {
+				"type-fest": "^0.20.2"
+			},
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/globby": {
+			"version": "11.1.0",
+			"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+			"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+			"dev": true,
+			"dependencies": {
+				"array-union": "^2.1.0",
+				"dir-glob": "^3.0.1",
+				"fast-glob": "^3.2.9",
+				"ignore": "^5.2.0",
+				"merge2": "^1.4.1",
+				"slash": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/has-flag": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+			"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/ignore": {
+			"version": "5.2.0",
+			"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+			"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+			"dev": true,
+			"engines": {
+				"node": ">= 4"
+			}
+		},
+		"node_modules/import-fresh": {
+			"version": "3.3.0",
+			"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+			"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+			"dev": true,
+			"dependencies": {
+				"parent-module": "^1.0.0",
+				"resolve-from": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/imurmurhash": {
+			"version": "0.1.4",
+			"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+			"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+			"dev": true,
+			"engines": {
+				"node": ">=0.8.19"
+			}
+		},
+		"node_modules/inflight": {
+			"version": "1.0.6",
+			"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+			"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+			"dev": true,
+			"dependencies": {
+				"once": "^1.3.0",
+				"wrappy": "1"
+			}
+		},
+		"node_modules/inherits": {
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+			"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+			"dev": true
+		},
+		"node_modules/is-extglob": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+			"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+			"dev": true,
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/is-glob": {
+			"version": "4.0.3",
+			"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+			"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+			"dev": true,
+			"dependencies": {
+				"is-extglob": "^2.1.1"
+			},
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/is-number": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+			"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+			"dev": true,
+			"engines": {
+				"node": ">=0.12.0"
+			}
+		},
+		"node_modules/isexe": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+			"dev": true
+		},
+		"node_modules/js-yaml": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+			"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+			"dev": true,
+			"dependencies": {
+				"argparse": "^2.0.1"
+			},
+			"bin": {
+				"js-yaml": "bin/js-yaml.js"
+			}
+		},
+		"node_modules/json-schema-traverse": {
+			"version": "0.4.1",
+			"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+			"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+			"dev": true
+		},
+		"node_modules/json-stable-stringify-without-jsonify": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+			"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+			"dev": true
+		},
+		"node_modules/levn": {
+			"version": "0.4.1",
+			"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+			"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+			"dev": true,
+			"dependencies": {
+				"prelude-ls": "^1.2.1",
+				"type-check": "~0.4.0"
+			},
+			"engines": {
+				"node": ">= 0.8.0"
+			}
+		},
+		"node_modules/lodash.merge": {
+			"version": "4.6.2",
+			"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+			"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+			"dev": true
+		},
+		"node_modules/lru-cache": {
+			"version": "6.0.0",
+			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+			"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+			"dev": true,
+			"dependencies": {
+				"yallist": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=10"
+			}
+		},
+		"node_modules/merge2": {
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+			"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+			"dev": true,
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/micromatch": {
+			"version": "4.0.5",
+			"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+			"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+			"dev": true,
+			"dependencies": {
+				"braces": "^3.0.2",
+				"picomatch": "^2.3.1"
+			},
+			"engines": {
+				"node": ">=8.6"
+			}
+		},
+		"node_modules/minimatch": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+			"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+			"dev": true,
+			"dependencies": {
+				"brace-expansion": "^1.1.7"
+			},
+			"engines": {
+				"node": "*"
+			}
+		},
+		"node_modules/ms": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+			"dev": true
+		},
+		"node_modules/natural-compare": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+			"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+			"dev": true
+		},
+		"node_modules/nodemon": {
+			"resolved": "../../node_modules/.pnpm/[email protected]/node_modules/nodemon",
+			"link": true
+		},
+		"node_modules/once": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+			"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+			"dev": true,
+			"dependencies": {
+				"wrappy": "1"
+			}
+		},
+		"node_modules/optionator": {
+			"version": "0.9.1",
+			"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+			"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+			"dev": true,
+			"dependencies": {
+				"deep-is": "^0.1.3",
+				"fast-levenshtein": "^2.0.6",
+				"levn": "^0.4.1",
+				"prelude-ls": "^1.2.1",
+				"type-check": "^0.4.0",
+				"word-wrap": "^1.2.3"
+			},
+			"engines": {
+				"node": ">= 0.8.0"
+			}
+		},
+		"node_modules/parent-module": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+			"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+			"dev": true,
+			"dependencies": {
+				"callsites": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/path-is-absolute": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+			"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+			"dev": true,
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/path-key": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+			"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/path-type": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+			"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/picomatch": {
+			"version": "2.3.1",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+			"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+			"dev": true,
+			"engines": {
+				"node": ">=8.6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
+		"node_modules/prelude-ls": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+			"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+			"dev": true,
+			"engines": {
+				"node": ">= 0.8.0"
+			}
+		},
+		"node_modules/punycode": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+			"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+			"dev": true,
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/queue-microtask": {
+			"version": "1.2.3",
+			"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+			"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/feross"
+				},
+				{
+					"type": "patreon",
+					"url": "https://www.patreon.com/feross"
+				},
+				{
+					"type": "consulting",
+					"url": "https://feross.org/support"
+				}
+			]
+		},
+		"node_modules/reflect-metadata": {
+			"resolved": "../../node_modules/.pnpm/[email protected]/node_modules/reflect-metadata",
+			"link": true
+		},
+		"node_modules/regexpp": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+			"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/mysticatea"
+			}
+		},
+		"node_modules/resolve-from": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+			"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+			"dev": true,
+			"engines": {
+				"node": ">=4"
+			}
+		},
+		"node_modules/reusify": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+			"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+			"dev": true,
+			"engines": {
+				"iojs": ">=1.0.0",
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/rimraf": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+			"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+			"dev": true,
+			"dependencies": {
+				"glob": "^7.1.3"
+			},
+			"bin": {
+				"rimraf": "bin.js"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/isaacs"
+			}
+		},
+		"node_modules/run-parallel": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+			"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/feross"
+				},
+				{
+					"type": "patreon",
+					"url": "https://www.patreon.com/feross"
+				},
+				{
+					"type": "consulting",
+					"url": "https://feross.org/support"
+				}
+			],
+			"dependencies": {
+				"queue-microtask": "^1.2.2"
+			}
+		},
+		"node_modules/rxjs": {
+			"resolved": "../../node_modules/.pnpm/[email protected]/node_modules/rxjs",
+			"link": true
+		},
+		"node_modules/semver": {
+			"version": "7.3.7",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+			"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+			"dev": true,
+			"dependencies": {
+				"lru-cache": "^6.0.0"
+			},
+			"bin": {
+				"semver": "bin/semver.js"
+			},
+			"engines": {
+				"node": ">=10"
+			}
+		},
+		"node_modules/shebang-command": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+			"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+			"dev": true,
+			"dependencies": {
+				"shebang-regex": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/shebang-regex": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+			"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/slash": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+			"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/strip-ansi": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+			"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+			"dev": true,
+			"dependencies": {
+				"ansi-regex": "^5.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/strip-json-comments": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+			"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/supports-color": {
+			"version": "7.2.0",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+			"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+			"dev": true,
+			"dependencies": {
+				"has-flag": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/text-table": {
+			"version": "0.2.0",
+			"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+			"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+			"dev": true
+		},
+		"node_modules/to-regex-range": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+			"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+			"dev": true,
+			"dependencies": {
+				"is-number": "^7.0.0"
+			},
+			"engines": {
+				"node": ">=8.0"
+			}
+		},
+		"node_modules/tslib": {
+			"version": "1.14.1",
+			"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+			"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+			"dev": true
+		},
+		"node_modules/tsutils": {
+			"version": "3.21.0",
+			"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+			"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+			"dev": true,
+			"dependencies": {
+				"tslib": "^1.8.1"
+			},
+			"engines": {
+				"node": ">= 6"
+			},
+			"peerDependencies": {
+				"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+			}
+		},
+		"node_modules/type-check": {
+			"version": "0.4.0",
+			"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+			"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+			"dev": true,
+			"dependencies": {
+				"prelude-ls": "^1.2.1"
+			},
+			"engines": {
+				"node": ">= 0.8.0"
+			}
+		},
+		"node_modules/type-fest": {
+			"version": "0.20.2",
+			"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+			"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/typescript": {
+			"resolved": "../../node_modules/.pnpm/[email protected]/node_modules/typescript",
+			"link": true
+		},
+		"node_modules/uri-js": {
+			"version": "4.4.1",
+			"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+			"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+			"dev": true,
+			"dependencies": {
+				"punycode": "^2.1.0"
+			}
+		},
+		"node_modules/v8-compile-cache": {
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+			"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+			"dev": true
+		},
+		"node_modules/which": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+			"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+			"dev": true,
+			"dependencies": {
+				"isexe": "^2.0.0"
+			},
+			"bin": {
+				"node-which": "bin/node-which"
+			},
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/word-wrap": {
+			"version": "1.2.3",
+			"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+			"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/wrappy": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+			"dev": true
+		},
+		"node_modules/yallist": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+			"dev": true
+		}
+	},
+	"dependencies": {
+		"@eslint/eslintrc": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
+			"integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==",
+			"dev": true,
+			"requires": {
+				"ajv": "^6.12.4",
+				"debug": "^4.3.2",
+				"espree": "^9.3.2",
+				"globals": "^13.15.0",
+				"ignore": "^5.2.0",
+				"import-fresh": "^3.2.1",
+				"js-yaml": "^4.1.0",
+				"minimatch": "^3.1.2",
+				"strip-json-comments": "^3.1.1"
+			}
+		},
+		"@humanwhocodes/config-array": {
+			"version": "0.9.5",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
+			"integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+			"dev": true,
+			"requires": {
+				"@humanwhocodes/object-schema": "^1.2.1",
+				"debug": "^4.1.1",
+				"minimatch": "^3.0.4"
+			}
+		},
+		"@humanwhocodes/object-schema": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+			"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+			"dev": true
+		},
+		"@nestjs/common": {
+			"version": "file:../../node_modules/.pnpm/@[email protected]_e7ea248743279784063e3708d703abc5/node_modules/@nestjs/common",
+			"requires": {
+				"axios": "0.27.2",
+				"iterare": "1.2.1",
+				"tslib": "2.4.0",
+				"uuid": "8.3.2"
+			}
+		},
+		"@nestjs/core": {
+			"version": "file:../../node_modules/.pnpm/@[email protected]_9530c9e4e8c33b27551732908d05d2fb/node_modules/@nestjs/core",
+			"requires": {
+				"@nestjs/common": "8.4.5",
+				"@nuxtjs/opencollective": "0.3.2",
+				"fast-safe-stringify": "2.1.1",
+				"iterare": "1.2.1",
+				"object-hash": "3.0.0",
+				"path-to-regexp": "3.2.0",
+				"tslib": "2.4.0",
+				"uuid": "8.3.2"
+			}
+		},
+		"@nestjs/platform-express": {
+			"version": "file:../../node_modules/.pnpm/@[email protected]_c0c9651cd01c4e2d3bda397a5c438062/node_modules/@nestjs/platform-express",
+			"requires": {
+				"@nestjs/common": "8.4.5",
+				"@nestjs/core": "8.4.5",
+				"body-parser": "1.20.0",
+				"cors": "2.8.5",
+				"express": "4.18.1",
+				"multer": "1.4.4",
+				"tslib": "2.4.0"
+			}
+		},
+		"@nodelib/fs.scandir": {
+			"version": "2.1.5",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+			"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+			"dev": true,
+			"requires": {
+				"@nodelib/fs.stat": "2.0.5",
+				"run-parallel": "^1.1.9"
+			}
+		},
+		"@nodelib/fs.stat": {
+			"version": "2.0.5",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+			"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+			"dev": true
+		},
+		"@nodelib/fs.walk": {
+			"version": "1.2.8",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+			"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+			"dev": true,
+			"requires": {
+				"@nodelib/fs.scandir": "2.1.5",
+				"fastq": "^1.6.0"
+			}
+		},
+		"@types/json-schema": {
+			"version": "7.0.11",
+			"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+			"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+			"dev": true
+		},
+		"@typescript-eslint/eslint-plugin": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.26.0.tgz",
+			"integrity": "sha512-oGCmo0PqnRZZndr+KwvvAUvD3kNE4AfyoGCwOZpoCncSh4MVD06JTE8XQa2u9u+NX5CsyZMBTEc2C72zx38eYA==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/scope-manager": "5.26.0",
+				"@typescript-eslint/type-utils": "5.26.0",
+				"@typescript-eslint/utils": "5.26.0",
+				"debug": "^4.3.4",
+				"functional-red-black-tree": "^1.0.1",
+				"ignore": "^5.2.0",
+				"regexpp": "^3.2.0",
+				"semver": "^7.3.7",
+				"tsutils": "^3.21.0"
+			}
+		},
+		"@typescript-eslint/parser": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.26.0.tgz",
+			"integrity": "sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/scope-manager": "5.26.0",
+				"@typescript-eslint/types": "5.26.0",
+				"@typescript-eslint/typescript-estree": "5.26.0",
+				"debug": "^4.3.4"
+			}
+		},
+		"@typescript-eslint/scope-manager": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.26.0.tgz",
+			"integrity": "sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/types": "5.26.0",
+				"@typescript-eslint/visitor-keys": "5.26.0"
+			}
+		},
+		"@typescript-eslint/type-utils": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.26.0.tgz",
+			"integrity": "sha512-7ccbUVWGLmcRDSA1+ADkDBl5fP87EJt0fnijsMFTVHXKGduYMgienC/i3QwoVhDADUAPoytgjbZbCOMj4TY55A==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/utils": "5.26.0",
+				"debug": "^4.3.4",
+				"tsutils": "^3.21.0"
+			}
+		},
+		"@typescript-eslint/types": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.26.0.tgz",
+			"integrity": "sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==",
+			"dev": true
+		},
+		"@typescript-eslint/typescript-estree": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.26.0.tgz",
+			"integrity": "sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/types": "5.26.0",
+				"@typescript-eslint/visitor-keys": "5.26.0",
+				"debug": "^4.3.4",
+				"globby": "^11.1.0",
+				"is-glob": "^4.0.3",
+				"semver": "^7.3.7",
+				"tsutils": "^3.21.0"
+			}
+		},
+		"@typescript-eslint/utils": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.26.0.tgz",
+			"integrity": "sha512-PJFwcTq2Pt4AMOKfe3zQOdez6InIDOjUJJD3v3LyEtxHGVVRK3Vo7Dd923t/4M9hSH2q2CLvcTdxlLPjcIk3eg==",
+			"dev": true,
+			"requires": {
+				"@types/json-schema": "^7.0.9",
+				"@typescript-eslint/scope-manager": "5.26.0",
+				"@typescript-eslint/types": "5.26.0",
+				"@typescript-eslint/typescript-estree": "5.26.0",
+				"eslint-scope": "^5.1.1",
+				"eslint-utils": "^3.0.0"
+			}
+		},
+		"@typescript-eslint/visitor-keys": {
+			"version": "5.26.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz",
+			"integrity": "sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/types": "5.26.0",
+				"eslint-visitor-keys": "^3.3.0"
+			}
+		},
+		"acorn": {
+			"version": "8.7.1",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
+			"integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+			"dev": true
+		},
+		"acorn-jsx": {
+			"version": "5.3.2",
+			"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+			"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+			"dev": true,
+			"requires": {}
+		},
+		"ajv": {
+			"version": "6.12.6",
+			"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+			"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+			"dev": true,
+			"requires": {
+				"fast-deep-equal": "^3.1.1",
+				"fast-json-stable-stringify": "^2.0.0",
+				"json-schema-traverse": "^0.4.1",
+				"uri-js": "^4.2.2"
+			}
+		},
+		"ansi-regex": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"dev": true
+		},
+		"ansi-styles": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+			"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+			"dev": true,
+			"requires": {
+				"color-convert": "^2.0.1"
+			}
+		},
+		"argparse": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+			"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+			"dev": true
+		},
+		"array-union": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+			"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+			"dev": true
+		},
+		"balanced-match": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+			"dev": true
+		},
+		"brace-expansion": {
+			"version": "1.1.11",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+			"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+			"dev": true,
+			"requires": {
+				"balanced-match": "^1.0.0",
+				"concat-map": "0.0.1"
+			}
+		},
+		"braces": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+			"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+			"dev": true,
+			"requires": {
+				"fill-range": "^7.0.1"
+			}
+		},
+		"callsites": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+			"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+			"dev": true
+		},
+		"chalk": {
+			"version": "4.1.2",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+			"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+			"dev": true,
+			"requires": {
+				"ansi-styles": "^4.1.0",
+				"supports-color": "^7.1.0"
+			}
+		},
+		"color-convert": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+			"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+			"dev": true,
+			"requires": {
+				"color-name": "~1.1.4"
+			}
+		},
+		"color-name": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+			"dev": true
+		},
+		"concat-map": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+			"dev": true
+		},
+		"cross-spawn": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+			"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+			"dev": true,
+			"requires": {
+				"path-key": "^3.1.0",
+				"shebang-command": "^2.0.0",
+				"which": "^2.0.1"
+			}
+		},
+		"debug": {
+			"version": "4.3.4",
+			"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+			"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+			"dev": true,
+			"requires": {
+				"ms": "2.1.2"
+			}
+		},
+		"deep-is": {
+			"version": "0.1.4",
+			"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+			"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+			"dev": true
+		},
+		"dir-glob": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+			"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+			"dev": true,
+			"requires": {
+				"path-type": "^4.0.0"
+			}
+		},
+		"doctrine": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+			"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+			"dev": true,
+			"requires": {
+				"esutils": "^2.0.2"
+			}
+		},
+		"escape-string-regexp": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+			"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+			"dev": true
+		},
+		"eslint": {
+			"version": "8.16.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz",
+			"integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==",
+			"dev": true,
+			"requires": {
+				"@eslint/eslintrc": "^1.3.0",
+				"@humanwhocodes/config-array": "^0.9.2",
+				"ajv": "^6.10.0",
+				"chalk": "^4.0.0",
+				"cross-spawn": "^7.0.2",
+				"debug": "^4.3.2",
+				"doctrine": "^3.0.0",
+				"escape-string-regexp": "^4.0.0",
+				"eslint-scope": "^7.1.1",
+				"eslint-utils": "^3.0.0",
+				"eslint-visitor-keys": "^3.3.0",
+				"espree": "^9.3.2",
+				"esquery": "^1.4.0",
+				"esutils": "^2.0.2",
+				"fast-deep-equal": "^3.1.3",
+				"file-entry-cache": "^6.0.1",
+				"functional-red-black-tree": "^1.0.1",
+				"glob-parent": "^6.0.1",
+				"globals": "^13.15.0",
+				"ignore": "^5.2.0",
+				"import-fresh": "^3.0.0",
+				"imurmurhash": "^0.1.4",
+				"is-glob": "^4.0.0",
+				"js-yaml": "^4.1.0",
+				"json-stable-stringify-without-jsonify": "^1.0.1",
+				"levn": "^0.4.1",
+				"lodash.merge": "^4.6.2",
+				"minimatch": "^3.1.2",
+				"natural-compare": "^1.4.0",
+				"optionator": "^0.9.1",
+				"regexpp": "^3.2.0",
+				"strip-ansi": "^6.0.1",
+				"strip-json-comments": "^3.1.0",
+				"text-table": "^0.2.0",
+				"v8-compile-cache": "^2.0.3"
+			},
+			"dependencies": {
+				"eslint-scope": {
+					"version": "7.1.1",
+					"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
+					"integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+					"dev": true,
+					"requires": {
+						"esrecurse": "^4.3.0",
+						"estraverse": "^5.2.0"
+					}
+				},
+				"estraverse": {
+					"version": "5.3.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+					"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+					"dev": true
+				}
+			}
+		},
+		"eslint-scope": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+			"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+			"dev": true,
+			"requires": {
+				"esrecurse": "^4.3.0",
+				"estraverse": "^4.1.1"
+			}
+		},
+		"eslint-utils": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+			"dev": true,
+			"requires": {
+				"eslint-visitor-keys": "^2.0.0"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "2.1.0",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+					"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+					"dev": true
+				}
+			}
+		},
+		"eslint-visitor-keys": {
+			"version": "3.3.0",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+			"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+			"dev": true
+		},
+		"espree": {
+			"version": "9.3.2",
+			"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
+			"integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+			"dev": true,
+			"requires": {
+				"acorn": "^8.7.1",
+				"acorn-jsx": "^5.3.2",
+				"eslint-visitor-keys": "^3.3.0"
+			}
+		},
+		"esquery": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+			"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+			"dev": true,
+			"requires": {
+				"estraverse": "^5.1.0"
+			},
+			"dependencies": {
+				"estraverse": {
+					"version": "5.3.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+					"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+					"dev": true
+				}
+			}
+		},
+		"esrecurse": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+			"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+			"dev": true,
+			"requires": {
+				"estraverse": "^5.2.0"
+			},
+			"dependencies": {
+				"estraverse": {
+					"version": "5.3.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+					"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+					"dev": true
+				}
+			}
+		},
+		"estraverse": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+			"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+			"dev": true
+		},
+		"esutils": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+			"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+			"dev": true
+		},
+		"fast-deep-equal": {
+			"version": "3.1.3",
+			"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+			"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+			"dev": true
+		},
+		"fast-glob": {
+			"version": "3.2.11",
+			"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
+			"integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+			"dev": true,
+			"requires": {
+				"@nodelib/fs.stat": "^2.0.2",
+				"@nodelib/fs.walk": "^1.2.3",
+				"glob-parent": "^5.1.2",
+				"merge2": "^1.3.0",
+				"micromatch": "^4.0.4"
+			},
+			"dependencies": {
+				"glob-parent": {
+					"version": "5.1.2",
+					"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+					"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+					"dev": true,
+					"requires": {
+						"is-glob": "^4.0.1"
+					}
+				}
+			}
+		},
+		"fast-json-stable-stringify": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+			"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+			"dev": true
+		},
+		"fast-levenshtein": {
+			"version": "2.0.6",
+			"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+			"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+			"dev": true
+		},
+		"fastq": {
+			"version": "1.13.0",
+			"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+			"integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+			"dev": true,
+			"requires": {
+				"reusify": "^1.0.4"
+			}
+		},
+		"file-entry-cache": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+			"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+			"dev": true,
+			"requires": {
+				"flat-cache": "^3.0.4"
+			}
+		},
+		"fill-range": {
+			"version": "7.0.1",
+			"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+			"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+			"dev": true,
+			"requires": {
+				"to-regex-range": "^5.0.1"
+			}
+		},
+		"flat-cache": {
+			"version": "3.0.4",
+			"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+			"integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+			"dev": true,
+			"requires": {
+				"flatted": "^3.1.0",
+				"rimraf": "^3.0.2"
+			}
+		},
+		"flatted": {
+			"version": "3.2.5",
+			"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
+			"integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
+			"dev": true
+		},
+		"fs.realpath": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+			"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+			"dev": true
+		},
+		"functional-red-black-tree": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+			"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+			"dev": true
+		},
+		"glob": {
+			"version": "7.2.3",
+			"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+			"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+			"dev": true,
+			"requires": {
+				"fs.realpath": "^1.0.0",
+				"inflight": "^1.0.4",
+				"inherits": "2",
+				"minimatch": "^3.1.1",
+				"once": "^1.3.0",
+				"path-is-absolute": "^1.0.0"
+			}
+		},
+		"glob-parent": {
+			"version": "6.0.2",
+			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+			"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+			"dev": true,
+			"requires": {
+				"is-glob": "^4.0.3"
+			}
+		},
+		"globals": {
+			"version": "13.15.0",
+			"resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz",
+			"integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==",
+			"dev": true,
+			"requires": {
+				"type-fest": "^0.20.2"
+			}
+		},
+		"globby": {
+			"version": "11.1.0",
+			"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+			"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+			"dev": true,
+			"requires": {
+				"array-union": "^2.1.0",
+				"dir-glob": "^3.0.1",
+				"fast-glob": "^3.2.9",
+				"ignore": "^5.2.0",
+				"merge2": "^1.4.1",
+				"slash": "^3.0.0"
+			}
+		},
+		"has-flag": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+			"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+			"dev": true
+		},
+		"ignore": {
+			"version": "5.2.0",
+			"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+			"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+			"dev": true
+		},
+		"import-fresh": {
+			"version": "3.3.0",
+			"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+			"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+			"dev": true,
+			"requires": {
+				"parent-module": "^1.0.0",
+				"resolve-from": "^4.0.0"
+			}
+		},
+		"imurmurhash": {
+			"version": "0.1.4",
+			"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+			"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+			"dev": true
+		},
+		"inflight": {
+			"version": "1.0.6",
+			"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+			"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+			"dev": true,
+			"requires": {
+				"once": "^1.3.0",
+				"wrappy": "1"
+			}
+		},
+		"inherits": {
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+			"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+			"dev": true
+		},
+		"is-extglob": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+			"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+			"dev": true
+		},
+		"is-glob": {
+			"version": "4.0.3",
+			"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+			"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+			"dev": true,
+			"requires": {
+				"is-extglob": "^2.1.1"
+			}
+		},
+		"is-number": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+			"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+			"dev": true
+		},
+		"isexe": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+			"dev": true
+		},
+		"js-yaml": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+			"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+			"dev": true,
+			"requires": {
+				"argparse": "^2.0.1"
+			}
+		},
+		"json-schema-traverse": {
+			"version": "0.4.1",
+			"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+			"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+			"dev": true
+		},
+		"json-stable-stringify-without-jsonify": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+			"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+			"dev": true
+		},
+		"levn": {
+			"version": "0.4.1",
+			"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+			"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+			"dev": true,
+			"requires": {
+				"prelude-ls": "^1.2.1",
+				"type-check": "~0.4.0"
+			}
+		},
+		"lodash.merge": {
+			"version": "4.6.2",
+			"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+			"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+			"dev": true
+		},
+		"lru-cache": {
+			"version": "6.0.0",
+			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+			"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+			"dev": true,
+			"requires": {
+				"yallist": "^4.0.0"
+			}
+		},
+		"merge2": {
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+			"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+			"dev": true
+		},
+		"micromatch": {
+			"version": "4.0.5",
+			"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+			"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+			"dev": true,
+			"requires": {
+				"braces": "^3.0.2",
+				"picomatch": "^2.3.1"
+			}
+		},
+		"minimatch": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+			"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+			"dev": true,
+			"requires": {
+				"brace-expansion": "^1.1.7"
+			}
+		},
+		"ms": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+			"dev": true
+		},
+		"natural-compare": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+			"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+			"dev": true
+		},
+		"nodemon": {
+			"version": "file:../../node_modules/.pnpm/[email protected]/node_modules/nodemon",
+			"requires": {
+				"@commitlint/cli": "^11.0.0",
+				"@commitlint/config-conventional": "^11.0.0",
+				"async": "1.4.2",
+				"chokidar": "^3.5.2",
+				"coffee-script": "~1.7.1",
+				"debug": "^3.2.7",
+				"eslint": "^7.32.0",
+				"husky": "^7.0.4",
+				"ignore-by-default": "^1.0.1",
+				"minimatch": "^3.0.4",
+				"mocha": "^2.5.3",
+				"nyc": "^15.1.0",
+				"proxyquire": "^1.8.0",
+				"pstree.remy": "^1.1.8",
+				"semantic-release": "^18.0.0",
+				"semver": "^5.7.1",
+				"should": "~4.0.0",
+				"supports-color": "^5.5.0",
+				"touch": "^3.1.0",
+				"undefsafe": "^2.0.5",
+				"update-notifier": "^5.1.0"
+			}
+		},
+		"once": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+			"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+			"dev": true,
+			"requires": {
+				"wrappy": "1"
+			}
+		},
+		"optionator": {
+			"version": "0.9.1",
+			"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+			"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+			"dev": true,
+			"requires": {
+				"deep-is": "^0.1.3",
+				"fast-levenshtein": "^2.0.6",
+				"levn": "^0.4.1",
+				"prelude-ls": "^1.2.1",
+				"type-check": "^0.4.0",
+				"word-wrap": "^1.2.3"
+			}
+		},
+		"parent-module": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+			"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+			"dev": true,
+			"requires": {
+				"callsites": "^3.0.0"
+			}
+		},
+		"path-is-absolute": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+			"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+			"dev": true
+		},
+		"path-key": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+			"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+			"dev": true
+		},
+		"path-type": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+			"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+			"dev": true
+		},
+		"picomatch": {
+			"version": "2.3.1",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+			"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+			"dev": true
+		},
+		"prelude-ls": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+			"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+			"dev": true
+		},
+		"punycode": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+			"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+			"dev": true
+		},
+		"queue-microtask": {
+			"version": "1.2.3",
+			"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+			"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+			"dev": true
+		},
+		"reflect-metadata": {
+			"version": "file:../../node_modules/.pnpm/[email protected]/node_modules/reflect-metadata",
+			"requires": {
+				"@types/chai": "^3.4.34",
+				"@types/mocha": "^2.2.34",
+				"@types/node": "^6.0.52",
+				"chai": "^3.5.0",
+				"del": "^2.2.2",
+				"ecmarkup": "^3.9.3",
+				"gulp": "^3.9.1",
+				"gulp-emu": "^1.1.0",
+				"gulp-live-server": "0.0.30",
+				"gulp-mocha": "^3.0.1",
+				"gulp-rename": "^1.2.2",
+				"gulp-sequence": "^0.4.6",
+				"gulp-tsb": "^2.0.3",
+				"mocha": "^3.2.0",
+				"typescript": "^2.1.4"
+			}
+		},
+		"regexpp": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+			"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+			"dev": true
+		},
+		"resolve-from": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+			"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+			"dev": true
+		},
+		"reusify": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+			"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+			"dev": true
+		},
+		"rimraf": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+			"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+			"dev": true,
+			"requires": {
+				"glob": "^7.1.3"
+			}
+		},
+		"run-parallel": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+			"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+			"dev": true,
+			"requires": {
+				"queue-microtask": "^1.2.2"
+			}
+		},
+		"rxjs": {
+			"version": "file:../../node_modules/.pnpm/[email protected]/node_modules/rxjs",
+			"requires": {
+				"@angular-devkit/build-optimizer": "0.4.6",
+				"@angular-devkit/schematics": "^11.0.7",
+				"@swc/core": "^1.2.128",
+				"@swc/helpers": "^0.3.2",
+				"@types/chai": "^4.2.11",
+				"@types/lodash": "4.14.102",
+				"@types/mocha": "^7.0.2",
+				"@types/node": "^14.14.6",
+				"@types/shelljs": "^0.8.8",
+				"@types/sinon": "4.1.3",
+				"@types/sinon-chai": "2.7.29",
+				"@types/source-map": "^0.5.2",
+				"@typescript-eslint/eslint-plugin": "^4.29.1",
+				"@typescript-eslint/parser": "^4.29.1",
+				"babel-polyfill": "6.26.0",
+				"chai": "^4.2.0",
+				"check-side-effects": "0.0.23",
+				"color": "3.0.0",
+				"colors": "1.1.2",
+				"cross-env": "5.1.3",
+				"cz-conventional-changelog": "1.2.0",
+				"dependency-cruiser": "^9.12.0",
+				"escape-string-regexp": "1.0.5",
+				"eslint": "^7.8.1",
+				"eslint-plugin-jasmine": "^2.10.1",
+				"form-data": "^3.0.0",
+				"fs-extra": "^8.1.0",
+				"glob": "7.1.2",
+				"google-closure-compiler-js": "20170218.0.0",
+				"husky": "^4.2.5",
+				"klaw-sync": "3.0.2",
+				"lint-staged": "^10.2.11",
+				"lodash": "^4.17.15",
+				"minimist": "^1.2.5",
+				"mocha": "^8.1.3",
+				"nodemon": "^1.9.2",
+				"npm-run-all": "4.1.2",
+				"opn-cli": "3.1.0",
+				"platform": "1.3.5",
+				"prettier": "^2.5.1",
+				"promise": "8.0.1",
+				"rollup": "0.66.6",
+				"rollup-plugin-alias": "1.4.0",
+				"rollup-plugin-inject": "2.0.0",
+				"rollup-plugin-node-resolve": "2.0.0",
+				"shelljs": "^0.8.4",
+				"shx": "^0.3.2",
+				"sinon": "4.3.0",
+				"sinon-chai": "2.14.0",
+				"source-map-support": "0.5.3",
+				"systemjs": "^0.21.0",
+				"ts-api-guardian": "^0.5.0",
+				"ts-node": "^9.1.1",
+				"tslib": "^2.1.0",
+				"tslint": "^5.20.1",
+				"tslint-config-prettier": "^1.18.0",
+				"tslint-etc": "1.13.10",
+				"tslint-no-toplevel-property-access": "0.0.2",
+				"tslint-no-unused-expression-chai": "0.0.3",
+				"typescript": "~4.2.0",
+				"validate-commit-msg": "2.14.0",
+				"web-streams-polyfill": "^3.0.2",
+				"webpack": "^4.31.0"
+			}
+		},
+		"semver": {
+			"version": "7.3.7",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+			"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+			"dev": true,
+			"requires": {
+				"lru-cache": "^6.0.0"
+			}
+		},
+		"shebang-command": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+			"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+			"dev": true,
+			"requires": {
+				"shebang-regex": "^3.0.0"
+			}
+		},
+		"shebang-regex": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+			"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+			"dev": true
+		},
+		"slash": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+			"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+			"dev": true
+		},
+		"strip-ansi": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+			"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+			"dev": true,
+			"requires": {
+				"ansi-regex": "^5.0.1"
+			}
+		},
+		"strip-json-comments": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+			"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+			"dev": true
+		},
+		"supports-color": {
+			"version": "7.2.0",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+			"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+			"dev": true,
+			"requires": {
+				"has-flag": "^4.0.0"
+			}
+		},
+		"text-table": {
+			"version": "0.2.0",
+			"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+			"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+			"dev": true
+		},
+		"to-regex-range": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+			"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+			"dev": true,
+			"requires": {
+				"is-number": "^7.0.0"
+			}
+		},
+		"tslib": {
+			"version": "1.14.1",
+			"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+			"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+			"dev": true
+		},
+		"tsutils": {
+			"version": "3.21.0",
+			"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+			"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+			"dev": true,
+			"requires": {
+				"tslib": "^1.8.1"
+			}
+		},
+		"type-check": {
+			"version": "0.4.0",
+			"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+			"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+			"dev": true,
+			"requires": {
+				"prelude-ls": "^1.2.1"
+			}
+		},
+		"type-fest": {
+			"version": "0.20.2",
+			"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+			"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+			"dev": true
+		},
+		"typescript": {
+			"version": "file:../../node_modules/.pnpm/[email protected]/node_modules/typescript",
+			"requires": {
+				"@octokit/rest": "latest",
+				"@types/browserify": "latest",
+				"@types/chai": "latest",
+				"@types/convert-source-map": "latest",
+				"@types/glob": "latest",
+				"@types/gulp": "^4.0.9",
+				"@types/gulp-concat": "latest",
+				"@types/gulp-newer": "latest",
+				"@types/gulp-rename": "0.0.33",
+				"@types/gulp-sourcemaps": "0.0.32",
+				"@types/jake": "latest",
+				"@types/merge2": "latest",
+				"@types/microsoft__typescript-etw": "latest",
+				"@types/minimatch": "latest",
+				"@types/minimist": "latest",
+				"@types/mkdirp": "latest",
+				"@types/mocha": "latest",
+				"@types/ms": "latest",
+				"@types/node": "latest",
+				"@types/node-fetch": "^2.3.4",
+				"@types/q": "latest",
+				"@types/source-map-support": "latest",
+				"@types/through2": "latest",
+				"@types/xml2js": "^0.4.0",
+				"@typescript-eslint/eslint-plugin": "^4.28.0",
+				"@typescript-eslint/experimental-utils": "^4.28.0",
+				"@typescript-eslint/parser": "^4.28.0",
+				"async": "latest",
+				"azure-devops-node-api": "^11.0.1",
+				"browser-resolve": "^1.11.2",
+				"browserify": "latest",
+				"chai": "latest",
+				"chalk": "^4.1.2",
+				"convert-source-map": "latest",
+				"del": "5.1.0",
+				"diff": "^4.0.2",
+				"eslint": "7.12.1",
+				"eslint-formatter-autolinkable-stylish": "1.1.4",
+				"eslint-plugin-import": "2.22.1",
+				"eslint-plugin-jsdoc": "30.7.6",
+				"eslint-plugin-no-null": "1.0.2",
+				"fancy-log": "latest",
+				"fs-extra": "^9.0.0",
+				"glob": "latest",
+				"gulp": "^4.0.0",
+				"gulp-concat": "latest",
+				"gulp-insert": "latest",
+				"gulp-newer": "latest",
+				"gulp-rename": "latest",
+				"gulp-sourcemaps": "latest",
+				"merge2": "latest",
+				"minimist": "latest",
+				"mkdirp": "latest",
+				"mocha": "latest",
+				"mocha-fivemat-progress-reporter": "latest",
+				"ms": "^2.1.3",
+				"node-fetch": "^2.6.1",
+				"plugin-error": "latest",
+				"pretty-hrtime": "^1.0.3",
+				"prex": "^0.4.3",
+				"q": "latest",
+				"source-map-support": "latest",
+				"through2": "latest",
+				"typescript": "^4.5.5",
+				"vinyl": "latest",
+				"vinyl-sourcemaps-apply": "latest",
+				"xml2js": "^0.4.19"
+			}
+		},
+		"uri-js": {
+			"version": "4.4.1",
+			"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+			"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+			"dev": true,
+			"requires": {
+				"punycode": "^2.1.0"
+			}
+		},
+		"v8-compile-cache": {
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+			"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+			"dev": true
+		},
+		"which": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+			"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+			"dev": true,
+			"requires": {
+				"isexe": "^2.0.0"
+			}
+		},
+		"word-wrap": {
+			"version": "1.2.3",
+			"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+			"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+			"dev": true
+		},
+		"wrappy": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+			"dev": true
+		},
+		"yallist": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+			"dev": true
+		}
+	}
+}

+ 44 - 0
package.json

@@ -0,0 +1,44 @@
+{
+	"name": "wyling-nest-demo",
+	"version": "1.0.0",
+	"description": "",
+	"scripts": {
+		"dev": "nodemon src/main.ts --watch src --exec \"eslint src && ts-node\"",
+		"build": "tsc",
+		"start": "node dist/main.js",
+		"ncc-build": "ncc build src/main.ts -o dist -m"
+	},
+	"keywords": [],
+	"author": "",
+	"license": "ISC",
+	"dependencies": {
+		"@nestjs/common": "^8.4.5",
+		"@nestjs/core": "^8.4.5",
+		"@nestjs/platform-express": "^8.4.5",
+		"@nestjs/swagger": "^5.2.1",
+		"class-transformer": "^0.5.1",
+		"class-validator": "^0.13.2",
+		"express": "^4.18.1",
+		"jsonwebtoken": "^8.5.1",
+		"module-alias": "^2.2.2",
+		"mysql": "^2.18.1",
+		"reflect-metadata": "^0.1.13",
+		"rxjs": "^7.5.5",
+		"sqlite3": "^5.0.8",
+		"swagger-ui-express": "^4.4.0",
+		"typeorm": "^0.3.6"
+	},
+	"devDependencies": {
+		"@types/express": "^4.17.13",
+		"@types/jsonwebtoken": "^8.5.8",
+		"@types/module-alias": "^2.0.1",
+		"@types/node": "^17.0.35",
+		"@types/sqlite3": "^3.1.8",
+		"@typescript-eslint/eslint-plugin": "^5.26.0",
+		"@typescript-eslint/parser": "^5.26.0",
+		"@vercel/ncc": "^0.34.0",
+		"eslint": "^8.16.0",
+		"nodemon": "^2.0.16",
+		"typescript": "^4.6.4"
+	}
+}

+ 7 - 0
src/app.module.ts

@@ -0,0 +1,7 @@
+import { Module } from '@nestjs/common';
+import { controllers } from './controllers';
+
+@Module({
+	controllers,
+})
+export class AppModule {}

+ 21 - 0
src/controllers/REST_Client/appPermission.http

@@ -0,0 +1,21 @@
+@baseUrl = http://127.0.0.1:3009/system/appPermission
+@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJzdXBlckFkbWluIiwiZW1haWwiOm51bGwsInBob25lIjpudWxsLCJpYXQiOjE2NTQ1MzA0MDEsImV4cCI6MTY1NDYxNjgwMX0.69kaREegPTdD8YzwUX_XbKoffSnBH5tZYp3jRfdDRqQ
+
+###增加权限
+
+POST {{baseUrl}}/addPermission HTTP/1.1
+content-type: application/json
+Authorization: {{token}}
+
+{
+    "permissionName": "sample",
+    "permissionKey": "113",
+    "pid": 4
+}
+
+###获取权限树
+
+GET {{baseUrl}}/getPermissionTree HTTP/1.1
+content-type: application/json
+Authorization: {{token}}
+

+ 5 - 0
src/controllers/index.ts

@@ -0,0 +1,5 @@
+import { AuthController } from './modules/auth';
+import { UserController } from './modules/user';
+import { AppPermissionController } from './modules/appPermission';
+
+export const controllers = [AuthController, UserController, AppPermissionController];

+ 43 - 0
src/controllers/modules/appPermission.ts

@@ -0,0 +1,43 @@
+import { Controller, Body, Post, Get } from '@nestjs/common';
+import { AppPermissionService } from '@/services';
+import { AppPermission } from '@/database/entities';
+import { IsNotEmpty, IsString, IsNumber } from 'class-validator';
+import { usePermissionGuard } from '@/guard';
+
+namespace AppPermissionDto {
+	/** 注册请求验证类 */
+	export class AddPermissionParams
+		implements Pick<AppPermission, 'permissionName' | 'permissionKey' | 'pid'>
+	{
+		@IsString({
+			message: '$property必须是字符串',
+		})
+		@IsNotEmpty()
+		permissionName: string;
+
+		@IsString({
+			message: '$property必须是字符串',
+		})
+		@IsNotEmpty()
+		permissionKey: string;
+
+		@IsNumber({})
+		@IsNotEmpty()
+		pid: number;
+	}
+}
+
+@Controller('system/appPermission')
+export class AppPermissionController {
+	/** 新增权限 */
+	@Post('addPermission')
+	AddPermission(@Body() params: AppPermissionDto.AddPermissionParams) {
+		return AppPermissionService.addPermission(params);
+	}
+	/** 查询权限树 */
+	@usePermissionGuard('system:appPermission:getPermissionTree')
+	@Get('getPermissionTree')
+	GetPermissionTree() {
+		return AppPermissionService.getPermissionTree(0);
+	}
+}

+ 59 - 0
src/controllers/modules/auth.ts

@@ -0,0 +1,59 @@
+import { Body, Controller, Post, Get, Request } from '@nestjs/common';
+import { AuthService } from '@/services';
+import { User } from '@/database/entities';
+import { IsNotEmpty, IsString, ValidateIf, Equals, IsHash } from 'class-validator';
+import { ApiProperty } from '@nestjs/swagger';
+
+namespace AuthDto {
+	/** 登陆请求验证类 */
+	export class LoginParams implements Pick<User, 'username' | 'password'> {
+		@ApiProperty({
+			description: '用户名',
+		})
+		@IsString({
+			message: '$property必须是字符串',
+		})
+		@IsNotEmpty()
+		username: string;
+
+		@ApiProperty({
+			description: '密码 md5加密后的32位字符串',
+		})
+		@IsHash('md5', { message: '$property必须是md5加密后的32位字符串' })
+		@IsNotEmpty()
+		password: string;
+	}
+	/** 注册请求参数类型 */
+	type RegisterParamsType = Pick<User, 'username' | 'password'> & { confirmPassword: string };
+	/** 注册请求验证类 */
+	export class RegisterParams extends LoginParams implements RegisterParamsType {
+		@ApiProperty({
+			description: '重复密码',
+		})
+		@ValidateIf((o, v) => o.password !== v)
+		@Equals('dahdkasdhakdhkdhakdhaskjdhakd', { message: '两次输入密码不一致' })
+		confirmPassword: string;
+	}
+}
+
+@Controller('system/auth')
+export class AuthController {
+	/** 登陆 */
+	@Post('login')
+	login(@Body() body: AuthDto.LoginParams) {
+		return AuthService.login(body);
+	}
+	/** 注册 */
+	@Post('register')
+	register(@Body() body: AuthDto.RegisterParams) {
+		return AuthService.register({
+			username: body.username,
+			password: body.password,
+		});
+	}
+	/** 获取登录用户信息 */
+	@Get('getUserInfo')
+	getUserInfo(@Request() { user }: { user: User }) {
+		return AuthService.getUserInfo({ id: user.id });
+	}
+}

+ 12 - 0
src/controllers/modules/user.ts

@@ -0,0 +1,12 @@
+import { Controller, Delete, Get, Request } from '@nestjs/common';
+import { UserService } from '@/services';
+import { User } from '@/database/entities';
+
+@Controller('system/user')
+export class UserController {
+	/** 批量删除用户 */
+	@Delete('deleteUsers')
+	deleteUsers() {
+		return UserService.deleteUsers([{ id: 1 }, { id: 2 }]);
+	}
+}

+ 35 - 0
src/database/entities/common/baseEntity.ts

@@ -0,0 +1,35 @@
+import {
+	CreateDateColumn,
+	UpdateDateColumn,
+	DeleteDateColumn,
+	PrimaryGeneratedColumn,
+} from 'typeorm';
+
+export class BaseEntity {
+	@PrimaryGeneratedColumn()
+	id: number;
+
+	@CreateDateColumn({
+		name: 'created_time',
+		type: 'datetime',
+		comment: '创建时间',
+		select: false,
+	})
+	createdTime: string;
+
+	@UpdateDateColumn({
+		name: 'updated_time',
+		type: 'datetime',
+		comment: '更新时间',
+		select: false,
+	})
+	updatedTime: string;
+
+	@DeleteDateColumn({
+		name: 'deleted_time',
+		type: 'datetime',
+		comment: '删除时间',
+		select: false,
+	})
+	deletedTime: string;
+}

+ 4 - 0
src/database/entities/index.ts

@@ -0,0 +1,4 @@
+export * from './modules/douyu';
+export * from './modules/role';
+export * from './modules/user';
+export * from './modules/appPermissions';

+ 22 - 0
src/database/entities/modules/appPermissions.ts

@@ -0,0 +1,22 @@
+import { Entity, Column } from 'typeorm';
+import { BaseEntity } from '../common/baseEntity';
+
+@Entity()
+export class AppPermission extends BaseEntity {
+	@Column({
+		length: 100,
+		comment: '权限名称',
+	})
+	permissionName: string;
+
+	@Column({
+		length: 100,
+		comment: '权限字符串',
+	})
+	permissionKey: string;
+
+	@Column({
+		comment: '父级ID',
+	})
+	pid: number;
+}

+ 48 - 0
src/database/entities/modules/douyu.ts

@@ -0,0 +1,48 @@
+import { Entity, Column } from 'typeorm';
+import { BaseEntity } from '../common/baseEntity';
+
+@Entity()
+export class DouyuAccount extends BaseEntity {
+	@Column({
+		length: 100,
+	})
+	nickName: string;
+
+	@Column({
+		length: 32,
+	})
+	password: string;
+
+	@Column({
+		length: 32,
+		default: '',
+	})
+	email: string;
+
+	@Column({
+		length: 32,
+	})
+	phone: string;
+
+	@Column({
+		default: '',
+	})
+	appToken: string;
+
+	@Column({
+		type: 'json',
+	})
+	appShortToken: string;
+
+	@Column({
+		type: 'text',
+		default: '',
+	})
+	LTP0: string;
+
+	@Column({
+		type: 'text',
+		default: '',
+	})
+	webCookie: string;
+}

+ 16 - 0
src/database/entities/modules/role.ts

@@ -0,0 +1,16 @@
+import { Entity, Column, ManyToMany, JoinTable } from 'typeorm';
+import { BaseEntity } from '../common/baseEntity';
+import { AppPermission } from './appPermissions';
+
+@Entity()
+export class Role extends BaseEntity {
+	@Column({
+		length: 100,
+		comment: '角色名',
+	})
+	roleName: string;
+
+	@ManyToMany(() => AppPermission)
+	@JoinTable()
+	permissions: AppPermission[];
+}

+ 37 - 0
src/database/entities/modules/user.ts

@@ -0,0 +1,37 @@
+import { Role } from './role';
+import { Entity, Column, ManyToMany, JoinTable } from 'typeorm';
+import { BaseEntity } from '../common/baseEntity';
+
+@Entity()
+export class User extends BaseEntity {
+	@Column({
+		length: 100,
+		comment: '用户名',
+	})
+	username: string;
+
+	@Column({
+		length: 32,
+		comment: '密码',
+		select: false,
+	})
+	password: string;
+
+	@Column({
+		length: 32,
+		default: null,
+		comment: '邮箱',
+	})
+	email: string;
+
+	@Column({
+		length: 32,
+		default: null,
+		comment: '手机',
+	})
+	phone: string;
+
+	@ManyToMany(() => Role)
+	@JoinTable()
+	roles: Role[];
+}

+ 20 - 0
src/database/index.ts

@@ -0,0 +1,20 @@
+import 'reflect-metadata';
+import { DataSource } from 'typeorm';
+import { User, Role, AppPermission } from './entities';
+import path from 'path';
+
+export const AppDataSource = new DataSource({
+	type: 'sqlite',
+	database: path.resolve(__dirname, './wyling.db'),
+	entities: [User, Role, AppPermission],
+	synchronize: true,
+});
+
+export namespace DatabaseRepository {
+	/** 用户表 */
+	export const UsersRepository = AppDataSource.getRepository(User);
+	/** 角色表 */
+	export const RolesRepository = AppDataSource.getRepository(Role);
+	/** 权限表 */
+	export const AppPermissionRepository = AppDataSource.getRepository(AppPermission);
+}

BIN
src/database/wyling.db


+ 1 - 0
src/guard/index.ts

@@ -0,0 +1 @@
+export * from './modules/permission.guard';

+ 21 - 0
src/guard/modules/permission.guard.ts

@@ -0,0 +1,21 @@
+import { Injectable, CanActivate, ExecutionContext, UseGuards } from '@nestjs/common';
+import { DatabaseRepository } from '@/database';
+
+/** 权限字符串守卫 */
+@Injectable()
+class PermissionGuard implements CanActivate {
+	constructor(private permissionKey: string) {}
+
+	async canActivate(context: ExecutionContext): Promise<boolean> {
+		const request = context.switchToHttp().getRequest();
+		const { permissions } = await DatabaseRepository.RolesRepository.findOneBy({
+			id: request.user.roleId,
+		});
+		const permissionKeys = permissions.map((item) => item.permissionKey);
+		return permissionKeys.includes('*') || permissionKeys.includes(this.permissionKey);
+	}
+}
+
+/** 权限字符串守卫装饰器 */
+export const usePermissionGuard = (permissionKey: string) =>
+	UseGuards(new PermissionGuard(permissionKey));

+ 22 - 0
src/main.ts

@@ -0,0 +1,22 @@
+//初始化项目前最优先设置路径别名,顺序乱了会报错
+import './plugins/alias';
+import { NestFactory } from '@nestjs/core';
+import { ValidationPipe } from '@nestjs/common';
+import { AppModule } from './app.module';
+import { initSwagger } from './plugins/swagger';
+import { JwtAuthMiddleware } from './middlewares';
+import { InitService } from '@/services';
+
+(async function bootstrap() {
+	const app = await NestFactory.create(AppModule);
+	//初始化swagger文档
+	initSwagger(app);
+	//初始化数据库
+	await InitService.initDatabase();
+	//全局auth中间件
+	app.use(JwtAuthMiddleware);
+	//全局验证器
+	app.useGlobalPipes(new ValidationPipe());
+	//启动监听端口
+	await app.listen(3009);
+})();

+ 1 - 0
src/middlewares/index.ts

@@ -0,0 +1 @@
+export * from './modules/auth.middleware';

+ 31 - 0
src/middlewares/modules/auth.middleware.ts

@@ -0,0 +1,31 @@
+import { Request, Response, NextFunction } from 'express';
+import { AuthService } from '@/services';
+import { HttpException } from '@nestjs/common';
+
+/** jwt鉴权中间件 */
+export const JwtAuthMiddleware = (req: Request, res: Response, next: NextFunction) => {
+	//白名单
+	if (['/system/auth/register', '/system/auth/login'].includes(req.path)) {
+		next();
+		return;
+	}
+	//获取token
+	const { authorization } = req.headers;
+	//验证token
+	if (!authorization) {
+		//没有token
+		next(new HttpException('请登录', 401));
+	} else {
+		//解析token
+		try {
+			//解析token
+			const user = AuthService.decodeJWT(authorization);
+			//设置用户信息
+			Reflect.set(req, 'user', user);
+			next();
+		} catch (error) {
+			//验证失败
+			next(new HttpException({ code: 500, msg: '无效token' }, 401));
+		}
+	}
+};

+ 7 - 0
src/plugins/alias.ts

@@ -0,0 +1,7 @@
+import moduleAlias from 'module-alias';
+import path from 'path';
+
+//设置路径别名
+moduleAlias.addAliases({
+	'@': path.resolve(__dirname, '../'),
+});

+ 8 - 0
src/plugins/swagger.ts

@@ -0,0 +1,8 @@
+import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
+import { INestApplication } from '@nestjs/common';
+
+export const initSwagger = (app: INestApplication) => {
+	const options = new DocumentBuilder().setTitle('wyling.cn文档').setVersion('1.0').build();
+	const document = SwaggerModule.createDocument(app, options);
+	SwaggerModule.setup('swagger', app, document);
+};

+ 4 - 0
src/services/index.ts

@@ -0,0 +1,4 @@
+export * from './modules/auth';
+export * from './modules/init';
+export * from './modules/permission';
+export * from './modules/user';

+ 57 - 0
src/services/modules/auth.ts

@@ -0,0 +1,57 @@
+import { User } from '@/database/entities';
+import { UserService } from './user';
+import Jsonwebtoken from 'jsonwebtoken';
+
+/** 权限服务 */
+export namespace AuthService {
+	/** 登录 */
+	export async function login(params: Pick<User, 'username' | 'password'>) {
+		// 验证码校验
+		// 校验成功后, 返回用户信息及token
+		const user = await UserService.getUserInfoByPassword(params);
+		return {
+			token: generateJWT(user),
+			userInfo: user,
+		};
+	}
+	/** 注册 */
+	export async function register(params: Pick<User, 'username' | 'password'>) {
+		// 验证码校验
+		// 校验成功后,创建用户
+		const user = await UserService.addUser(params);
+		return {
+			token: generateJWT(user),
+			userInfo: user,
+		};
+	}
+	/** 登出 */
+	export async function logout() {
+		return true;
+	}
+	/** 获取用户信息 */
+	export async function getUserInfo(params: Pick<User, 'id'>) {
+		return await UserService.getUserInfoByID({ id: params.id }, true);
+	}
+	/** Jwt秘钥 */
+	const JWT_SECRET = 'wyling-nest-demo';
+	/** 生成Jwt */
+	export function generateJWT(user: User) {
+		const token = Jsonwebtoken.sign(
+			{
+				id: user.id,
+				username: user.username,
+				email: user.email,
+				phone: user.phone,
+			},
+			JWT_SECRET,
+			{
+				expiresIn: '1d',
+			}
+		);
+		return token;
+	}
+	/** 解析Jwt */
+	export function decodeJWT(token: string) {
+		return Jsonwebtoken.verify(token, JWT_SECRET);
+	}
+}

+ 56 - 0
src/services/modules/init.ts

@@ -0,0 +1,56 @@
+import { AppDataSource, DatabaseRepository } from '@/database';
+import { Role, User } from '@/database/entities';
+
+/** 初始化服务 */
+export namespace InitService {
+	/** 初始化数据库 */
+	export async function initDatabase() {
+		//初始化数据库连接
+		await AppDataSource.initialize();
+		//初始化超级管理员角色
+		let role = await DatabaseRepository.RolesRepository.findOne({
+			where: { roleName: '超级管理员' },
+		});
+		if (!role) {
+			role = await DatabaseRepository.RolesRepository.save({
+				...new Role(),
+				roleName: '超级管理员',
+			});
+		}
+		//初始化老板角色
+		let role2 = await DatabaseRepository.RolesRepository.findOne({
+			where: { roleName: '老板' },
+		});
+		if (!role2) {
+			role2 = await DatabaseRepository.RolesRepository.save({
+				...new Role(),
+				roleName: '老板',
+			});
+		}
+		//初始化超级管理员用户
+		const user = await DatabaseRepository.UsersRepository.findOne({
+			where: { username: 'superAdmin' },
+		});
+		const roles = await DatabaseRepository.RolesRepository.find();
+		if (!user) {
+			await DatabaseRepository.UsersRepository.save({
+				...new User(),
+				username: 'superAdmin',
+				password: 'e10adc3949ba59abbe56e057f20f883e',
+				roles: roles,
+			});
+		}
+		//初始化超级管理员2用户
+		const user2 = await DatabaseRepository.UsersRepository.findOne({
+			where: { username: 'superAdmin2' },
+		});
+		if (!user2) {
+			await DatabaseRepository.UsersRepository.save({
+				...new User(),
+				username: 'superAdmin2',
+				password: 'e10adc3949ba59abbe56e057f20f883e',
+				roles: roles,
+			});
+		}
+	}
+}

+ 67 - 0
src/services/modules/permission.ts

@@ -0,0 +1,67 @@
+import { DatabaseRepository } from '@/database';
+import { AppPermission } from '@/database/entities';
+import { HttpException } from '@nestjs/common';
+
+/** App权限服务 */
+export namespace AppPermissionService {
+	/** 新增app权限 */
+	export async function addPermission(
+		permission: Pick<AppPermission, 'permissionName' | 'permissionKey' | 'pid'>
+	) {
+		const oldPermission = await DatabaseRepository.AppPermissionRepository.findOne({
+			where: { permissionKey: permission.permissionKey },
+		});
+		if (oldPermission) {
+			throw new HttpException('权限字符串已存在', 400);
+		}
+		const parent = await DatabaseRepository.AppPermissionRepository.findOneBy({
+			id: permission.pid,
+		});
+		if (!parent && permission.pid !== 0) {
+			throw new HttpException('父级权限不存在', 400);
+		}
+		return await DatabaseRepository.AppPermissionRepository.save({
+			...new AppPermission(),
+			...permission,
+		});
+	}
+	/** 修改app权限 */
+	export async function editPermission(
+		permission: Pick<AppPermission, 'id' | 'permissionName' | 'permissionKey' | 'pid'>
+	) {
+		const permissionEntity = await DatabaseRepository.AppPermissionRepository.findOne({
+			where: { id: permission.id },
+		});
+		if (!permissionEntity) {
+			throw new HttpException('权限不存在', 400);
+		}
+		const editAfterPermission = await DatabaseRepository.AppPermissionRepository.save({
+			...permissionEntity,
+			...permission,
+		});
+		return editAfterPermission;
+	}
+	/** 删除app权限 */
+	export async function deletePermission(params: Pick<AppPermission, 'id'>) {
+		const permissionEntity = await DatabaseRepository.AppPermissionRepository.findOne({
+			where: { id: params.id },
+		});
+		if (!permissionEntity) {
+			throw new HttpException('权限不存在', 400);
+		}
+		const deleteAfterPermission = await DatabaseRepository.AppPermissionRepository.softRemove(
+			permissionEntity
+		);
+		return deleteAfterPermission;
+	}
+	/** 查询app权限树 */
+	export async function getPermissionTree(pid: number) {
+		const permissionList = await DatabaseRepository.AppPermissionRepository.find({
+			where: { pid },
+		});
+		for (const item of permissionList) {
+			Reflect.set(item, 'children', await getPermissionTree(item.id));
+		}
+		return permissionList;
+	}
+}

+ 100 - 0
src/services/modules/user.ts

@@ -0,0 +1,100 @@
+import { DatabaseRepository } from '@/database';
+import { User } from '@/database/entities';
+import { HttpException } from '@nestjs/common';
+
+/** 用户服务 */
+export namespace UserService {
+	/** 新增用户参数类型 */
+	type AddUserParams = Pick<User, 'username' | 'password'> & Partial<Pick<User, 'email' | 'phone'>>;
+	/** 新增用户 */
+	export async function addUser(params: AddUserParams) {
+		const oldUser = await DatabaseRepository.UsersRepository.findOne({
+			where: { username: params.username },
+		});
+		if (oldUser) {
+			throw new HttpException('用户已存在', 400);
+		} else {
+			const newUser = { ...new User(), ...params };
+			const user = await DatabaseRepository.UsersRepository.save(newUser);
+			Reflect.deleteProperty(user, 'password');
+			return user;
+		}
+	}
+
+	/** 修改用户参数类型 */
+	type EditUserParams = Pick<User, 'id'> &
+		Partial<Pick<User, 'username' | 'password' | 'email' | 'phone'>>;
+	/** 修改用户 */
+	export async function editUser(params: EditUserParams) {
+		const user = await DatabaseRepository.UsersRepository.findOne({ where: { id: params.id } });
+		if (!user) {
+			throw new HttpException('用户不存在', 400);
+		}
+		const res = await DatabaseRepository.UsersRepository.save({ ...user, ...params });
+		return res;
+	}
+
+	/** 删除用户 */
+	export async function deleteUser(params: Pick<User, 'id'>) {
+		const user = await DatabaseRepository.UsersRepository.findOne({ where: { id: params.id } });
+		if (!user) {
+			throw new HttpException('用户不存在', 400);
+		}
+		const res = await DatabaseRepository.UsersRepository.softRemove(user);
+		return res;
+	}
+
+	/** 批量删除用户 */
+	export async function deleteUsers(params: Pick<User, 'id'>[] = []) {
+		const res = await DatabaseRepository.UsersRepository.softRemove(params);
+		return res;
+	}
+
+	/** 恢复用户 */
+	export async function restoreUser(params: Pick<User, 'id'>) {
+		const user = await DatabaseRepository.UsersRepository.findOne({
+			where: { id: params.id },
+			withDeleted: true,
+		});
+		if (!user) {
+			throw new HttpException('用户不存在', 400);
+		}
+		const res = await DatabaseRepository.UsersRepository.recover(user);
+		return res;
+	}
+
+	/** 批量恢复用户 */
+	export async function restoreUsers(params: Pick<User, 'id'>[] = []) {
+		const res = await DatabaseRepository.UsersRepository.recover(params);
+		return res;
+	}
+
+	/** 根据ID获取用户信息 */
+	export async function getUserInfoByID(params: Pick<User, 'id'>, isDetail = false) {
+		const user = await DatabaseRepository.UsersRepository.findOne({
+			where: { id: params.id },
+			relations: isDetail ? ['roles'] : [],
+		});
+		if (!user) {
+			throw new HttpException('用户不存在', 400);
+		} else {
+			return user;
+		}
+	}
+
+	/** 根据用户密码获取用户信息 */
+	export async function getUserInfoByPassword(params: Pick<User, 'username' | 'password'>) {
+		const user = await DatabaseRepository.UsersRepository.findOne({
+			where: {
+				username: params.username,
+				password: params.password,
+			},
+			relations: ['roles'],
+		});
+		if (!user) {
+			throw new HttpException('用户名密码错误', 400);
+		} else {
+			return user;
+		}
+	}
+}

+ 8 - 0
tsconfig.build.json

@@ -0,0 +1,8 @@
+{
+	"extends": "./tsconfig.json",
+	"exclude": ["node_modules", "test", "dist", "**/*spec.ts"],
+	"compilerOptions": {
+		"sourceMap": false,
+		"declaration": false
+	}
+}

+ 20 - 0
tsconfig.json

@@ -0,0 +1,20 @@
+{
+	"compilerOptions": {
+		"baseUrl": "./",
+		"rootDir": "./src",
+		"outDir": "./dist",
+		"paths": {
+			"@/*": ["src/*"]
+		},
+		"module": "commonjs",
+		"removeComments": true,
+		"emitDecoratorMetadata": true,
+		"experimentalDecorators": true,
+		"allowSyntheticDefaultImports": true,
+		"target": "esnext",
+		"sourceMap": false, //生成suorceMap
+		"declaration": false, //生成声明文件
+		"incremental": true, //增量编译,生成tsbuildinfo,加快第二次编译速度
+		"esModuleInterop": true
+	}
+}