Merge branch 'auth'

This commit is contained in:
Jeremy Yin 2019-07-09 21:41:29 +08:00
commit 9256190503
15 changed files with 358 additions and 3 deletions

View File

@ -22,12 +22,18 @@
"dependencies": { "dependencies": {
"@nestjs/common": "^6.0.0", "@nestjs/common": "^6.0.0",
"@nestjs/core": "^6.0.0", "@nestjs/core": "^6.0.0",
"@nestjs/jwt": "^6.1.1",
"@nestjs/passport": "^6.1.0",
"@nestjs/platform-express": "^6.0.0", "@nestjs/platform-express": "^6.0.0",
"@nestjs/typeorm": "^6.1.2", "@nestjs/typeorm": "^6.1.2",
"@types/bcrypt": "^3.0.0", "@types/bcrypt": "^3.0.0",
"@types/passport": "^1.0.0",
"@types/passport-jwt": "^3.0.1",
"bcrypt": "^3.0.6", "bcrypt": "^3.0.6",
"class-transformer": "^0.2.3", "class-transformer": "^0.2.3",
"mysql": "^2.17.1", "mysql": "^2.17.1",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"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",

View File

@ -4,6 +4,7 @@ import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { PostModule } from './modules/post/post.module'; import { PostModule } from './modules/post/post.module';
import { UserModule } from './modules/user/user.module'; import { UserModule } from './modules/user/user.module';
import { AuthModule } from './modules/auth/auth.module';
@Module({ @Module({
imports: [ imports: [
@ -15,10 +16,12 @@ import { UserModule } from './modules/user/user.module';
password: 'jeremy', password: 'jeremy',
database: 'nest', database: 'nest',
synchronize: true, synchronize: true,
logging: true,
entities: [__dirname + '/**/*.entity{.ts,.js}'], entities: [__dirname + '/**/*.entity{.ts,.js}'],
}), }),
PostModule, PostModule,
UserModule, UserModule,
AuthModule,
], ],
controllers: [AppController], controllers: [AppController],
providers: [AppService], providers: [AppService],

View File

@ -0,0 +1,3 @@
import { createParamDecorator } from "@nestjs/common";
export const User = createParamDecorator((data, req) => req.user)

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
describe('Auth Controller', () => {
let controller: AuthController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
}).compile();
controller = module.get<AuthController>(AuthController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,27 @@
import { Controller, Post, Body, Get, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LoginDto } from './login.dto';
import { AuthGuard } from '@nestjs/passport';
import { User } from '../../core/decorators/user.decorator';
@Controller('auth')
export class AuthController {
constructor(
private readonly authService: AuthService,
) { }
@Post('login')
async login(@Body() data: LoginDto) {
return await this.authService.login(data)
}
@Get('test')
@UseGuards(AuthGuard())
async authTest(@User() user) {
console.log('user: ', user)
return {
message: 'ok',
}
}
}

View File

@ -0,0 +1,4 @@
export interface JwtPayload {
id: number;
username: string
}

View File

@ -0,0 +1,25 @@
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UserModule } from '../user/user.module';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './strategies/jwt.strategy';
@Module({
imports: [
UserModule,
JwtModule.register({
secret: 'nDSAR3+K4pLD+HIl9xWFY/n7maMxLwPTj5gscZvd9Vo=',
signOptions: {
expiresIn: '12h',
}
}),
PassportModule.register({
defaultStrategy: 'jwt',
}),
],
controllers: [AuthController],
providers: [AuthService, JwtStrategy]
})
export class AuthModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
describe('AuthService', () => {
let service: AuthService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AuthService],
}).compile();
service = module.get<AuthService>(AuthService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,42 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UserService } from '../user/user.service';
import { LoginDto } from './login.dto';
import { JwtPayload } from './auth.interface';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(
private readonly userService: UserService,
private readonly jwtService: JwtService,
) {}
async login(data: LoginDto) {
const { username, password } = data
const entity = await this.userService.findByUserName(username)
console.log(entity)
if (!entity) {
throw new UnauthorizedException('用户不存在')
}
const match = await entity.comparePassword(password)
console.log(match)
if (!match) {
throw new UnauthorizedException('密码错误')
}
const { id } = entity
const payload = {username, id}
const token = this.signToken(payload)
return {
...payload,
token
}
}
signToken(data: JwtPayload) {
return this.jwtService.sign(data)
}
}

View File

@ -0,0 +1,4 @@
export class LoginDto {
readonly username: string;
readonly password: string;
}

View File

@ -0,0 +1,27 @@
import { Injectable, UnauthorizedException } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy, ExtractJwt } from "passport-jwt";
import { JwtPayload } from "../auth.interface";
import { UserService } from "../../user/user.service";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private readonly userService: UserService
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'nDSAR3+K4pLD+HIl9xWFY/n7maMxLwPTj5gscZvd9Vo=',
})
}
async validate(payload: JwtPayload) {
console.log(payload)
const { username } = payload
const entity = await this.userService.findByUserName(username)
if (!entity) {
throw new UnauthorizedException('用户不存在')
}
return entity
}
}

View File

@ -27,6 +27,7 @@ export class User {
} }
async comparePassword(password: string) { async comparePassword(password: string) {
console.log(password, this.password)
return await bcrypt.compare(password, this.password); return await bcrypt.compare(password, this.password);
} }
} }

View File

@ -9,6 +9,7 @@ import { User } from './user.entity';
TypeOrmModule.forFeature([User]), TypeOrmModule.forFeature([User]),
], ],
controllers: [UserController], controllers: [UserController],
providers: [UserService] providers: [UserService],
exports: [UserService]
}) })
export class UserModule {} export class UserModule {}

View File

@ -43,4 +43,8 @@ export class UserService {
entity.password = newPassword entity.password = newPassword
return await this.userRepository.save(entity) return await this.userRepository.save(entity)
} }
async findByUserName(username: string) {
return await this.userRepository.findOne({ username })
}
} }

176
yarn.lock
View File

@ -39,6 +39,19 @@
optional "0.1.4" optional "0.1.4"
uuid "3.3.2" uuid "3.3.2"
"@nestjs/jwt@^6.1.1":
version "6.1.1"
resolved "https://registry.npm.taobao.org/@nestjs/jwt/download/@nestjs/jwt-6.1.1.tgz#78883321fc8663a7cf32aa725a70adc8454bbf5d"
integrity sha1-eIgzIfyGY6fPMqpyWnCtyEVLv10=
dependencies:
"@types/jsonwebtoken" "7.2.8"
jsonwebtoken "8.4.0"
"@nestjs/passport@^6.1.0":
version "6.1.0"
resolved "https://registry.npm.taobao.org/@nestjs/passport/download/@nestjs/passport-6.1.0.tgz#80da326cc976a82530648d8025b04c8e2d41c10e"
integrity sha1-gNoybMl2qCUwZI2AJbBMji1BwQ4=
"@nestjs/platform-express@^6.0.0": "@nestjs/platform-express@^6.0.0":
version "6.3.1" version "6.3.1"
resolved "https://registry.npm.taobao.org/@nestjs/platform-express/download/@nestjs/platform-express-6.3.1.tgz#8adb602a5bb9571b9d58646bd52141a26ea8ba3e" resolved "https://registry.npm.taobao.org/@nestjs/platform-express/download/@nestjs/platform-express-6.3.1.tgz#8adb602a5bb9571b9d58646bd52141a26ea8ba3e"
@ -105,7 +118,7 @@
"@types/node" "*" "@types/node" "*"
"@types/range-parser" "*" "@types/range-parser" "*"
"@types/express@^4.16.0": "@types/express@*", "@types/express@^4.16.0":
version "4.17.0" version "4.17.0"
resolved "https://registry.npm.taobao.org/@types/express/download/@types/express-4.17.0.tgz#49eaedb209582a86f12ed9b725160f12d04ef287" resolved "https://registry.npm.taobao.org/@types/express/download/@types/express-4.17.0.tgz#49eaedb209582a86f12ed9b725160f12d04ef287"
integrity sha1-SertsglYKobxLtm3JRYPEtBO8oc= integrity sha1-SertsglYKobxLtm3JRYPEtBO8oc=
@ -124,6 +137,20 @@
resolved "https://registry.npm.taobao.org/@types/json5/download/@types/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" resolved "https://registry.npm.taobao.org/@types/json5/download/@types/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/jsonwebtoken@*":
version "8.3.2"
resolved "https://registry.npm.taobao.org/@types/jsonwebtoken/download/@types/jsonwebtoken-8.3.2.tgz#e3d5245197152346fae7ee87d5541aa5a92d0362"
integrity sha1-49UkUZcVI0b65+6H1VQapaktA2I=
dependencies:
"@types/node" "*"
"@types/jsonwebtoken@7.2.8":
version "7.2.8"
resolved "https://registry.npm.taobao.org/@types/jsonwebtoken/download/@types/jsonwebtoken-7.2.8.tgz#8d199dab4ddb5bba3234f8311b804d2027af2b3a"
integrity sha1-jRmdq03bW7oyNPgxG4BNICevKzo=
dependencies:
"@types/node" "*"
"@types/mime@*": "@types/mime@*":
version "2.0.1" version "2.0.1"
resolved "https://registry.npm.taobao.org/@types/mime/download/@types/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" resolved "https://registry.npm.taobao.org/@types/mime/download/@types/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d"
@ -139,6 +166,30 @@
resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-10.14.9.tgz#2e8d678039d27943ce53a1913386133227fd9066" resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-10.14.9.tgz#2e8d678039d27943ce53a1913386133227fd9066"
integrity sha1-Lo1ngDnSeUPOU6GRM4YTMif9kGY= integrity sha1-Lo1ngDnSeUPOU6GRM4YTMif9kGY=
"@types/passport-jwt@^3.0.1":
version "3.0.1"
resolved "https://registry.npm.taobao.org/@types/passport-jwt/download/@types/passport-jwt-3.0.1.tgz#bc4c2610815565de977ea1a580c047d71c646084"
integrity sha1-vEwmEIFVZd6XfqGlgMBH1xxkYIQ=
dependencies:
"@types/express" "*"
"@types/jsonwebtoken" "*"
"@types/passport-strategy" "*"
"@types/passport-strategy@*":
version "0.2.35"
resolved "https://registry.npm.taobao.org/@types/passport-strategy/download/@types/passport-strategy-0.2.35.tgz#e52f5212279ea73f02d9b06af67efe9cefce2d0c"
integrity sha1-5S9SEieepz8C2bBq9n7+nO/OLQw=
dependencies:
"@types/express" "*"
"@types/passport" "*"
"@types/passport@*", "@types/passport@^1.0.0":
version "1.0.0"
resolved "https://registry.npm.taobao.org/@types/passport/download/@types/passport-1.0.0.tgz#747fa127a747a145ff279f3df3e07c425e5ff297"
integrity sha1-dH+hJ6dHoUX/J5898+B8Ql5f8pc=
dependencies:
"@types/express" "*"
"@types/range-parser@*": "@types/range-parser@*":
version "1.2.3" version "1.2.3"
resolved "https://registry.npm.taobao.org/@types/range-parser/download/@types/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" resolved "https://registry.npm.taobao.org/@types/range-parser/download/@types/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
@ -723,6 +774,11 @@ bser@^2.0.0:
dependencies: dependencies:
node-int64 "^0.4.0" node-int64 "^0.4.0"
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.npm.taobao.org/buffer-equal-constant-time/download/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
buffer-from@1.x, buffer-from@^1.0.0: buffer-from@1.x, buffer-from@^1.0.0:
version "1.1.1" version "1.1.1"
resolved "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" resolved "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@ -1311,6 +1367,13 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0" jsbn "~0.1.0"
safer-buffer "^2.1.0" safer-buffer "^2.1.0"
ecdsa-sig-formatter@1.0.11:
version "1.0.11"
resolved "https://registry.npm.taobao.org/ecdsa-sig-formatter/download/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
integrity sha1-rg8PothQRe8UqBfao86azQSJ5b8=
dependencies:
safe-buffer "^5.0.1"
ee-first@1.1.1: ee-first@1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" resolved "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -2982,6 +3045,37 @@ json5@^1.0.1:
dependencies: dependencies:
minimist "^1.2.0" minimist "^1.2.0"
jsonwebtoken@8.4.0:
version "8.4.0"
resolved "https://registry.npm.taobao.org/jsonwebtoken/download/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a"
integrity sha1-h1f3tMt0QNhtXi877O+nBTbI5Go=
dependencies:
jws "^3.1.5"
lodash.includes "^4.3.0"
lodash.isboolean "^3.0.3"
lodash.isinteger "^4.0.4"
lodash.isnumber "^3.0.3"
lodash.isplainobject "^4.0.6"
lodash.isstring "^4.0.1"
lodash.once "^4.0.0"
ms "^2.1.1"
jsonwebtoken@^8.2.0:
version "8.5.1"
resolved "https://registry.npm.taobao.org/jsonwebtoken/download/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
integrity sha1-AOceC431TCEhofJhN98igGc7zA0=
dependencies:
jws "^3.2.2"
lodash.includes "^4.3.0"
lodash.isboolean "^3.0.3"
lodash.isinteger "^4.0.4"
lodash.isnumber "^3.0.3"
lodash.isplainobject "^4.0.6"
lodash.isstring "^4.0.1"
lodash.once "^4.0.0"
ms "^2.1.1"
semver "^5.6.0"
jsprim@^1.2.2: jsprim@^1.2.2:
version "1.4.1" version "1.4.1"
resolved "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" resolved "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@ -2992,6 +3086,23 @@ jsprim@^1.2.2:
json-schema "0.2.3" json-schema "0.2.3"
verror "1.10.0" verror "1.10.0"
jwa@^1.4.1:
version "1.4.1"
resolved "https://registry.npm.taobao.org/jwa/download/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
integrity sha1-dDwymFy56YZVUw1TZBtmyGRbA5o=
dependencies:
buffer-equal-constant-time "1.0.1"
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
jws@^3.1.5, jws@^3.2.2:
version "3.2.2"
resolved "https://registry.npm.taobao.org/jws/download/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
integrity sha1-ABCZ82OUaMlBQADpmZX6UvtHgwQ=
dependencies:
jwa "^1.4.1"
safe-buffer "^5.0.1"
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2" version "3.2.2"
resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@ -3087,6 +3198,41 @@ locate-path@^3.0.0:
p-locate "^3.0.0" p-locate "^3.0.0"
path-exists "^3.0.0" path-exists "^3.0.0"
lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.npm.taobao.org/lodash.includes/download/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
lodash.isboolean@^3.0.3:
version "3.0.3"
resolved "https://registry.npm.taobao.org/lodash.isboolean/download/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
lodash.isinteger@^4.0.4:
version "4.0.4"
resolved "https://registry.npm.taobao.org/lodash.isinteger/download/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
lodash.isnumber@^3.0.3:
version "3.0.3"
resolved "https://registry.npm.taobao.org/lodash.isnumber/download/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.npm.taobao.org/lodash.isplainobject/download/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
lodash.isstring@^4.0.1:
version "4.0.1"
resolved "https://registry.npm.taobao.org/lodash.isstring/download/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
lodash.once@^4.0.0:
version "4.1.1"
resolved "https://registry.npm.taobao.org/lodash.once/download/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
lodash.sortby@^4.7.0: lodash.sortby@^4.7.0:
version "4.7.0" version "4.7.0"
resolved "https://registry.npm.taobao.org/lodash.sortby/download/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" resolved "https://registry.npm.taobao.org/lodash.sortby/download/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
@ -3822,6 +3968,27 @@ pascalcase@^0.1.1:
resolved "https://registry.npm.taobao.org/pascalcase/download/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" resolved "https://registry.npm.taobao.org/pascalcase/download/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
passport-jwt@^4.0.0:
version "4.0.0"
resolved "https://registry.npm.taobao.org/passport-jwt/download/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065"
integrity sha1-fwvnupQuKLn10iwuu7jOlu988GU=
dependencies:
jsonwebtoken "^8.2.0"
passport-strategy "^1.0.0"
passport-strategy@1.x.x, passport-strategy@^1.0.0:
version "1.0.0"
resolved "https://registry.npm.taobao.org/passport-strategy/download/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4"
integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=
passport@^0.4.0:
version "0.4.0"
resolved "https://registry.npm.taobao.org/passport/download/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811"
integrity sha1-xQlWkTR71a07XhgCOMORTRbwWBE=
dependencies:
passport-strategy "1.x.x"
pause "0.0.1"
path-dirname@^1.0.0: path-dirname@^1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.npm.taobao.org/path-dirname/download/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" resolved "https://registry.npm.taobao.org/path-dirname/download/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
@ -3873,6 +4040,11 @@ path-type@^1.0.0:
pify "^2.0.0" pify "^2.0.0"
pinkie-promise "^2.0.0" pinkie-promise "^2.0.0"
pause@0.0.1:
version "0.0.1"
resolved "https://registry.npm.taobao.org/pause/download/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d"
integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=
performance-now@^2.1.0: performance-now@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" resolved "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
@ -4335,7 +4507,7 @@ semver-diff@^2.0.0:
dependencies: dependencies:
semver "^5.0.3" semver "^5.0.3"
"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5, semver@^5.5.0: "semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5, semver@^5.5.0, semver@^5.6.0:
version "5.7.0" version "5.7.0"
resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.0.tgz?cache=0&sync_timestamp=1559063729249&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.0.tgz?cache=0&sync_timestamp=1559063729249&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
integrity sha1-eQp89v6lRZuslhELKbYEEtyP+Ws= integrity sha1-eQp89v6lRZuslhELKbYEEtyP+Ws=