作者 陈志颖

feat:增加common

@@ -2873,6 +2873,11 @@ @@ -2873,6 +2873,11 @@
2873 "resolved": "https://registry.npmjs.org/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz", 2873 "resolved": "https://registry.npmjs.org/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz",
2874 "integrity": "sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g==" 2874 "integrity": "sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g=="
2875 }, 2875 },
  2876 + "@types/validator": {
  2877 + "version": "13.1.3",
  2878 + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.1.3.tgz",
  2879 + "integrity": "sha512-DaOWN1zf7j+8nHhqXhIgNmS+ltAC53NXqGxYuBhWqWgqolRhddKzfZU814lkHQSTG0IUfQxU7Cg0gb8fFWo2mA=="
  2880 + },
2876 "@types/webpack": { 2881 "@types/webpack": {
2877 "version": "4.41.26", 2882 "version": "4.41.26",
2878 "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz", 2883 "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz",
@@ -3642,6 +3647,155 @@ @@ -3642,6 +3647,155 @@
3642 "@apollo/protobufjs": "^1.0.3" 3647 "@apollo/protobufjs": "^1.0.3"
3643 } 3648 }
3644 }, 3649 },
  3650 + "apollo-server": {
  3651 + "version": "2.21.0",
  3652 + "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.21.0.tgz",
  3653 + "integrity": "sha512-OqngjOSB0MEH6VKGWHcrqt4y39HlhYh9CrMvn4PhadTt53IPYRmBglk5qSRA8xMorGqy60iKrOReqj5YfCjTOg==",
  3654 + "requires": {
  3655 + "apollo-server-core": "^2.21.0",
  3656 + "apollo-server-express": "^2.21.0",
  3657 + "express": "^4.0.0",
  3658 + "graphql-subscriptions": "^1.0.0",
  3659 + "graphql-tools": "^4.0.8",
  3660 + "stoppable": "^1.1.0"
  3661 + },
  3662 + "dependencies": {
  3663 + "@types/node-fetch": {
  3664 + "version": "2.5.7",
  3665 + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz",
  3666 + "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==",
  3667 + "requires": {
  3668 + "@types/node": "*",
  3669 + "form-data": "^3.0.0"
  3670 + }
  3671 + },
  3672 + "apollo-env": {
  3673 + "version": "0.6.6",
  3674 + "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.6.6.tgz",
  3675 + "integrity": "sha512-hXI9PjJtzmD34XviBU+4sPMOxnifYrHVmxpjykqI/dUD2G3yTiuRaiQqwRwB2RCdwC1Ug/jBfoQ/NHDTnnjndQ==",
  3676 + "requires": {
  3677 + "@types/node-fetch": "2.5.7",
  3678 + "core-js": "^3.0.1",
  3679 + "node-fetch": "^2.2.0",
  3680 + "sha.js": "^2.4.11"
  3681 + }
  3682 + },
  3683 + "apollo-graphql": {
  3684 + "version": "0.6.1",
  3685 + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.6.1.tgz",
  3686 + "integrity": "sha512-ZRXAV+k+hboCVS+FW86FW/QgnDR7gm/xMUwJPGXEbV53OLGuQQdIT0NCYK7AzzVkCfsbb7NJ3mmEclkZY9uuxQ==",
  3687 + "requires": {
  3688 + "apollo-env": "^0.6.6",
  3689 + "lodash.sortby": "^4.7.0"
  3690 + }
  3691 + },
  3692 + "apollo-server-core": {
  3693 + "version": "2.21.0",
  3694 + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.21.0.tgz",
  3695 + "integrity": "sha512-GtIiq2F0dVDLzzIuO5+dK/pGq/sGxYlKCqAuQQqzYg0fvZ7fukyluXtcTe0tMI+FJZjU0j0WnKgiLsboCoAlPQ==",
  3696 + "requires": {
  3697 + "@apollographql/apollo-tools": "^0.4.3",
  3698 + "@apollographql/graphql-playground-html": "1.6.26",
  3699 + "@apollographql/graphql-upload-8-fork": "^8.1.3",
  3700 + "@types/ws": "^7.0.0",
  3701 + "apollo-cache-control": "^0.11.6",
  3702 + "apollo-datasource": "^0.7.3",
  3703 + "apollo-graphql": "^0.6.0",
  3704 + "apollo-reporting-protobuf": "^0.6.2",
  3705 + "apollo-server-caching": "^0.5.3",
  3706 + "apollo-server-env": "^3.0.0",
  3707 + "apollo-server-errors": "^2.4.2",
  3708 + "apollo-server-plugin-base": "^0.10.4",
  3709 + "apollo-server-types": "^0.6.3",
  3710 + "apollo-tracing": "^0.12.2",
  3711 + "async-retry": "^1.2.1",
  3712 + "fast-json-stable-stringify": "^2.0.0",
  3713 + "graphql-extensions": "^0.12.8",
  3714 + "graphql-tag": "^2.11.0",
  3715 + "graphql-tools": "^4.0.8",
  3716 + "loglevel": "^1.6.7",
  3717 + "lru-cache": "^6.0.0",
  3718 + "sha.js": "^2.4.11",
  3719 + "subscriptions-transport-ws": "^0.9.11",
  3720 + "uuid": "^8.0.0",
  3721 + "ws": "^6.0.0"
  3722 + }
  3723 + },
  3724 + "apollo-server-env": {
  3725 + "version": "3.0.0",
  3726 + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.0.0.tgz",
  3727 + "integrity": "sha512-tPSN+VttnPsoQAl/SBVUpGbLA97MXG990XIwq6YUnJyAixrrsjW1xYG7RlaOqetxm80y5mBZKLrRDiiSsW/vog==",
  3728 + "requires": {
  3729 + "node-fetch": "^2.1.2",
  3730 + "util.promisify": "^1.0.0"
  3731 + }
  3732 + },
  3733 + "apollo-server-plugin-base": {
  3734 + "version": "0.10.4",
  3735 + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.10.4.tgz",
  3736 + "integrity": "sha512-HRhbyHgHFTLP0ImubQObYhSgpmVH4Rk1BinnceZmwudIVLKrqayIVOELdyext/QnSmmzg5W7vF3NLGBcVGMqDg==",
  3737 + "requires": {
  3738 + "apollo-server-types": "^0.6.3"
  3739 + }
  3740 + },
  3741 + "apollo-server-types": {
  3742 + "version": "0.6.3",
  3743 + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.6.3.tgz",
  3744 + "integrity": "sha512-aVR7SlSGGY41E1f11YYz5bvwA89uGmkVUtzMiklDhZ7IgRJhysT5Dflt5IuwDxp+NdQkIhVCErUXakopocFLAg==",
  3745 + "requires": {
  3746 + "apollo-reporting-protobuf": "^0.6.2",
  3747 + "apollo-server-caching": "^0.5.3",
  3748 + "apollo-server-env": "^3.0.0"
  3749 + }
  3750 + },
  3751 + "apollo-tracing": {
  3752 + "version": "0.12.2",
  3753 + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.12.2.tgz",
  3754 + "integrity": "sha512-SYN4o0C0wR1fyS3+P0FthyvsQVHFopdmN3IU64IaspR/RZScPxZ3Ae8uu++fTvkQflAkglnFM0aX6DkZERBp6w==",
  3755 + "requires": {
  3756 + "apollo-server-env": "^3.0.0",
  3757 + "apollo-server-plugin-base": "^0.10.4"
  3758 + }
  3759 + },
  3760 + "form-data": {
  3761 + "version": "3.0.1",
  3762 + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
  3763 + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
  3764 + "requires": {
  3765 + "asynckit": "^0.4.0",
  3766 + "combined-stream": "^1.0.8",
  3767 + "mime-types": "^2.1.12"
  3768 + }
  3769 + },
  3770 + "graphql-tools": {
  3771 + "version": "4.0.8",
  3772 + "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz",
  3773 + "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==",
  3774 + "requires": {
  3775 + "apollo-link": "^1.2.14",
  3776 + "apollo-utilities": "^1.0.1",
  3777 + "deprecated-decorator": "^0.1.6",
  3778 + "iterall": "^1.1.3",
  3779 + "uuid": "^3.1.0"
  3780 + },
  3781 + "dependencies": {
  3782 + "uuid": {
  3783 + "version": "3.4.0",
  3784 + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
  3785 + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
  3786 + }
  3787 + }
  3788 + },
  3789 + "ws": {
  3790 + "version": "6.2.1",
  3791 + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
  3792 + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
  3793 + "requires": {
  3794 + "async-limiter": "~1.0.0"
  3795 + }
  3796 + }
  3797 + }
  3798 + },
3645 "apollo-server-caching": { 3799 "apollo-server-caching": {
3646 "version": "0.5.3", 3800 "version": "0.5.3",
3647 "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.3.tgz", 3801 "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.3.tgz",
@@ -4804,6 +4958,11 @@ @@ -4804,6 +4958,11 @@
4804 "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", 4958 "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==",
4805 "dev": true 4959 "dev": true
4806 }, 4960 },
  4961 + "class-transformer": {
  4962 + "version": "0.4.0",
  4963 + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz",
  4964 + "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA=="
  4965 + },
4807 "class-utils": { 4966 "class-utils": {
4808 "version": "0.3.6", 4967 "version": "0.3.6",
4809 "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", 4968 "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@@ -4827,6 +4986,16 @@ @@ -4827,6 +4986,16 @@
4827 } 4986 }
4828 } 4987 }
4829 }, 4988 },
  4989 + "class-validator": {
  4990 + "version": "0.13.1",
  4991 + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.1.tgz",
  4992 + "integrity": "sha512-zWIeYFhUitvAHBwNhDdCRK09hWx+P0HUwFE8US8/CxFpMVzkUK8RJl7yOIE+BVu2lxyPNgeOaFv78tLE47jBIg==",
  4993 + "requires": {
  4994 + "@types/validator": "^13.1.3",
  4995 + "libphonenumber-js": "^1.9.7",
  4996 + "validator": "^13.5.2"
  4997 + }
  4998 + },
4830 "clean-stack": { 4999 "clean-stack": {
4831 "version": "2.2.0", 5000 "version": "2.2.0",
4832 "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", 5001 "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -8016,6 +8185,11 @@ @@ -8016,6 +8185,11 @@
8016 "type-check": "~0.4.0" 8185 "type-check": "~0.4.0"
8017 } 8186 }
8018 }, 8187 },
  8188 + "libphonenumber-js": {
  8189 + "version": "1.9.11",
  8190 + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.11.tgz",
  8191 + "integrity": "sha512-ussVs6j3k0NEU4PNwWmVNGgmZQ88YrqzAw80ztmBfEhIQr55FpjFzPoDk5sWIfOmPuY1jmCKrxWCIemkBKqSPw=="
  8192 + },
8019 "lines-and-columns": { 8193 "lines-and-columns": {
8020 "version": "1.1.6", 8194 "version": "1.1.6",
8021 "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", 8195 "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@@ -10339,6 +10513,11 @@ @@ -10339,6 +10513,11 @@
10339 "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", 10513 "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
10340 "dev": true 10514 "dev": true
10341 }, 10515 },
  10516 + "stoppable": {
  10517 + "version": "1.1.0",
  10518 + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
  10519 + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="
  10520 + },
10342 "streamsearch": { 10521 "streamsearch": {
10343 "version": "0.1.2", 10522 "version": "0.1.2",
10344 "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", 10523 "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
@@ -11283,6 +11462,11 @@ @@ -11283,6 +11462,11 @@
11283 "spdx-expression-parse": "^3.0.0" 11462 "spdx-expression-parse": "^3.0.0"
11284 } 11463 }
11285 }, 11464 },
  11465 + "validator": {
  11466 + "version": "13.5.2",
  11467 + "resolved": "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz",
  11468 + "integrity": "sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ=="
  11469 + },
11286 "vary": { 11470 "vary": {
11287 "version": "1.1.2", 11471 "version": "1.1.2",
11288 "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 11472 "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -26,7 +26,10 @@ @@ -26,7 +26,10 @@
26 "@nestjs/core": "^7.5.1", 26 "@nestjs/core": "^7.5.1",
27 "@nestjs/graphql": "^7.9.9", 27 "@nestjs/graphql": "^7.9.9",
28 "@nestjs/platform-express": "^7.5.1", 28 "@nestjs/platform-express": "^7.5.1",
  29 + "apollo-server": "^2.21.0",
29 "apollo-server-express": "^2.21.0", 30 "apollo-server-express": "^2.21.0",
  31 + "class-transformer": "^0.4.0",
  32 + "class-validator": "^0.13.1",
30 "graphql": "^15.5.0", 33 "graphql": "^15.5.0",
31 "graphql-tools": "^7.0.4", 34 "graphql-tools": "^7.0.4",
32 "nestjs-config": "^1.4.7", 35 "nestjs-config": "^1.4.7",
  1 +import { Module } from '@nestjs/common';
  2 +import { AuthorsService } from './authors.service';
  3 +import { AuthorsResolver } from './authors.resolver';
  4 +@Module({
  5 + providers: [AuthorsService, AuthorsResolver],
  6 +})
  7 +export class AuthorsModule {}
@@ -9,15 +9,25 @@ import { @@ -9,15 +9,25 @@ import {
9 Int, 9 Int,
10 } from '@nestjs/graphql'; 10 } from '@nestjs/graphql';
11 import { PubSub } from 'graphql-subscriptions'; 11 import { PubSub } from 'graphql-subscriptions';
12 -import { Author } from './models/aothor.model'; 12 +import { Author } from './models/author.model';
13 import { Post } from './models/post.model'; 13 import { Post } from './models/post.model';
14 -import { AuthorService } from './author.service'; 14 +import { AuthorsService } from './authors.service';
  15 +import { PostsService } from './posts.service';
15 16
16 const pubSub = new PubSub(); 17 const pubSub = new PubSub();
17 18
18 @Resolver(() => Author) 19 @Resolver(() => Author)
19 -export class AuthorResolver {  
20 - constructor(private authorsService: AuthorService) {} 20 +export class AuthorsResolver {
  21 + constructor(
  22 + private authorsService: AuthorsService,
  23 + private postsService: PostsService,
  24 + ) {}
  25 +
  26 + @Query((returns) => Author)
  27 + async author(@Args('id', { type: () => Int }) id: number) {
  28 + return this.authorsService.findOneById(id);
  29 + }
  30 +
21 // 根据id查询作者信息 31 // 根据id查询作者信息
22 @Query((returns) => Author, { 32 @Query((returns) => Author, {
23 name: 'author', 33 name: 'author',
1 import { Injectable } from '@nestjs/common'; 1 import { Injectable } from '@nestjs/common';
2 @Injectable() 2 @Injectable()
3 -export class AuthorService { 3 +export class AuthorsService {
4 async findOneById() {} 4 async findOneById() {}
5 -}  
  5 +}
  1 +import { ArgsType, Field, Int } from '@nestjs/graphql';
  2 +import { MinLength } from 'class-validator';
  3 +
  4 +@ArgsType()
  5 +class GetAuthorArgs {
  6 + @Field({ nullable: true })
  7 + firstName?: string;
  8 +
  9 + @Field({ defaultValue: '' })
  10 + @MinLength(3)
  11 + lastName: string;
  12 +}
  1 +import { SchemaDirectiveVisitor } from 'apollo-server';
  2 +import { defaultFieldResolver, GraphQLField } from 'graphql';
  3 +
  4 +export class UpperCaseDirective extends SchemaDirectiveVisitor {
  5 + visitFieldDefinition(field: GraphQLField<any, any>) {
  6 + const { resolve = defaultFieldResolver } = field;
  7 + field.resolve = async function (...args) {
  8 + const result = await resolve.apply(this, args);
  9 + if (typeof result === 'string') {
  10 + return result.toUpperCase();
  11 + }
  12 + return result;
  13 + };
  14 + }
  15 +}
  1 +import { Plugin } from '@nestjs/graphql';
  2 +import {
  3 + ApolloServerPlugin,
  4 + GraphQLRequestListener,
  5 +} from 'apollo-server-plugin-base';
  6 +
  7 +@Plugin()
  8 +export class LoggingPlugin implements ApolloServerPlugin {
  9 + requestDidStart(): GraphQLRequestListener {
  10 + console.log('Request started');
  11 + return {
  12 + willSendResponse() {
  13 + console.log('Will send response');
  14 + },
  15 + };
  16 + }
  17 +}
  1 +import { CustomScalar, Scalar } from '@nestjs/graphql';
  2 +import { Kind } from 'graphql';
  3 +
  4 +@Scalar('Date')
  5 +export class DateScalar implements CustomScalar<number, Date> {
  6 + description = 'Date custom scalar type';
  7 +
  8 + parseValue(value: number): Date {
  9 + return new Date(value); // value from the client
  10 + }
  11 +
  12 + serialize(value: Date): number {
  13 + return value.getTime(); // value sent to the client
  14 + }
  15 +
  16 + parseLiteral(ast: any): Date {
  17 + if (ast.kind === Kind.INT) {
  18 + return new Date(ast.value);
  19 + }
  20 + return null;
  21 + }
  22 +}
1 -import { Module } from '@nestjs/common';  
2 -import { AuthorService } from './author.service';  
3 -import { AuthorResolver } from './author.resolver';  
4 -@Module({  
5 - providers: [AuthorService, AuthorResolver],  
6 -})  
7 -export class AuthorModule {}  
1 import { Test, TestingModule } from '@nestjs/testing'; 1 import { Test, TestingModule } from '@nestjs/testing';
2 import { INestApplication } from '@nestjs/common'; 2 import { INestApplication } from '@nestjs/common';
3 import * as request from 'supertest'; 3 import * as request from 'supertest';
4 -import { AppModule } from './../src/app.module'; 4 +import { ApplicationModule } from './../src/app.module';
5 5
6 describe('AppController (e2e)', () => { 6 describe('AppController (e2e)', () => {
7 let app: INestApplication; 7 let app: INestApplication;
8 8
9 beforeEach(async () => { 9 beforeEach(async () => {
10 const moduleFixture: TestingModule = await Test.createTestingModule({ 10 const moduleFixture: TestingModule = await Test.createTestingModule({
11 - imports: [AppModule], 11 + imports: [ApplicationModule],
12 }).compile(); 12 }).compile();
13 13
14 app = moduleFixture.createNestApplication(); 14 app = moduleFixture.createNestApplication();