fix: app config shared
This commit is contained in:
3
.github/workflows/docker.yml
vendored
3
.github/workflows/docker.yml
vendored
@@ -42,5 +42,6 @@ jobs:
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }},innei/mx-server:latest
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -19,4 +19,5 @@
|
||||
"cSpell.words": [
|
||||
"qaqdmin"
|
||||
],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
}
|
||||
23
package.json
23
package.json
@@ -53,18 +53,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "*",
|
||||
"@nestjs/common": "8.0.7",
|
||||
"@nestjs/common": "8.0.9",
|
||||
"@nestjs/config": "1.0.1",
|
||||
"@nestjs/core": "8.0.7",
|
||||
"@nestjs/core": "8.0.9",
|
||||
"@nestjs/graphql": "9.0.5",
|
||||
"@nestjs/jwt": "8.0.0",
|
||||
"@nestjs/mapped-types": "*",
|
||||
"@nestjs/passport": "8.0.1",
|
||||
"@nestjs/platform-fastify": "8.0.7",
|
||||
"@nestjs/platform-socket.io": "8.0.7",
|
||||
"@nestjs/platform-fastify": "8.0.9",
|
||||
"@nestjs/platform-socket.io": "8.0.9",
|
||||
"@nestjs/schedule": "1.0.1",
|
||||
"@nestjs/swagger": "5.0.9",
|
||||
"@nestjs/websockets": "8.0.7",
|
||||
"@nestjs/swagger": "5.1.0",
|
||||
"@nestjs/websockets": "8.0.9",
|
||||
"@typegoose/auto-increment": "1.0.0",
|
||||
"@typegoose/typegoose": "8.3.0",
|
||||
"algoliasearch": "4.10.5",
|
||||
@@ -117,9 +117,9 @@
|
||||
"devDependencies": {
|
||||
"@innei-util/eslint-config-ts": "latest",
|
||||
"@innei-util/prettier": "latest",
|
||||
"@nestjs/cli": "8.1.1",
|
||||
"@nestjs/cli": "8.1.2",
|
||||
"@nestjs/schematics": "8.0.3",
|
||||
"@nestjs/testing": "8.0.7",
|
||||
"@nestjs/testing": "8.0.9",
|
||||
"@types/bcrypt": "5.0.0",
|
||||
"@types/cache-manager": "3.4.2",
|
||||
"@types/ejs": "3.1.0",
|
||||
@@ -128,7 +128,7 @@
|
||||
"@types/jest": "27.0.2",
|
||||
"@types/lodash": "4.14.175",
|
||||
"@types/marked": "3.0.1",
|
||||
"@types/mongoose-paginate-v2": "1.3.11",
|
||||
"@types/mongoose-paginate-v2": "1.4.0",
|
||||
"@types/node": "16.9.2",
|
||||
"@types/nodemailer": "6.4.4",
|
||||
"@types/passport-jwt": "3.0.6",
|
||||
@@ -140,7 +140,7 @@
|
||||
"fastify": "*",
|
||||
"husky": "7.0.2",
|
||||
"ioredis": "*",
|
||||
"jest": "27.2.3",
|
||||
"jest": "27.2.4",
|
||||
"lint-staged": "11.1.2",
|
||||
"prettier": "2.4.1",
|
||||
"rimraf": "3.0.2",
|
||||
@@ -156,6 +156,7 @@
|
||||
"webpack-node-externals": "3.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"typescript": "4.4.3"
|
||||
"typescript": "4.4.3",
|
||||
"apollo-server-fastify/fastify": "*"
|
||||
}
|
||||
}
|
||||
41
patch/bootstrap.js
vendored
Normal file
41
patch/bootstrap.js
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// import { getModelForClass, mongoose } from '@typegoose/typegoose'
|
||||
// import { config } from 'dotenv'
|
||||
// import { ConnectionBase } from 'mongoose'
|
||||
// import * as APP from '../src/app.config.mjs'
|
||||
// import { CategoryModel } from '../src/modules/category/category.model'
|
||||
// import { NoteModel } from '../src/modules/note/note.model'
|
||||
// import { PostModel } from '../src/modules/post/post.model'
|
||||
// const env = config().parsed || {}
|
||||
// const url = APP.MONGO_DB.uri
|
||||
|
||||
// const opt = {
|
||||
// useCreateIndex: true,
|
||||
// useFindAndModify: false,
|
||||
// useNewUrlParser: true,
|
||||
// useUnifiedTopology: true,
|
||||
// autoIndex: true,
|
||||
// }
|
||||
// mongoose.connect(url, opt)
|
||||
// const post = getModelForClass(PostModel)
|
||||
// const note = getModelForClass(NoteModel)
|
||||
// const category = getModelForClass(CategoryModel)
|
||||
|
||||
// const Config = {
|
||||
// env,
|
||||
// db: (mongoose.connection as any).client.db(
|
||||
// APP.MONGO_DB.collectionName,
|
||||
// ) as ConnectionBase,
|
||||
// models: {
|
||||
// post,
|
||||
// note,
|
||||
// category,
|
||||
// },
|
||||
// }
|
||||
// async function bootstrap(cb: (config: typeof Config) => any) {
|
||||
// await cb.call(this, Config)
|
||||
|
||||
// mongoose.disconnect()
|
||||
// process.exit()
|
||||
// }
|
||||
|
||||
// export { bootstrap as patch }
|
||||
@@ -1,41 +0,0 @@
|
||||
import { getModelForClass, mongoose } from '@typegoose/typegoose'
|
||||
import { config } from 'dotenv'
|
||||
import { ConnectionBase } from 'mongoose'
|
||||
import * as APP from '../src/app.config'
|
||||
import { CategoryModel } from '../src/modules/category/category.model'
|
||||
import { NoteModel } from '../src/modules/note/note.model'
|
||||
import { PostModel } from '../src/modules/post/post.model'
|
||||
const env = config().parsed || {}
|
||||
const url = APP.MONGO_DB.uri
|
||||
|
||||
const opt = {
|
||||
useCreateIndex: true,
|
||||
useFindAndModify: false,
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
autoIndex: true,
|
||||
}
|
||||
mongoose.connect(url, opt)
|
||||
const post = getModelForClass(PostModel)
|
||||
const note = getModelForClass(NoteModel)
|
||||
const category = getModelForClass(CategoryModel)
|
||||
|
||||
const Config = {
|
||||
env,
|
||||
db: (mongoose.connection as any).client.db(
|
||||
APP.MONGO_DB.collectionName,
|
||||
) as ConnectionBase,
|
||||
models: {
|
||||
post,
|
||||
note,
|
||||
category,
|
||||
},
|
||||
}
|
||||
async function bootstrap(cb: (config: typeof Config) => any) {
|
||||
await cb.call(this, Config)
|
||||
|
||||
mongoose.disconnect()
|
||||
process.exit()
|
||||
}
|
||||
|
||||
export { bootstrap as patch }
|
||||
11
patch/global.d.ts
vendored
11
patch/global.d.ts
vendored
@@ -1,11 +0,0 @@
|
||||
import { ModelType } from '@typegoose/typegoose/lib/types'
|
||||
import { Document, PaginateModel } from 'mongoose'
|
||||
/// <reference types="../global" />
|
||||
declare global {
|
||||
export type KV<T = any> = Record<string, T>
|
||||
|
||||
// @ts-ignore
|
||||
export type MongooseModel<T> = ModelType<T> & PaginateModel<T & Document>
|
||||
}
|
||||
|
||||
export {}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"declaration": false,
|
||||
"removeComments": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es2017",
|
||||
"sourceMap": false,
|
||||
"outDir": "./dist",
|
||||
"baseUrl": ".",
|
||||
"noImplicitAny": false,
|
||||
"incremental": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"~": [
|
||||
"../src"
|
||||
],
|
||||
"~/*": [
|
||||
"../src/*"
|
||||
]
|
||||
},
|
||||
},
|
||||
"include": [
|
||||
"*.ts",
|
||||
"../src"
|
||||
],
|
||||
"exclude": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
// patch for version lower than v2.0.0-alpha.1
|
||||
// // patch for version lower than v2.0.0-alpha.1
|
||||
|
||||
import { patch } from './bootstrap'
|
||||
// import { patch } from './bootstrap'
|
||||
|
||||
patch(async ({ models: { note, post, category } }) => {
|
||||
await Promise.all([
|
||||
[note, post].map((model) => {
|
||||
return model.updateMany(
|
||||
{},
|
||||
{
|
||||
$unset: ['options'],
|
||||
},
|
||||
)
|
||||
}),
|
||||
category.updateMany({}, { $unset: { count: '' } }),
|
||||
])
|
||||
})
|
||||
// patch(async ({ models: { note, post, category } }) => {
|
||||
// await Promise.all([
|
||||
// [note, post].map((model) => {
|
||||
// return model.updateMany(
|
||||
// {},
|
||||
// {
|
||||
// $unset: ['options'],
|
||||
// },
|
||||
// )
|
||||
// }),
|
||||
// category.updateMany({}, { $unset: { count: '' } }),
|
||||
// ])
|
||||
// })
|
||||
|
||||
1166
pnpm-lock.yaml
generated
1166
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
63
src/app.config.js
Normal file
63
src/app.config.js
Normal file
@@ -0,0 +1,63 @@
|
||||
const yargs = require('yargs')
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true })
|
||||
|
||||
/**
|
||||
* @type {any}
|
||||
*/
|
||||
const argv = yargs.argv
|
||||
console.log(argv)
|
||||
|
||||
exports.API_VERSION = 2
|
||||
exports.CROSS_DOMAIN = {
|
||||
allowedOrigins: argv.allowedOrigins
|
||||
? argv.allowedOrigins?.split?.(',')
|
||||
: [
|
||||
'innei.ren',
|
||||
'shizuri.net',
|
||||
'localhost:9528',
|
||||
'localhost:2323',
|
||||
'127.0.0.1',
|
||||
'mbp.cc',
|
||||
'local.innei.test',
|
||||
'22333322.xyz',
|
||||
],
|
||||
// allowedReferer: 'innei.ren',
|
||||
}
|
||||
|
||||
exports.MONGO_DB = {
|
||||
collectionName: argv.collection_name || 'mx-space',
|
||||
host: argv.db_host || '127.0.0.1',
|
||||
port: argv.db_port || 27017,
|
||||
get uri() {
|
||||
return `mongodb://${this.host}:${this.port}/${
|
||||
process.env.TEST ? 'mx-space_unitest' : this.collectionName
|
||||
}`
|
||||
},
|
||||
}
|
||||
|
||||
exports.REDIS = {
|
||||
host: argv.redis_host || 'localhost',
|
||||
port: argv.redis_port || 6379,
|
||||
password: argv.redis_password || null,
|
||||
ttl: null,
|
||||
httpCacheTTL: 5,
|
||||
max: 5,
|
||||
disableApiCache:
|
||||
(isDev || argv.disableCache) && !process.env['ENABLE_CACHE_DEBUG'],
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {import('axios').AxiosRequestConfig}
|
||||
*/
|
||||
exports.AXIOS_CONFIG = {
|
||||
timeout: 10000,
|
||||
}
|
||||
|
||||
exports.SECURITY = {
|
||||
jwtSecret: argv.jwtSecret || 'asjhczxiucipoiopiqm2376',
|
||||
jwtExpire: '7d',
|
||||
// 跳过登陆鉴权
|
||||
skipAuth: argv.skipAuth ?? false,
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
import type { AxiosRequestConfig } from 'axios'
|
||||
import yargs from 'yargs'
|
||||
const argv = yargs.argv as any
|
||||
console.log(argv)
|
||||
|
||||
export const API_VERSION = 2
|
||||
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 = {
|
||||
collectionName: (argv.collection_name as string) || 'mx-space',
|
||||
host: argv.db_host || '127.0.0.1',
|
||||
port: argv.db_port || 27017,
|
||||
get uri() {
|
||||
return `mongodb://${this.host}:${this.port}/${
|
||||
process.env.TEST ? 'mx-space_unitest' : this.collectionName
|
||||
}`
|
||||
},
|
||||
}
|
||||
|
||||
export const REDIS = {
|
||||
host: argv.redis_host || 'localhost',
|
||||
port: argv.redis_port || 6379,
|
||||
password: (argv.redis_password || null) as string,
|
||||
ttl: null,
|
||||
httpCacheTTL: 5,
|
||||
max: 5,
|
||||
disableApiCache:
|
||||
(isDev || argv.disableCache) && !process.env['ENABLE_CACHE_DEBUG'],
|
||||
}
|
||||
|
||||
export const AXIOS_CONFIG: AxiosRequestConfig = {
|
||||
timeout: 10000,
|
||||
}
|
||||
|
||||
export const SECURITY = {
|
||||
jwtSecret: argv.jwtSecret || 'asjhczxiucipoiopiqm2376',
|
||||
jwtExpire: '7d',
|
||||
// 跳过登陆鉴权
|
||||
skipAuth: argv.skipAuth ?? false,
|
||||
}
|
||||
@@ -82,6 +82,7 @@ mkdirs()
|
||||
playground: isDev,
|
||||
autoSchemaFile: join(process.cwd(), 'schema.gql'),
|
||||
context: ({ req }) => ({ req }),
|
||||
cors: false,
|
||||
}),
|
||||
|
||||
AggregateModule,
|
||||
|
||||
@@ -102,6 +102,7 @@ export class AnalyzeInterceptor implements NestInterceptor {
|
||||
|
||||
const url = request.url
|
||||
|
||||
process.nextTick(async () => {
|
||||
try {
|
||||
this.parser.setUA(request.headers['user-agent'])
|
||||
|
||||
@@ -133,10 +134,13 @@ export class AnalyzeInterceptor implements NestInterceptor {
|
||||
// ip access in redis
|
||||
const client = this.cacheService.getClient()
|
||||
|
||||
const count = await client.sadd(getRedisKey(RedisKeys.Access, 'ips'), ip)
|
||||
const count = await client.sadd(
|
||||
getRedisKey(RedisKeys.Access, 'ips'),
|
||||
ip,
|
||||
)
|
||||
if (count) {
|
||||
// record uv to db
|
||||
process.nextTick(async () => {
|
||||
|
||||
const uvRecord = await this.options.findOne({ name: 'uv' })
|
||||
if (uvRecord) {
|
||||
await uvRecord.updateOne({
|
||||
@@ -150,11 +154,11 @@ export class AnalyzeInterceptor implements NestInterceptor {
|
||||
value: 1,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
|
||||
return call$
|
||||
}
|
||||
|
||||
2
src/processors/cache/cache.config.service.ts
vendored
2
src/processors/cache/cache.config.service.ts
vendored
@@ -24,7 +24,7 @@ export class CacheConfigService implements CacheOptionsFactory {
|
||||
port: REDIS.port as number,
|
||||
}
|
||||
if (REDIS.password) {
|
||||
redisOptions.password = REDIS.password
|
||||
redisOptions.password = REDIS.password as any
|
||||
}
|
||||
return {
|
||||
store: redisStore,
|
||||
|
||||
52
test/src/gql.resolver.e2e-spec.ts
Normal file
52
test/src/gql.resolver.e2e-spec.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { GraphQLModule } from '@nestjs/graphql'
|
||||
import { NestFastifyApplication } from '@nestjs/platform-fastify'
|
||||
import { Test } from '@nestjs/testing'
|
||||
import { join } from 'path'
|
||||
import { AppResolver } from '~/app.resolver'
|
||||
import { fastifyApp } from '~/common/adapt/fastify'
|
||||
|
||||
describe('GQL test (e2e)', () => {
|
||||
let app: NestFastifyApplication
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
imports: [
|
||||
GraphQLModule.forRoot({
|
||||
autoSchemaFile: join(process.cwd(), 'schema.gql'),
|
||||
context: ({ req }) => ({ req }),
|
||||
}),
|
||||
AppResolver,
|
||||
],
|
||||
}).compile()
|
||||
app = moduleRef.createNestApplication<NestFastifyApplication>(fastifyApp)
|
||||
await app.init()
|
||||
await app.getHttpAdapter().getInstance().ready()
|
||||
})
|
||||
|
||||
it('GET /graphql', () => {
|
||||
return app
|
||||
.inject({
|
||||
method: 'post',
|
||||
url: '/graphql',
|
||||
payload: {
|
||||
operationName: null,
|
||||
variables: {},
|
||||
query: ` {
|
||||
sayHello
|
||||
}`,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(res.json()).toStrictEqual({
|
||||
data: {
|
||||
sayHello: 'Hello World!',
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close()
|
||||
})
|
||||
})
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"test",
|
||||
"dist",
|
||||
"**/*spec.ts"
|
||||
]
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
"target": "ES2019",
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"noImplicitAny": false,
|
||||
"incremental": true,
|
||||
|
||||
Reference in New Issue
Block a user