chore: qaq
This commit is contained in:
4
global.d.ts
vendored
Normal file
4
global.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
declare global {
|
||||
export type KV<T = any> = Record<string, T>
|
||||
}
|
||||
export {}
|
||||
24
jest.config.js
Normal file
24
jest.config.js
Normal file
@@ -0,0 +1,24 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const { pathsToModuleNameMapper } = require('ts-jest/utils')
|
||||
// In the following statement, replace `./tsconfig` with the path to your `tsconfig` file
|
||||
// which contains the path mapping (ie the `compilerOptions.paths` option):
|
||||
const { compilerOptions } = require('./tsconfig.json')
|
||||
|
||||
module.exports = {
|
||||
moduleFileExtensions: ['js', 'json', 'ts'],
|
||||
rootDir: '.',
|
||||
testRegex: '.*\\.spec\\.ts$',
|
||||
transform: {
|
||||
'^.+\\.(t|j)s$': 'ts-jest',
|
||||
},
|
||||
collectCoverageFrom: ['**/*.(t|j)s'],
|
||||
coverageDirectory: '../coverage',
|
||||
testEnvironment: 'node',
|
||||
moduleNameMapper: {
|
||||
...pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/' }),
|
||||
'^src/(.*)$': '<rootDir>/src/$1',
|
||||
'^test/(.*)$': '<rootDir>/test/$1',
|
||||
src: '<rootDir>/src',
|
||||
'^test$': '<rootDir>/test',
|
||||
},
|
||||
}
|
||||
25
package.json
25
package.json
@@ -38,12 +38,15 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^8.0.4",
|
||||
"@nestjs/config": "^1.0.1",
|
||||
"@nestjs/core": "^8.0.4",
|
||||
"@nestjs/passport": "^8.0.0",
|
||||
"@nestjs/platform-fastify": "^8.0.4",
|
||||
"@nestjs/swagger": "^5.0.8",
|
||||
"@typegoose/auto-increment": "^0.6.0",
|
||||
"@typegoose/typegoose": "8.0.0",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"argv": "^0.0.2",
|
||||
"bcrypt": "^5.0.1",
|
||||
"chalk": "^4.1.1",
|
||||
"class-transformer": "^0.4.0",
|
||||
@@ -53,13 +56,15 @@
|
||||
"lint-staged": "^11.1.0",
|
||||
"mongoose": "^5.13.3",
|
||||
"mongoose-lean-virtuals": "^0.8.0",
|
||||
"nestjs-typegoose": "^7.1.38",
|
||||
"passport": "^0.4.1",
|
||||
"passport-jwt": "^4.0.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.2.0",
|
||||
"snakecase-keys": "^4.0.2"
|
||||
"snakecase-keys": "^4.0.2",
|
||||
"zx": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^8.0.2",
|
||||
@@ -72,7 +77,6 @@
|
||||
"@typescript-eslint/eslint-plugin": "4.28.4",
|
||||
"@typescript-eslint/parser": "4.28.4",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^10.0.0",
|
||||
"eslint": "^7.31.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
@@ -84,22 +88,5 @@
|
||||
"ts-node": "^10.1.0",
|
||||
"tsconfig-paths": "^3.10.1",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"json",
|
||||
"ts"
|
||||
],
|
||||
"rootDir": "src",
|
||||
"testRegex": ".*\\.spec\\.ts$",
|
||||
"transform": {
|
||||
"^.+\\.(t|j)s$": "ts-jest"
|
||||
},
|
||||
"collectCoverageFrom": [
|
||||
"**/*.(t|j)s"
|
||||
],
|
||||
"coverageDirectory": "../coverage",
|
||||
"testEnvironment": "node"
|
||||
}
|
||||
}
|
||||
132
pnpm-lock.yaml
generated
132
pnpm-lock.yaml
generated
@@ -3,7 +3,9 @@ lockfileVersion: 5.3
|
||||
specifiers:
|
||||
'@nestjs/cli': ^8.0.2
|
||||
'@nestjs/common': ^8.0.4
|
||||
'@nestjs/config': ^1.0.1
|
||||
'@nestjs/core': ^8.0.4
|
||||
'@nestjs/passport': ^8.0.0
|
||||
'@nestjs/platform-fastify': ^8.0.4
|
||||
'@nestjs/schematics': ^8.0.2
|
||||
'@nestjs/swagger': ^5.0.8
|
||||
@@ -17,12 +19,12 @@ specifiers:
|
||||
'@types/supertest': ^2.0.11
|
||||
'@typescript-eslint/eslint-plugin': 4.28.4
|
||||
'@typescript-eslint/parser': 4.28.4
|
||||
argv: ^0.0.2
|
||||
bcrypt: ^5.0.1
|
||||
chalk: ^4.1.1
|
||||
class-transformer: ^0.4.0
|
||||
class-validator: ^0.13.1
|
||||
cross-env: ^7.0.3
|
||||
dotenv: ^10.0.0
|
||||
eslint: ^7.31.0
|
||||
eslint-config-prettier: ^8.3.0
|
||||
eslint-plugin-prettier: ^3.4.0
|
||||
@@ -32,6 +34,7 @@ specifiers:
|
||||
lint-staged: ^11.1.0
|
||||
mongoose: ^5.13.3
|
||||
mongoose-lean-virtuals: ^0.8.0
|
||||
nestjs-typegoose: ^7.1.38
|
||||
passport: ^0.4.1
|
||||
passport-jwt: ^4.0.0
|
||||
passport-local: ^1.0.0
|
||||
@@ -46,15 +49,19 @@ specifiers:
|
||||
ts-node: ^10.1.0
|
||||
tsconfig-paths: ^3.10.1
|
||||
typescript: ^4.3.5
|
||||
zx: ^2.0.0
|
||||
|
||||
dependencies:
|
||||
'@nestjs/common': 8.0.4_e911b02ebc86a0e92191a7b133b2fcd0
|
||||
'@nestjs/config': 1.0.1_e4988ec8350f50541cb1b028c87076a8
|
||||
'@nestjs/core': 8.0.4_e4988ec8350f50541cb1b028c87076a8
|
||||
'@nestjs/passport': 8.0.0_8ffbbd1dfbd3e60a0a9ef125c15ec754
|
||||
'@nestjs/platform-fastify': 8.0.4_dbb23fa745e40b87eda38a58a66b6bd5
|
||||
'@nestjs/swagger': 5.0.8_00ec01bd1a1595869e3c10a21b92c5e7
|
||||
'@typegoose/auto-increment': 0.6.0_mongoose@5.13.3
|
||||
'@typegoose/typegoose': 8.0.0_mongoose@5.13.3
|
||||
'@types/bcrypt': 5.0.0
|
||||
argv: 0.0.2
|
||||
bcrypt: 5.0.1
|
||||
chalk: 4.1.1
|
||||
class-transformer: 0.4.0
|
||||
@@ -64,6 +71,7 @@ dependencies:
|
||||
lint-staged: 11.1.0
|
||||
mongoose: 5.13.3
|
||||
mongoose-lean-virtuals: 0.8.0_mongoose@5.13.3
|
||||
nestjs-typegoose: 7.1.38_ad6502a9e63d94834e95766efca460e3
|
||||
passport: 0.4.1
|
||||
passport-jwt: 4.0.0
|
||||
passport-local: 1.0.0
|
||||
@@ -71,6 +79,7 @@ dependencies:
|
||||
rimraf: 3.0.2
|
||||
rxjs: 7.2.0
|
||||
snakecase-keys: 4.0.2
|
||||
zx: 2.0.0
|
||||
|
||||
devDependencies:
|
||||
'@nestjs/cli': 8.0.2
|
||||
@@ -83,7 +92,6 @@ devDependencies:
|
||||
'@typescript-eslint/eslint-plugin': 4.28.4_b1648df9f9ba40bdeef3710a5a5af353
|
||||
'@typescript-eslint/parser': 4.28.4_eslint@7.31.0+typescript@4.3.5
|
||||
cross-env: 7.0.3
|
||||
dotenv: 10.0.0
|
||||
eslint: 7.31.0
|
||||
eslint-config-prettier: 8.3.0_eslint@7.31.0
|
||||
eslint-plugin-prettier: 3.4.0_19f511d6aa08b367b6cb59e8f50291ca
|
||||
@@ -829,6 +837,24 @@ packages:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/@nestjs/config/1.0.1_e4988ec8350f50541cb1b028c87076a8:
|
||||
resolution: {integrity: sha512-azMl4uYlFIhYsywFxPJT81RxF3Pnn0TZW3EEmr0Wa0Wex8R2xpvBNrCcrOgW3TB1xGMP7eqBrlfsVh5ZP82szg==}
|
||||
peerDependencies:
|
||||
'@nestjs/common': ^7.0.0 || ^8.0.0
|
||||
reflect-metadata: ^0.1.13
|
||||
rxjs: ^6.0.0 || ^7.2.0
|
||||
dependencies:
|
||||
'@nestjs/common': 8.0.4_e911b02ebc86a0e92191a7b133b2fcd0
|
||||
dotenv: 10.0.0
|
||||
dotenv-expand: 5.1.0
|
||||
lodash.get: 4.4.2
|
||||
lodash.has: 4.5.2
|
||||
lodash.set: 4.3.2
|
||||
reflect-metadata: 0.1.13
|
||||
rxjs: 7.2.0
|
||||
uuid: 8.3.2
|
||||
dev: false
|
||||
|
||||
/@nestjs/core/8.0.4_e4988ec8350f50541cb1b028c87076a8:
|
||||
resolution: {integrity: sha512-1clCaGtVZTE7/tEvVj1FLwgFTHIlaCvwfPSMgxhGalTrx+cM8MoqEGLWklqS5bS+YfQscI1+Gn3OLdWlRcGbRQ==}
|
||||
requiresBuild: true
|
||||
@@ -873,6 +899,16 @@ packages:
|
||||
reflect-metadata: 0.1.13
|
||||
dev: false
|
||||
|
||||
/@nestjs/passport/8.0.0_8ffbbd1dfbd3e60a0a9ef125c15ec754:
|
||||
resolution: {integrity: sha512-pIuOA+dEgOW0hg/qVV9uegitUHN1dKY8nEZhOtwj9FErJfCVZpQce8OH06n7yngqGTzvkkjjr/TzfuA1o8/A5A==}
|
||||
peerDependencies:
|
||||
'@nestjs/common': ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
passport: ^0.4.0
|
||||
dependencies:
|
||||
'@nestjs/common': 8.0.4_e911b02ebc86a0e92191a7b133b2fcd0
|
||||
passport: 0.4.1
|
||||
dev: false
|
||||
|
||||
/@nestjs/platform-fastify/8.0.4_dbb23fa745e40b87eda38a58a66b6bd5:
|
||||
resolution: {integrity: sha512-fseMiMf2eDYdREFRzZnVwIPrhvVHG42UnsX5FSqQlWfECe5NZ7ErOnKh537QgPS+VOQhuhsyiQkArPWrBDbNSg==}
|
||||
peerDependencies:
|
||||
@@ -1133,6 +1169,12 @@ packages:
|
||||
'@types/serve-static': 1.13.10
|
||||
dev: true
|
||||
|
||||
/@types/fs-extra/9.0.12:
|
||||
resolution: {integrity: sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==}
|
||||
dependencies:
|
||||
'@types/node': 16.4.8
|
||||
dev: false
|
||||
|
||||
/@types/graceful-fs/4.1.5:
|
||||
resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==}
|
||||
dependencies:
|
||||
@@ -1170,6 +1212,10 @@ packages:
|
||||
resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==}
|
||||
dev: true
|
||||
|
||||
/@types/minimist/1.2.2:
|
||||
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
|
||||
dev: false
|
||||
|
||||
/@types/mongodb/3.6.20:
|
||||
resolution: {integrity: sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==}
|
||||
dependencies:
|
||||
@@ -1177,6 +1223,13 @@ packages:
|
||||
'@types/node': 16.4.1
|
||||
dev: false
|
||||
|
||||
/@types/node-fetch/2.5.12:
|
||||
resolution: {integrity: sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==}
|
||||
dependencies:
|
||||
'@types/node': 16.4.8
|
||||
form-data: 3.0.1
|
||||
dev: false
|
||||
|
||||
/@types/node/15.14.2:
|
||||
resolution: {integrity: sha512-dvMUE/m2LbXPwlvVuzCyslTEtQ2ZwuuFClDrOQ6mp2CenCg971719PTILZ4I6bTP27xfFFc+o7x2TkLuun/MPw==}
|
||||
dev: false
|
||||
@@ -1193,6 +1246,10 @@ packages:
|
||||
resolution: {integrity: sha512-FKyawK3o5KL16AwbeFajen8G4K3mmqUrQsehn5wNKs8IzlKHE8TfnSmILXVMVziAEcnB23u1RCFU1NT6hSyr7Q==}
|
||||
dev: false
|
||||
|
||||
/@types/node/16.4.8:
|
||||
resolution: {integrity: sha512-VL7RZyCpfYEmbyd3/Eq5RNYhZt7yoL1JThZQ3KzimzhLya2Qa86U1ZZmioNWAAjiz99z1ED1xF9NUV2srvfVrA==}
|
||||
dev: false
|
||||
|
||||
/@types/parse-json/4.0.0:
|
||||
resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
|
||||
|
||||
@@ -1670,6 +1727,11 @@ packages:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: false
|
||||
|
||||
/argv/0.0.2:
|
||||
resolution: {integrity: sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=}
|
||||
engines: {node: '>=0.6.10'}
|
||||
dev: false
|
||||
|
||||
/array-union/2.1.0:
|
||||
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1689,7 +1751,6 @@ packages:
|
||||
|
||||
/asynckit/0.4.0:
|
||||
resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=}
|
||||
dev: true
|
||||
|
||||
/at-least-node/1.0.0:
|
||||
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
||||
@@ -2094,7 +2155,6 @@ packages:
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
dev: true
|
||||
|
||||
/commander/2.20.3:
|
||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||
@@ -2271,7 +2331,6 @@ packages:
|
||||
/delayed-stream/1.0.0:
|
||||
resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: true
|
||||
|
||||
/delegates/1.0.0:
|
||||
resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=}
|
||||
@@ -2345,10 +2404,14 @@ packages:
|
||||
tslib: 2.3.0
|
||||
dev: false
|
||||
|
||||
/dotenv-expand/5.1.0:
|
||||
resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==}
|
||||
dev: false
|
||||
|
||||
/dotenv/10.0.0:
|
||||
resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
dev: false
|
||||
|
||||
/ecdsa-sig-formatter/1.0.11:
|
||||
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
|
||||
@@ -2922,7 +2985,6 @@ packages:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.31
|
||||
dev: true
|
||||
|
||||
/formidable/1.2.2:
|
||||
resolution: {integrity: sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==}
|
||||
@@ -2945,7 +3007,6 @@ packages:
|
||||
graceful-fs: 4.2.6
|
||||
jsonfile: 6.1.0
|
||||
universalify: 2.0.0
|
||||
dev: true
|
||||
|
||||
/fs-extra/9.1.0:
|
||||
resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
|
||||
@@ -3082,7 +3143,6 @@ packages:
|
||||
|
||||
/graceful-fs/4.2.6:
|
||||
resolution: {integrity: sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==}
|
||||
dev: true
|
||||
|
||||
/has-bigints/1.0.1:
|
||||
resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==}
|
||||
@@ -3305,6 +3365,10 @@ packages:
|
||||
ci-info: 3.2.0
|
||||
dev: true
|
||||
|
||||
/is-class/0.0.9:
|
||||
resolution: {integrity: sha512-kUfRnejcRC9YLgblxoJ76dp9gZ3vMKTrDS5I6z2UVMOsHHSImNKCJocjQTkZr38PwiSZ9LVklaHEENaVYeFTXg==}
|
||||
dev: false
|
||||
|
||||
/is-core-module/2.5.0:
|
||||
resolution: {integrity: sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==}
|
||||
dependencies:
|
||||
@@ -4070,7 +4134,6 @@ packages:
|
||||
universalify: 2.0.0
|
||||
optionalDependencies:
|
||||
graceful-fs: 4.2.6
|
||||
dev: true
|
||||
|
||||
/jsonwebtoken/8.5.1:
|
||||
resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==}
|
||||
@@ -4205,6 +4268,14 @@ packages:
|
||||
resolution: {integrity: sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=}
|
||||
dev: true
|
||||
|
||||
/lodash.get/4.4.2:
|
||||
resolution: {integrity: sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=}
|
||||
dev: false
|
||||
|
||||
/lodash.has/4.5.2:
|
||||
resolution: {integrity: sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=}
|
||||
dev: false
|
||||
|
||||
/lodash.includes/4.3.0:
|
||||
resolution: {integrity: sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=}
|
||||
dev: false
|
||||
@@ -4237,6 +4308,10 @@ packages:
|
||||
resolution: {integrity: sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=}
|
||||
dev: false
|
||||
|
||||
/lodash.set/4.3.2:
|
||||
resolution: {integrity: sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=}
|
||||
dev: false
|
||||
|
||||
/lodash.toarray/4.4.0:
|
||||
resolution: {integrity: sha1-JMS/zWsvuji/0FlNsRedjptlZWE=}
|
||||
dev: true
|
||||
@@ -4358,14 +4433,12 @@ packages:
|
||||
/mime-db/1.48.0:
|
||||
resolution: {integrity: sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/mime-types/2.1.31:
|
||||
resolution: {integrity: sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dependencies:
|
||||
mime-db: 1.48.0
|
||||
dev: true
|
||||
|
||||
/mime/1.6.0:
|
||||
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
|
||||
@@ -4390,7 +4463,6 @@ packages:
|
||||
|
||||
/minimist/1.2.5:
|
||||
resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
|
||||
dev: true
|
||||
|
||||
/minipass/3.1.3:
|
||||
resolution: {integrity: sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==}
|
||||
@@ -4537,6 +4609,23 @@ packages:
|
||||
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
|
||||
dev: true
|
||||
|
||||
/nestjs-typegoose/7.1.38_ad6502a9e63d94834e95766efca460e3:
|
||||
resolution: {integrity: sha512-hYgDliG2IS5CJkzRsTbbfwZk+IP0jEyCaxcRqqXvxZaP5miiH9UvGm3K0hg8X5DuVkmsgTzW3+MxOXmcLm9BOA==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
peerDependencies:
|
||||
'@nestjs/common': ^6.10.1 || ^7.0.0
|
||||
'@nestjs/core': ^6.10.1 || ^7.0.0
|
||||
'@typegoose/typegoose': ^6.2.1 || ^7.0.0
|
||||
mongoose: ^5.10.6
|
||||
dependencies:
|
||||
'@nestjs/common': 8.0.4_e911b02ebc86a0e92191a7b133b2fcd0
|
||||
'@nestjs/core': 8.0.4_e4988ec8350f50541cb1b028c87076a8
|
||||
'@typegoose/typegoose': 8.0.0_mongoose@5.13.3
|
||||
is-class: 0.0.9
|
||||
mongoose: 5.13.3
|
||||
reflect-metadata: 0.1.13
|
||||
dev: false
|
||||
|
||||
/no-case/3.0.4:
|
||||
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
||||
dependencies:
|
||||
@@ -5886,7 +5975,6 @@ packages:
|
||||
/universalify/2.0.0:
|
||||
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
dev: true
|
||||
|
||||
/uri-js/4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
@@ -6158,3 +6246,19 @@ packages:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/zx/2.0.0:
|
||||
resolution: {integrity: sha512-OF8YvqseMMmtDaASqO+8+0/tJZvykLK0hX9YBAaRO9l7Hc+YjNKjpgJTjrmncgEURoyDr9Ln4r/qBtEuDNZstg==}
|
||||
engines: {node: '>= 14.8.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@types/fs-extra': 9.0.12
|
||||
'@types/minimist': 1.2.2
|
||||
'@types/node': 16.4.8
|
||||
'@types/node-fetch': 2.5.12
|
||||
chalk: 4.1.1
|
||||
fs-extra: 10.0.0
|
||||
minimist: 1.2.5
|
||||
node-fetch: 2.6.1
|
||||
which: 2.0.2
|
||||
dev: false
|
||||
|
||||
26
src/app.config.ts
Normal file
26
src/app.config.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import argv from 'argv'
|
||||
export const CROSS_DOMAIN = {
|
||||
allowedOrigins: [
|
||||
'innei.ren',
|
||||
'shizuri.net',
|
||||
'localhost:9528',
|
||||
'localhost:2323',
|
||||
'127.0.0.1',
|
||||
'mbp.cc',
|
||||
'local.innei.test',
|
||||
'22333322.xyz',
|
||||
],
|
||||
allowedReferer: 'innei.ren',
|
||||
}
|
||||
|
||||
export const MONGO_DB = {
|
||||
uri: `mongodb://127.0.0.1:${argv.dbport || '27017'}/mx-space`,
|
||||
}
|
||||
|
||||
export const REDIS = {
|
||||
host: argv.redis_host || 'localhost',
|
||||
port: argv.redis_port || 6379,
|
||||
password: (argv.redis_password || null) as string,
|
||||
ttl: null,
|
||||
defaultCacheTTL: 60 * 60 * 24,
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'
|
||||
import { AppController } from './app.controller'
|
||||
import { AppService } from './app.service'
|
||||
|
||||
describe('AppController', () => {
|
||||
let appController: AppController
|
||||
@@ -8,15 +7,19 @@ describe('AppController', () => {
|
||||
beforeEach(async () => {
|
||||
const app: TestingModule = await Test.createTestingModule({
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
}).compile()
|
||||
|
||||
appController = app.get<AppController>(AppController)
|
||||
})
|
||||
|
||||
describe('root', () => {
|
||||
it('should return "Hello World!"', () => {
|
||||
expect(appController.getHello()).toBe('Hello World!')
|
||||
it('should return has schema object', async () => {
|
||||
const obj = await appController.appInfo()
|
||||
expect(Object.keys(obj)).toStrictEqual(['name', 'version', 'hash'])
|
||||
})
|
||||
|
||||
it('should return pong', () => {
|
||||
expect(appController.ping()).toBe('pong')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,12 +1,30 @@
|
||||
import { Controller, Get } from '@nestjs/common'
|
||||
import { AppService } from './app.service'
|
||||
|
||||
import PKG from '../package.json'
|
||||
// import { $ } from 'zx'
|
||||
import { execSync } from 'child_process'
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(private readonly appService: AppService) {}
|
||||
|
||||
@Get()
|
||||
getHello(): string {
|
||||
return this.appService.getHello()
|
||||
async appInfo(): Promise<IAppInfo> {
|
||||
const cmd = `git log --pretty=oneline | head -n 1 | cut -d' ' -f1`
|
||||
const hash = execSync(cmd, { encoding: 'utf-8' }).split('\n')[0]
|
||||
// const hash = await $`git log --pretty=oneline | head -n 1 | cut -d' ' -f1`
|
||||
return {
|
||||
// hash: hash.stdout,
|
||||
name: PKG.name,
|
||||
version: PKG.version,
|
||||
hash,
|
||||
}
|
||||
}
|
||||
|
||||
@Get('/ping')
|
||||
ping(): 'pong' {
|
||||
return 'pong'
|
||||
}
|
||||
}
|
||||
|
||||
interface IAppInfo {
|
||||
version: string
|
||||
hash: string
|
||||
name: string
|
||||
}
|
||||
|
||||
@@ -1,12 +1,30 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { Module, OnModuleInit } from '@nestjs/common'
|
||||
import { ConfigModule } from '@nestjs/config'
|
||||
import { AppController } from './app.controller'
|
||||
import { AppService } from './app.service'
|
||||
import { InitModule } from './modules/init/init.module'
|
||||
import { UserModule } from './modules/user/user.module'
|
||||
import { HelperModule } from './modules/helper/helper.module'
|
||||
import { PostModule } from './modules/post/post.module';
|
||||
import { CategoryModule } from './modules/category/category.module';
|
||||
|
||||
@Module({
|
||||
imports: [InitModule, UserModule],
|
||||
imports: [
|
||||
InitModule,
|
||||
UserModule,
|
||||
ConfigModule.forRoot({
|
||||
envFilePath: [
|
||||
'.env.development.local',
|
||||
'.env.development',
|
||||
'.env.production.local',
|
||||
'.env.production',
|
||||
'.env',
|
||||
],
|
||||
isGlobal: true,
|
||||
}),
|
||||
HelperModule,
|
||||
PostModule,
|
||||
CategoryModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
getHello(): string {
|
||||
return 'Hello World!'
|
||||
}
|
||||
}
|
||||
16
src/common/decorator/auth.decorator.ts
Normal file
16
src/common/decorator/auth.decorator.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { applyDecorators, UseGuards } from '@nestjs/common'
|
||||
import { AuthGuard } from '@nestjs/passport'
|
||||
import { ApiBearerAuth, ApiUnauthorizedResponse } from '@nestjs/swagger'
|
||||
import { isDev } from '~/utils'
|
||||
|
||||
export function Auth() {
|
||||
const decorators = []
|
||||
if (!isDev) {
|
||||
decorators.push(UseGuards(AuthGuard('jwt')))
|
||||
}
|
||||
decorators.push(
|
||||
ApiBearerAuth(),
|
||||
ApiUnauthorizedResponse({ description: 'Unauthorized' }),
|
||||
)
|
||||
return applyDecorators(...decorators)
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
import { homedir } from 'os'
|
||||
import { join } from 'path'
|
||||
import { isDev } from 'src/utils'
|
||||
import { isDev } from '~/utils'
|
||||
|
||||
export const HOME = homedir()
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { NestFactory } from '@nestjs/core'
|
||||
import { AppModule } from './app.module'
|
||||
import { NestFastifyApplication } from '@nestjs/platform-fastify'
|
||||
import { fastifyApp } from './core/adapt/fastify'
|
||||
import { fastifyApp } from './common/adapt/fastify'
|
||||
import { isDev } from './utils'
|
||||
import { Logger } from '@nestjs/common'
|
||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
|
||||
import { CROSS_DOMAIN } from './app.config'
|
||||
// const PORT = parseInt(process.env.PORT) || 2333
|
||||
const PORT = 2333
|
||||
const APIVersion = 1
|
||||
const Origin = process.env.ORIGIN || ''
|
||||
const Origin = CROSS_DOMAIN.allowedOrigins
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create<NestFastifyApplication>(
|
||||
@@ -16,7 +17,7 @@ async function bootstrap() {
|
||||
fastifyApp,
|
||||
)
|
||||
|
||||
const hosts = Origin.split(',').map((host) => new RegExp(host, 'i'))
|
||||
const hosts = Origin.map((host) => new RegExp(host, 'i'))
|
||||
|
||||
app.enableCors({
|
||||
origin: (origin, callback) => {
|
||||
@@ -47,6 +48,7 @@ async function bootstrap() {
|
||||
if (isDev) {
|
||||
Logger.debug(`http://localhost:${PORT}/api-docs`)
|
||||
}
|
||||
|
||||
Logger.log('Server is up.')
|
||||
})
|
||||
}
|
||||
|
||||
22
src/modules/category/category.model.ts
Normal file
22
src/modules/category/category.model.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { DocumentType, index, modelOptions, prop } from '@typegoose/typegoose'
|
||||
import { BaseModel } from '~/shared/base.model'
|
||||
|
||||
export type CategoryDocument = DocumentType<CategoryModel>
|
||||
|
||||
export enum CategoryType {
|
||||
Category,
|
||||
Tag,
|
||||
}
|
||||
|
||||
@index({ slug: -1 })
|
||||
@modelOptions({ options: { customName: 'Category' } })
|
||||
export class CategoryModel extends BaseModel {
|
||||
@prop({ unique: true, trim: true, required: true })
|
||||
name!: string
|
||||
|
||||
@prop({ default: CategoryType.Category })
|
||||
type?: CategoryType
|
||||
|
||||
@prop({ unique: true, required: true })
|
||||
slug!: string
|
||||
}
|
||||
10
src/modules/category/category.module.ts
Normal file
10
src/modules/category/category.module.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { forwardRef, Module } from '@nestjs/common'
|
||||
import { PostModule } from '../post/post.module'
|
||||
import { CategoryService } from './category.service'
|
||||
|
||||
@Module({
|
||||
imports: [forwardRef(() => PostModule)],
|
||||
providers: [CategoryService],
|
||||
exports: [CategoryService],
|
||||
})
|
||||
export class CategoryModule {}
|
||||
21
src/modules/category/category.service.spec.ts
Normal file
21
src/modules/category/category.service.spec.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'
|
||||
import { getFakeCategoryModel, getFakePostModel } from 'test/db-model.mock'
|
||||
import { PostModule } from '../post/post.module'
|
||||
import { CategoryService } from './category.service'
|
||||
|
||||
describe('CategoryService', () => {
|
||||
let service: CategoryService
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [getFakePostModel(), getFakeCategoryModel(), CategoryService],
|
||||
imports: [PostModule],
|
||||
}).compile()
|
||||
|
||||
service = module.get<CategoryService>(CategoryService)
|
||||
})
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined()
|
||||
})
|
||||
})
|
||||
19
src/modules/category/category.service.ts
Normal file
19
src/modules/category/category.service.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { forwardRef, Inject, Injectable } from '@nestjs/common'
|
||||
import { ReturnModelType } from '@typegoose/typegoose'
|
||||
import { InjectModel } from 'nestjs-typegoose'
|
||||
import { PostService } from '../post/post.service'
|
||||
import { CategoryModel } from './category.model'
|
||||
|
||||
@Injectable()
|
||||
export class CategoryService {
|
||||
constructor(
|
||||
@InjectModel(CategoryModel)
|
||||
private readonly categoryModel: ReturnModelType<typeof CategoryModel>,
|
||||
|
||||
private postService: PostService,
|
||||
) {}
|
||||
|
||||
findCategoryById(categoryId: string) {
|
||||
return this.categoryModel.findById(categoryId)
|
||||
}
|
||||
}
|
||||
27
src/modules/helper/db.module.ts
Normal file
27
src/modules/helper/db.module.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Global, Module } from '@nestjs/common'
|
||||
import { TypegooseModule } from 'nestjs-typegoose'
|
||||
import { MONGO_DB } from '~/app.config'
|
||||
import { CategoryModel } from '../category/category.model'
|
||||
import { PostModel } from '../post/post.model'
|
||||
import { UserModel } from '../user/user.model'
|
||||
|
||||
const models = TypegooseModule.forFeature([UserModel, PostModel, CategoryModel])
|
||||
@Module({
|
||||
imports: [
|
||||
TypegooseModule.forRootAsync({
|
||||
useFactory: () => ({
|
||||
uri: MONGO_DB.uri,
|
||||
useCreateIndex: true,
|
||||
useFindAndModify: false,
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
autoIndex: true,
|
||||
}),
|
||||
}),
|
||||
models,
|
||||
],
|
||||
|
||||
exports: [models],
|
||||
})
|
||||
@Global()
|
||||
export class DbModule {}
|
||||
5
src/modules/helper/helper.module.ts
Normal file
5
src/modules/helper/helper.module.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { DbModule } from './db.module'
|
||||
|
||||
@Module({ imports: [DbModule] })
|
||||
export class HelperModule {}
|
||||
18
src/modules/post/post.controller.spec.ts
Normal file
18
src/modules/post/post.controller.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { PostController } from './post.controller';
|
||||
|
||||
describe('PostController', () => {
|
||||
let controller: PostController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [PostController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<PostController>(PostController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
4
src/modules/post/post.controller.ts
Normal file
4
src/modules/post/post.controller.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Controller } from '@nestjs/common'
|
||||
|
||||
@Controller('posts')
|
||||
export class PostController {}
|
||||
44
src/modules/post/post.model.ts
Normal file
44
src/modules/post/post.model.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { index, modelOptions, prop, Ref, Severity } from '@typegoose/typegoose'
|
||||
import { Schema } from 'mongoose'
|
||||
import { CountMixed as Count, WriteBaseModel } from '~/shared/base.model'
|
||||
import { CategoryModel as Category } from '../category/category.model'
|
||||
|
||||
@index({ slug: 1 })
|
||||
@index({ modified: -1 })
|
||||
@index({ text: 'text' })
|
||||
@modelOptions({ options: { customName: 'Post', allowMixed: Severity.ALLOW } })
|
||||
export class PostModel extends WriteBaseModel {
|
||||
@prop({ trim: true, unique: true, required: true })
|
||||
slug!: string
|
||||
|
||||
@prop()
|
||||
summary?: string
|
||||
|
||||
@prop({ ref: () => Category, required: true })
|
||||
categoryId: Ref<Category>
|
||||
|
||||
@prop({
|
||||
ref: () => Category,
|
||||
foreignField: '_id',
|
||||
localField: 'categoryId',
|
||||
justOne: true,
|
||||
})
|
||||
public category: Ref<Category>
|
||||
|
||||
@prop({ default: false })
|
||||
hide?: boolean
|
||||
|
||||
@prop({ default: true })
|
||||
copyright?: boolean
|
||||
|
||||
@prop({
|
||||
type: String,
|
||||
})
|
||||
tags?: string[]
|
||||
|
||||
@prop({ type: Count, default: { read: 0, like: 0 }, _id: false })
|
||||
count?: Count
|
||||
|
||||
@prop({ type: Schema.Types.Mixed })
|
||||
options?: Record<any, any>
|
||||
}
|
||||
12
src/modules/post/post.module.ts
Normal file
12
src/modules/post/post.module.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { forwardRef, Module } from '@nestjs/common'
|
||||
import { CategoryModule } from '../category/category.module'
|
||||
import { PostController } from './post.controller'
|
||||
import { PostService } from './post.service'
|
||||
|
||||
@Module({
|
||||
controllers: [PostController],
|
||||
providers: [PostService],
|
||||
imports: [forwardRef(() => CategoryModule)],
|
||||
exports: [PostService],
|
||||
})
|
||||
export class PostModule {}
|
||||
22
src/modules/post/post.service.spec.ts
Normal file
22
src/modules/post/post.service.spec.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { forwardRef } from '@nestjs/common'
|
||||
import { Test, TestingModule } from '@nestjs/testing'
|
||||
import { getFakeCategoryModel, getFakePostModel } from 'test/db-model.mock'
|
||||
import { CategoryModule } from '../category/category.module'
|
||||
import { PostService } from './post.service'
|
||||
|
||||
describe('PostService', () => {
|
||||
let service: PostService
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [getFakePostModel(), getFakeCategoryModel(), PostService],
|
||||
imports: [forwardRef(() => CategoryModule)],
|
||||
}).compile()
|
||||
|
||||
service = module.get<PostService>(PostService)
|
||||
})
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined()
|
||||
})
|
||||
})
|
||||
33
src/modules/post/post.service.ts
Normal file
33
src/modules/post/post.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import {
|
||||
forwardRef,
|
||||
Inject,
|
||||
Injectable,
|
||||
UnprocessableEntityException,
|
||||
} from '@nestjs/common'
|
||||
import { ReturnModelType } from '@typegoose/typegoose'
|
||||
import { InjectModel } from 'nestjs-typegoose'
|
||||
import { CategoryService } from '../category/category.service'
|
||||
import { PostModel } from './post.model'
|
||||
|
||||
@Injectable()
|
||||
export class PostService {
|
||||
constructor(
|
||||
@InjectModel(PostModel)
|
||||
private readonly postModel: ReturnModelType<typeof PostModel>,
|
||||
@Inject(forwardRef(() => CategoryService))
|
||||
private categoryService: CategoryService,
|
||||
) {}
|
||||
|
||||
async create(post: Partial<PostModel>) {
|
||||
const { categoryId } = post
|
||||
|
||||
const category = await this.categoryService.findCategoryById(
|
||||
categoryId as any as string,
|
||||
)
|
||||
if (!category) {
|
||||
throw new UnprocessableEntityException('分类丢失了 ಠ_ಠ')
|
||||
}
|
||||
const res = this.postModel.create(post)
|
||||
return res
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
import { DocumentType, modelOptions, prop } from '@typegoose/typegoose'
|
||||
import {
|
||||
DocumentType,
|
||||
modelOptions,
|
||||
prop,
|
||||
Severity,
|
||||
} from '@typegoose/typegoose'
|
||||
import { Schema } from 'mongoose'
|
||||
import { BaseModel } from 'src/shared/base.module'
|
||||
|
||||
import { hashSync } from 'bcrypt'
|
||||
import { BaseModel } from 'src/shared/base.model'
|
||||
export type UserDocument = DocumentType<UserModel>
|
||||
|
||||
export class OAuthModel {
|
||||
@@ -25,7 +31,7 @@ export class TokenModel {
|
||||
name: string
|
||||
}
|
||||
|
||||
@modelOptions({ options: { customName: 'User' } })
|
||||
@modelOptions({ options: { customName: 'User', allowMixed: Severity.ALLOW } })
|
||||
export class UserModel extends BaseModel {
|
||||
@prop({ required: true, unique: true, trim: true })
|
||||
username!: string
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'
|
||||
import { getModelToken } from 'nestjs-typegoose'
|
||||
import { UserService } from './user.service'
|
||||
|
||||
const fakeModel = jest.fn()
|
||||
|
||||
describe('UserService', () => {
|
||||
let service: UserService
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [UserService],
|
||||
providers: [
|
||||
UserService,
|
||||
{
|
||||
provide: getModelToken('UserModel'),
|
||||
useValue: fakeModel,
|
||||
},
|
||||
],
|
||||
}).compile()
|
||||
|
||||
service = module.get<UserService>(UserService)
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ReturnModelType } from '@typegoose/typegoose'
|
||||
import { InjectModel } from 'nestjs-typegoose'
|
||||
import { UserModel } from './user.model'
|
||||
|
||||
@Injectable()
|
||||
export class UserService {}
|
||||
export class UserService {
|
||||
constructor(
|
||||
@InjectModel(UserModel)
|
||||
private userModel: ReturnModelType<typeof UserModel>,
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { prop } from '@typegoose/typegoose'
|
||||
import { modelOptions, prop } from '@typegoose/typegoose'
|
||||
import { IsNotEmpty, IsString } from 'class-validator'
|
||||
export class BaseModel {
|
||||
created?: Date
|
||||
@@ -48,3 +48,15 @@ export abstract class WriteBaseModel extends BaseCommentIndexModel {
|
||||
@prop({ default: () => new Date() })
|
||||
modified: Date
|
||||
}
|
||||
|
||||
@modelOptions({
|
||||
schemaOptions: { id: false, _id: false },
|
||||
options: { customName: 'count' },
|
||||
})
|
||||
export class CountMixed {
|
||||
@prop({ default: 0 })
|
||||
read?: number
|
||||
|
||||
@prop({ default: 0 })
|
||||
like?: number
|
||||
}
|
||||
20
test/db-model.mock.ts
Normal file
20
test/db-model.mock.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Provider } from '@nestjs/common'
|
||||
import { getModelToken } from 'nestjs-typegoose'
|
||||
|
||||
const getFakeModel = () => jest.fn()
|
||||
|
||||
export const getFakePostModel = (): Provider<any> => {
|
||||
const model = getFakeModel()
|
||||
return {
|
||||
useValue: model,
|
||||
provide: getModelToken('PostModel'),
|
||||
}
|
||||
}
|
||||
|
||||
export const getFakeCategoryModel = (): Provider<any> => {
|
||||
const model = getFakeModel()
|
||||
return {
|
||||
useValue: model,
|
||||
provide: getModelToken('CategoryModel'),
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"module": "CommonJS",
|
||||
"declaration": true,
|
||||
"removeComments": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
@@ -10,8 +10,17 @@
|
||||
"target": "es2017",
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
"baseUrl": "./",
|
||||
"baseUrl": ".",
|
||||
"incremental": true,
|
||||
"skipLibCheck": true
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"~": [
|
||||
"./src"
|
||||
],
|
||||
"~/*": [
|
||||
"./src/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user