├── .gitignore ├── README.md ├── backend ├── Dockerfile ├── README.md ├── generated │ └── nexus-typegen.ts ├── package-lock.json ├── package.json ├── prisma │ ├── Dockerfile │ ├── project.prisma │ └── seed.ts ├── src │ ├── index.ts │ ├── schema.graphql │ └── types.ts └── tsconfig.json ├── docker-compose.yml ├── frontend ├── Dockerfile ├── README.md ├── codegen.yml ├── components │ ├── delete-post.tsx │ ├── feed.tsx │ ├── main-layout.tsx │ ├── new-draft.tsx │ ├── publish-draft.tsx │ ├── signup-user.tsx │ └── users.tsx ├── generated │ └── apollo-components.tsx ├── graphql │ ├── fragments │ │ ├── post.gql │ │ └── user.gql │ ├── mutations │ │ ├── createDraft.gql │ │ ├── deleteOnePost.gql │ │ ├── publish.gql │ │ └── signupUser.gql │ └── queries │ │ ├── feed.gql │ │ ├── post.gql │ │ └── users.gql ├── next-env.d.ts ├── next.config.js ├── package-lock.json ├── package.json ├── pages │ ├── _app.jsx │ └── index.tsx ├── tsconfig.json └── utils │ ├── init-apollo.js │ └── with-apollo-client.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 28 | node_modules 29 | 30 | .DS_Store 31 | .next/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | docker-prisma2 2 | -------------------------------------------------------------------------------- /backend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10.16.0 2 | RUN npm install -g --unsafe-perm prisma2 3 | 4 | RUN mkdir /app 5 | WORKDIR /app 6 | 7 | COPY package*.json ./ 8 | COPY prisma ./prisma/ 9 | 10 | RUN npm install 11 | RUN prisma2 generate 12 | 13 | 14 | CMD [ "npm", "start" ] -------------------------------------------------------------------------------- /backend/README.md: -------------------------------------------------------------------------------- 1 | # GraphQL Server Example 2 | 3 | This example shows how to implement a **GraphQL server with TypeScript** based on [Photon JS](https://photonjs.prisma.io/), [graphql-yoga](https://github.com/prisma/graphql-yoga) and [GraphQL Nexus](https://nexus.js.org/). 4 | 5 | ## How to use 6 | 7 | ### 1. Download example & install dependencies 8 | 9 | Clone the repository: 10 | 11 | ``` 12 | git clone git@github.com:prisma/photonjs.git 13 | ``` 14 | 15 | Install Node dependencies: 16 | 17 | ``` 18 | cd photonjs/examples/typescript/graphql 19 | npm install 20 | ``` 21 | 22 | ### 2. Install the Prisma 2 CLI 23 | 24 | To run the example, you need the [Prisma 2 CLI](https://github.com/prisma/prisma2-docs/blob/master/prisma-2-cli.md): 25 | 26 | ``` 27 | npm install -g prisma2 28 | ``` 29 | 30 | ### 3. Set up database 31 | 32 | For this example, you'll use a simple [SQLite database](https://www.sqlite.org/index.html). To set up your database, run: 33 | 34 | ``` 35 | prisma2 lift save --name 'init' 36 | prisma2 lift up 37 | ``` 38 | 39 | You can now use the [SQLite Browser](https://sqlitebrowser.org/) to view and edit your data in the `./prisma/dev.db` file that was created when you ran `prisma2 lift up`. 40 | 41 | ### 4. Generate Photon (type-safe database client) 42 | 43 | Run the following command to generate [Photon JS](https://photonjs.prisma.io/): 44 | 45 | ``` 46 | prisma2 generate 47 | ``` 48 | 49 | Now you can seed your database using the `seed` script from `package.json`: 50 | 51 | ``` 52 | npm run seed 53 | ``` 54 | 55 | ### 5. Start the GraphQL server 56 | 57 | Launch your GraphQL server with this command: 58 | 59 | ``` 60 | npm run start 61 | ``` 62 | 63 | Navigate to [http://localhost:4000](http://localhost:4000) in your browser to explore the API of your GraphQL server in a [GraphQL Playground](https://github.com/prisma/graphql-playground). 64 | 65 | ### 6. Using the GraphQL API 66 | 67 | The schema that specifies the API operations of your GraphQL server is defined in [`./src/schema.graphql`](./src/schema.graphql). Below are a number of operations that you can send to the API using the GraphQL Playground. 68 | 69 | Feel free to adjust any operation by adding or removing fields. The GraphQL Playground helps you with its auto-completion and query validation features. 70 | 71 | #### Retrieve all published posts and their authors 72 | 73 | ```graphql 74 | query { 75 | feed { 76 | id 77 | title 78 | content 79 | published 80 | author { 81 | id 82 | name 83 | email 84 | } 85 | } 86 | } 87 | ``` 88 | 89 |
See more API operations 90 | 91 | #### Create a new user 92 | 93 | ```graphql 94 | mutation { 95 | signupUser( 96 | name: "Sarah" 97 | email: "sarah@prisma.io" 98 | ) { 99 | id 100 | } 101 | } 102 | ``` 103 | 104 | #### Create a new draft 105 | 106 | ```graphql 107 | mutation { 108 | createDraft( 109 | title: "Join the Prisma Slack" 110 | content: "https://slack.prisma.io" 111 | authorEmail: "alice@prisma.io" 112 | ) { 113 | id 114 | published 115 | } 116 | } 117 | ``` 118 | 119 | #### Publish an existing draft 120 | 121 | ```graphql 122 | mutation { 123 | publish(id: "__POST_ID__") { 124 | id 125 | published 126 | } 127 | } 128 | ``` 129 | 130 | > **Note**: You need to replace the `__POST_ID__`-placeholder with an actual `id` from a `Post` item. You can find one e.g. using the `filterPosts`-query. 131 | 132 | #### Search for posts with a specific title or content 133 | 134 | ```graphql 135 | { 136 | filterPosts(searchString: "graphql") { 137 | id 138 | title 139 | content 140 | published 141 | author { 142 | id 143 | name 144 | email 145 | } 146 | } 147 | } 148 | ``` 149 | 150 | #### Retrieve a single post 151 | 152 | ```graphql 153 | { 154 | post(id: "__POST_ID__") { 155 | id 156 | title 157 | content 158 | published 159 | author { 160 | id 161 | name 162 | email 163 | } 164 | } 165 | } 166 | ``` 167 | 168 | > **Note**: You need to replace the `__POST_ID__`-placeholder with an actual `id` from a `Post` item. You can find one e.g. using the `filterPosts`-query. 169 | 170 | #### Delete a post 171 | 172 | ```graphql 173 | mutation { 174 | deletePost(id: "__POST_ID__") { 175 | id 176 | } 177 | } 178 | ``` 179 | 180 | > **Note**: You need to replace the `__POST_ID__`-placeholder with an actual `id` from a `Post` item. You can find one e.g. using the `filterPosts`-query. 181 | 182 |
183 | 184 | ### 7. Changing the GraphQL schema 185 | 186 | To make changes to the GraphQL schema, you need to manipulate the `Query` and `Mutation` types that are defined in [`index.ts`](./src/index.ts). 187 | 188 | Note that the [`start`](./package.json#L4) script also starts a development server that automatically updates your schema every time you save a file. This way, the auto-generated [GraphQL schema](./src/schema.graphql) updates whenever you make changes in to the `Query` or `Mutation` types inside your TypeScript code. 189 | 190 | ## Next steps 191 | 192 | - Read the [Prisma 2 announcement](https://www.prisma.io/blog/announcing-prisma-2-zq1s745db8i5/) 193 | - Check out the [Prisma 2 docs](https://github.com/prisma/prisma2-docs) 194 | - Share your feedback in the [`prisma2-preview`](https://prisma.slack.com/messages/CKQTGR6T0/) channel on the Prisma Slack -------------------------------------------------------------------------------- /backend/generated/nexus-typegen.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file was automatically generated by GraphQL Nexus 3 | * Do not make changes to this file directly 4 | */ 5 | 6 | import * as ctx from "../src/types" 7 | import * as photon from "@generated/photon" 8 | import { core } from "nexus" 9 | 10 | declare global { 11 | interface NexusGenCustomOutputMethods { 12 | crud: NexusPrisma 13 | model: NexusPrisma 14 | } 15 | } 16 | 17 | declare global { 18 | interface NexusGen extends NexusGenTypes {} 19 | } 20 | 21 | export interface NexusGenInputs { 22 | PostCreateManyWithoutPostsInput: { // input type 23 | connect?: NexusGenInputs['PostWhereUniqueInput'][] | null; // [PostWhereUniqueInput!] 24 | create?: NexusGenInputs['PostCreateWithoutAuthorInput'][] | null; // [PostCreateWithoutAuthorInput!] 25 | } 26 | PostCreateWithoutAuthorInput: { // input type 27 | content?: string | null; // String 28 | id?: string | null; // ID 29 | published: boolean; // Boolean! 30 | title: string; // String! 31 | } 32 | PostWhereUniqueInput: { // input type 33 | id?: string | null; // ID 34 | } 35 | UserCreateInput: { // input type 36 | email: string; // String! 37 | id?: string | null; // ID 38 | name?: string | null; // String 39 | posts?: NexusGenInputs['PostCreateManyWithoutPostsInput'] | null; // PostCreateManyWithoutPostsInput 40 | } 41 | } 42 | 43 | export interface NexusGenEnums { 44 | } 45 | 46 | export interface NexusGenRootTypes { 47 | Mutation: {}; 48 | Post: photon.Post; 49 | Query: {}; 50 | User: photon.User; 51 | String: string; 52 | Int: number; 53 | Float: number; 54 | Boolean: boolean; 55 | ID: string; 56 | DateTime: any; 57 | } 58 | 59 | export interface NexusGenAllTypes extends NexusGenRootTypes { 60 | PostCreateManyWithoutPostsInput: NexusGenInputs['PostCreateManyWithoutPostsInput']; 61 | PostCreateWithoutAuthorInput: NexusGenInputs['PostCreateWithoutAuthorInput']; 62 | PostWhereUniqueInput: NexusGenInputs['PostWhereUniqueInput']; 63 | UserCreateInput: NexusGenInputs['UserCreateInput']; 64 | } 65 | 66 | export interface NexusGenFieldTypes { 67 | Mutation: { // field return type 68 | createDraft: NexusGenRootTypes['Post']; // Post! 69 | deleteOnePost: NexusGenRootTypes['Post'] | null; // Post 70 | publish: NexusGenRootTypes['Post'] | null; // Post 71 | signupUser: NexusGenRootTypes['User']; // User! 72 | } 73 | Post: { // field return type 74 | content: string | null; // String 75 | createdAt: any; // DateTime! 76 | id: string; // ID! 77 | published: boolean; // Boolean! 78 | title: string; // String! 79 | updatedAt: any; // DateTime! 80 | } 81 | Query: { // field return type 82 | feed: NexusGenRootTypes['Post'][]; // [Post!]! 83 | filterPosts: NexusGenRootTypes['Post'][]; // [Post!]! 84 | post: NexusGenRootTypes['Post'] | null; // Post 85 | users: NexusGenRootTypes['User'][]; // [User!]! 86 | } 87 | User: { // field return type 88 | email: string; // String! 89 | id: string; // ID! 90 | name: string | null; // String 91 | posts: NexusGenRootTypes['Post'][] | null; // [Post!] 92 | } 93 | } 94 | 95 | export interface NexusGenArgTypes { 96 | Mutation: { 97 | createDraft: { // args 98 | authorEmail?: string | null; // String 99 | content?: string | null; // String 100 | title?: string | null; // String 101 | } 102 | deleteOnePost: { // args 103 | where: NexusGenInputs['PostWhereUniqueInput']; // PostWhereUniqueInput! 104 | } 105 | publish: { // args 106 | id?: string | null; // ID 107 | } 108 | signupUser: { // args 109 | data: NexusGenInputs['UserCreateInput']; // UserCreateInput! 110 | } 111 | } 112 | Query: { 113 | feed: { // args 114 | published?: boolean | null; // Boolean 115 | } 116 | filterPosts: { // args 117 | searchString?: string | null; // String 118 | } 119 | post: { // args 120 | where: NexusGenInputs['PostWhereUniqueInput']; // PostWhereUniqueInput! 121 | } 122 | } 123 | User: { 124 | posts: { // args 125 | after?: string | null; // String 126 | before?: string | null; // String 127 | first?: number | null; // Int 128 | last?: number | null; // Int 129 | skip?: number | null; // Int 130 | } 131 | } 132 | } 133 | 134 | export interface NexusGenAbstractResolveReturnTypes { 135 | } 136 | 137 | export interface NexusGenInheritedFields {} 138 | 139 | export type NexusGenObjectNames = "Mutation" | "Post" | "Query" | "User"; 140 | 141 | export type NexusGenInputNames = "PostCreateManyWithoutPostsInput" | "PostCreateWithoutAuthorInput" | "PostWhereUniqueInput" | "UserCreateInput"; 142 | 143 | export type NexusGenEnumNames = never; 144 | 145 | export type NexusGenInterfaceNames = never; 146 | 147 | export type NexusGenScalarNames = "Boolean" | "DateTime" | "Float" | "ID" | "Int" | "String"; 148 | 149 | export type NexusGenUnionNames = never; 150 | 151 | export interface NexusGenTypes { 152 | context: ctx.Context; 153 | inputTypes: NexusGenInputs; 154 | rootTypes: NexusGenRootTypes; 155 | argTypes: NexusGenArgTypes; 156 | fieldTypes: NexusGenFieldTypes; 157 | allTypes: NexusGenAllTypes; 158 | inheritedFields: NexusGenInheritedFields; 159 | objectNames: NexusGenObjectNames; 160 | inputNames: NexusGenInputNames; 161 | enumNames: NexusGenEnumNames; 162 | interfaceNames: NexusGenInterfaceNames; 163 | scalarNames: NexusGenScalarNames; 164 | unionNames: NexusGenUnionNames; 165 | allInputTypes: NexusGenTypes['inputNames'] | NexusGenTypes['enumNames'] | NexusGenTypes['scalarNames']; 166 | allOutputTypes: NexusGenTypes['objectNames'] | NexusGenTypes['enumNames'] | NexusGenTypes['unionNames'] | NexusGenTypes['interfaceNames'] | NexusGenTypes['scalarNames']; 167 | allNamedTypes: NexusGenTypes['allInputTypes'] | NexusGenTypes['allOutputTypes'] 168 | abstractTypes: NexusGenTypes['interfaceNames'] | NexusGenTypes['unionNames']; 169 | abstractResolveReturn: NexusGenAbstractResolveReturnTypes; 170 | } -------------------------------------------------------------------------------- /backend/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-graphql", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "@prisma/nexus": { 7 | "version": "0.0.1", 8 | "resolved": "https://registry.npmjs.org/@prisma/nexus/-/nexus-0.0.1.tgz", 9 | "integrity": "sha512-eRAbVUOLPr0copaj7u7Q9w2hlPNHp77XuOMC+O7dmYiM/204Gl7Whp1SCmGq98hjb3NaJbNMJpq3lfJL4GTgqg==", 10 | "requires": { 11 | "tslib": "^1.9.3" 12 | } 13 | }, 14 | "@types/body-parser": { 15 | "version": "1.17.0", 16 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", 17 | "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==", 18 | "requires": { 19 | "@types/connect": "*", 20 | "@types/node": "*" 21 | }, 22 | "dependencies": { 23 | "@types/node": { 24 | "version": "12.0.10", 25 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.10.tgz", 26 | "integrity": "sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ==" 27 | } 28 | } 29 | }, 30 | "@types/connect": { 31 | "version": "3.4.32", 32 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", 33 | "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", 34 | "requires": { 35 | "@types/node": "*" 36 | }, 37 | "dependencies": { 38 | "@types/node": { 39 | "version": "12.0.10", 40 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.10.tgz", 41 | "integrity": "sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ==" 42 | } 43 | } 44 | }, 45 | "@types/cors": { 46 | "version": "2.8.5", 47 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.5.tgz", 48 | "integrity": "sha512-GmK8AKu8i+s+EChK/uZ5IbrXPcPaQKWaNSGevDT/7o3gFObwSUQwqb1jMqxuo+YPvj0ckGzINI+EO7EHcmJjKg==", 49 | "requires": { 50 | "@types/express": "*" 51 | } 52 | }, 53 | "@types/express": { 54 | "version": "4.17.0", 55 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.0.tgz", 56 | "integrity": "sha512-CjaMu57cjgjuZbh9DpkloeGxV45CnMGlVd+XpG7Gm9QgVrd7KFq+X4HY0vM+2v0bczS48Wg7bvnMY5TN+Xmcfw==", 57 | "requires": { 58 | "@types/body-parser": "*", 59 | "@types/express-serve-static-core": "*", 60 | "@types/serve-static": "*" 61 | } 62 | }, 63 | "@types/express-serve-static-core": { 64 | "version": "4.16.7", 65 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.7.tgz", 66 | "integrity": "sha512-847KvL8Q1y3TtFLRTXcVakErLJQgdpFSaq+k043xefz9raEf0C7HalpSY7OW5PyjCnY8P7bPW5t/Co9qqp+USg==", 67 | "requires": { 68 | "@types/node": "*", 69 | "@types/range-parser": "*" 70 | }, 71 | "dependencies": { 72 | "@types/node": { 73 | "version": "12.0.10", 74 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.10.tgz", 75 | "integrity": "sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ==" 76 | } 77 | } 78 | }, 79 | "@types/graphql": { 80 | "version": "14.2.2", 81 | "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-14.2.2.tgz", 82 | "integrity": "sha512-okXbUmdZFMO3AYBEJCcpJFPFDkKmIiZZBqWD5TmPtAv+GHfjD2qLZEI0PvZ8IWMU4ozoK2HV2lDxWjw4LbVlnw==" 83 | }, 84 | "@types/graphql-deduplicator": { 85 | "version": "2.0.0", 86 | "resolved": "https://registry.npmjs.org/@types/graphql-deduplicator/-/graphql-deduplicator-2.0.0.tgz", 87 | "integrity": "sha512-swUwj5hWF1yFzbUXStLJrUa0ksAt11B8+SwhsAjQAX0LYJ1LLioAyuDcJ9bovWbsNzIXJYXLvljSPQw8nR728w==" 88 | }, 89 | "@types/mime": { 90 | "version": "2.0.1", 91 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", 92 | "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" 93 | }, 94 | "@types/node": { 95 | "version": "10.14.9", 96 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.9.tgz", 97 | "integrity": "sha512-NelG/dSahlXYtSoVPErrp06tYFrvzj8XLWmKA+X8x0W//4MqbUyZu++giUG/v0bjAT6/Qxa8IjodrfdACyb0Fg==", 98 | "dev": true 99 | }, 100 | "@types/range-parser": { 101 | "version": "1.2.3", 102 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", 103 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" 104 | }, 105 | "@types/serve-static": { 106 | "version": "1.13.2", 107 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz", 108 | "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==", 109 | "requires": { 110 | "@types/express-serve-static-core": "*", 111 | "@types/mime": "*" 112 | } 113 | }, 114 | "@types/strip-bom": { 115 | "version": "3.0.0", 116 | "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", 117 | "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", 118 | "dev": true 119 | }, 120 | "@types/strip-json-comments": { 121 | "version": "0.0.30", 122 | "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", 123 | "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", 124 | "dev": true 125 | }, 126 | "@types/zen-observable": { 127 | "version": "0.5.4", 128 | "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.5.4.tgz", 129 | "integrity": "sha512-sW6xN96wUak4tgc89d0tbTg7QDGYhGv5hvQIS6h4mRCd8h2btiZ80loPU8cyLwsBbA4ZeQt0FjvUhJ4rNhdsGg==" 130 | }, 131 | "@wry/equality": { 132 | "version": "0.1.9", 133 | "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.9.tgz", 134 | "integrity": "sha512-mB6ceGjpMGz1ZTza8HYnrPGos2mC6So4NhS1PtZ8s4Qt0K7fBiIGhpSxUbQmhwcSWE3no+bYxmI2OL6KuXYmoQ==", 135 | "requires": { 136 | "tslib": "^1.9.3" 137 | } 138 | }, 139 | "accepts": { 140 | "version": "1.3.7", 141 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 142 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 143 | "requires": { 144 | "mime-types": "~2.1.24", 145 | "negotiator": "0.6.2" 146 | } 147 | }, 148 | "apollo-cache-control": { 149 | "version": "0.1.1", 150 | "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz", 151 | "integrity": "sha512-XJQs167e9u+e5ybSi51nGYr70NPBbswdvTEHtbtXbwkZ+n9t0SLPvUcoqceayOSwjK1XYOdU/EKPawNdb3rLQA==", 152 | "requires": { 153 | "graphql-extensions": "^0.0.x" 154 | } 155 | }, 156 | "apollo-link": { 157 | "version": "1.2.12", 158 | "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.12.tgz", 159 | "integrity": "sha512-fsgIAXPKThyMVEMWQsUN22AoQI+J/pVXcjRGAShtk97h7D8O+SPskFinCGEkxPeQpE83uKaqafB2IyWdjN+J3Q==", 160 | "requires": { 161 | "apollo-utilities": "^1.3.0", 162 | "ts-invariant": "^0.4.0", 163 | "tslib": "^1.9.3", 164 | "zen-observable-ts": "^0.8.19" 165 | } 166 | }, 167 | "apollo-server-core": { 168 | "version": "1.4.0", 169 | "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-1.4.0.tgz", 170 | "integrity": "sha512-BP1Vh39krgEjkQxbjTdBURUjLHbFq1zeOChDJgaRsMxGtlhzuLWwwC6lLdPatN8jEPbeHq8Tndp9QZ3iQZOKKA==", 171 | "requires": { 172 | "apollo-cache-control": "^0.1.0", 173 | "apollo-tracing": "^0.1.0", 174 | "graphql-extensions": "^0.0.x" 175 | } 176 | }, 177 | "apollo-server-express": { 178 | "version": "1.4.0", 179 | "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-1.4.0.tgz", 180 | "integrity": "sha512-zkH00nxhLnJfO0HgnNPBTfZw8qI5ILaPZ5TecMCI9+Y9Ssr2b0bFr9pBRsXy9eudPhI+/O4yqegSUsnLdF/CPw==", 181 | "requires": { 182 | "apollo-server-core": "^1.4.0", 183 | "apollo-server-module-graphiql": "^1.4.0" 184 | } 185 | }, 186 | "apollo-server-lambda": { 187 | "version": "1.3.6", 188 | "resolved": "https://registry.npmjs.org/apollo-server-lambda/-/apollo-server-lambda-1.3.6.tgz", 189 | "integrity": "sha1-varDfxQ8Z5jkC4rnVYC6ZzzqJg4=", 190 | "requires": { 191 | "apollo-server-core": "^1.3.6", 192 | "apollo-server-module-graphiql": "^1.3.4" 193 | } 194 | }, 195 | "apollo-server-module-graphiql": { 196 | "version": "1.4.0", 197 | "resolved": "https://registry.npmjs.org/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz", 198 | "integrity": "sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA==" 199 | }, 200 | "apollo-tracing": { 201 | "version": "0.1.4", 202 | "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.1.4.tgz", 203 | "integrity": "sha512-Uv+1nh5AsNmC3m130i2u3IqbS+nrxyVV3KYimH5QKsdPjxxIQB3JAT+jJmpeDxBel8gDVstNmCh82QSLxLSIdQ==", 204 | "requires": { 205 | "graphql-extensions": "~0.0.9" 206 | } 207 | }, 208 | "apollo-upload-server": { 209 | "version": "7.1.0", 210 | "resolved": "https://registry.npmjs.org/apollo-upload-server/-/apollo-upload-server-7.1.0.tgz", 211 | "integrity": "sha512-cD9ReCeyurYwZyEDqJYb5TOc9dt8yhPzS+MtrY3iJdqw+pqiiyPngAvVXHjN+Ca7Lajvom4/AT/PBrYVDMM3Kw==", 212 | "requires": { 213 | "busboy": "^0.2.14", 214 | "fs-capacitor": "^1.0.0", 215 | "http-errors": "^1.7.0", 216 | "object-path": "^0.11.4" 217 | } 218 | }, 219 | "apollo-utilities": { 220 | "version": "1.3.2", 221 | "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.2.tgz", 222 | "integrity": "sha512-JWNHj8XChz7S4OZghV6yc9FNnzEXj285QYp/nLNh943iObycI5GTDO3NGR9Dth12LRrSFMeDOConPfPln+WGfg==", 223 | "requires": { 224 | "@wry/equality": "^0.1.2", 225 | "fast-json-stable-stringify": "^2.0.0", 226 | "ts-invariant": "^0.4.0", 227 | "tslib": "^1.9.3" 228 | } 229 | }, 230 | "arg": { 231 | "version": "4.1.0", 232 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", 233 | "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", 234 | "dev": true 235 | }, 236 | "array-find-index": { 237 | "version": "1.0.2", 238 | "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", 239 | "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", 240 | "dev": true 241 | }, 242 | "array-flatten": { 243 | "version": "1.1.1", 244 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 245 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 246 | }, 247 | "async-limiter": { 248 | "version": "1.0.0", 249 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", 250 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" 251 | }, 252 | "aws-lambda": { 253 | "version": "0.1.2", 254 | "resolved": "https://registry.npmjs.org/aws-lambda/-/aws-lambda-0.1.2.tgz", 255 | "integrity": "sha1-GbFYUHXfMWeVl7l2pfHe9h8SzO4=", 256 | "requires": { 257 | "aws-sdk": "^*", 258 | "commander": "^2.5.0", 259 | "dotenv": "^0.4.0" 260 | } 261 | }, 262 | "aws-sdk": { 263 | "version": "2.485.0", 264 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.485.0.tgz", 265 | "integrity": "sha512-VTmsIPrf9yblghjM5P7hCUG9ysYB+m67mo6/laWeJeGWLxePwtfvVAjhmmXkOJIv0JFSwNfJJ5KpI3Mtu0avsQ==", 266 | "requires": { 267 | "buffer": "4.9.1", 268 | "events": "1.1.1", 269 | "ieee754": "1.1.8", 270 | "jmespath": "0.15.0", 271 | "querystring": "0.2.0", 272 | "sax": "1.2.1", 273 | "url": "0.10.3", 274 | "uuid": "3.3.2", 275 | "xml2js": "0.4.19" 276 | } 277 | }, 278 | "backo2": { 279 | "version": "1.0.2", 280 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", 281 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" 282 | }, 283 | "balanced-match": { 284 | "version": "1.0.0", 285 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 286 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 287 | "dev": true 288 | }, 289 | "base64-js": { 290 | "version": "1.3.0", 291 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", 292 | "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" 293 | }, 294 | "body-parser": { 295 | "version": "1.19.0", 296 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 297 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 298 | "requires": { 299 | "bytes": "3.1.0", 300 | "content-type": "~1.0.4", 301 | "debug": "2.6.9", 302 | "depd": "~1.1.2", 303 | "http-errors": "1.7.2", 304 | "iconv-lite": "0.4.24", 305 | "on-finished": "~2.3.0", 306 | "qs": "6.7.0", 307 | "raw-body": "2.4.0", 308 | "type-is": "~1.6.17" 309 | }, 310 | "dependencies": { 311 | "http-errors": { 312 | "version": "1.7.2", 313 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 314 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 315 | "requires": { 316 | "depd": "~1.1.2", 317 | "inherits": "2.0.3", 318 | "setprototypeof": "1.1.1", 319 | "statuses": ">= 1.5.0 < 2", 320 | "toidentifier": "1.0.0" 321 | } 322 | }, 323 | "inherits": { 324 | "version": "2.0.3", 325 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 326 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 327 | } 328 | } 329 | }, 330 | "body-parser-graphql": { 331 | "version": "1.1.0", 332 | "resolved": "https://registry.npmjs.org/body-parser-graphql/-/body-parser-graphql-1.1.0.tgz", 333 | "integrity": "sha512-bOBF4n1AnUjcY1SzLeibeIx4XOuYqEkjn/Lm4yKhnN6KedoXMv4hVqgcKHGRnxOMJP64tErqrQU+4cihhpbJXg==", 334 | "requires": { 335 | "body-parser": "^1.18.2" 336 | } 337 | }, 338 | "brace-expansion": { 339 | "version": "1.1.11", 340 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 341 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 342 | "dev": true, 343 | "requires": { 344 | "balanced-match": "^1.0.0", 345 | "concat-map": "0.0.1" 346 | } 347 | }, 348 | "buffer": { 349 | "version": "4.9.1", 350 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", 351 | "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", 352 | "requires": { 353 | "base64-js": "^1.0.2", 354 | "ieee754": "^1.1.4", 355 | "isarray": "^1.0.0" 356 | }, 357 | "dependencies": { 358 | "isarray": { 359 | "version": "1.0.0", 360 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 361 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 362 | } 363 | } 364 | }, 365 | "buffer-from": { 366 | "version": "1.1.1", 367 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 368 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 369 | }, 370 | "busboy": { 371 | "version": "0.2.14", 372 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", 373 | "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", 374 | "requires": { 375 | "dicer": "0.2.5", 376 | "readable-stream": "1.1.x" 377 | } 378 | }, 379 | "bytes": { 380 | "version": "3.1.0", 381 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 382 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 383 | }, 384 | "camelcase": { 385 | "version": "2.1.1", 386 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", 387 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", 388 | "dev": true 389 | }, 390 | "camelcase-keys": { 391 | "version": "2.1.0", 392 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", 393 | "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", 394 | "dev": true, 395 | "requires": { 396 | "camelcase": "^2.0.0", 397 | "map-obj": "^1.0.0" 398 | } 399 | }, 400 | "commander": { 401 | "version": "2.20.0", 402 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", 403 | "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" 404 | }, 405 | "concat-map": { 406 | "version": "0.0.1", 407 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 408 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 409 | "dev": true 410 | }, 411 | "content-disposition": { 412 | "version": "0.5.3", 413 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 414 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 415 | "requires": { 416 | "safe-buffer": "5.1.2" 417 | } 418 | }, 419 | "content-type": { 420 | "version": "1.0.4", 421 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 422 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 423 | }, 424 | "cookie": { 425 | "version": "0.4.0", 426 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 427 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 428 | }, 429 | "cookie-signature": { 430 | "version": "1.0.6", 431 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 432 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 433 | }, 434 | "core-js": { 435 | "version": "2.6.9", 436 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", 437 | "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" 438 | }, 439 | "core-util-is": { 440 | "version": "1.0.2", 441 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 442 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 443 | }, 444 | "cors": { 445 | "version": "2.8.5", 446 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 447 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 448 | "requires": { 449 | "object-assign": "^4", 450 | "vary": "^1" 451 | } 452 | }, 453 | "currently-unhandled": { 454 | "version": "0.4.1", 455 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", 456 | "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", 457 | "dev": true, 458 | "requires": { 459 | "array-find-index": "^1.0.1" 460 | } 461 | }, 462 | "dateformat": { 463 | "version": "1.0.12", 464 | "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", 465 | "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", 466 | "dev": true, 467 | "requires": { 468 | "get-stdin": "^4.0.1", 469 | "meow": "^3.3.0" 470 | } 471 | }, 472 | "debounce": { 473 | "version": "1.2.0", 474 | "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz", 475 | "integrity": "sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg==", 476 | "dev": true 477 | }, 478 | "debug": { 479 | "version": "2.6.9", 480 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 481 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 482 | "requires": { 483 | "ms": "2.0.0" 484 | } 485 | }, 486 | "decamelize": { 487 | "version": "1.2.0", 488 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 489 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 490 | "dev": true 491 | }, 492 | "depd": { 493 | "version": "1.1.2", 494 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 495 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 496 | }, 497 | "deprecated-decorator": { 498 | "version": "0.1.6", 499 | "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", 500 | "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=" 501 | }, 502 | "destroy": { 503 | "version": "1.0.4", 504 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 505 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 506 | }, 507 | "dicer": { 508 | "version": "0.2.5", 509 | "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", 510 | "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", 511 | "requires": { 512 | "readable-stream": "1.1.x", 513 | "streamsearch": "0.1.2" 514 | } 515 | }, 516 | "diff": { 517 | "version": "4.0.1", 518 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", 519 | "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", 520 | "dev": true 521 | }, 522 | "dotenv": { 523 | "version": "0.4.0", 524 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-0.4.0.tgz", 525 | "integrity": "sha1-9vs1E2PC2SIHJFxzeALJq1rhSVo=" 526 | }, 527 | "dynamic-dedupe": { 528 | "version": "0.3.0", 529 | "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", 530 | "integrity": "sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=", 531 | "dev": true, 532 | "requires": { 533 | "xtend": "^4.0.0" 534 | } 535 | }, 536 | "ee-first": { 537 | "version": "1.1.1", 538 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 539 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 540 | }, 541 | "encodeurl": { 542 | "version": "1.0.2", 543 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 544 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 545 | }, 546 | "error-ex": { 547 | "version": "1.3.2", 548 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 549 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 550 | "dev": true, 551 | "requires": { 552 | "is-arrayish": "^0.2.1" 553 | } 554 | }, 555 | "escape-html": { 556 | "version": "1.0.3", 557 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 558 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 559 | }, 560 | "etag": { 561 | "version": "1.8.1", 562 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 563 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 564 | }, 565 | "eventemitter3": { 566 | "version": "3.1.2", 567 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", 568 | "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" 569 | }, 570 | "events": { 571 | "version": "1.1.1", 572 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", 573 | "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" 574 | }, 575 | "express": { 576 | "version": "4.17.1", 577 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 578 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 579 | "requires": { 580 | "accepts": "~1.3.7", 581 | "array-flatten": "1.1.1", 582 | "body-parser": "1.19.0", 583 | "content-disposition": "0.5.3", 584 | "content-type": "~1.0.4", 585 | "cookie": "0.4.0", 586 | "cookie-signature": "1.0.6", 587 | "debug": "2.6.9", 588 | "depd": "~1.1.2", 589 | "encodeurl": "~1.0.2", 590 | "escape-html": "~1.0.3", 591 | "etag": "~1.8.1", 592 | "finalhandler": "~1.1.2", 593 | "fresh": "0.5.2", 594 | "merge-descriptors": "1.0.1", 595 | "methods": "~1.1.2", 596 | "on-finished": "~2.3.0", 597 | "parseurl": "~1.3.3", 598 | "path-to-regexp": "0.1.7", 599 | "proxy-addr": "~2.0.5", 600 | "qs": "6.7.0", 601 | "range-parser": "~1.2.1", 602 | "safe-buffer": "5.1.2", 603 | "send": "0.17.1", 604 | "serve-static": "1.14.1", 605 | "setprototypeof": "1.1.1", 606 | "statuses": "~1.5.0", 607 | "type-is": "~1.6.18", 608 | "utils-merge": "1.0.1", 609 | "vary": "~1.1.2" 610 | } 611 | }, 612 | "fast-json-stable-stringify": { 613 | "version": "2.0.0", 614 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 615 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 616 | }, 617 | "filewatcher": { 618 | "version": "3.0.1", 619 | "resolved": "https://registry.npmjs.org/filewatcher/-/filewatcher-3.0.1.tgz", 620 | "integrity": "sha1-9KGVc1Xdr0Q8zXiolfPVXiPIoDQ=", 621 | "dev": true, 622 | "requires": { 623 | "debounce": "^1.0.0" 624 | } 625 | }, 626 | "finalhandler": { 627 | "version": "1.1.2", 628 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 629 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 630 | "requires": { 631 | "debug": "2.6.9", 632 | "encodeurl": "~1.0.2", 633 | "escape-html": "~1.0.3", 634 | "on-finished": "~2.3.0", 635 | "parseurl": "~1.3.3", 636 | "statuses": "~1.5.0", 637 | "unpipe": "~1.0.0" 638 | } 639 | }, 640 | "find-up": { 641 | "version": "1.1.2", 642 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 643 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 644 | "dev": true, 645 | "requires": { 646 | "path-exists": "^2.0.0", 647 | "pinkie-promise": "^2.0.0" 648 | } 649 | }, 650 | "forwarded": { 651 | "version": "0.1.2", 652 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 653 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 654 | }, 655 | "fresh": { 656 | "version": "0.5.2", 657 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 658 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 659 | }, 660 | "fs-capacitor": { 661 | "version": "1.0.1", 662 | "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-1.0.1.tgz", 663 | "integrity": "sha512-XdZK0Q78WP29Vm3FGgJRhRhrBm51PagovzWtW2kJ3Q6cYJbGtZqWSGTSPwvtEkyjIirFd7b8Yes/dpOYjt4RRQ==" 664 | }, 665 | "fs.realpath": { 666 | "version": "1.0.0", 667 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 668 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 669 | "dev": true 670 | }, 671 | "get-stdin": { 672 | "version": "4.0.1", 673 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", 674 | "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", 675 | "dev": true 676 | }, 677 | "glob": { 678 | "version": "7.1.4", 679 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", 680 | "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", 681 | "dev": true, 682 | "requires": { 683 | "fs.realpath": "^1.0.0", 684 | "inflight": "^1.0.4", 685 | "inherits": "2", 686 | "minimatch": "^3.0.4", 687 | "once": "^1.3.0", 688 | "path-is-absolute": "^1.0.0" 689 | } 690 | }, 691 | "graceful-fs": { 692 | "version": "4.2.0", 693 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", 694 | "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", 695 | "dev": true 696 | }, 697 | "graphql": { 698 | "version": "14.4.1", 699 | "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.4.1.tgz", 700 | "integrity": "sha512-g4HUH26CohlMjaHneXMAtvG3QtO6peJIUTFxrPW4g5LNnXkUuFoBI6Bk1c14Q5kW8+FyjM/tTbePTgpiVB/2hQ==", 701 | "requires": { 702 | "iterall": "^1.2.2" 703 | } 704 | }, 705 | "graphql-deduplicator": { 706 | "version": "2.0.3", 707 | "resolved": "https://registry.npmjs.org/graphql-deduplicator/-/graphql-deduplicator-2.0.3.tgz", 708 | "integrity": "sha512-ldfdY0o4TxhcM2qzJO48TrJHwKCb/wetJxUAzD9e73GI1fZiKLD3I/tIpMwTBqYUNfTqaoOWayUFtA/1KbIvlQ==" 709 | }, 710 | "graphql-extensions": { 711 | "version": "0.0.10", 712 | "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.0.10.tgz", 713 | "integrity": "sha512-TnQueqUDCYzOSrpQb3q1ngDSP2otJSF+9yNLrQGPzkMsvnQ+v6e2d5tl+B35D4y+XpmvVnAn4T3ZK28mkILveA==", 714 | "requires": { 715 | "core-js": "^2.5.3", 716 | "source-map-support": "^0.5.1" 717 | } 718 | }, 719 | "graphql-import": { 720 | "version": "0.7.1", 721 | "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.7.1.tgz", 722 | "integrity": "sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw==", 723 | "requires": { 724 | "lodash": "^4.17.4", 725 | "resolve-from": "^4.0.0" 726 | } 727 | }, 728 | "graphql-middleware": { 729 | "version": "3.0.2", 730 | "resolved": "https://registry.npmjs.org/graphql-middleware/-/graphql-middleware-3.0.2.tgz", 731 | "integrity": "sha512-sRqu1sF+77z42z1OVM1QDHKQWnWY5K3nAgqWiZwx3U4tqNZprrDuXxSChPMliV343IrVkpYdejUYq9w24Ot3FA==", 732 | "requires": { 733 | "graphql-tools": "^4.0.4" 734 | } 735 | }, 736 | "graphql-playground-html": { 737 | "version": "1.6.12", 738 | "resolved": "https://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.6.12.tgz", 739 | "integrity": "sha512-yOYFwwSMBL0MwufeL8bkrNDgRE7eF/kTHiwrqn9FiR9KLcNIl1xw9l9a+6yIRZM56JReQOHpbQFXTZn1IuSKRg==" 740 | }, 741 | "graphql-playground-middleware-express": { 742 | "version": "1.7.11", 743 | "resolved": "https://registry.npmjs.org/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.11.tgz", 744 | "integrity": "sha512-sKItB4s3FxqlwCgXdMfwRAfssSoo31bcFsGAAg/HzaZLicY6CDlofKXP8G5iPDerB6NaoAcAaBLutLzl9sd4fQ==", 745 | "requires": { 746 | "graphql-playground-html": "1.6.12" 747 | } 748 | }, 749 | "graphql-playground-middleware-lambda": { 750 | "version": "1.7.12", 751 | "resolved": "https://registry.npmjs.org/graphql-playground-middleware-lambda/-/graphql-playground-middleware-lambda-1.7.12.tgz", 752 | "integrity": "sha512-fJ1Y0Ck5ctmfaQFoWv7vNnVP7We19P3miVmOT85YPrjpzbMYv0wPfxm4Zjt8nnqXr0KU9nGW53tz3K7/Lvzxtw==", 753 | "requires": { 754 | "graphql-playground-html": "1.6.12" 755 | } 756 | }, 757 | "graphql-subscriptions": { 758 | "version": "0.5.8", 759 | "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz", 760 | "integrity": "sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ==", 761 | "requires": { 762 | "iterall": "^1.2.1" 763 | } 764 | }, 765 | "graphql-tools": { 766 | "version": "4.0.5", 767 | "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.5.tgz", 768 | "integrity": "sha512-kQCh3IZsMqquDx7zfIGWBau42xe46gmqabwYkpPlCLIjcEY1XK+auP7iGRD9/205BPyoQdY8hT96MPpgERdC9Q==", 769 | "requires": { 770 | "apollo-link": "^1.2.3", 771 | "apollo-utilities": "^1.0.1", 772 | "deprecated-decorator": "^0.1.6", 773 | "iterall": "^1.1.3", 774 | "uuid": "^3.1.0" 775 | } 776 | }, 777 | "graphql-yoga": { 778 | "version": "1.17.4", 779 | "resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-1.17.4.tgz", 780 | "integrity": "sha512-zOXFtmS43xDLoECKiuA3xVWH/wLDvLH1D/5fBKcaMFdF43ifDfnA9N6dlGggqAoOhqBnrqHwDpoKlJ6sI1LuxA==", 781 | "requires": { 782 | "@types/cors": "^2.8.4", 783 | "@types/express": "^4.11.1", 784 | "@types/graphql": "^14.0.0", 785 | "@types/graphql-deduplicator": "^2.0.0", 786 | "@types/zen-observable": "^0.5.3", 787 | "apollo-server-express": "^1.3.6", 788 | "apollo-server-lambda": "1.3.6", 789 | "apollo-upload-server": "^7.0.0", 790 | "aws-lambda": "^0.1.2", 791 | "body-parser-graphql": "1.1.0", 792 | "cors": "^2.8.4", 793 | "express": "^4.16.3", 794 | "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0", 795 | "graphql-deduplicator": "^2.0.1", 796 | "graphql-import": "^0.7.0", 797 | "graphql-middleware": "3.0.2", 798 | "graphql-playground-middleware-express": "1.7.11", 799 | "graphql-playground-middleware-lambda": "1.7.12", 800 | "graphql-subscriptions": "^0.5.8", 801 | "graphql-tools": "^4.0.0", 802 | "subscriptions-transport-ws": "^0.9.8" 803 | } 804 | }, 805 | "growly": { 806 | "version": "1.3.0", 807 | "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", 808 | "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", 809 | "dev": true 810 | }, 811 | "hosted-git-info": { 812 | "version": "2.7.1", 813 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", 814 | "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", 815 | "dev": true 816 | }, 817 | "http-errors": { 818 | "version": "1.7.3", 819 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", 820 | "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", 821 | "requires": { 822 | "depd": "~1.1.2", 823 | "inherits": "2.0.4", 824 | "setprototypeof": "1.1.1", 825 | "statuses": ">= 1.5.0 < 2", 826 | "toidentifier": "1.0.0" 827 | } 828 | }, 829 | "iconv-lite": { 830 | "version": "0.4.24", 831 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 832 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 833 | "requires": { 834 | "safer-buffer": ">= 2.1.2 < 3" 835 | } 836 | }, 837 | "ieee754": { 838 | "version": "1.1.8", 839 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", 840 | "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" 841 | }, 842 | "indent-string": { 843 | "version": "2.1.0", 844 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", 845 | "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", 846 | "dev": true, 847 | "requires": { 848 | "repeating": "^2.0.0" 849 | } 850 | }, 851 | "inflight": { 852 | "version": "1.0.6", 853 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 854 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 855 | "dev": true, 856 | "requires": { 857 | "once": "^1.3.0", 858 | "wrappy": "1" 859 | } 860 | }, 861 | "inherits": { 862 | "version": "2.0.4", 863 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 864 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 865 | }, 866 | "ipaddr.js": { 867 | "version": "1.9.0", 868 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", 869 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" 870 | }, 871 | "is-arrayish": { 872 | "version": "0.2.1", 873 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 874 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 875 | "dev": true 876 | }, 877 | "is-finite": { 878 | "version": "1.0.2", 879 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", 880 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", 881 | "dev": true, 882 | "requires": { 883 | "number-is-nan": "^1.0.0" 884 | } 885 | }, 886 | "is-utf8": { 887 | "version": "0.2.1", 888 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 889 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", 890 | "dev": true 891 | }, 892 | "is-wsl": { 893 | "version": "1.1.0", 894 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", 895 | "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", 896 | "dev": true 897 | }, 898 | "isarray": { 899 | "version": "0.0.1", 900 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 901 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 902 | }, 903 | "isexe": { 904 | "version": "2.0.0", 905 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 906 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 907 | "dev": true 908 | }, 909 | "iterall": { 910 | "version": "1.2.2", 911 | "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", 912 | "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" 913 | }, 914 | "jmespath": { 915 | "version": "0.15.0", 916 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", 917 | "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" 918 | }, 919 | "load-json-file": { 920 | "version": "1.1.0", 921 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", 922 | "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", 923 | "dev": true, 924 | "requires": { 925 | "graceful-fs": "^4.1.2", 926 | "parse-json": "^2.2.0", 927 | "pify": "^2.0.0", 928 | "pinkie-promise": "^2.0.0", 929 | "strip-bom": "^2.0.0" 930 | } 931 | }, 932 | "lodash": { 933 | "version": "4.17.11", 934 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", 935 | "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" 936 | }, 937 | "loud-rejection": { 938 | "version": "1.6.0", 939 | "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", 940 | "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", 941 | "dev": true, 942 | "requires": { 943 | "currently-unhandled": "^0.4.1", 944 | "signal-exit": "^3.0.0" 945 | } 946 | }, 947 | "make-error": { 948 | "version": "1.3.5", 949 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", 950 | "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", 951 | "dev": true 952 | }, 953 | "map-obj": { 954 | "version": "1.0.1", 955 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", 956 | "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", 957 | "dev": true 958 | }, 959 | "media-typer": { 960 | "version": "0.3.0", 961 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 962 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 963 | }, 964 | "meow": { 965 | "version": "3.7.0", 966 | "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", 967 | "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", 968 | "dev": true, 969 | "requires": { 970 | "camelcase-keys": "^2.0.0", 971 | "decamelize": "^1.1.2", 972 | "loud-rejection": "^1.0.0", 973 | "map-obj": "^1.0.1", 974 | "minimist": "^1.1.3", 975 | "normalize-package-data": "^2.3.4", 976 | "object-assign": "^4.0.1", 977 | "read-pkg-up": "^1.0.1", 978 | "redent": "^1.0.0", 979 | "trim-newlines": "^1.0.0" 980 | } 981 | }, 982 | "merge-descriptors": { 983 | "version": "1.0.1", 984 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 985 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 986 | }, 987 | "methods": { 988 | "version": "1.1.2", 989 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 990 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 991 | }, 992 | "mime": { 993 | "version": "1.6.0", 994 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 995 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 996 | }, 997 | "mime-db": { 998 | "version": "1.40.0", 999 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 1000 | "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" 1001 | }, 1002 | "mime-types": { 1003 | "version": "2.1.24", 1004 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 1005 | "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", 1006 | "requires": { 1007 | "mime-db": "1.40.0" 1008 | } 1009 | }, 1010 | "minimatch": { 1011 | "version": "3.0.4", 1012 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1013 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1014 | "dev": true, 1015 | "requires": { 1016 | "brace-expansion": "^1.1.7" 1017 | } 1018 | }, 1019 | "minimist": { 1020 | "version": "1.2.0", 1021 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 1022 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 1023 | "dev": true 1024 | }, 1025 | "mkdirp": { 1026 | "version": "0.5.1", 1027 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1028 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1029 | "dev": true, 1030 | "requires": { 1031 | "minimist": "0.0.8" 1032 | }, 1033 | "dependencies": { 1034 | "minimist": { 1035 | "version": "0.0.8", 1036 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1037 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 1038 | "dev": true 1039 | } 1040 | } 1041 | }, 1042 | "ms": { 1043 | "version": "2.0.0", 1044 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1045 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1046 | }, 1047 | "negotiator": { 1048 | "version": "0.6.2", 1049 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 1050 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 1051 | }, 1052 | "nexus": { 1053 | "version": "0.11.7", 1054 | "resolved": "https://registry.npmjs.org/nexus/-/nexus-0.11.7.tgz", 1055 | "integrity": "sha512-d5iD9jKn8n8tfFerisxYmKlrJmj5omPS49+s1xv2O2q5GiagDH4ySxajg0vsf0EMT2K+OvlCuSxT0xarS1gqKw==", 1056 | "requires": { 1057 | "tslib": "^1.9.3" 1058 | } 1059 | }, 1060 | "node-notifier": { 1061 | "version": "5.4.0", 1062 | "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", 1063 | "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", 1064 | "dev": true, 1065 | "requires": { 1066 | "growly": "^1.3.0", 1067 | "is-wsl": "^1.1.0", 1068 | "semver": "^5.5.0", 1069 | "shellwords": "^0.1.1", 1070 | "which": "^1.3.0" 1071 | } 1072 | }, 1073 | "normalize-package-data": { 1074 | "version": "2.5.0", 1075 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", 1076 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", 1077 | "dev": true, 1078 | "requires": { 1079 | "hosted-git-info": "^2.1.4", 1080 | "resolve": "^1.10.0", 1081 | "semver": "2 || 3 || 4 || 5", 1082 | "validate-npm-package-license": "^3.0.1" 1083 | } 1084 | }, 1085 | "number-is-nan": { 1086 | "version": "1.0.1", 1087 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 1088 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 1089 | "dev": true 1090 | }, 1091 | "object-assign": { 1092 | "version": "4.1.1", 1093 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1094 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1095 | }, 1096 | "object-path": { 1097 | "version": "0.11.4", 1098 | "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", 1099 | "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" 1100 | }, 1101 | "on-finished": { 1102 | "version": "2.3.0", 1103 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1104 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1105 | "requires": { 1106 | "ee-first": "1.1.1" 1107 | } 1108 | }, 1109 | "once": { 1110 | "version": "1.4.0", 1111 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1112 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1113 | "dev": true, 1114 | "requires": { 1115 | "wrappy": "1" 1116 | } 1117 | }, 1118 | "parse-json": { 1119 | "version": "2.2.0", 1120 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 1121 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 1122 | "dev": true, 1123 | "requires": { 1124 | "error-ex": "^1.2.0" 1125 | } 1126 | }, 1127 | "parseurl": { 1128 | "version": "1.3.3", 1129 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1130 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 1131 | }, 1132 | "path-exists": { 1133 | "version": "2.1.0", 1134 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 1135 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 1136 | "dev": true, 1137 | "requires": { 1138 | "pinkie-promise": "^2.0.0" 1139 | } 1140 | }, 1141 | "path-is-absolute": { 1142 | "version": "1.0.1", 1143 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1144 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1145 | "dev": true 1146 | }, 1147 | "path-parse": { 1148 | "version": "1.0.6", 1149 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 1150 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 1151 | "dev": true 1152 | }, 1153 | "path-to-regexp": { 1154 | "version": "0.1.7", 1155 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1156 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1157 | }, 1158 | "path-type": { 1159 | "version": "1.1.0", 1160 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", 1161 | "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", 1162 | "dev": true, 1163 | "requires": { 1164 | "graceful-fs": "^4.1.2", 1165 | "pify": "^2.0.0", 1166 | "pinkie-promise": "^2.0.0" 1167 | } 1168 | }, 1169 | "pify": { 1170 | "version": "2.3.0", 1171 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1172 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 1173 | "dev": true 1174 | }, 1175 | "pinkie": { 1176 | "version": "2.0.4", 1177 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1178 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 1179 | "dev": true 1180 | }, 1181 | "pinkie-promise": { 1182 | "version": "2.0.1", 1183 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1184 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1185 | "dev": true, 1186 | "requires": { 1187 | "pinkie": "^2.0.0" 1188 | } 1189 | }, 1190 | "proxy-addr": { 1191 | "version": "2.0.5", 1192 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", 1193 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", 1194 | "requires": { 1195 | "forwarded": "~0.1.2", 1196 | "ipaddr.js": "1.9.0" 1197 | } 1198 | }, 1199 | "punycode": { 1200 | "version": "1.3.2", 1201 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 1202 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" 1203 | }, 1204 | "qs": { 1205 | "version": "6.7.0", 1206 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 1207 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 1208 | }, 1209 | "querystring": { 1210 | "version": "0.2.0", 1211 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 1212 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" 1213 | }, 1214 | "range-parser": { 1215 | "version": "1.2.1", 1216 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1217 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 1218 | }, 1219 | "raw-body": { 1220 | "version": "2.4.0", 1221 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 1222 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 1223 | "requires": { 1224 | "bytes": "3.1.0", 1225 | "http-errors": "1.7.2", 1226 | "iconv-lite": "0.4.24", 1227 | "unpipe": "1.0.0" 1228 | }, 1229 | "dependencies": { 1230 | "http-errors": { 1231 | "version": "1.7.2", 1232 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 1233 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 1234 | "requires": { 1235 | "depd": "~1.1.2", 1236 | "inherits": "2.0.3", 1237 | "setprototypeof": "1.1.1", 1238 | "statuses": ">= 1.5.0 < 2", 1239 | "toidentifier": "1.0.0" 1240 | } 1241 | }, 1242 | "inherits": { 1243 | "version": "2.0.3", 1244 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1245 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 1246 | } 1247 | } 1248 | }, 1249 | "read-pkg": { 1250 | "version": "1.1.0", 1251 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", 1252 | "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", 1253 | "dev": true, 1254 | "requires": { 1255 | "load-json-file": "^1.0.0", 1256 | "normalize-package-data": "^2.3.2", 1257 | "path-type": "^1.0.0" 1258 | } 1259 | }, 1260 | "read-pkg-up": { 1261 | "version": "1.0.1", 1262 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", 1263 | "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", 1264 | "dev": true, 1265 | "requires": { 1266 | "find-up": "^1.0.0", 1267 | "read-pkg": "^1.0.0" 1268 | } 1269 | }, 1270 | "readable-stream": { 1271 | "version": "1.1.14", 1272 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 1273 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 1274 | "requires": { 1275 | "core-util-is": "~1.0.0", 1276 | "inherits": "~2.0.1", 1277 | "isarray": "0.0.1", 1278 | "string_decoder": "~0.10.x" 1279 | } 1280 | }, 1281 | "redent": { 1282 | "version": "1.0.0", 1283 | "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", 1284 | "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", 1285 | "dev": true, 1286 | "requires": { 1287 | "indent-string": "^2.1.0", 1288 | "strip-indent": "^1.0.1" 1289 | } 1290 | }, 1291 | "repeating": { 1292 | "version": "2.0.1", 1293 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", 1294 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", 1295 | "dev": true, 1296 | "requires": { 1297 | "is-finite": "^1.0.0" 1298 | } 1299 | }, 1300 | "resolve": { 1301 | "version": "1.11.1", 1302 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", 1303 | "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", 1304 | "dev": true, 1305 | "requires": { 1306 | "path-parse": "^1.0.6" 1307 | } 1308 | }, 1309 | "resolve-from": { 1310 | "version": "4.0.0", 1311 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1312 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" 1313 | }, 1314 | "rimraf": { 1315 | "version": "2.6.3", 1316 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1317 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1318 | "dev": true, 1319 | "requires": { 1320 | "glob": "^7.1.3" 1321 | } 1322 | }, 1323 | "safe-buffer": { 1324 | "version": "5.1.2", 1325 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1326 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1327 | }, 1328 | "safer-buffer": { 1329 | "version": "2.1.2", 1330 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1331 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1332 | }, 1333 | "sax": { 1334 | "version": "1.2.1", 1335 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", 1336 | "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" 1337 | }, 1338 | "semver": { 1339 | "version": "5.7.0", 1340 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", 1341 | "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", 1342 | "dev": true 1343 | }, 1344 | "send": { 1345 | "version": "0.17.1", 1346 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 1347 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 1348 | "requires": { 1349 | "debug": "2.6.9", 1350 | "depd": "~1.1.2", 1351 | "destroy": "~1.0.4", 1352 | "encodeurl": "~1.0.2", 1353 | "escape-html": "~1.0.3", 1354 | "etag": "~1.8.1", 1355 | "fresh": "0.5.2", 1356 | "http-errors": "~1.7.2", 1357 | "mime": "1.6.0", 1358 | "ms": "2.1.1", 1359 | "on-finished": "~2.3.0", 1360 | "range-parser": "~1.2.1", 1361 | "statuses": "~1.5.0" 1362 | }, 1363 | "dependencies": { 1364 | "ms": { 1365 | "version": "2.1.1", 1366 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1367 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 1368 | } 1369 | } 1370 | }, 1371 | "serve-static": { 1372 | "version": "1.14.1", 1373 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 1374 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 1375 | "requires": { 1376 | "encodeurl": "~1.0.2", 1377 | "escape-html": "~1.0.3", 1378 | "parseurl": "~1.3.3", 1379 | "send": "0.17.1" 1380 | } 1381 | }, 1382 | "setprototypeof": { 1383 | "version": "1.1.1", 1384 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 1385 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 1386 | }, 1387 | "shellwords": { 1388 | "version": "0.1.1", 1389 | "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", 1390 | "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", 1391 | "dev": true 1392 | }, 1393 | "signal-exit": { 1394 | "version": "3.0.2", 1395 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1396 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 1397 | "dev": true 1398 | }, 1399 | "source-map": { 1400 | "version": "0.6.1", 1401 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1402 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 1403 | }, 1404 | "source-map-support": { 1405 | "version": "0.5.12", 1406 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", 1407 | "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", 1408 | "requires": { 1409 | "buffer-from": "^1.0.0", 1410 | "source-map": "^0.6.0" 1411 | } 1412 | }, 1413 | "spdx-correct": { 1414 | "version": "3.1.0", 1415 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", 1416 | "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", 1417 | "dev": true, 1418 | "requires": { 1419 | "spdx-expression-parse": "^3.0.0", 1420 | "spdx-license-ids": "^3.0.0" 1421 | } 1422 | }, 1423 | "spdx-exceptions": { 1424 | "version": "2.2.0", 1425 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", 1426 | "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", 1427 | "dev": true 1428 | }, 1429 | "spdx-expression-parse": { 1430 | "version": "3.0.0", 1431 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 1432 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 1433 | "dev": true, 1434 | "requires": { 1435 | "spdx-exceptions": "^2.1.0", 1436 | "spdx-license-ids": "^3.0.0" 1437 | } 1438 | }, 1439 | "spdx-license-ids": { 1440 | "version": "3.0.4", 1441 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", 1442 | "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", 1443 | "dev": true 1444 | }, 1445 | "statuses": { 1446 | "version": "1.5.0", 1447 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1448 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 1449 | }, 1450 | "streamsearch": { 1451 | "version": "0.1.2", 1452 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", 1453 | "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" 1454 | }, 1455 | "string_decoder": { 1456 | "version": "0.10.31", 1457 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1458 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 1459 | }, 1460 | "strip-bom": { 1461 | "version": "2.0.0", 1462 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", 1463 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", 1464 | "dev": true, 1465 | "requires": { 1466 | "is-utf8": "^0.2.0" 1467 | } 1468 | }, 1469 | "strip-indent": { 1470 | "version": "1.0.1", 1471 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", 1472 | "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", 1473 | "dev": true, 1474 | "requires": { 1475 | "get-stdin": "^4.0.1" 1476 | } 1477 | }, 1478 | "strip-json-comments": { 1479 | "version": "2.0.1", 1480 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1481 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1482 | "dev": true 1483 | }, 1484 | "subscriptions-transport-ws": { 1485 | "version": "0.9.16", 1486 | "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.16.tgz", 1487 | "integrity": "sha512-pQdoU7nC+EpStXnCfh/+ho0zE0Z+ma+i7xvj7bkXKb1dvYHSZxgRPaU6spRP+Bjzow67c/rRDoix5RT0uU9omw==", 1488 | "requires": { 1489 | "backo2": "^1.0.2", 1490 | "eventemitter3": "^3.1.0", 1491 | "iterall": "^1.2.1", 1492 | "symbol-observable": "^1.0.4", 1493 | "ws": "^5.2.0" 1494 | } 1495 | }, 1496 | "symbol-observable": { 1497 | "version": "1.2.0", 1498 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", 1499 | "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" 1500 | }, 1501 | "toidentifier": { 1502 | "version": "1.0.0", 1503 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 1504 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 1505 | }, 1506 | "tree-kill": { 1507 | "version": "1.2.1", 1508 | "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", 1509 | "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", 1510 | "dev": true 1511 | }, 1512 | "trim-newlines": { 1513 | "version": "1.0.0", 1514 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", 1515 | "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", 1516 | "dev": true 1517 | }, 1518 | "ts-invariant": { 1519 | "version": "0.4.4", 1520 | "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", 1521 | "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", 1522 | "requires": { 1523 | "tslib": "^1.9.3" 1524 | } 1525 | }, 1526 | "ts-node": { 1527 | "version": "8.3.0", 1528 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", 1529 | "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", 1530 | "dev": true, 1531 | "requires": { 1532 | "arg": "^4.1.0", 1533 | "diff": "^4.0.1", 1534 | "make-error": "^1.1.1", 1535 | "source-map-support": "^0.5.6", 1536 | "yn": "^3.0.0" 1537 | } 1538 | }, 1539 | "ts-node-dev": { 1540 | "version": "1.0.0-pre.40", 1541 | "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.0.0-pre.40.tgz", 1542 | "integrity": "sha512-78CptStf6oA5wKkRXQPEMBR5zowhnw2bvCETRMhkz2DsuussA56s6lKgUX4EiMMiPkyYdSm8jkJ875j4eo4nkQ==", 1543 | "dev": true, 1544 | "requires": { 1545 | "dateformat": "~1.0.4-1.2.3", 1546 | "dynamic-dedupe": "^0.3.0", 1547 | "filewatcher": "~3.0.0", 1548 | "minimist": "^1.1.3", 1549 | "mkdirp": "^0.5.1", 1550 | "node-notifier": "^5.4.0", 1551 | "resolve": "^1.0.0", 1552 | "rimraf": "^2.6.1", 1553 | "source-map-support": "^0.5.12", 1554 | "tree-kill": "^1.2.1", 1555 | "ts-node": "*", 1556 | "tsconfig": "^7.0.0" 1557 | } 1558 | }, 1559 | "tsconfig": { 1560 | "version": "7.0.0", 1561 | "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", 1562 | "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", 1563 | "dev": true, 1564 | "requires": { 1565 | "@types/strip-bom": "^3.0.0", 1566 | "@types/strip-json-comments": "0.0.30", 1567 | "strip-bom": "^3.0.0", 1568 | "strip-json-comments": "^2.0.0" 1569 | }, 1570 | "dependencies": { 1571 | "strip-bom": { 1572 | "version": "3.0.0", 1573 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 1574 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", 1575 | "dev": true 1576 | } 1577 | } 1578 | }, 1579 | "tslib": { 1580 | "version": "1.10.0", 1581 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", 1582 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" 1583 | }, 1584 | "type-is": { 1585 | "version": "1.6.18", 1586 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1587 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1588 | "requires": { 1589 | "media-typer": "0.3.0", 1590 | "mime-types": "~2.1.24" 1591 | } 1592 | }, 1593 | "typescript": { 1594 | "version": "3.5.2", 1595 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz", 1596 | "integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==", 1597 | "dev": true 1598 | }, 1599 | "unpipe": { 1600 | "version": "1.0.0", 1601 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1602 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1603 | }, 1604 | "url": { 1605 | "version": "0.10.3", 1606 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", 1607 | "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", 1608 | "requires": { 1609 | "punycode": "1.3.2", 1610 | "querystring": "0.2.0" 1611 | } 1612 | }, 1613 | "utils-merge": { 1614 | "version": "1.0.1", 1615 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1616 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1617 | }, 1618 | "uuid": { 1619 | "version": "3.3.2", 1620 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 1621 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 1622 | }, 1623 | "validate-npm-package-license": { 1624 | "version": "3.0.4", 1625 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 1626 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 1627 | "dev": true, 1628 | "requires": { 1629 | "spdx-correct": "^3.0.0", 1630 | "spdx-expression-parse": "^3.0.0" 1631 | } 1632 | }, 1633 | "vary": { 1634 | "version": "1.1.2", 1635 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1636 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1637 | }, 1638 | "which": { 1639 | "version": "1.3.1", 1640 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1641 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1642 | "dev": true, 1643 | "requires": { 1644 | "isexe": "^2.0.0" 1645 | } 1646 | }, 1647 | "wrappy": { 1648 | "version": "1.0.2", 1649 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1650 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1651 | "dev": true 1652 | }, 1653 | "ws": { 1654 | "version": "5.2.2", 1655 | "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", 1656 | "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", 1657 | "requires": { 1658 | "async-limiter": "~1.0.0" 1659 | } 1660 | }, 1661 | "xml2js": { 1662 | "version": "0.4.19", 1663 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", 1664 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", 1665 | "requires": { 1666 | "sax": ">=0.6.0", 1667 | "xmlbuilder": "~9.0.1" 1668 | } 1669 | }, 1670 | "xmlbuilder": { 1671 | "version": "9.0.7", 1672 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", 1673 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" 1674 | }, 1675 | "xtend": { 1676 | "version": "4.0.1", 1677 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 1678 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", 1679 | "dev": true 1680 | }, 1681 | "yn": { 1682 | "version": "3.1.0", 1683 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.0.tgz", 1684 | "integrity": "sha512-kKfnnYkbTfrAdd0xICNFw7Atm8nKpLcLv9AZGEt+kczL/WQVai4e2V6ZN8U/O+iI6WrNuJjNNOyu4zfhl9D3Hg==", 1685 | "dev": true 1686 | }, 1687 | "zen-observable": { 1688 | "version": "0.8.14", 1689 | "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.14.tgz", 1690 | "integrity": "sha512-kQz39uonEjEESwh+qCi83kcC3rZJGh4mrZW7xjkSQYXkq//JZHTtKo+6yuVloTgMtzsIWOJrjIrKvk/dqm0L5g==" 1691 | }, 1692 | "zen-observable-ts": { 1693 | "version": "0.8.19", 1694 | "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.19.tgz", 1695 | "integrity": "sha512-u1a2rpE13G+jSzrg3aiCqXU5tN2kw41b+cBZGmnc+30YimdkKiDj9bTowcB41eL77/17RF/h+393AuVgShyheQ==", 1696 | "requires": { 1697 | "tslib": "^1.9.3", 1698 | "zen-observable": "^0.8.0" 1699 | } 1700 | } 1701 | } 1702 | } 1703 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-graphql", 3 | "scripts": { 4 | "start": "ts-node-dev --no-notify --respawn --transpileOnly ./src", 5 | "seed": "ts-node prisma/seed.ts", 6 | "postinstall": "prisma2 generate" 7 | }, 8 | "dependencies": { 9 | "@prisma/nexus": "^0.0.1", 10 | "graphql-yoga": "1.17.4", 11 | "nexus": "0.11.7" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "10.14.9", 15 | "ts-node": "^8.3.0", 16 | "ts-node-dev": "1.0.0-pre.40", 17 | "typescript": "3.5.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /backend/prisma/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10.16.0 2 | RUN npm install -g --unsafe-perm prisma2 3 | 4 | RUN mkdir /app 5 | WORKDIR /app 6 | 7 | COPY ./ ./prisma/ 8 | 9 | CMD [ "prisma2", "dev"] 10 | -------------------------------------------------------------------------------- /backend/prisma/project.prisma: -------------------------------------------------------------------------------- 1 | 2 | datasource db { 3 | provider = "mysql" 4 | url = "mysql://root:prisma@mysql:3306/prisma" 5 | } 6 | 7 | generator photon { 8 | provider = "photonjs" 9 | } 10 | 11 | generator nexus_prisma { 12 | provider = "nexus-prisma" 13 | output = "node_modules/@generated/nexus-prisma" 14 | } 15 | 16 | model User { 17 | id String @default(cuid()) @id @unique 18 | email String @unique 19 | name String? 20 | posts Post[] 21 | } 22 | 23 | model Post { 24 | id String @default(cuid()) @id @unique 25 | createdAt DateTime @default(now()) 26 | updatedAt DateTime @updatedAt 27 | published Boolean 28 | title String 29 | content String? 30 | author User? 31 | } -------------------------------------------------------------------------------- /backend/prisma/seed.ts: -------------------------------------------------------------------------------- 1 | import Photon from '@generated/photon' 2 | const photon = new Photon() 3 | 4 | async function main() { 5 | const user1 = await photon.users.create({ 6 | data: { 7 | email: 'alice@prisma.io', 8 | name: 'Alice', 9 | posts: { 10 | create: { 11 | title: 'Join us for Prisma Day 2019 in Berlin', 12 | content: 'https://www.prisma.io/day/', 13 | published: true, 14 | }, 15 | }, 16 | }, 17 | }) 18 | const user2 = await photon.users.create({ 19 | data: { 20 | email: 'bob@prisma.io', 21 | name: 'Bob', 22 | posts: { 23 | create: [ 24 | { 25 | title: 'Subscribe to GraphQL Weekly for community news', 26 | content: 'https://graphqlweekly.com/', 27 | published: true, 28 | }, 29 | { 30 | title: 'Follow Prisma on Twitter', 31 | content: 'https://twitter.com/prisma', 32 | published: false, 33 | }, 34 | ], 35 | }, 36 | }, 37 | }) 38 | 39 | console.log({ user1, user2 }) 40 | } 41 | 42 | main() 43 | .catch(e => console.error(e)) 44 | .finally(async () => { 45 | await photon.disconnect() 46 | }) 47 | -------------------------------------------------------------------------------- /backend/src/index.ts: -------------------------------------------------------------------------------- 1 | import { nexusPrismaPlugin } from '@generated/nexus-prisma'; 2 | import Photon from '@generated/photon'; 3 | import { idArg, makeSchema, objectType, stringArg, booleanArg } from '@prisma/nexus'; 4 | import { GraphQLServer } from 'graphql-yoga'; 5 | import { join } from 'path'; 6 | import { Context } from './types'; 7 | 8 | const photon = new Photon(); 9 | 10 | const nexusPrisma = nexusPrismaPlugin({ 11 | photon: (ctx: Context) => ctx.photon 12 | }); 13 | 14 | export const User = objectType({ 15 | name: 'User', 16 | definition(t) { 17 | t.model.id(); 18 | t.model.name(); 19 | t.model.email(); 20 | t.model.posts({ 21 | pagination: false 22 | }); 23 | } 24 | }); 25 | 26 | export const Post = objectType({ 27 | name: 'Post', 28 | definition(t) { 29 | t.model.id(); 30 | t.model.title(); 31 | t.model.content(); 32 | t.model.createdAt(); 33 | t.model.updatedAt(); 34 | t.model.published(); 35 | } 36 | }); 37 | 38 | const Query = objectType({ 39 | name: 'Query', 40 | definition(t) { 41 | t.crud.findOnePost({ 42 | alias: 'post' 43 | }); 44 | 45 | t.list.field('users', { 46 | type: 'User', 47 | resolve: (parent, args, ctx) => { 48 | return ctx.photon.users.findMany({}); 49 | } 50 | }); 51 | 52 | t.list.field('feed', { 53 | type: 'Post', 54 | args: { 55 | published: booleanArg() 56 | }, 57 | resolve: (parent, { published }, ctx) => { 58 | return ctx.photon.posts.findMany({ 59 | where: { published } 60 | }); 61 | } 62 | }); 63 | 64 | t.list.field('filterPosts', { 65 | type: 'Post', 66 | args: { 67 | searchString: stringArg({ nullable: true }) 68 | }, 69 | resolve: (parent, { searchString }, ctx) => { 70 | return ctx.photon.posts.findMany({ 71 | where: { 72 | OR: [ 73 | { 74 | title: { 75 | contains: searchString 76 | } 77 | }, 78 | { 79 | content: { 80 | contains: searchString 81 | } 82 | } 83 | ] 84 | } 85 | }); 86 | } 87 | }); 88 | } 89 | }); 90 | 91 | const Mutation = objectType({ 92 | name: 'Mutation', 93 | definition(t) { 94 | t.crud.createOneUser({ alias: 'signupUser' }); 95 | t.crud.deleteOnePost(); 96 | 97 | t.field('createDraft', { 98 | type: 'Post', 99 | args: { 100 | title: stringArg(), 101 | content: stringArg({ nullable: true }), 102 | authorEmail: stringArg() 103 | }, 104 | resolve: (parent, { title, content, authorEmail }, ctx) => { 105 | return ctx.photon.posts.create({ 106 | data: { 107 | title, 108 | content, 109 | published: false, 110 | author: { 111 | connect: { email: authorEmail } 112 | } 113 | } 114 | }); 115 | } 116 | }); 117 | 118 | t.field('publish', { 119 | type: 'Post', 120 | nullable: true, 121 | args: { 122 | id: idArg() 123 | }, 124 | resolve: (parent, { id }, ctx) => { 125 | return ctx.photon.posts.update({ 126 | where: { id }, 127 | data: { published: true } 128 | }); 129 | } 130 | }); 131 | } 132 | }); 133 | 134 | const schema = makeSchema({ 135 | types: [Query, Mutation, Post, User, nexusPrisma], 136 | outputs: { 137 | typegen: join(__dirname, '../generated/nexus-typegen.ts'), 138 | schema: join(__dirname, '/schema.graphql') 139 | }, 140 | typegenAutoConfig: { 141 | sources: [ 142 | { 143 | source: '@generated/photon', 144 | alias: 'photon' 145 | }, 146 | { 147 | source: join(__dirname, 'types.ts'), 148 | alias: 'ctx' 149 | } 150 | ], 151 | contextType: 'ctx.Context' 152 | } 153 | }); 154 | 155 | const server = new GraphQLServer({ 156 | schema, 157 | context: request => { 158 | return { 159 | ...request, 160 | photon 161 | }; 162 | } 163 | }); 164 | 165 | server.start(() => console.log(`🚀 Server ready at http://localhost:4000`)); 166 | -------------------------------------------------------------------------------- /backend/src/schema.graphql: -------------------------------------------------------------------------------- 1 | ### This file was autogenerated by GraphQL Nexus 2 | ### Do not make changes to this file directly 3 | 4 | 5 | """DateTime""" 6 | scalar DateTime 7 | 8 | type Mutation { 9 | createDraft(authorEmail: String, content: String, title: String): Post! 10 | deleteOnePost(where: PostWhereUniqueInput!): Post 11 | publish(id: ID): Post 12 | signupUser(data: UserCreateInput!): User! 13 | } 14 | 15 | type Post { 16 | content: String 17 | createdAt: DateTime! 18 | id: ID! 19 | published: Boolean! 20 | title: String! 21 | updatedAt: DateTime! 22 | } 23 | 24 | input PostCreateManyWithoutPostsInput { 25 | connect: [PostWhereUniqueInput!] 26 | create: [PostCreateWithoutAuthorInput!] 27 | } 28 | 29 | input PostCreateWithoutAuthorInput { 30 | content: String 31 | id: ID 32 | published: Boolean! 33 | title: String! 34 | } 35 | 36 | input PostWhereUniqueInput { 37 | id: ID 38 | } 39 | 40 | type Query { 41 | feed(published: Boolean): [Post!]! 42 | filterPosts(searchString: String): [Post!]! 43 | post(where: PostWhereUniqueInput!): Post 44 | users: [User!]! 45 | } 46 | 47 | type User { 48 | email: String! 49 | id: ID! 50 | name: String 51 | posts(after: String, before: String, first: Int, last: Int, skip: Int): [Post!] 52 | } 53 | 54 | input UserCreateInput { 55 | email: String! 56 | id: ID 57 | name: String 58 | posts: PostCreateManyWithoutPostsInput 59 | } 60 | -------------------------------------------------------------------------------- /backend/src/types.ts: -------------------------------------------------------------------------------- 1 | import Photon from '@generated/photon' 2 | 3 | export interface Context { 4 | photon: Photon 5 | } 6 | -------------------------------------------------------------------------------- /backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "outDir": "dist", 5 | "lib": ["esnext", "dom"], 6 | // "strict": true, // `strict` is commented because of this issue: https://github.com/prisma/prisma/issues/3774; all its options except `strictNullChecks` & `strictPropertyInitialization` are explicitly set below. 7 | "noImplicitAny": true, 8 | "noImplicitThis": true, 9 | "alwaysStrict": true, 10 | "strictBindCallApply": true, 11 | "strictFunctionTypes": true, 12 | "skipLibCheck": true // `skipLibCheck` is enabled until this is issue is fixed: https://github.com/prisma/nexus-prisma/issues/82 13 | } 14 | } -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | mysql: 4 | container_name: mysql 5 | ports: 6 | - '3306:3306' 7 | image: mysql:5.7 8 | restart: always 9 | environment: 10 | MYSQL_DATABASE: prisma 11 | MYSQL_ROOT_PASSWORD: prisma 12 | volumes: 13 | - mysql:/var/lib/mysql 14 | prisma: 15 | links: 16 | - mysql 17 | depends_on: 18 | - mysql 19 | container_name: prisma 20 | ports: 21 | - '5555:5555' 22 | build: 23 | context: backend/prisma 24 | dockerfile: Dockerfile 25 | volumes: 26 | - prisma:/app/prisma 27 | backend: 28 | links: 29 | - mysql 30 | depends_on: 31 | - mysql 32 | container_name: backend 33 | ports: 34 | - '4000:4000' 35 | build: 36 | context: backend 37 | dockerfile: Dockerfile 38 | volumes: 39 | - ./backend:/app 40 | - /app/node_modules 41 | - prisma:/app/prisma 42 | frontend: 43 | container_name: frontend 44 | ports: 45 | - '3000:3000' 46 | build: 47 | context: frontend 48 | dockerfile: Dockerfile 49 | volumes: 50 | - ./frontend:/app 51 | - /app/node_modules 52 | - /app/.next 53 | 54 | volumes: 55 | prisma: 56 | mysql: 57 | -------------------------------------------------------------------------------- /frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10.16.0 2 | 3 | WORKDIR /app 4 | 5 | COPY package*.json ./ 6 | RUN npm install 7 | 8 | CMD [ "npm", "run", "dev" ] -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # TypeScript Next.js example 2 | 3 | This is a really simple project that show the usage of Next.js with TypeScript. 4 | 5 | ## How to use it? 6 | 7 | ### Using `create-next-app` 8 | 9 | Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example: 10 | 11 | ```bash 12 | npx create-next-app --example with-typescript with-typescript-app 13 | # or 14 | yarn create next-app --example with-typescript with-typescript-app 15 | ``` 16 | 17 | ### Download manually 18 | 19 | Download the example: 20 | 21 | ```bash 22 | curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-typescript 23 | cd with-typescript 24 | ``` 25 | 26 | Install it and run: 27 | 28 | ```bash 29 | npm install 30 | npm run dev 31 | # or 32 | yarn 33 | yarn dev 34 | ``` 35 | 36 | ## The idea behind the example 37 | 38 | This example shows how to integrate the TypeScript type system into Next.js. Since TypeScript is supported out of the box with Next.js, all we have to do is to install TypeScript. 39 | 40 | ``` 41 | npm install --save-dev typescript 42 | ``` 43 | 44 | To enable TypeScript's features, we install the type declaratons for React and Node. 45 | 46 | ``` 47 | npm install --save-dev @types/react @types/react-dom @types/node 48 | ``` 49 | 50 | When we run `next dev` the next time, Next.js will start looking for any `.ts` or `.tsx` files in our project and builds it. It even automatically creates a `tsconfig.json` file for our project with the recommended settings. 51 | 52 | Next.js has built-in TypeScript declarations, so we'll get autocompletion for Next.js' modules straight away. 53 | 54 | A `type-check` script is also added to `package.json`, which runs TypeScript's `tsc` CLI in `noEmit` mode to run type-checking separately. You can then include this, for example, in your `test` scripts. 55 | -------------------------------------------------------------------------------- /frontend/codegen.yml: -------------------------------------------------------------------------------- 1 | overwrite: true 2 | schema: 'http://backend:4000/' 3 | documents: graphql/**/*.gql 4 | generates: 5 | generated/apollo-components.tsx: 6 | config: 7 | withHOC: false 8 | withComponent: true 9 | plugins: 10 | - 'typescript' 11 | - 'typescript-operations' 12 | - 'typescript-react-apollo' 13 | -------------------------------------------------------------------------------- /frontend/components/delete-post.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button } from 'antd'; 3 | import { DeleteOnePostComponent, FeedQueryDocument } from '../generated/apollo-components'; 4 | 5 | type Props = { 6 | id: string; 7 | }; 8 | 9 | class DeletePost extends React.Component { 10 | render() { 11 | const { id } = this.props; 12 | return ( 13 | 14 | {deleteOnePost => ( 15 | 29 | )} 30 | 31 | ); 32 | } 33 | } 34 | 35 | export default DeletePost; 36 | -------------------------------------------------------------------------------- /frontend/components/feed.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Table, Button } from 'antd'; 3 | import { FeedQueryComponent } from '../generated/apollo-components'; 4 | import PublishDraft from './publish-draft'; 5 | import DeletePost from './delete-post'; 6 | 7 | type Props = { 8 | published: boolean; 9 | }; 10 | 11 | class FeedList extends React.PureComponent { 12 | render() { 13 | const { published } = this.props; 14 | return ( 15 | 16 | {({ loading, error, data }) => { 17 | if (loading) return

Loading...

; 18 | if (error) return

Error

; 19 | 20 | if (data && 'feed' in data && data.feed.length > 0) { 21 | const feedData = data.feed.map(({ id, title, content }, i) => ({ 22 | key: i, 23 | title, 24 | content, 25 | id 26 | })); 27 | const columns = [ 28 | { 29 | title: 'Title', 30 | dataIndex: 'title', 31 | key: 'title' 32 | }, 33 | { 34 | title: 'Content', 35 | dataIndex: 'content', 36 | key: 'content' 37 | }, 38 | { 39 | title: 'Action', 40 | key: 'action', 41 | render: ({ id }: { id: string }) => { 42 | return ( 43 | 44 | {published ? null : } 45 | 46 | 47 | ); 48 | } 49 | } 50 | ]; 51 | return ; 52 | } 53 | 54 | return

No results yet.

; 55 | }} 56 | 57 | ); 58 | } 59 | } 60 | 61 | export default FeedList; 62 | -------------------------------------------------------------------------------- /frontend/components/main-layout.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode, Component } from 'react'; 2 | import { Layout } from 'antd'; 3 | import Link from 'next/link'; 4 | import Head from 'next/head'; 5 | 6 | const { Footer, Header, Content } = Layout; 7 | 8 | type Props = { 9 | title?: string; 10 | children: ReactNode; 11 | }; 12 | 13 | class MainLayout extends Component { 14 | render() { 15 | const { children, title } = this.props; 16 | return ( 17 | 18 | 19 | {title} 20 | 21 | 22 | 23 |
24 | 29 |
30 | {children} 31 |
32 |
33 | I'm here to stay (Footer) 34 |
35 |
36 | ); 37 | } 38 | } 39 | 40 | export default MainLayout; 41 | -------------------------------------------------------------------------------- /frontend/components/new-draft.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Row, Col, Button, Form, Input } from 'antd'; 3 | import { CreateDraftMutationComponent, FeedQueryDocument } from '../generated/apollo-components'; 4 | 5 | type Props = {}; 6 | const initialState = { title: '', content: '', authorEmail: '' }; 7 | type State = typeof initialState; 8 | 9 | class NewDraft extends React.Component { 10 | state: State = initialState; 11 | 12 | handleChange = (event: React.ChangeEvent) => { 13 | const { name, value } = event.target; 14 | this.setState({ [name]: value }); 15 | }; 16 | 17 | render() { 18 | return ( 19 | 20 | {createDraft => ( 21 |
{ 23 | e.preventDefault(); 24 | createDraft({ 25 | variables: { ...this.state }, 26 | refetchQueries: [ 27 | { query: FeedQueryDocument, variables: { published: true } }, 28 | { query: FeedQueryDocument, variables: { published: false } } 29 | ] 30 | }).then(res => { 31 | console.log(res); 32 | this.setState({ title: '', content: '', authorEmail: '' }); 33 | }); 34 | }} 35 | > 36 | 37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | )} 66 | 67 | ); 68 | } 69 | } 70 | 71 | export default NewDraft; 72 | -------------------------------------------------------------------------------- /frontend/components/publish-draft.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button } from 'antd'; 3 | import { PublishMutationComponent, FeedQueryDocument } from '../generated/apollo-components'; 4 | 5 | type Props = { 6 | id: string; 7 | }; 8 | 9 | class PublishDraft extends React.Component { 10 | render() { 11 | const { id } = this.props; 12 | return ( 13 | 14 | {publishDraft => ( 15 | 28 | )} 29 | 30 | ); 31 | } 32 | } 33 | 34 | export default PublishDraft; 35 | -------------------------------------------------------------------------------- /frontend/components/signup-user.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Row, Col, Button, Form, Input } from 'antd'; 3 | import { SignupUserMutationComponent, UsersQueryDocument } from '../generated/apollo-components'; 4 | 5 | type Props = {}; 6 | const initialState = { name: '', email: '' }; 7 | type State = typeof initialState; 8 | 9 | class SignupUser extends React.Component { 10 | state: State = initialState; 11 | 12 | handleChange = (event: React.ChangeEvent) => { 13 | const { name, value } = event.target; 14 | this.setState({ [name]: value }); 15 | }; 16 | 17 | render() { 18 | return ( 19 | 20 | {createUser => ( 21 |
{ 23 | e.preventDefault(); 24 | createUser({ 25 | variables: { ...this.state }, 26 | refetchQueries: [{ query: UsersQueryDocument }] 27 | }).then(() => { 28 | this.setState({ name: '', email: '' }); 29 | }); 30 | }} 31 | > 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | )} 51 | 52 | ); 53 | } 54 | } 55 | 56 | export default SignupUser; 57 | -------------------------------------------------------------------------------- /frontend/components/users.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Table } from 'antd'; 3 | import { UsersQueryComponent } from '../generated/apollo-components'; 4 | 5 | type Props = {}; 6 | 7 | class UsersList extends React.PureComponent { 8 | render() { 9 | return ( 10 | 11 | {({ loading, error, data }) => { 12 | if (loading) return

Loading...

; 13 | if (error) return

Error

; 14 | 15 | if (data && 'users' in data && data.users.length > 0) { 16 | const feedData = data.users.map(({ name, email }, i) => ({ 17 | key: i, 18 | name, 19 | email 20 | })); 21 | const columns = [ 22 | { 23 | title: 'Name', 24 | dataIndex: 'name', 25 | key: 'name' 26 | }, 27 | { 28 | title: 'Email', 29 | dataIndex: 'email', 30 | key: 'email' 31 | } 32 | ]; 33 | return
; 34 | } 35 | 36 | return

No users yet.

; 37 | }} 38 | 39 | ); 40 | } 41 | } 42 | 43 | export default UsersList; 44 | -------------------------------------------------------------------------------- /frontend/generated/apollo-components.tsx: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | import * as ReactApollo from "react-apollo"; 3 | import * as React from "react"; 4 | export type Maybe = T | null; 5 | export type Omit = Pick>; 6 | /** All built-in and custom scalars, mapped to their actual values */ 7 | export type Scalars = { 8 | ID: string; 9 | String: string; 10 | Boolean: boolean; 11 | Int: number; 12 | Float: number; 13 | /** DateTime */ 14 | DateTime: any; 15 | }; 16 | 17 | export type Mutation = { 18 | __typename?: "Mutation"; 19 | signupUser: User; 20 | deleteOnePost?: Maybe; 21 | createDraft: Post; 22 | publish?: Maybe; 23 | }; 24 | 25 | export type MutationSignupUserArgs = { 26 | data: UserCreateInput; 27 | }; 28 | 29 | export type MutationDeleteOnePostArgs = { 30 | where: PostWhereUniqueInput; 31 | }; 32 | 33 | export type MutationCreateDraftArgs = { 34 | title?: Maybe; 35 | content?: Maybe; 36 | authorEmail?: Maybe; 37 | }; 38 | 39 | export type MutationPublishArgs = { 40 | id?: Maybe; 41 | }; 42 | 43 | export type Post = { 44 | __typename?: "Post"; 45 | id: Scalars["ID"]; 46 | title: Scalars["String"]; 47 | content?: Maybe; 48 | createdAt: Scalars["DateTime"]; 49 | updatedAt: Scalars["DateTime"]; 50 | published: Scalars["Boolean"]; 51 | }; 52 | 53 | export type PostCreateManyWithoutPostsInput = { 54 | create?: Maybe>; 55 | connect?: Maybe>; 56 | }; 57 | 58 | export type PostCreateWithoutAuthorInput = { 59 | id?: Maybe; 60 | published: Scalars["Boolean"]; 61 | title: Scalars["String"]; 62 | content?: Maybe; 63 | }; 64 | 65 | export type PostWhereUniqueInput = { 66 | id?: Maybe; 67 | }; 68 | 69 | export type Query = { 70 | __typename?: "Query"; 71 | post?: Maybe; 72 | users: Array; 73 | feed: Array; 74 | filterPosts: Array; 75 | }; 76 | 77 | export type QueryPostArgs = { 78 | where: PostWhereUniqueInput; 79 | }; 80 | 81 | export type QueryFeedArgs = { 82 | published?: Maybe; 83 | }; 84 | 85 | export type QueryFilterPostsArgs = { 86 | searchString?: Maybe; 87 | }; 88 | 89 | export type User = { 90 | __typename?: "User"; 91 | id: Scalars["ID"]; 92 | name?: Maybe; 93 | email: Scalars["String"]; 94 | posts?: Maybe>; 95 | }; 96 | 97 | export type UserPostsArgs = { 98 | skip?: Maybe; 99 | after?: Maybe; 100 | before?: Maybe; 101 | first?: Maybe; 102 | last?: Maybe; 103 | }; 104 | 105 | export type UserCreateInput = { 106 | id?: Maybe; 107 | email: Scalars["String"]; 108 | name?: Maybe; 109 | posts?: Maybe; 110 | }; 111 | export type PostFragmentFragment = { __typename?: "Post" } & Pick< 112 | Post, 113 | "id" | "published" | "title" | "content" | "published" 114 | >; 115 | 116 | export type UserFragmentFragment = { __typename?: "User" } & Pick< 117 | User, 118 | "id" | "name" | "email" 119 | >; 120 | 121 | export type CreateDraftMutationMutationVariables = { 122 | title: Scalars["String"]; 123 | content: Scalars["String"]; 124 | authorEmail: Scalars["String"]; 125 | }; 126 | 127 | export type CreateDraftMutationMutation = { __typename?: "Mutation" } & { 128 | createDraft: { __typename?: "Post" } & PostFragmentFragment; 129 | }; 130 | 131 | export type DeleteOnePostMutationVariables = { 132 | id: Scalars["ID"]; 133 | }; 134 | 135 | export type DeleteOnePostMutation = { __typename?: "Mutation" } & { 136 | deleteOnePost: Maybe<{ __typename?: "Post" } & PostFragmentFragment>; 137 | }; 138 | 139 | export type PublishMutationMutationVariables = { 140 | id: Scalars["ID"]; 141 | }; 142 | 143 | export type PublishMutationMutation = { __typename?: "Mutation" } & { 144 | publish: Maybe<{ __typename?: "Post" } & PostFragmentFragment>; 145 | }; 146 | 147 | export type SignupUserMutationMutationVariables = { 148 | name: Scalars["String"]; 149 | email: Scalars["String"]; 150 | }; 151 | 152 | export type SignupUserMutationMutation = { __typename?: "Mutation" } & { 153 | signupUser: { __typename?: "User" } & UserFragmentFragment; 154 | }; 155 | 156 | export type FeedQueryQueryVariables = { 157 | published: Scalars["Boolean"]; 158 | }; 159 | 160 | export type FeedQueryQuery = { __typename?: "Query" } & { 161 | feed: Array<{ __typename?: "Post" } & PostFragmentFragment>; 162 | }; 163 | 164 | export type PostQueryQueryVariables = { 165 | id: Scalars["ID"]; 166 | }; 167 | 168 | export type PostQueryQuery = { __typename?: "Query" } & { 169 | post: Maybe<{ __typename?: "Post" } & PostFragmentFragment>; 170 | }; 171 | 172 | export type UsersQueryQueryVariables = {}; 173 | 174 | export type UsersQueryQuery = { __typename?: "Query" } & { 175 | users: Array<{ __typename?: "User" } & UserFragmentFragment>; 176 | }; 177 | export const PostFragmentFragmentDoc = gql` 178 | fragment PostFragment on Post { 179 | id 180 | published 181 | title 182 | content 183 | published 184 | } 185 | `; 186 | export const UserFragmentFragmentDoc = gql` 187 | fragment UserFragment on User { 188 | id 189 | name 190 | email 191 | } 192 | `; 193 | export const CreateDraftMutationDocument = gql` 194 | mutation createDraftMutation( 195 | $title: String! 196 | $content: String! 197 | $authorEmail: String! 198 | ) { 199 | createDraft(title: $title, content: $content, authorEmail: $authorEmail) { 200 | ...PostFragment 201 | } 202 | } 203 | ${PostFragmentFragmentDoc} 204 | `; 205 | export type CreateDraftMutationMutationFn = ReactApollo.MutationFn< 206 | CreateDraftMutationMutation, 207 | CreateDraftMutationMutationVariables 208 | >; 209 | export type CreateDraftMutationComponentProps = Omit< 210 | ReactApollo.MutationProps< 211 | CreateDraftMutationMutation, 212 | CreateDraftMutationMutationVariables 213 | >, 214 | "mutation" 215 | >; 216 | 217 | export const CreateDraftMutationComponent = ( 218 | props: CreateDraftMutationComponentProps 219 | ) => ( 220 | 224 | mutation={CreateDraftMutationDocument} 225 | {...props} 226 | /> 227 | ); 228 | 229 | export const DeleteOnePostDocument = gql` 230 | mutation deleteOnePost($id: ID!) { 231 | deleteOnePost(where: { id: $id }) { 232 | ...PostFragment 233 | } 234 | } 235 | ${PostFragmentFragmentDoc} 236 | `; 237 | export type DeleteOnePostMutationFn = ReactApollo.MutationFn< 238 | DeleteOnePostMutation, 239 | DeleteOnePostMutationVariables 240 | >; 241 | export type DeleteOnePostComponentProps = Omit< 242 | ReactApollo.MutationProps< 243 | DeleteOnePostMutation, 244 | DeleteOnePostMutationVariables 245 | >, 246 | "mutation" 247 | >; 248 | 249 | export const DeleteOnePostComponent = (props: DeleteOnePostComponentProps) => ( 250 | 251 | mutation={DeleteOnePostDocument} 252 | {...props} 253 | /> 254 | ); 255 | 256 | export const PublishMutationDocument = gql` 257 | mutation publishMutation($id: ID!) { 258 | publish(id: $id) { 259 | ...PostFragment 260 | } 261 | } 262 | ${PostFragmentFragmentDoc} 263 | `; 264 | export type PublishMutationMutationFn = ReactApollo.MutationFn< 265 | PublishMutationMutation, 266 | PublishMutationMutationVariables 267 | >; 268 | export type PublishMutationComponentProps = Omit< 269 | ReactApollo.MutationProps< 270 | PublishMutationMutation, 271 | PublishMutationMutationVariables 272 | >, 273 | "mutation" 274 | >; 275 | 276 | export const PublishMutationComponent = ( 277 | props: PublishMutationComponentProps 278 | ) => ( 279 | 283 | mutation={PublishMutationDocument} 284 | {...props} 285 | /> 286 | ); 287 | 288 | export const SignupUserMutationDocument = gql` 289 | mutation signupUserMutation($name: String!, $email: String!) { 290 | signupUser(data: { name: $name, email: $email }) { 291 | ...UserFragment 292 | } 293 | } 294 | ${UserFragmentFragmentDoc} 295 | `; 296 | export type SignupUserMutationMutationFn = ReactApollo.MutationFn< 297 | SignupUserMutationMutation, 298 | SignupUserMutationMutationVariables 299 | >; 300 | export type SignupUserMutationComponentProps = Omit< 301 | ReactApollo.MutationProps< 302 | SignupUserMutationMutation, 303 | SignupUserMutationMutationVariables 304 | >, 305 | "mutation" 306 | >; 307 | 308 | export const SignupUserMutationComponent = ( 309 | props: SignupUserMutationComponentProps 310 | ) => ( 311 | 315 | mutation={SignupUserMutationDocument} 316 | {...props} 317 | /> 318 | ); 319 | 320 | export const FeedQueryDocument = gql` 321 | query feedQuery($published: Boolean!) { 322 | feed(published: $published) { 323 | ...PostFragment 324 | } 325 | } 326 | ${PostFragmentFragmentDoc} 327 | `; 328 | export type FeedQueryComponentProps = Omit< 329 | ReactApollo.QueryProps, 330 | "query" 331 | > & 332 | ({ variables: FeedQueryQueryVariables; skip?: false } | { skip: true }); 333 | 334 | export const FeedQueryComponent = (props: FeedQueryComponentProps) => ( 335 | 336 | query={FeedQueryDocument} 337 | {...props} 338 | /> 339 | ); 340 | 341 | export const PostQueryDocument = gql` 342 | query postQuery($id: ID!) { 343 | post(where: { id: $id }) { 344 | ...PostFragment 345 | } 346 | } 347 | ${PostFragmentFragmentDoc} 348 | `; 349 | export type PostQueryComponentProps = Omit< 350 | ReactApollo.QueryProps, 351 | "query" 352 | > & 353 | ({ variables: PostQueryQueryVariables; skip?: false } | { skip: true }); 354 | 355 | export const PostQueryComponent = (props: PostQueryComponentProps) => ( 356 | 357 | query={PostQueryDocument} 358 | {...props} 359 | /> 360 | ); 361 | 362 | export const UsersQueryDocument = gql` 363 | query usersQuery { 364 | users { 365 | ...UserFragment 366 | } 367 | } 368 | ${UserFragmentFragmentDoc} 369 | `; 370 | export type UsersQueryComponentProps = Omit< 371 | ReactApollo.QueryProps, 372 | "query" 373 | >; 374 | 375 | export const UsersQueryComponent = (props: UsersQueryComponentProps) => ( 376 | 377 | query={UsersQueryDocument} 378 | {...props} 379 | /> 380 | ); 381 | -------------------------------------------------------------------------------- /frontend/graphql/fragments/post.gql: -------------------------------------------------------------------------------- 1 | #import from '../user.gql' 2 | 3 | fragment PostFragment on Post { 4 | id 5 | published 6 | title 7 | content 8 | published 9 | } 10 | -------------------------------------------------------------------------------- /frontend/graphql/fragments/user.gql: -------------------------------------------------------------------------------- 1 | fragment UserFragment on User { 2 | id 3 | name 4 | email 5 | } 6 | -------------------------------------------------------------------------------- /frontend/graphql/mutations/createDraft.gql: -------------------------------------------------------------------------------- 1 | #import from '../fragments/post.gql' 2 | 3 | mutation createDraftMutation($title: String!, $content: String!, $authorEmail: String!) { 4 | createDraft(title: $title, content: $content, authorEmail: $authorEmail) { 5 | ...PostFragment 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/graphql/mutations/deleteOnePost.gql: -------------------------------------------------------------------------------- 1 | #import from '../fragments/post.gql' 2 | 3 | mutation deleteOnePost($id: ID!) { 4 | deleteOnePost(where: { id: $id }) { 5 | ...PostFragment 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/graphql/mutations/publish.gql: -------------------------------------------------------------------------------- 1 | #import from '../fragments/post.gql' 2 | 3 | mutation publishMutation($id: ID!) { 4 | publish(id: $id) { 5 | ...PostFragment 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/graphql/mutations/signupUser.gql: -------------------------------------------------------------------------------- 1 | #import from '../fragments/user.gql' 2 | 3 | mutation signupUserMutation($name: String!, $email: String!) { 4 | signupUser(data: { name: $name, email: $email }) { 5 | ...UserFragment 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/graphql/queries/feed.gql: -------------------------------------------------------------------------------- 1 | #import from '../fragments/post.gql' 2 | 3 | query feedQuery($published: Boolean!) { 4 | feed(published: $published) { 5 | ...PostFragment 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/graphql/queries/post.gql: -------------------------------------------------------------------------------- 1 | #import from '../fragments/post.gql' 2 | 3 | query postQuery($id: ID!) { 4 | post(where: { id: $id }) { 5 | ...PostFragment 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/graphql/queries/users.gql: -------------------------------------------------------------------------------- 1 | #import from '../fragments/user.gql' 2 | 3 | query usersQuery { 4 | users { 5 | ...UserFragment 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /frontend/next.config.js: -------------------------------------------------------------------------------- 1 | const withGraphql = require('next-plugin-graphql'); 2 | const withCSS = require('@zeit/next-css'); 3 | 4 | const path = require('path'); 5 | 6 | module.exports = withCSS( 7 | withGraphql({ 8 | // webpack: function(config, options) { 9 | // config.resolve.alias['components'] = path.join(__dirname, 'components'); 10 | // config.resolve.alias['graphql'] = path.join(__dirname, 'graphql'); 11 | // config.resolve.alias['interfaces'] = path.join(__dirname, 'interfaces'); 12 | // config.resolve.alias['pages'] = path.join(__dirname, 'pages'); 13 | // config.resolve.alias['utils'] = path.join(__dirname, 'utils'); 14 | // } 15 | }) 16 | ); 17 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-typescript", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "dev": "next", 6 | "build": "next build", 7 | "start": "next start", 8 | "type-check": "tsc", 9 | "generate": "gql-gen --config codegen.yml" 10 | }, 11 | "dependencies": { 12 | "@zeit/next-css": "^1.0.1", 13 | "antd": "^3.20.0", 14 | "apollo-boost": "^0.4.3", 15 | "graphql": "^14.4.1", 16 | "isomorphic-unfetch": "^3.0.0", 17 | "lodash": "^4.17.11", 18 | "next": "8.1.1-canary.61", 19 | "next-plugin-graphql": "0.0.2", 20 | "react": "^16.7.0", 21 | "react-apollo": "^2.5.8", 22 | "react-dom": "^16.7.0" 23 | }, 24 | "devDependencies": { 25 | "@graphql-codegen/cli": "^1.3.1", 26 | "@graphql-codegen/typescript": "^1.3.1", 27 | "@graphql-codegen/typescript-operations": "^1.3.1", 28 | "@graphql-codegen/typescript-react-apollo": "^1.3.1", 29 | "@types/node": "^11.13.9", 30 | "@types/react": "^16.8.15", 31 | "@types/react-dom": "^16.0.11", 32 | "typescript": "3.5.2" 33 | }, 34 | "license": "ISC" 35 | } 36 | -------------------------------------------------------------------------------- /frontend/pages/_app.jsx: -------------------------------------------------------------------------------- 1 | import App, { Container } from 'next/app'; 2 | import React from 'react'; 3 | import withApolloClient from '../utils/with-apollo-client'; 4 | import { ApolloProvider } from 'react-apollo'; 5 | import 'antd/dist/antd.css'; 6 | class MyApp extends App { 7 | render() { 8 | const { Component, pageProps, apolloClient } = this.props; 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | 19 | export default withApolloClient(MyApp); 20 | -------------------------------------------------------------------------------- /frontend/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { NextPage } from 'next'; 3 | import Layout from '../components/main-layout'; 4 | import FeedList from '../components/feed'; 5 | import NewDraft from '../components/new-draft'; 6 | import UsersList from '../components/users'; 7 | import SignupUser from '../components/signup-user'; 8 | 9 | const IndexPage: NextPage = () => { 10 | return ( 11 | 12 |

Simple Prisma 2 Blog Example

13 |

Create User

14 | 15 |

Users

16 | 17 | 18 |

Create Draft

19 | 20 |

Feed

21 | 22 |

Hidden Feed

23 | 24 |
25 | ); 26 | }; 27 | 28 | export default IndexPage; 29 | -------------------------------------------------------------------------------- /frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "alwaysStrict": true, 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "isolatedModules": true, 8 | "jsx": "preserve", 9 | "lib": [ 10 | "dom", 11 | "es2017" 12 | ], 13 | "module": "esnext", 14 | "moduleResolution": "node", 15 | "noEmit": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "resolveJsonModule": true, 20 | "skipLibCheck": true, 21 | "strict": true, 22 | "target": "esnext" 23 | }, 24 | "exclude": [ 25 | "node_modules" 26 | ], 27 | "include": [ 28 | "**/*.ts", 29 | "**/*.tsx" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /frontend/utils/init-apollo.js: -------------------------------------------------------------------------------- 1 | import { ApolloClient, InMemoryCache, HttpLink } from 'apollo-boost'; 2 | import fetch from 'isomorphic-unfetch'; 3 | 4 | let apolloClient = null; 5 | 6 | function create(initialState) { 7 | // Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient 8 | const isBrowser = typeof window !== 'undefined'; 9 | return new ApolloClient({ 10 | connectToDevTools: isBrowser, 11 | ssrMode: !isBrowser, // Disables forceFetch on the server (so queries are only run once) 12 | link: new HttpLink({ 13 | uri: isBrowser ? 'http://localhost:4000' : 'http://backend:4000', // Server URL (must be absolute) 14 | credentials: 'same-origin', // Additional fetch() options like `credentials` or `headers` 15 | // Use fetch() polyfill on the server 16 | fetch: !isBrowser && fetch 17 | }), 18 | cache: new InMemoryCache().restore(initialState || {}) 19 | }); 20 | } 21 | 22 | export default function initApollo(initialState) { 23 | // Make sure to create a new client for every server-side request so that data 24 | // isn't shared between connections (which would be bad) 25 | if (typeof window === 'undefined') { 26 | return create(initialState); 27 | } 28 | 29 | // Reuse client on the client-side 30 | if (!apolloClient) { 31 | apolloClient = create(initialState); 32 | } 33 | 34 | return apolloClient; 35 | } 36 | -------------------------------------------------------------------------------- /frontend/utils/with-apollo-client.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import initApollo from './init-apollo'; 3 | import Head from 'next/head'; 4 | import { getDataFromTree } from 'react-apollo'; 5 | 6 | export default App => { 7 | return class Apollo extends React.Component { 8 | static displayName = 'withApollo(App)'; 9 | static async getInitialProps(ctx) { 10 | const { Component, router } = ctx; 11 | 12 | let appProps = {}; 13 | if (App.getInitialProps) { 14 | appProps = await App.getInitialProps(ctx); 15 | } 16 | 17 | // Run all GraphQL queries in the component tree 18 | // and extract the resulting data 19 | const apollo = initApollo(); 20 | if (typeof window === 'undefined') { 21 | try { 22 | // Run all GraphQL queries 23 | await getDataFromTree(); 24 | } catch (error) { 25 | // Prevent Apollo Client GraphQL errors from crashing SSR. 26 | // Handle them in components via the data.error prop: 27 | // https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error 28 | console.error('Error while running `getDataFromTree`', error); 29 | } 30 | 31 | // getDataFromTree does not call componentWillUnmount 32 | // head side effect therefore need to be cleared manually 33 | Head.rewind(); 34 | } 35 | 36 | // Extract query data from the Apollo store 37 | const apolloState = apollo.cache.extract(); 38 | 39 | return { 40 | ...appProps, 41 | apolloState 42 | }; 43 | } 44 | 45 | constructor(props) { 46 | super(props); 47 | this.apolloClient = initApollo(props.apolloState); 48 | } 49 | 50 | render() { 51 | return ; 52 | } 53 | }; 54 | }; 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docker-prisma", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "docker-compose up --build", 8 | "stop": "docker-compose down", 9 | "clean": "docker system prune -af", 10 | "seed": "docker exec -it prisma npm run seed", 11 | "generate": "docker exec -it frontend npm run generate", 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "author": "", 15 | "license": "ISC", 16 | "dependencies": { 17 | "graphql-tag": "^2.10.1" 18 | } 19 | } 20 | --------------------------------------------------------------------------------