chore: replace redis with ioredis

This commit is contained in:
Innei
2021-08-31 20:12:30 +08:00
parent 44b835d177
commit f3fb7ecb26
16 changed files with 139 additions and 6931 deletions

View File

@@ -11,5 +11,8 @@
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
}

View File

@@ -1,5 +1,11 @@
# MX server next generation
2021-08-31
开始写了
---
NestJS 8 发布了, 打算找个时间重构一下现有的后端.
但是最近在实习, 真的没有时间啊, 烦.

1
global.d.ts vendored
View File

@@ -1,4 +1,5 @@
declare global {
export type KV<T = any> = Record<string, T>
}
export {}

View File

@@ -52,7 +52,7 @@
"argv": "^0.0.2",
"bcrypt": "^5.0.1",
"cache-manager": "3.4.4",
"cache-manager-redis-store": "2.0.0",
"cache-manager-ioredis": "^2.1.0",
"chalk": "^4.1.2",
"class-transformer": "^0.4.0",
"class-validator": "^0.13.1",
@@ -77,22 +77,26 @@
"@nestjs/cli": "^8.1.1",
"@nestjs/schematics": "^8.0.2",
"@nestjs/testing": "^8.0.6",
"@types/cache-manager": "^3.4.2",
"@types/ioredis": "^4.27.1",
"@types/jest": "^27.0.1",
"@types/lodash": "^4.14.172",
"@types/node": "^16.7.1",
"@types/passport-jwt": "^3.0.6",
"@types/passport-local": "^1.0.34",
"@types/redis": "2.8.31",
"@types/socket.io": "3.0.2",
"@types/supertest": "^2.0.11",
"cross-env": "^7.0.3",
"eslint": "^7.32.0",
"fastify": "*",
"husky": "^7.0.1",
"ioredis": "*",
"jest": "27.1.0",
"lint-staged": "^11.1.2",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"run-script-webpack-plugin": "^0.0.11",
"socket.io": "*",
"supertest": "^6.1.6",
"ts-jest": "^27.0.5",
"ts-loader": "^9.2.5",

156
pnpm-lock.yaml generated
View File

@@ -18,26 +18,29 @@ specifiers:
'@typegoose/auto-increment': ^0.9.0
'@typegoose/typegoose': 8.2.0
'@types/bcrypt': ^5.0.0
'@types/cache-manager': ^3.4.2
'@types/ioredis': ^4.27.1
'@types/jest': ^27.0.1
'@types/lodash': ^4.14.172
'@types/node': ^16.7.1
'@types/passport-jwt': ^3.0.6
'@types/passport-local': ^1.0.34
'@types/redis': 2.8.31
'@types/socket.io': 3.0.2
'@types/supertest': ^2.0.11
argv: ^0.0.2
bcrypt: ^5.0.1
cache-manager: 3.4.4
cache-manager-redis-store: 2.0.0
cache-manager-ioredis: ^2.1.0
chalk: ^4.1.2
class-transformer: ^0.4.0
class-validator: ^0.13.1
cross-env: ^7.0.3
dayjs: ^1.10.6
eslint: ^7.32.0
fastify: '*'
fastify-swagger: ^4.9.0
husky: ^7.0.1
ioredis: '*'
jest: 27.1.0
lint-staged: ^11.1.2
lodash: ^4.17.21
@@ -55,6 +58,7 @@ specifiers:
run-script-webpack-plugin: ^0.0.11
rxjs: ^7.3.0
snakecase-keys: ^4.0.2
socket.io: '*'
supertest: ^6.1.6
ts-jest: ^27.0.5
ts-loader: ^9.2.5
@@ -80,7 +84,7 @@ dependencies:
argv: 0.0.2
bcrypt: 5.0.1
cache-manager: 3.4.4
cache-manager-redis-store: 2.0.0
cache-manager-ioredis: 2.1.0
chalk: 4.1.2
class-transformer: 0.4.0
class-validator: 0.13.1
@@ -105,22 +109,26 @@ devDependencies:
'@nestjs/cli': 8.1.1
'@nestjs/schematics': 8.0.3_typescript@4.4.2
'@nestjs/testing': 8.0.6_67f7e5db8827badcb202b1d38f6b1aea
'@types/cache-manager': 3.4.2
'@types/ioredis': 4.27.1
'@types/jest': 27.0.1
'@types/lodash': 4.14.172
'@types/node': 16.7.8
'@types/passport-jwt': 3.0.6
'@types/passport-local': 1.0.34
'@types/redis': 2.8.31
'@types/socket.io': 3.0.2
'@types/supertest': 2.0.11
cross-env: 7.0.3
eslint: 7.32.0
fastify: 3.20.1
husky: 7.0.2
ioredis: 4.27.9
jest: 27.1.0_ts-node@10.2.1
lint-staged: 11.1.2
prettier: 2.3.2
rimraf: 3.0.2
run-script-webpack-plugin: 0.0.11
socket.io: 4.1.3
supertest: 6.1.6
ts-jest: 27.0.5_d6279bcaf6e2c6aa91a58343d133ee67
ts-loader: 9.2.5_typescript@4.4.2+webpack@5.51.1
@@ -567,7 +575,6 @@ packages:
resolution: {integrity: sha512-gvCOUNpXsWrIQ3A4aXCLIdblL0tDq42BG/2Xw7oxbil9h11uow10ztS2GuFazNBfjbrsZ5nl+nPl5jDSjj5TSg==}
dependencies:
ajv: 6.12.6
dev: false
/@humanwhocodes/config-array/0.5.0:
resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==}
@@ -1243,6 +1250,10 @@ packages:
'@types/node': 16.7.8
dev: false
/@types/cache-manager/3.4.2:
resolution: {integrity: sha512-1IwA74t5ID4KWo0Kndal16MhiPSZgMe1fGc+MLT6j5r+Ab7jku36PFTl4PP6MiWw0BJscM9QpZEo00qixNQoRg==}
dev: true
/@types/component-emitter/1.2.10:
resolution: {integrity: sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==}
@@ -1303,6 +1314,12 @@ packages:
'@types/node': 16.7.8
dev: true
/@types/ioredis/4.27.1:
resolution: {integrity: sha512-+JichYPCtVapxi5Z+7V/8Uhn+4Piz+rkb03JQTQ0kW0pkV71+bmzSTkpwmIqa7FfWIszp0VbRyN8gfgWDNQMdA==}
dependencies:
'@types/node': 16.7.8
dev: true
/@types/istanbul-lib-coverage/2.0.3:
resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==}
dev: true
@@ -1422,17 +1439,6 @@ packages:
'@types/node': 16.7.8
dev: true
/@types/socket.io/3.0.2:
resolution: {integrity: sha512-pu0sN9m5VjCxBZVK8hW37ZcMe8rjn4HHggBN5CbaRTvFwv5jOmuIRZEuddsBPa9Th0ts0SIo3Niukq+95cMBbQ==}
deprecated: This is a stub types definition. socket.io provides its own type definitions, so you do not need this installed.
dependencies:
socket.io: 4.2.0
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
dev: true
/@types/stack-utils/2.0.1:
resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
dev: true
@@ -1693,7 +1699,6 @@ packages:
/abstract-logging/2.0.1:
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
dev: false
/accepts/1.3.7:
resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==}
@@ -1883,7 +1888,6 @@ packages:
/archy/1.0.0:
resolution: {integrity: sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=}
dev: false
/are-we-there-yet/1.1.5:
resolution: {integrity: sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==}
@@ -1945,7 +1949,6 @@ packages:
/atomic-sleep/1.0.0:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'}
dev: false
/author-regex/1.0.0:
resolution: {integrity: sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=}
@@ -1961,7 +1964,6 @@ packages:
queue-microtask: 1.2.3
transitivePeerDependencies:
- supports-color
dev: false
/axios/0.21.1:
resolution: {integrity: sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==}
@@ -2156,11 +2158,13 @@ packages:
ieee754: 1.2.1
dev: true
/cache-manager-redis-store/2.0.0:
resolution: {integrity: sha512-bWLWlUg6nCYHiJLCCYxY2MgvwvKnvlWwrbuynrzpjEIhfArD2GC9LtutIHFEPeyGVQN6C+WEw+P3r+BFBwhswg==}
engines: {node: '>= 8.3'}
/cache-manager-ioredis/2.1.0:
resolution: {integrity: sha512-TCxbp9ceuFveTKWuNaCX8QjoC41rAlHen4s63u9Yd+iXlw3efYmimc/u935PKPxSdhkXpnMes4mxtK3/yb0L4g==}
engines: {node: '>=6.0.0'}
dependencies:
redis: 3.1.2
ioredis: 4.27.9
transitivePeerDependencies:
- supports-color
dev: false
/cache-manager/3.4.4:
@@ -2327,6 +2331,10 @@ packages:
engines: {node: '>=0.8'}
dev: true
/cluster-key-slot/1.1.0:
resolution: {integrity: sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==}
engines: {node: '>=0.10.0'}
/co/4.6.0:
resolution: {integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
@@ -2572,7 +2580,6 @@ packages:
/denque/1.5.1:
resolution: {integrity: sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==}
engines: {node: '>=0.10'}
dev: false
/depd/1.1.2:
resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=}
@@ -2701,24 +2708,6 @@ packages:
- bufferutil
- supports-color
- utf-8-validate
dev: false
/engine.io/5.2.0:
resolution: {integrity: sha512-d1DexkQx87IFr1FLuV+0f5kAm1Hk1uOVijLOb+D1sDO2QMb7YjE02VHtZtxo7xIXMgcWLb+vl3HRT0rI9tr4jQ==}
engines: {node: '>=10.0.0'}
dependencies:
accepts: 1.3.7
base64id: 2.0.0
cookie: 0.4.1
cors: 2.8.5
debug: 4.3.2
engine.io-parser: 4.0.3
ws: 7.4.6
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
dev: true
/enhanced-resolve/5.8.2:
resolution: {integrity: sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==}
@@ -3019,7 +3008,6 @@ packages:
/fast-decode-uri-component/1.0.1:
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
dev: false
/fast-deep-equal/3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -3046,7 +3034,6 @@ packages:
deepmerge: 4.2.2
rfdc: 1.3.0
string-similarity: 4.0.4
dev: false
/fast-levenshtein/2.0.6:
resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=}
@@ -3055,7 +3042,6 @@ packages:
/fast-redact/3.0.2:
resolution: {integrity: sha512-YN+CYfCVRVMUZOUPeinHNKgytM1wPI/C/UCLEi56EsY2dwwvI00kIJHJoI7pMVqGoMew8SMZ2SSfHKHULHXDsg==}
engines: {node: '>=6'}
dev: false
/fast-safe-stringify/2.0.8:
resolution: {integrity: sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==}
@@ -3069,7 +3055,6 @@ packages:
/fastify-error/0.3.1:
resolution: {integrity: sha512-oCfpcsDndgnDVgiI7bwFKAun2dO+4h84vBlkWsWnz/OUK9Reff5UFoFl241xTiLeHWX/vU9zkDVXqYUxjOwHcQ==}
dev: false
/fastify-formbody/5.1.0:
resolution: {integrity: sha512-dLFQ8gMQeLuV45J72svDbrp6CZ3hxsaiK2dd3vzoiCs9wEmCSbbJV+/afQl1cfvf19+NfCIzYVQIg1r4yO4Epw==}
@@ -3106,7 +3091,6 @@ packages:
/fastify-warning/0.2.0:
resolution: {integrity: sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw==}
dev: false
/fastify/3.20.1:
resolution: {integrity: sha512-AzIpPuHdPaRBMWCg+LbnfGvhmBVpF1tRihGOfpxnUphL1eh8ZrN1GbY3cXY07yn4fUNzYsByTkc9/IjwXH7DAQ==}
@@ -3129,7 +3113,6 @@ packages:
tiny-lru: 7.0.6
transitivePeerDependencies:
- supports-color
dev: false
/fastq/1.12.0:
resolution: {integrity: sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==}
@@ -3171,7 +3154,6 @@ packages:
fast-deep-equal: 3.1.3
safe-regex2: 2.0.0
semver-store: 0.3.0
dev: false
/find-up/4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
@@ -3191,7 +3173,6 @@ packages:
/flatstr/1.0.12:
resolution: {integrity: sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==}
dev: false
/flatted/3.2.2:
resolution: {integrity: sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==}
@@ -3242,7 +3223,6 @@ packages:
/forwarded/0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
dev: false
/fresh/0.5.2:
resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=}
@@ -3598,10 +3578,27 @@ packages:
engines: {node: '>= 0.10'}
dev: true
/ioredis/4.27.9:
resolution: {integrity: sha512-hAwrx9F+OQ0uIvaJefuS3UTqW+ByOLyLIV+j0EH8ClNVxvFyH9Vmb08hCL4yje6mDYT5zMquShhypkd50RRzkg==}
engines: {node: '>=6'}
dependencies:
cluster-key-slot: 1.1.0
debug: 4.3.2
denque: 1.5.1
lodash.defaults: 4.2.0
lodash.flatten: 4.4.0
lodash.isarguments: 3.1.0
p-map: 2.1.0
redis-commands: 1.7.0
redis-errors: 1.2.0
redis-parser: 3.0.0
standard-as-callback: 2.1.0
transitivePeerDependencies:
- supports-color
/ipaddr.js/1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
dev: false
/is-arrayish/0.2.1:
resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
@@ -4491,7 +4488,6 @@ packages:
fastify-warning: 0.2.0
readable-stream: 3.6.0
set-cookie-parser: 2.4.8
dev: false
/lines-and-columns/1.1.6:
resolution: {integrity: sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=}
@@ -4551,6 +4547,12 @@ packages:
resolution: {integrity: sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=}
dev: true
/lodash.defaults/4.2.0:
resolution: {integrity: sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=}
/lodash.flatten/4.4.0:
resolution: {integrity: sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=}
/lodash.get/4.4.2:
resolution: {integrity: sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=}
dev: false
@@ -4563,6 +4565,9 @@ packages:
resolution: {integrity: sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=}
dev: false
/lodash.isarguments/3.1.0:
resolution: {integrity: sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=}
/lodash.isboolean/3.0.3:
resolution: {integrity: sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=}
dev: false
@@ -5150,6 +5155,10 @@ packages:
p-limit: 2.3.0
dev: true
/p-map/2.1.0:
resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
engines: {node: '>=6'}
/p-map/4.0.0:
resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
engines: {node: '>=10'}
@@ -5259,7 +5268,6 @@ packages:
/pino-std-serializers/3.2.0:
resolution: {integrity: sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==}
dev: false
/pino/6.13.1:
resolution: {integrity: sha512-QQf67BU+cANnc/2U+wzUV20UjO5oBryWpnNyKshdLfT9BdeiXlh9wxLGmOjAuBWMYITdMs+BtJSQQNlGRNbWpA==}
@@ -5272,7 +5280,6 @@ packages:
pino-std-serializers: 3.2.0
quick-format-unescaped: 4.0.3
sonic-boom: 1.4.1
dev: false
/pirates/4.0.1:
resolution: {integrity: sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==}
@@ -5372,7 +5379,6 @@ packages:
dependencies:
forwarded: 0.2.0
ipaddr.js: 1.9.1
dev: false
/psl/1.8.0:
resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==}
@@ -5401,7 +5407,6 @@ packages:
/quick-format-unescaped/4.0.3:
resolution: {integrity: sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg==}
dev: false
/randombytes/2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
@@ -5454,19 +5459,16 @@ packages:
/redis-commands/1.7.0:
resolution: {integrity: sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==}
dev: false
/redis-errors/1.2.0:
resolution: {integrity: sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=}
engines: {node: '>=4'}
dev: false
/redis-parser/3.0.0:
resolution: {integrity: sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=}
engines: {node: '>=4'}
dependencies:
redis-errors: 1.2.0
dev: false
/redis/3.1.2:
resolution: {integrity: sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==}
@@ -5536,7 +5538,6 @@ packages:
/ret/0.2.2:
resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==}
engines: {node: '>=4'}
dev: false
/reusify/1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
@@ -5544,7 +5545,6 @@ packages:
/rfdc/1.3.0:
resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==}
dev: false
/rimraf/3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
@@ -5591,7 +5591,6 @@ packages:
resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==}
dependencies:
ret: 0.2.2
dev: false
/safer-buffer/2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
@@ -5632,7 +5631,6 @@ packages:
/secure-json-parse/2.4.0:
resolution: {integrity: sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==}
dev: false
/semver-compare/1.0.0:
resolution: {integrity: sha1-De4hahyUGrN+nvsXiPavxf9VN/w=}
@@ -5640,7 +5638,6 @@ packages:
/semver-store/0.3.0:
resolution: {integrity: sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg==}
dev: false
/semver/5.7.1:
resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
@@ -5689,7 +5686,6 @@ packages:
/set-cookie-parser/2.4.8:
resolution: {integrity: sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==}
dev: false
/setprototypeof/1.1.1:
resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==}
@@ -5807,33 +5803,12 @@ packages:
- bufferutil
- supports-color
- utf-8-validate
dev: false
/socket.io/4.2.0:
resolution: {integrity: sha512-sjlGfMmnaWvTRVxGRGWyhd9ctpg4APxWAxu85O/SxekkxHhfxmePWZbaYCkeX5QQX0z1YEnKOlNt6w82E4Nzug==}
engines: {node: '>=10.0.0'}
dependencies:
'@types/cookie': 0.4.1
'@types/cors': 2.8.12
'@types/node': 16.7.8
accepts: 1.3.7
base64id: 2.0.0
debug: 4.3.2
engine.io: 5.2.0
socket.io-adapter: 2.3.2
socket.io-parser: 4.0.4
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
dev: true
/sonic-boom/1.4.1:
resolution: {integrity: sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==}
dependencies:
atomic-sleep: 1.0.0
flatstr: 1.0.12
dev: false
/sort-object-keys/1.1.3:
resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==}
@@ -5891,6 +5866,9 @@ packages:
escape-string-regexp: 2.0.0
dev: true
/standard-as-callback/2.1.0:
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
/statuses/1.5.0:
resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=}
engines: {node: '>= 0.6'}
@@ -5911,7 +5889,6 @@ packages:
/string-similarity/4.0.4:
resolution: {integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==}
dev: false
/string-width/1.0.2:
resolution: {integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=}
@@ -6186,7 +6163,6 @@ packages:
/tiny-lru/7.0.6:
resolution: {integrity: sha512-zNYO0Kvgn5rXzWpL0y3RS09sMK67eGaQj9805jlK9G6pSadfriTczzLHFXa/xcW4mIRfmlB9HyQ/+SgL0V1uow==}
engines: {node: '>=6'}
dev: false
/tmp/0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}

View File

@@ -1,5 +1,4 @@
import {
CacheInterceptor,
MiddlewareConsumer,
Module,
NestModule,
@@ -60,8 +59,8 @@ export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(AnalyzeMiddleware)
.forRoutes({ path: '*', method: RequestMethod.GET })
.forRoutes({ path: '(.*?)', method: RequestMethod.GET })
.apply(SkipBrowserDefaultRequestMiddleware, SecurityMiddleware)
.forRoutes({ path: '*', method: RequestMethod.ALL })
.forRoutes({ path: '(.*?)', method: RequestMethod.ALL })
}
}

View File

@@ -7,11 +7,11 @@ import {
Logger,
} from '@nestjs/common'
import { FastifyReply, FastifyRequest } from 'fastify'
import { writeFileSync } from 'fs'
import { resolve } from 'path'
import { LOGGER_DIR } from '~/constants/path.constant'
import { isDev } from '~/utils/index.util'
import { getIp } from '../../utils/ip.util'
import { writeFileSync } from 'fs'
import { LOGGER_DIR } from '~/constants/path.constant'
import { resolve } from 'path'
type myError = {
readonly status: number
readonly statusCode?: number

View File

@@ -1,4 +1,4 @@
export enum RedisNames {
export enum RedisKeys {
Access = 'access',
Like = 'like',
Read = 'read',

View File

@@ -1,17 +1,17 @@
import { Logger } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { NestFastifyApplication } from '@nestjs/platform-fastify'
import { fastifyApp } from './common/adapt/fastify'
import { isDev } from './utils/index.util'
import { CacheInterceptor, Logger } from '@nestjs/common'
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
import { CROSS_DOMAIN } from './app.config'
import { AppModule } from './app.module'
import { fastifyApp } from './common/adapt/fastify'
import { SpiderGuard } from './common/guard/spider.guard'
import { LoggingInterceptor } from './common/interceptors/logging.interceptor'
import {
JSONSerializeInterceptor,
ResponseInterceptor,
} from './common/interceptors/response.interceptors'
import { SpiderGuard } from './common/guard/spider.guard'
import { LoggingInterceptor } from './common/interceptors/logging.interceptor'
import { isDev } from './utils/index.util'
// const PORT = parseInt(process.env.PORT) || 2333
const PORT = 2333
const APIVersion = 1

View File

@@ -9,17 +9,18 @@ import {
SerializeOptions,
UseGuards,
} from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'
import { HttpCache } from '~/common/decorator/cache.decorator'
import { CurrentUser } from '~/common/decorator/current-user.decorator'
import { IpLocation, IpRecord } from '~/common/decorator/ip.decorator'
import { IsMaster } from '~/common/decorator/role.decorator'
import { getAvatar } from '~/utils/index.util'
import { AuthService } from '../auth/auth.service'
import { RolesGuard } from '../auth/roles.guard'
import { LoginDto, UserDto, UserPatchDto } from './dto/user.dto'
import { UserDocument, UserModel } from './user.model'
import { UserService } from './user.service'
import { IsMaster } from '~/common/decorator/role.decorator'
import { AuthGuard } from '@nestjs/passport'
import { getAvatar } from '~/utils/index.util'
import { LoginDto, UserDto, UserPatchDto } from './dto/user.dto'
@ApiTags('User Routes')
@Controller(['master', 'user'])
@@ -50,6 +51,7 @@ export class UserController {
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '登录' })
@UseGuards(AuthGuard('local'))
@HttpCache({ disable: true })
async login(
@Body() dto: LoginDto,
@CurrentUser() user: UserDocument,
@@ -76,14 +78,16 @@ export class UserController {
@ApiOperation({ summary: '判断当前 Token 是否有效 ' })
@ApiBearerAuth()
@UseGuards(RolesGuard)
@HttpCache({ disable: true })
checkLogged(@IsMaster() isMaster: boolean) {
return { ok: Number(isMaster), isGuest: !isMaster }
return { ok: +isMaster, isGuest: !isMaster }
}
@Patch()
@ApiOperation({ summary: '修改主人的信息 ' })
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'))
@HttpCache({ disable: true })
async patchMasterData(
@Body() body: UserPatchDto,
@CurrentUser() user: UserDocument,

View File

@@ -6,9 +6,13 @@ import {
} from '@nestjs/common'
import { ReturnModelType } from '@typegoose/typegoose'
import { compareSync } from 'bcrypt'
import dayjs from 'dayjs'
import { nanoid } from 'nanoid'
import { InjectModel } from 'nestjs-typegoose'
import { RedisKeys } from '~/constants/cache.constant'
import { CacheService } from '~/processors/cache/cache.service'
import { getAvatar } from '~/utils/index.util'
import { getRedisKey } from '~/utils/redis.util'
import { AuthService } from '../auth/auth.service'
import { UserDocument, UserModel } from './user.model'
@@ -19,6 +23,7 @@ export class UserService {
@InjectModel(UserModel)
private readonly userModel: ReturnModelType<typeof UserModel>,
private readonly authService: AuthService,
private readonly redis: CacheService,
) {}
async getMasterInfo(getLoginIp = false) {
@@ -100,30 +105,19 @@ export class UserService {
lastLoginIp: ip,
})
// save to redis
new Promise(async (resolve) => {
// const redisClient = this.redisService.getClient(RedisNames.LoginRecord)
// const dateFormat = dayjs().format('YYYY-MM-DD')
// const value = JSON.parse(
// (await redisClient.get(dateFormat)) || '[]',
// ) as LoginRecord[]
// const stringify = fastJson({
// title: 'login-record schema',
// type: 'array',
// items: {
// type: 'object',
// properties: {
// ip: { type: 'string' },
// date: { type: 'string' },
// },
// },
// })
// await redisClient.set(
// dateFormat,
// stringify(value.concat({ date: new Date().toISOString(), ip })),
// )
// resolve(null)
process.nextTick(async () => {
const redisClient = this.redis.getClient()
const dateFormat = dayjs().format('YYYY-MM-DD')
await redisClient.sadd(
getRedisKey(RedisKeys.LoginRecord, dateFormat),
JSON.stringify({ date: new Date().toISOString(), ip }),
)
})
this.Logger.warn('主人已登录, IP: ' + ip)
return PrevFootstep
}
// TODO 获取最近登陆次数 时间 从 Redis 取
}

View File

@@ -10,7 +10,8 @@ import {
CacheOptionsFactory,
Injectable,
} from '@nestjs/common'
import redisStore from 'cache-manager-redis-store'
// import redisStore from 'cache-manager-redis-store'
import redisStore from 'cache-manager-ioredis'
import { ClientOpts } from 'redis'
import { REDIS } from '~/app.config'

View File

@@ -1,104 +1,39 @@
/**
* Cache service.
* @file Cache 缓存模块服务
* @module processor/cache/service
* @author Surmon <https://github.com/surmon-china>
*/
import { CACHE_MANAGER, Inject, Injectable, Logger } from '@nestjs/common'
import { RedisClient } from 'redis'
import { Cache } from 'cache-manager'
import { Redis } from 'ioredis'
// Cache 客户端管理器
export interface ICacheManager {
store: {
getClient(): RedisClient
}
get(key: TCacheKey): any
set(key: TCacheKey, value: string, options?: { ttl: number }): any
}
// 获取器
export type TCacheKey = string
export type TCacheResult<T> = Promise<T>
// IO 模式通用返回结构
export interface ICacheIoResult<T> {
get(): TCacheResult<T>
update(): TCacheResult<T>
}
// Promise 模式参数
export interface ICachePromiseOption<T> {
key: TCacheKey
promise(): TCacheResult<T>
}
// Promise & IO 模式参数
export interface ICachePromiseIoOption<T> extends ICachePromiseOption<T> {
ioMode?: boolean
}
// Interval & Timeout 超时模式参数(毫秒)
export interface ICacheIntervalTimeoutOption {
error?: number
success?: number
}
// Interval & Timing 定时模式参数(毫秒)
export interface ICacheIntervalTimingOption {
error: number
schedule: any
}
// Interval 模式参数
export interface ICacheIntervalOption<T> {
key: TCacheKey
promise(): TCacheResult<T>
timeout?: ICacheIntervalTimeoutOption
timing?: ICacheIntervalTimingOption
}
// Interval 模式返回类型
export type TCacheIntervalResult<T> = () => TCacheResult<T>
// Interval & IO 模式参数
export interface ICacheIntervalIOOption<T> extends ICacheIntervalOption<T> {
ioMode?: boolean
}
/**
* @class CacheService
* @classdesc 承载缓存服务
* @example CacheService.get(CacheKey).then()
* @example CacheService.set(CacheKey).then()
* @example CacheService.promise({ option })()
* @example CacheService.interval({ option })()
*/
@Injectable()
export class CacheService {
private cache!: ICacheManager
private cache!: Cache
private logger = new Logger(CacheService.name)
constructor(@Inject(CACHE_MANAGER) cache: ICacheManager) {
constructor(@Inject(CACHE_MANAGER) cache: Cache) {
console.log(cache)
this.cache = cache
this.redisClient.on('ready', () => {
this.logger.log('Redis 已准备好!')
})
}
private get redisClient(): RedisClient {
private get redisClient(): Redis {
// @ts-expect-error
return this.cache.store.getClient()
}
// 客户端是否可用
private get checkCacheServiceAvailable(): boolean {
return this.redisClient.connected
}
public get<T>(key: TCacheKey): TCacheResult<T> {
if (!this.checkCacheServiceAvailable) {
return Promise.reject('缓存客户端没准备好!')
}
return this.cache.get(key)
}
@@ -107,51 +42,10 @@ export class CacheService {
value: any,
options?: { ttl: number },
): TCacheResult<T> {
if (!this.checkCacheServiceAvailable) {
return Promise.reject('缓存客户端没准备好!')
}
return this.cache.set(key, value, options)
}
public getClient() {
if (!this.checkCacheServiceAvailable) {
throw '缓存客户端没准备好!'
}
return this.cache
}
/**
* @function promise
* @description 被动更新 | 双向同步 模式Promise -> Redis
* @example CacheService.promise({ key: CacheKey, promise() }) -> promise()
* @example CacheService.promise({ key: CacheKey, promise(), ioMode: true }) -> { get: promise(), update: promise() }
*/
promise<T>(options: ICachePromiseOption<T>): TCacheResult<T>
promise<T>(options: ICachePromiseIoOption<T>): ICacheIoResult<T>
promise(options) {
const { key, promise, ioMode = false } = options
// 包装任务
const doPromiseTask = () => {
return promise().then((data) => {
this.set(key, data)
return data
})
}
// Promise 拦截模式(返回死数据)
const handlePromiseMode = () => {
return this.get(key).then((value) => {
return value !== null && value !== undefined ? value : doPromiseTask()
})
}
// 双向同步模式(返回获取器和更新器)
const handleIoMode = () => ({
get: handlePromiseMode,
update: doPromiseTask,
})
return ioMode ? handleIoMode() : handlePromiseMode()
return this.redisClient
}
}

View File

@@ -7,9 +7,8 @@
* @Coding with Love
*/
import { FastifyRequest } from 'fastify'
import type { FastifyRequest } from 'fastify'
import { IncomingMessage } from 'http'
export const getIp = (request: FastifyRequest | IncomingMessage) => {
const _ = request as any

7
src/utils/redis.util.ts Normal file
View File

@@ -0,0 +1,7 @@
import { RedisKeys } from '~/constants/cache.constant'
export const getRedisKey = (key: RedisKeys, ...concatKeys: string[]) => {
return `mx:${key}${
concatKeys && concatKeys.length ? '_' + concatKeys.join('_') : ''
}`
}

6680
yarn.lock

File diff suppressed because it is too large Load Diff