Merge branch 'core'
This commit is contained in:
commit
d5ddcbfc30
10
package.json
10
package.json
|
@ -22,7 +22,9 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nestjs/common": "^6.0.0",
|
"@nestjs/common": "^6.0.0",
|
||||||
"@nestjs/core": "^6.0.0",
|
"@nestjs/core": "^6.0.0",
|
||||||
"@nestjs/platform-express": "^6.0.0",
|
"@nestjs/platform-express": "^6.0.0",
|
||||||
|
"class-transformer": "^0.2.3",
|
||||||
|
"class-validator": "^0.9.1",
|
||||||
"reflect-metadata": "^0.1.12",
|
"reflect-metadata": "^0.1.12",
|
||||||
"rimraf": "^2.6.2",
|
"rimraf": "^2.6.2",
|
||||||
"rxjs": "^6.3.3"
|
"rxjs": "^6.3.3"
|
||||||
|
@ -46,7 +48,11 @@
|
||||||
"wait-on": "^3.2.0"
|
"wait-on": "^3.2.0"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"moduleFileExtensions": ["js", "json", "ts"],
|
"moduleFileExtensions": [
|
||||||
|
"js",
|
||||||
|
"json",
|
||||||
|
"ts"
|
||||||
|
],
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"testRegex": ".spec.ts$",
|
"testRegex": ".spec.ts$",
|
||||||
"transform": {
|
"transform": {
|
||||||
|
|
|
@ -1,11 +1,32 @@
|
||||||
import { Module } from '@nestjs/common';
|
import { Module, NestModule, MiddlewareConsumer} from '@nestjs/common';
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { PostsController } from './posts/posts.controller';
|
import { PostsModule } from './modules/posts/posts.module';
|
||||||
|
import { DemoMiddleware } from './core/middleware/demo.middleware'
|
||||||
|
import { APP_GUARD } from '@nestjs/core';
|
||||||
|
import { DemoRolesGuard } from './core/guards/demo-roles.guard'
|
||||||
|
import { APP_INTERCEPTOR } from '@nestjs/core';
|
||||||
|
import { LoggingInterceptor } from './core/interceptors/logging.interceptor'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [],
|
imports: [PostsModule],
|
||||||
controllers: [AppController, PostsController],
|
controllers: [AppController],
|
||||||
providers: [AppService],
|
providers: [
|
||||||
|
AppService,
|
||||||
|
{
|
||||||
|
provide: APP_GUARD,
|
||||||
|
useClass: DemoRolesGuard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: APP_INTERCEPTOR,
|
||||||
|
useClass: LoggingInterceptor,
|
||||||
|
}
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule implements NestModule {
|
||||||
|
configure(consumer: MiddlewareConsumer) {
|
||||||
|
consumer.apply(DemoMiddleware).forRoutes('posts')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
import { ReflectMetadata, SetMetadata } from '@nestjs/common';
|
||||||
|
|
||||||
|
export const Roles = (...args: string[]) => SetMetadata('roles', args);
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { createParamDecorator } from '@nestjs/common'
|
||||||
|
|
||||||
|
export const User = createParamDecorator((data, req) => {
|
||||||
|
console.log('data:', data)
|
||||||
|
|
||||||
|
return req.user[data]
|
||||||
|
})
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { DemoFilter } from './demo.filter';
|
||||||
|
|
||||||
|
describe('DemoFilter', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(new DemoFilter()).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Catch(HttpException)
|
||||||
|
export class DemoFilter<T> implements ExceptionFilter {
|
||||||
|
catch(exception: HttpException, host: ArgumentsHost) {
|
||||||
|
const ctx = host.switchToHttp();
|
||||||
|
const response = ctx.getResponse();
|
||||||
|
const request = ctx.getRequest();
|
||||||
|
const status = exception.getStatus();
|
||||||
|
|
||||||
|
response.status(status).json({
|
||||||
|
statusCode: status,
|
||||||
|
path: request.url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { DemoAuthGuard } from './demo-auth.guard';
|
||||||
|
|
||||||
|
describe('DemoAuthGuard', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(new DemoAuthGuard()).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DemoAuthGuard implements CanActivate {
|
||||||
|
canActivate(
|
||||||
|
context: ExecutionContext,
|
||||||
|
): boolean | Promise<boolean> | Observable<boolean> {
|
||||||
|
const request = context.switchToHttp().getRequest();
|
||||||
|
|
||||||
|
return request.header('x-demo') === 'secret';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { DemoRolesGuard } from './demo-roles.guard';
|
||||||
|
|
||||||
|
describe('DemoRolesGuard', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(new DemoRolesGuard()).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { Reflector } from '@nestjs/core';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DemoRolesGuard implements CanActivate {
|
||||||
|
constructor(private readonly reflector: Reflector) {}
|
||||||
|
|
||||||
|
canActivate(
|
||||||
|
context: ExecutionContext,
|
||||||
|
): boolean | Promise<boolean> | Observable<boolean> {
|
||||||
|
console.log('handler:', context.getHandler());
|
||||||
|
console.log('class:', context.getClass());
|
||||||
|
|
||||||
|
const roles = this.reflector.get<string[]>('roles', context.getHandler())
|
||||||
|
console.log(roles)
|
||||||
|
|
||||||
|
if (!roles) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const request = context.switchToHttp().getRequest();
|
||||||
|
const { user } = request;
|
||||||
|
const hasRole = () => user.roles.some(item => roles.includes(item))
|
||||||
|
|
||||||
|
return user && user.roles && hasRole();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { ErrorsInterceptor } from './errors.interceptor';
|
||||||
|
|
||||||
|
describe('ErrorsInterceptor', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(new ErrorsInterceptor()).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { CallHandler, ExecutionContext, Injectable, NestInterceptor, BadGatewayException } from '@nestjs/common';
|
||||||
|
import { Observable, throwError } from 'rxjs';
|
||||||
|
import { catchError } from 'rxjs/operators'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ErrorsInterceptor implements NestInterceptor {
|
||||||
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||||
|
return next
|
||||||
|
.handle()
|
||||||
|
.pipe(
|
||||||
|
catchError(error => throwError(new BadGatewayException()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { LoggingInterceptor } from './logging.interceptor';
|
||||||
|
|
||||||
|
describe('LoggingInterceptor', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(new LoggingInterceptor()).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { tap } from 'rxjs/operators'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LoggingInterceptor implements NestInterceptor {
|
||||||
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||||
|
console.log('I am a interceptor!')
|
||||||
|
|
||||||
|
const now = Date.now();
|
||||||
|
console.log('before...');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return next
|
||||||
|
.handle()
|
||||||
|
.pipe(
|
||||||
|
tap(() => console.log(`after... ${Date.now() - now}ms`))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { TransformInterceptor } from './transform.interceptor';
|
||||||
|
|
||||||
|
describe('TransformInterceptor', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(new TransformInterceptor()).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
export interface Response<T>{
|
||||||
|
data: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
|
||||||
|
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
|
||||||
|
return next
|
||||||
|
.handle()
|
||||||
|
.pipe(
|
||||||
|
map(item => ({data: item})) // 这个map和js那个map貌似还是有点不一样,那边返回的是一个数组呀?
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { DemoMiddleware } from './demo.middleware';
|
||||||
|
|
||||||
|
describe('DemoMiddleware', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(new DemoMiddleware()).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Injectable, NestMiddleware } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DemoMiddleware implements NestMiddleware {
|
||||||
|
use(req: any, res: any, next: () => void) {
|
||||||
|
console.log('hello ~')
|
||||||
|
req.user = {
|
||||||
|
roles: [
|
||||||
|
'guest'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.header('x-demo') === 'secret') {
|
||||||
|
req.user = {
|
||||||
|
roles: [
|
||||||
|
'member'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { DemoPipe } from './demo.pipe';
|
||||||
|
|
||||||
|
describe('DemoPipe', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(new DemoPipe()).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DemoPipe implements PipeTransform {
|
||||||
|
transform(value: any, metadata: ArgumentMetadata) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
import { DemoFilter } from './core/filters/demo.filter'
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
|
// app.useGlobalFilters(new DemoFilter());
|
||||||
await app.listen(3000);
|
await app.listen(3000);
|
||||||
}
|
}
|
||||||
bootstrap();
|
bootstrap();
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export interface Post {
|
||||||
|
title: string
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { IsString } from 'class-validator'
|
||||||
|
|
||||||
|
export class CreatePostDto {
|
||||||
|
@IsString()
|
||||||
|
readonly title: string
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { Controller, Get, Post, Req, Query, Headers, Param, Body, HttpException, HttpStatus, ForbiddenException, UseFilters, UsePipes, ValidationPipe, ParseIntPipe, UseGuards, SetMetadata, UseInterceptors } from '@nestjs/common';
|
||||||
|
import { CreatePostDto } from './post.dto';
|
||||||
|
import { DemoService } from './providers/demo/demo.service'
|
||||||
|
import { DemoFilter } from '../../core/filters/demo.filter'
|
||||||
|
import { DemoAuthGuard } from '../../core/guards/demo-auth.guard'
|
||||||
|
import { Roles } from '../../core/decorators/roles.decorator'
|
||||||
|
import { User } from '../../core/decorators/user.decorator'
|
||||||
|
import { LoggingInterceptor } from '../../core/interceptors/logging.interceptor'
|
||||||
|
import { TransformInterceptor } from '../../core/interceptors/transform.interceptor'
|
||||||
|
import { ErrorsInterceptor } from '../../core/interceptors/errors.interceptor'
|
||||||
|
|
||||||
|
@Controller('posts')
|
||||||
|
// @UseGuards(DemoAuthGuard)
|
||||||
|
// @UseFilters(DemoFilter)
|
||||||
|
// @ UseInterceptors(LoggingInterceptor)
|
||||||
|
export class PostsController {
|
||||||
|
|
||||||
|
constructor(private readonly demoService: DemoService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@UseInterceptors(TransformInterceptor)
|
||||||
|
@UseInterceptors(ErrorsInterceptor)
|
||||||
|
index() {
|
||||||
|
throw new ForbiddenException();
|
||||||
|
// return this.demoService.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
show(@Param('id', ParseIntPipe) id) {
|
||||||
|
console.log('typeof id:', typeof id);
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: `Post ${id}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
// @UseFilters(DemoFilter)
|
||||||
|
@UsePipes(ValidationPipe)
|
||||||
|
// @SetMetadata('roles', ['member', 89])
|
||||||
|
// @Roles('member', 'tester')
|
||||||
|
@Roles(...['member', 'tester'])
|
||||||
|
store(@Body() post: CreatePostDto, @User('roles') roles) {
|
||||||
|
console.log('roles:', roles)
|
||||||
|
|
||||||
|
|
||||||
|
// throw new HttpException('没有权限!', HttpStatus.FORBIDDEN)
|
||||||
|
// throw new ForbiddenException('没有权限!')
|
||||||
|
this.demoService.create(post);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { PostsController } from './posts.controller';
|
||||||
|
import { DemoService } from "./providers/demo/demo.service";
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [PostsController],
|
||||||
|
providers: [DemoService]
|
||||||
|
})
|
||||||
|
export class PostsModule {}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { DemoService } from './demo.service';
|
||||||
|
|
||||||
|
describe('DemoService', () => {
|
||||||
|
let service: DemoService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [DemoService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<DemoService>(DemoService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { Post } from 'src/modules/posts/interfaces/post.interface';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DemoService {
|
||||||
|
private readonly posts: Post[] = [];
|
||||||
|
|
||||||
|
findAll(): Post[] {
|
||||||
|
return this.posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
create(post: Post) {
|
||||||
|
this.posts.push(post);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
export class CreatePostDto {
|
|
||||||
readonly title: string
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
import { Controller, Get, Post, Req, Query, Headers, Param, Body } from '@nestjs/common';
|
|
||||||
import { CreatePostDto } from './post.dto';
|
|
||||||
|
|
||||||
@Controller('posts')
|
|
||||||
export class PostsController {
|
|
||||||
@Get()
|
|
||||||
index(@Headers('authorization') headers, @Query() query) {
|
|
||||||
console.log(headers)
|
|
||||||
console.log(query)
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
title: 'hello ~'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get(':id')
|
|
||||||
show(@Param() params) {
|
|
||||||
return {
|
|
||||||
title: `Post ${params.id}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post()
|
|
||||||
store(@Body() post: CreatePostDto) {
|
|
||||||
console.log(post)
|
|
||||||
return post
|
|
||||||
}
|
|
||||||
}
|
|
23
yarn.lock
23
yarn.lock
|
@ -797,6 +797,11 @@ ci-info@^1.5.0:
|
||||||
resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
|
resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
|
||||||
integrity sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc=
|
integrity sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc=
|
||||||
|
|
||||||
|
class-transformer@^0.2.3:
|
||||||
|
version "0.2.3"
|
||||||
|
resolved "https://registry.npm.taobao.org/class-transformer/download/class-transformer-0.2.3.tgz#598c92ca71dcca73f91ccb875d74a3847ccfa32d"
|
||||||
|
integrity sha1-WYySynHcynP5HMuHXXSjhHzPoy0=
|
||||||
|
|
||||||
class-utils@^0.3.5:
|
class-utils@^0.3.5:
|
||||||
version "0.3.6"
|
version "0.3.6"
|
||||||
resolved "https://registry.npm.taobao.org/class-utils/download/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
|
resolved "https://registry.npm.taobao.org/class-utils/download/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
|
||||||
|
@ -807,6 +812,14 @@ class-utils@^0.3.5:
|
||||||
isobject "^3.0.0"
|
isobject "^3.0.0"
|
||||||
static-extend "^0.1.1"
|
static-extend "^0.1.1"
|
||||||
|
|
||||||
|
class-validator@^0.9.1:
|
||||||
|
version "0.9.1"
|
||||||
|
resolved "https://registry.npm.taobao.org/class-validator/download/class-validator-0.9.1.tgz#d60e58c5d14abca0a41bce38cf792ad4c46d1531"
|
||||||
|
integrity sha1-1g5YxdFKvKCkG844z3kq1MRtFTE=
|
||||||
|
dependencies:
|
||||||
|
google-libphonenumber "^3.1.6"
|
||||||
|
validator "10.4.0"
|
||||||
|
|
||||||
cli-boxes@^1.0.0:
|
cli-boxes@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.npm.taobao.org/cli-boxes/download/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
|
resolved "https://registry.npm.taobao.org/cli-boxes/download/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
|
||||||
|
@ -1787,6 +1800,11 @@ globals@^9.18.0:
|
||||||
resolved "https://registry.npm.taobao.org/globals/download/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
|
resolved "https://registry.npm.taobao.org/globals/download/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
|
||||||
integrity sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=
|
integrity sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=
|
||||||
|
|
||||||
|
google-libphonenumber@^3.1.6:
|
||||||
|
version "3.2.2"
|
||||||
|
resolved "https://registry.npm.taobao.org/google-libphonenumber/download/google-libphonenumber-3.2.2.tgz#3d9d7ba727e99a50812f21b0ed313723b76c5c54"
|
||||||
|
integrity sha1-PZ17pyfpmlCBLyGw7TE3I7dsXFQ=
|
||||||
|
|
||||||
got@^6.7.1:
|
got@^6.7.1:
|
||||||
version "6.7.1"
|
version "6.7.1"
|
||||||
resolved "https://registry.npm.taobao.org/got/download/got-6.7.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fgot%2Fdownload%2Fgot-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
|
resolved "https://registry.npm.taobao.org/got/download/got-6.7.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fgot%2Fdownload%2Fgot-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
|
||||||
|
@ -4925,6 +4943,11 @@ validate-npm-package-license@^3.0.1:
|
||||||
spdx-correct "^3.0.0"
|
spdx-correct "^3.0.0"
|
||||||
spdx-expression-parse "^3.0.0"
|
spdx-expression-parse "^3.0.0"
|
||||||
|
|
||||||
|
validator@10.4.0:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://registry.npm.taobao.org/validator/download/validator-10.4.0.tgz#ee99a44afb3bb5ed350a159f056ca72a204cfc3c"
|
||||||
|
integrity sha1-7pmkSvs7te01ChWfBWynKiBM/Dw=
|
||||||
|
|
||||||
vary@^1, vary@~1.1.2:
|
vary@^1, vary@~1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||||
|
|
Loading…
Reference in New Issue