Showing
39 changed files
with
484 additions
and
567 deletions
1 | -import { ValidationPipe } from '@nestjs/common'; | 1 | +import { ValidationPipe } from '@nestjs/common' |
2 | -import { NestFactory } from '@nestjs/core'; | 2 | +import { NestFactory } from '@nestjs/core' |
3 | -import { AppModule } from './app.module'; | 3 | +import { AppModule } from './app.module' |
4 | 4 | ||
5 | async function bootstrap() { | 5 | async function bootstrap() { |
6 | - const app = await NestFactory.create(AppModule); | 6 | + const app = await NestFactory.create(AppModule) |
7 | 7 | ||
8 | - app.useGlobalPipes(new ValidationPipe()); | 8 | + app.useGlobalPipes(new ValidationPipe()) |
9 | - await app.listen(3000); | 9 | + await app.listen(5000) |
10 | } | 10 | } |
11 | -bootstrap(); | 11 | +bootstrap() | ... | ... |
... | @@ -2,9 +2,9 @@ overwrite: true | ... | @@ -2,9 +2,9 @@ overwrite: true |
2 | require: | 2 | require: |
3 | - ts-node/register | 3 | - ts-node/register |
4 | generates: | 4 | generates: |
5 | - ./types/api-generated-types.ts: | 5 | + ./src/types/api-generated-types.ts: |
6 | schema: "src/graphql/api/api.graphql" | 6 | schema: "src/graphql/api/api.graphql" |
7 | - # documents: "src/graphql/api/**/*.graphql" | 7 | + # documents: "src/graphql/api/*.graphql" |
8 | plugins: | 8 | plugins: |
9 | - "typescript" | 9 | - "typescript" |
10 | # - 'fragment-matcher' | 10 | # - 'fragment-matcher' | ... | ... |
project/packages/shared/dist/index.js
0 → 100644
1 | +"use strict"; | ||
2 | +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
3 | + if (k2 === undefined) k2 = k; | ||
4 | + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
5 | +}) : (function(o, m, k, k2) { | ||
6 | + if (k2 === undefined) k2 = k; | ||
7 | + o[k2] = m[k]; | ||
8 | +})); | ||
9 | +var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
10 | + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
11 | +}; | ||
12 | +Object.defineProperty(exports, "__esModule", { value: true }); | ||
13 | +__exportStar(require("./types/api-generated-types"), exports); |
1 | +export declare type Maybe<T> = T | null; | ||
2 | +export declare type Exact<T extends { | ||
3 | + [key: string]: unknown; | ||
4 | +}> = { | ||
5 | + [K in keyof T]: T[K]; | ||
6 | +}; | ||
7 | +export declare type MakeOptional<T, K extends keyof T> = Omit<T, K> & { | ||
8 | + [SubKey in K]?: Maybe<T[SubKey]>; | ||
9 | +}; | ||
10 | +export declare type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { | ||
11 | + [SubKey in K]: Maybe<T[SubKey]>; | ||
12 | +}; | ||
13 | +/** All built-in and custom scalars, mapped to their actual values */ | ||
14 | +export declare type Scalars = { | ||
15 | + ID: string; | ||
16 | + String: string; | ||
17 | + Boolean: boolean; | ||
18 | + Int: number; | ||
19 | + Float: number; | ||
20 | +}; | ||
21 | +export declare type Comment = { | ||
22 | + __typename?: 'Comment'; | ||
23 | + author: Scalars['String']; | ||
24 | + content: Scalars['String']; | ||
25 | + created_date: Scalars['String']; | ||
26 | + id: Scalars['Int']; | ||
27 | + parent: Scalars['Int']; | ||
28 | + post_id: Scalars['Int']; | ||
29 | + updated_date?: Maybe<Scalars['String']>; | ||
30 | +}; | ||
31 | +export declare type CreateCommentInput = { | ||
32 | + content: Scalars['String']; | ||
33 | + parent?: Maybe<Scalars['Float']>; | ||
34 | + post_id: Scalars['Int']; | ||
35 | +}; | ||
36 | +export declare type CreateLikeableInput = { | ||
37 | + like_dislike: Scalars['Int']; | ||
38 | + likeable_id: Scalars['Int']; | ||
39 | + likeable_type: Scalars['String']; | ||
40 | +}; | ||
41 | +export declare type CreateMyInput = { | ||
42 | + name: Scalars['String']; | ||
43 | + type?: Maybe<Scalars['String']>; | ||
44 | +}; | ||
45 | +export declare type CreatePostInput = { | ||
46 | + category: Scalars['String']; | ||
47 | + content: Scalars['String']; | ||
48 | + title: Scalars['String']; | ||
49 | +}; | ||
50 | +export declare type GetCommentInput = { | ||
51 | + author?: Maybe<Scalars['String']>; | ||
52 | + parent?: Maybe<Scalars['String']>; | ||
53 | + post_id?: Maybe<Scalars['Float']>; | ||
54 | +}; | ||
55 | +export declare type GetLikeableInput = { | ||
56 | + likeable_id?: Maybe<Scalars['Float']>; | ||
57 | + likeable_type: Scalars['String']; | ||
58 | + user_id?: Maybe<Scalars['String']>; | ||
59 | +}; | ||
60 | +export declare type GetPostInput = { | ||
61 | + author?: Maybe<Scalars['String']>; | ||
62 | + category?: Maybe<Scalars['String']>; | ||
63 | + id?: Maybe<Scalars['Float']>; | ||
64 | +}; | ||
65 | +export declare type Likeable = { | ||
66 | + __typename?: 'Likeable'; | ||
67 | + created_date: Scalars['String']; | ||
68 | + id: Scalars['Int']; | ||
69 | + like_dislike: Scalars['Int']; | ||
70 | + likeable_id: Scalars['Int']; | ||
71 | + likeable_type: Scalars['String']; | ||
72 | + user_id: Scalars['String']; | ||
73 | +}; | ||
74 | +export declare type Mutation = { | ||
75 | + __typename?: 'Mutation'; | ||
76 | + createComment: Comment; | ||
77 | + createLikeable: Likeable; | ||
78 | + createMyPage: MyPage; | ||
79 | + createPost: Post; | ||
80 | +}; | ||
81 | +export declare type MutationcreateCommentArgs = { | ||
82 | + input: CreateCommentInput; | ||
83 | +}; | ||
84 | +export declare type MutationcreateLikeableArgs = { | ||
85 | + input: CreateLikeableInput; | ||
86 | +}; | ||
87 | +export declare type MutationcreateMyPageArgs = { | ||
88 | + createMyInput: CreateMyInput; | ||
89 | +}; | ||
90 | +export declare type MutationcreatePostArgs = { | ||
91 | + input: CreatePostInput; | ||
92 | +}; | ||
93 | +export declare type MyPage = { | ||
94 | + __typename?: 'MyPage'; | ||
95 | + id: Scalars['Int']; | ||
96 | + name: Scalars['String']; | ||
97 | + type?: Maybe<Scalars['String']>; | ||
98 | +}; | ||
99 | +export declare type Post = { | ||
100 | + __typename?: 'Post'; | ||
101 | + author: Scalars['String']; | ||
102 | + category: Scalars['String']; | ||
103 | + content: Scalars['String']; | ||
104 | + created_date: Scalars['String']; | ||
105 | + id: Scalars['Int']; | ||
106 | + title: Scalars['String']; | ||
107 | + updated_date?: Maybe<Scalars['String']>; | ||
108 | +}; | ||
109 | +export declare type Query = { | ||
110 | + __typename?: 'Query'; | ||
111 | + getAllComments: Array<Comment>; | ||
112 | + getAllLikes: Array<Likeable>; | ||
113 | + getAllPosts: Array<Post>; | ||
114 | + getComment: Comment; | ||
115 | + getLikeable: Likeable; | ||
116 | + getPost: Post; | ||
117 | + getSomeComments: Array<Comment>; | ||
118 | + getSomePosts: Array<Post>; | ||
119 | + getTotalLikes: Scalars['Float']; | ||
120 | + myPage: Array<MyPage>; | ||
121 | +}; | ||
122 | +export declare type QuerygetCommentArgs = { | ||
123 | + id: Scalars['Float']; | ||
124 | +}; | ||
125 | +export declare type QuerygetLikeableArgs = { | ||
126 | + id: Scalars['Float']; | ||
127 | +}; | ||
128 | +export declare type QuerygetPostArgs = { | ||
129 | + id: Scalars['Float']; | ||
130 | +}; | ||
131 | +export declare type QuerygetSomeCommentsArgs = { | ||
132 | + input: GetCommentInput; | ||
133 | +}; | ||
134 | +export declare type QuerygetSomePostsArgs = { | ||
135 | + input: GetPostInput; | ||
136 | +}; | ||
137 | +export declare type QuerygetTotalLikesArgs = { | ||
138 | + input: GetLikeableInput; | ||
139 | +}; |
1 | { | 1 | { |
2 | "name": "@graphql-community/shared", | 2 | "name": "@graphql-community/shared", |
3 | "version": "1.0.0", | 3 | "version": "1.0.0", |
4 | + "main": "dist/index.js", | ||
5 | + "types": "dist/index.d.ts", | ||
4 | "scripts": { | 6 | "scripts": { |
5 | - "dev": "next", | 7 | + "build": "rimraf dist && tsc --build", |
6 | - "build": "next build", | ||
7 | - "start": "next start", | ||
8 | "typegen" : "graphql-codegen --config codegen.yml" | 8 | "typegen" : "graphql-codegen --config codegen.yml" |
9 | }, | 9 | }, |
10 | "dependencies": { | 10 | "dependencies": { | ... | ... |
project/packages/shared/src/index.ts
0 → 100644
1 | +export * from "./types/api-generated-types"; |
project/packages/shared/tsconfig.json
0 → 100644
1 | +{ | ||
2 | + "compilerOptions": { | ||
3 | + "allowJs": true, | ||
4 | + "esModuleInterop": true, | ||
5 | + "isolatedModules": true, | ||
6 | + "jsx": "preserve", | ||
7 | + "lib": ["dom", "es2017"], | ||
8 | + "module": "commonjs", | ||
9 | + "moduleResolution": "node", | ||
10 | + "noFallthroughCasesInSwitch": true, | ||
11 | + "declaration": true, | ||
12 | + "resolveJsonModule": true, | ||
13 | + "skipLibCheck": true, | ||
14 | + "strict": true, | ||
15 | + "target": "es2017", | ||
16 | + "outDir" : "./dist", | ||
17 | + "rootDir": "./src" | ||
18 | + }, | ||
19 | + "exclude": ["node_modules"], | ||
20 | + "include": ["**/*.ts", "**/*.tsx"] | ||
21 | + } | ||
22 | + | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
project/packages/web/.babelrc
0 → 100644
project/packages/web/.graphql-let.yml
0 → 100644
1 | -# Apollo Example | 1 | +# TypeScript and GraphQL Example |
2 | 2 | ||
3 | -[Apollo](https://www.apollographql.com/client/) is a GraphQL client that allows you to easily query the exact data you need from a GraphQL server. In addition to fetching and mutating data, Apollo analyzes your queries and their results to construct a client-side cache of your data, which is kept up to date as further queries and mutations are run. | 3 | +One of the strengths of GraphQL is [enforcing data types on runtime](https://graphql.github.io/graphql-spec/June2018/#sec-Value-Completion). Further, TypeScript and [GraphQL Code Generator](https://graphql-code-generator.com/) (graphql-codegen) make it safer by typing data statically, so you can write truly type-protected code with rich IDE assists. |
4 | 4 | ||
5 | -In this simple example, we integrate Apollo seamlessly with [Next.js data fetching methods](https://nextjs.org/docs/basic-features/data-fetching) to fetch queries in the server and hydrate them in the browser. | 5 | +This template extends [Apollo Server and Client Example](https://github.com/vercel/next.js/tree/canary/examples/api-routes-apollo-server-and-client#readme) by rewriting in TypeScript and integrating [graphql-let](https://github.com/piglovesyou/graphql-let#readme), which runs [TypeScript React Apollo](https://graphql-code-generator.com/docs/plugins/typescript-react-apollo) in [graphql-codegen](https://github.com/dotansimha/graphql-code-generator#readme) under the hood. It enhances the typed GraphQL use as below: |
6 | 6 | ||
7 | -This example relies on [Prisma + Nexus](https://github.com/prisma-labs/nextjs-graphql-api-examples) for its GraphQL backend. | 7 | +```tsx |
8 | +import { useNewsQuery } from './news.graphql' | ||
8 | 9 | ||
9 | -## Demo | 10 | +const News = () => { |
11 | + // Typed already️⚡️ | ||
12 | + const { data: { news } } = useNewsQuery() | ||
10 | 13 | ||
11 | -[https://next-with-apollo.now.sh](https://next-with-apollo.now.sh) | 14 | + return <div>{news.map(...)}</div> |
15 | +} | ||
16 | +``` | ||
17 | + | ||
18 | +By default `**/*.graphqls` is recognized as GraphQL schema and `**/*.graphql` as GraphQL documents. If you prefer the other extensions, make sure the settings of the webpack loader in `next.config.js` and `.graphql-let.yml` are consistent. | ||
12 | 19 | ||
13 | ## Deploy your own | 20 | ## Deploy your own |
14 | 21 | ||
15 | Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): | 22 | Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): |
16 | 23 | ||
17 | -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-apollo&project-name=with-apollo&repository-name=with-apollo) | 24 | +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-typescript-graphql&project-name=with-typescript-graphql&repository-name=with-typescript-graphql) |
18 | 25 | ||
19 | ## How to use | 26 | ## How to use |
20 | 27 | ||
21 | Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: | 28 | Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: |
22 | 29 | ||
23 | ```bash | 30 | ```bash |
24 | -npx create-next-app --example with-apollo with-apollo-app | 31 | +npx create-next-app --example with-typescript-graphql with-typescript-graphql-app |
25 | # or | 32 | # or |
26 | -yarn create next-app --example with-apollo with-apollo-app | 33 | +yarn create next-app --example with-typescript-graphql with-typescript-graphql-app |
27 | ``` | 34 | ``` |
28 | 35 | ||
29 | Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). | 36 | Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). | ... | ... |
1 | -export default function App({ children }) { | ||
2 | - return ( | ||
3 | - <main> | ||
4 | - {children} | ||
5 | - <style jsx global>{` | ||
6 | - * { | ||
7 | - font-family: Menlo, Monaco, 'Lucida Console', 'Liberation Mono', | ||
8 | - 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', | ||
9 | - monospace, serif; | ||
10 | - } | ||
11 | - body { | ||
12 | - margin: 0; | ||
13 | - padding: 25px 50px; | ||
14 | - } | ||
15 | - a { | ||
16 | - color: #22bad9; | ||
17 | - } | ||
18 | - p { | ||
19 | - font-size: 14px; | ||
20 | - line-height: 24px; | ||
21 | - } | ||
22 | - article { | ||
23 | - margin: 0 auto; | ||
24 | - max-width: 650px; | ||
25 | - } | ||
26 | - button { | ||
27 | - align-items: center; | ||
28 | - background-color: #22bad9; | ||
29 | - border: 0; | ||
30 | - color: white; | ||
31 | - display: flex; | ||
32 | - padding: 5px 7px; | ||
33 | - transition: background-color 0.3s; | ||
34 | - } | ||
35 | - button:active { | ||
36 | - background-color: #1b9db7; | ||
37 | - } | ||
38 | - button:disabled { | ||
39 | - background-color: #b5bebf; | ||
40 | - } | ||
41 | - button:focus { | ||
42 | - outline: none; | ||
43 | - } | ||
44 | - `}</style> | ||
45 | - </main> | ||
46 | - ) | ||
47 | -} |
1 | -import { useRouter } from 'next/router' | ||
2 | -import Link from 'next/link' | ||
3 | - | ||
4 | -export default function Header() { | ||
5 | - const { pathname } = useRouter() | ||
6 | - | ||
7 | - return ( | ||
8 | - <header> | ||
9 | - <Link href="/"> | ||
10 | - <a className={pathname === '/' ? 'is-active' : ''}>Home</a> | ||
11 | - </Link> | ||
12 | - <Link href="/about"> | ||
13 | - <a className={pathname === '/about' ? 'is-active' : ''}>About</a> | ||
14 | - </Link> | ||
15 | - <Link href="/client-only"> | ||
16 | - <a className={pathname === '/client-only' ? 'is-active' : ''}> | ||
17 | - Client-Only | ||
18 | - </a> | ||
19 | - </Link> | ||
20 | - <Link href="/ssr"> | ||
21 | - <a className={pathname === '/ssr' ? 'is-active' : ''}>SSR</a> | ||
22 | - </Link> | ||
23 | - <style jsx>{` | ||
24 | - header { | ||
25 | - margin-bottom: 25px; | ||
26 | - } | ||
27 | - a { | ||
28 | - font-size: 14px; | ||
29 | - margin-right: 15px; | ||
30 | - text-decoration: none; | ||
31 | - } | ||
32 | - .is-active { | ||
33 | - text-decoration: underline; | ||
34 | - } | ||
35 | - `}</style> | ||
36 | - </header> | ||
37 | - ) | ||
38 | -} |
1 | -const InfoBox = ({ children }) => ( | ||
2 | - <div className="info"> | ||
3 | - <style jsx>{` | ||
4 | - .info { | ||
5 | - margin-top: 20px; | ||
6 | - margin-bottom: 20px; | ||
7 | - padding-top: 20px; | ||
8 | - padding-bottom: 20px; | ||
9 | - border-top: 1px solid #ececec; | ||
10 | - border-bottom: 1px solid #ececec; | ||
11 | - } | ||
12 | - `}</style> | ||
13 | - {children} | ||
14 | - </div> | ||
15 | -) | ||
16 | - | ||
17 | -export default InfoBox |
1 | -import { gql, useQuery, NetworkStatus } from '@apollo/client' | ||
2 | -import ErrorMessage from './ErrorMessage' | ||
3 | -import PostUpvoter from './PostUpvoter' | ||
4 | - | ||
5 | -export const ALL_POSTS_QUERY = gql` | ||
6 | - query allPosts($first: Int!, $skip: Int!) { | ||
7 | - allPosts(orderBy: { createdAt: desc }, first: $first, skip: $skip) { | ||
8 | - id | ||
9 | - title | ||
10 | - votes | ||
11 | - url | ||
12 | - createdAt | ||
13 | - } | ||
14 | - _allPostsMeta { | ||
15 | - count | ||
16 | - } | ||
17 | - } | ||
18 | -` | ||
19 | - | ||
20 | -export const allPostsQueryVars = { | ||
21 | - skip: 0, | ||
22 | - first: 10, | ||
23 | -} | ||
24 | - | ||
25 | -export default function PostList() { | ||
26 | - const { loading, error, data, fetchMore, networkStatus } = useQuery( | ||
27 | - ALL_POSTS_QUERY, | ||
28 | - { | ||
29 | - variables: allPostsQueryVars, | ||
30 | - // Setting this value to true will make the component rerender when | ||
31 | - // the "networkStatus" changes, so we are able to know if it is fetching | ||
32 | - // more data | ||
33 | - notifyOnNetworkStatusChange: true, | ||
34 | - } | ||
35 | - ) | ||
36 | - | ||
37 | - const loadingMorePosts = networkStatus === NetworkStatus.fetchMore | ||
38 | - | ||
39 | - const loadMorePosts = () => { | ||
40 | - fetchMore({ | ||
41 | - variables: { | ||
42 | - skip: allPosts.length, | ||
43 | - }, | ||
44 | - }) | ||
45 | - } | ||
46 | - | ||
47 | - if (error) return <ErrorMessage message="Error loading posts." /> | ||
48 | - if (loading && !loadingMorePosts) return <div>Loading</div> | ||
49 | - | ||
50 | - const { allPosts, _allPostsMeta } = data | ||
51 | - const areMorePosts = allPosts.length < _allPostsMeta.count | ||
52 | - | ||
53 | - return ( | ||
54 | - <section> | ||
55 | - <ul> | ||
56 | - {allPosts.map((post, index) => ( | ||
57 | - <li key={post.id}> | ||
58 | - <div> | ||
59 | - <span>{index + 1}. </span> | ||
60 | - <a href={post.url}>{post.title}</a> | ||
61 | - <PostUpvoter id={post.id} votes={post.votes} /> | ||
62 | - </div> | ||
63 | - </li> | ||
64 | - ))} | ||
65 | - </ul> | ||
66 | - {areMorePosts && ( | ||
67 | - <button onClick={() => loadMorePosts()} disabled={loadingMorePosts}> | ||
68 | - {loadingMorePosts ? 'Loading...' : 'Show More'} | ||
69 | - </button> | ||
70 | - )} | ||
71 | - <style jsx>{` | ||
72 | - section { | ||
73 | - padding-bottom: 20px; | ||
74 | - } | ||
75 | - li { | ||
76 | - display: block; | ||
77 | - margin-bottom: 10px; | ||
78 | - } | ||
79 | - div { | ||
80 | - align-items: center; | ||
81 | - display: flex; | ||
82 | - } | ||
83 | - a { | ||
84 | - font-size: 14px; | ||
85 | - margin-right: 10px; | ||
86 | - text-decoration: none; | ||
87 | - padding-bottom: 0; | ||
88 | - border: 0; | ||
89 | - } | ||
90 | - span { | ||
91 | - font-size: 14px; | ||
92 | - margin-right: 5px; | ||
93 | - } | ||
94 | - ul { | ||
95 | - margin: 0; | ||
96 | - padding: 0; | ||
97 | - } | ||
98 | - button:before { | ||
99 | - align-self: center; | ||
100 | - border-style: solid; | ||
101 | - border-width: 6px 4px 0 4px; | ||
102 | - border-color: #ffffff transparent transparent transparent; | ||
103 | - content: ''; | ||
104 | - height: 0; | ||
105 | - margin-right: 5px; | ||
106 | - width: 0; | ||
107 | - } | ||
108 | - `}</style> | ||
109 | - </section> | ||
110 | - ) | ||
111 | -} |
1 | -import { gql, useMutation } from '@apollo/client' | ||
2 | - | ||
3 | -const UPDATE_POST_MUTATION = gql` | ||
4 | - mutation votePost($id: String!) { | ||
5 | - votePost(id: $id) { | ||
6 | - id | ||
7 | - votes | ||
8 | - __typename | ||
9 | - } | ||
10 | - } | ||
11 | -` | ||
12 | - | ||
13 | -export default function PostUpvoter({ votes, id }) { | ||
14 | - const [updatePost] = useMutation(UPDATE_POST_MUTATION) | ||
15 | - | ||
16 | - const upvotePost = () => { | ||
17 | - updatePost({ | ||
18 | - variables: { | ||
19 | - id, | ||
20 | - }, | ||
21 | - optimisticResponse: { | ||
22 | - __typename: 'Mutation', | ||
23 | - votePost: { | ||
24 | - __typename: 'Post', | ||
25 | - id, | ||
26 | - votes: votes + 1, | ||
27 | - }, | ||
28 | - }, | ||
29 | - }) | ||
30 | - } | ||
31 | - | ||
32 | - return ( | ||
33 | - <button onClick={() => upvotePost()}> | ||
34 | - {votes} | ||
35 | - <style jsx>{` | ||
36 | - button { | ||
37 | - background-color: transparent; | ||
38 | - border: 1px solid #e4e4e4; | ||
39 | - color: #000; | ||
40 | - } | ||
41 | - button:active { | ||
42 | - background-color: transparent; | ||
43 | - } | ||
44 | - button:before { | ||
45 | - align-self: center; | ||
46 | - border-color: transparent transparent #000000 transparent; | ||
47 | - border-style: solid; | ||
48 | - border-width: 0 4px 6px 4px; | ||
49 | - content: ''; | ||
50 | - height: 0; | ||
51 | - margin-right: 5px; | ||
52 | - width: 0; | ||
53 | - } | ||
54 | - `}</style> | ||
55 | - </button> | ||
56 | - ) | ||
57 | -} |
1 | -import { gql, useMutation } from '@apollo/client' | ||
2 | - | ||
3 | -const CREATE_POST_MUTATION = gql` | ||
4 | - mutation createPost($title: String!, $url: String!) { | ||
5 | - createPost(title: $title, url: $url) { | ||
6 | - id | ||
7 | - title | ||
8 | - votes | ||
9 | - url | ||
10 | - createdAt | ||
11 | - } | ||
12 | - } | ||
13 | -` | ||
14 | - | ||
15 | -export default function Submit() { | ||
16 | - const [createPost, { loading }] = useMutation(CREATE_POST_MUTATION) | ||
17 | - | ||
18 | - const handleSubmit = (event) => { | ||
19 | - event.preventDefault() | ||
20 | - const form = event.target | ||
21 | - const formData = new window.FormData(form) | ||
22 | - const title = formData.get('title') | ||
23 | - const url = formData.get('url') | ||
24 | - form.reset() | ||
25 | - | ||
26 | - createPost({ | ||
27 | - variables: { title, url }, | ||
28 | - update: (cache, { data: { createPost } }) => { | ||
29 | - cache.modify({ | ||
30 | - fields: { | ||
31 | - allPosts(existingPosts = []) { | ||
32 | - const newPostRef = cache.writeFragment({ | ||
33 | - data: createPost, | ||
34 | - fragment: gql` | ||
35 | - fragment NewPost on allPosts { | ||
36 | - id | ||
37 | - type | ||
38 | - } | ||
39 | - `, | ||
40 | - }) | ||
41 | - return [newPostRef, ...existingPosts] | ||
42 | - }, | ||
43 | - }, | ||
44 | - }) | ||
45 | - }, | ||
46 | - }) | ||
47 | - } | ||
48 | - | ||
49 | - return ( | ||
50 | - <form onSubmit={handleSubmit}> | ||
51 | - <h1>Submit</h1> | ||
52 | - <input placeholder="title" name="title" type="text" required /> | ||
53 | - <input placeholder="url" name="url" type="url" required /> | ||
54 | - <button type="submit" disabled={loading}> | ||
55 | - Submit | ||
56 | - </button> | ||
57 | - <style jsx>{` | ||
58 | - form { | ||
59 | - border-bottom: 1px solid #ececec; | ||
60 | - padding-bottom: 20px; | ||
61 | - margin-bottom: 20px; | ||
62 | - } | ||
63 | - h1 { | ||
64 | - font-size: 20px; | ||
65 | - } | ||
66 | - input { | ||
67 | - display: block; | ||
68 | - margin-bottom: 10px; | ||
69 | - } | ||
70 | - `}</style> | ||
71 | - </form> | ||
72 | - ) | ||
73 | -} |
project/packages/web/jest.config.js
0 → 100644
1 | +module.exports = { | ||
2 | + roots: ['<rootDir>'], | ||
3 | + moduleFileExtensions: ['ts', 'tsx', 'js', 'json', 'jsx'], | ||
4 | + testPathIgnorePatterns: ['<rootDir>[/\\\\](node_modules|.next)[/\\\\]'], | ||
5 | + transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(ts|tsx)$'], | ||
6 | + transform: { | ||
7 | + '^.+\\.(ts|tsx)$': 'babel-jest', | ||
8 | + '\\.graphql$': [ | ||
9 | + 'graphql-let/jestTransformer', | ||
10 | + { subsequentTransformer: 'babel-jest' }, | ||
11 | + ], | ||
12 | + }, | ||
13 | +} |
1 | -import { useMemo } from 'react' | 1 | +import { useMemo } from "react"; |
2 | -import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client' | 2 | +import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client"; |
3 | -import { concatPagination } from '@apollo/client/utilities' | 3 | +import { concatPagination } from "@apollo/client/utilities"; |
4 | -import merge from 'deepmerge' | 4 | +import merge from "deepmerge"; |
5 | -import isEqual from 'lodash/isEqual' | ||
6 | 5 | ||
7 | -export const APOLLO_STATE_PROP_NAME = '__APOLLO_STATE__' | 6 | +export const APOLLO_STATE_PROP_NAME = "__APOLLO_STATE__"; |
8 | 7 | ||
9 | -let apolloClient | 8 | +let apolloClient: any; |
10 | 9 | ||
11 | function createApolloClient() { | 10 | function createApolloClient() { |
12 | return new ApolloClient({ | 11 | return new ApolloClient({ |
13 | - ssrMode: typeof window === 'undefined', | 12 | + ssrMode: typeof window === "undefined", |
14 | link: new HttpLink({ | 13 | link: new HttpLink({ |
15 | - uri: 'https://nextjs-graphql-with-prisma-simple.vercel.app/api', // Server URL (must be absolute) | 14 | + uri: "http://localhost:5000/graphql", // Server URL (must be absolute) |
16 | - credentials: 'same-origin', // Additional fetch() options like `credentials` or `headers` | 15 | + credentials: "same-origin", // Additional fetch() options like `credentials` or `headers` |
17 | }), | 16 | }), |
18 | cache: new InMemoryCache({ | 17 | cache: new InMemoryCache({ |
19 | typePolicies: { | 18 | typePolicies: { |
... | @@ -24,50 +23,42 @@ function createApolloClient() { | ... | @@ -24,50 +23,42 @@ function createApolloClient() { |
24 | }, | 23 | }, |
25 | }, | 24 | }, |
26 | }), | 25 | }), |
27 | - }) | 26 | + }); |
28 | } | 27 | } |
29 | 28 | ||
30 | export function initializeApollo(initialState = null) { | 29 | export function initializeApollo(initialState = null) { |
31 | - const _apolloClient = apolloClient ?? createApolloClient() | 30 | + const _apolloClient = apolloClient ?? createApolloClient(); |
32 | 31 | ||
33 | // If your page has Next.js data fetching methods that use Apollo Client, the initial state | 32 | // If your page has Next.js data fetching methods that use Apollo Client, the initial state |
34 | // gets hydrated here | 33 | // gets hydrated here |
35 | if (initialState) { | 34 | if (initialState) { |
36 | // Get existing cache, loaded during client side data fetching | 35 | // Get existing cache, loaded during client side data fetching |
37 | - const existingCache = _apolloClient.extract() | 36 | + const existingCache = _apolloClient.extract(); |
38 | 37 | ||
39 | // Merge the existing cache into data passed from getStaticProps/getServerSideProps | 38 | // Merge the existing cache into data passed from getStaticProps/getServerSideProps |
40 | - const data = merge(initialState, existingCache, { | 39 | + const data = merge(initialState as any, existingCache); |
41 | - // combine arrays using object equality (like in sets) | ||
42 | - arrayMerge: (destinationArray, sourceArray) => [ | ||
43 | - ...sourceArray, | ||
44 | - ...destinationArray.filter((d) => | ||
45 | - sourceArray.every((s) => !isEqual(d, s)) | ||
46 | - ), | ||
47 | - ], | ||
48 | - }) | ||
49 | 40 | ||
50 | // Restore the cache with the merged data | 41 | // Restore the cache with the merged data |
51 | - _apolloClient.cache.restore(data) | 42 | + _apolloClient.cache.restore(data); |
52 | } | 43 | } |
53 | // For SSG and SSR always create a new Apollo Client | 44 | // For SSG and SSR always create a new Apollo Client |
54 | - if (typeof window === 'undefined') return _apolloClient | 45 | + if (typeof window === "undefined") return _apolloClient; |
55 | // Create the Apollo Client once in the client | 46 | // Create the Apollo Client once in the client |
56 | - if (!apolloClient) apolloClient = _apolloClient | 47 | + if (!apolloClient) apolloClient = _apolloClient; |
57 | 48 | ||
58 | - return _apolloClient | 49 | + return _apolloClient; |
59 | } | 50 | } |
60 | 51 | ||
61 | -export function addApolloState(client, pageProps) { | 52 | +export function addApolloState(client: any, pageProps: any) { |
62 | if (pageProps?.props) { | 53 | if (pageProps?.props) { |
63 | - pageProps.props[APOLLO_STATE_PROP_NAME] = client.cache.extract() | 54 | + pageProps.props[APOLLO_STATE_PROP_NAME] = client.cache.extract(); |
64 | } | 55 | } |
65 | 56 | ||
66 | - return pageProps | 57 | + return pageProps; |
67 | } | 58 | } |
68 | 59 | ||
69 | -export function useApollo(pageProps) { | 60 | +export function useApollo(pageProps: any) { |
70 | - const state = pageProps[APOLLO_STATE_PROP_NAME] | 61 | + const state = pageProps[APOLLO_STATE_PROP_NAME]; |
71 | - const store = useMemo(() => initializeApollo(state), [state]) | 62 | + const store = useMemo(() => initializeApollo(state), [state]); |
72 | - return store | 63 | + return store; |
73 | } | 64 | } | ... | ... |
project/packages/web/next-env.d.ts
0 → 100644
project/packages/web/next.config.js
0 → 100644
1 | +module.exports = { | ||
2 | + webpack(config, options) { | ||
3 | + config.module.rules.push({ | ||
4 | + test: /\.graphql$/, | ||
5 | + exclude: /node_modules/, | ||
6 | + use: [options.defaultLoaders.babel, { loader: 'graphql-let/loader' }], | ||
7 | + }) | ||
8 | + | ||
9 | + config.module.rules.push({ | ||
10 | + test: /\.graphqls$/, | ||
11 | + exclude: /node_modules/, | ||
12 | + use: ['graphql-let/schema/loader'], | ||
13 | + }) | ||
14 | + | ||
15 | + config.module.rules.push({ | ||
16 | + test: /\.ya?ml$/, | ||
17 | + type: 'json', | ||
18 | + use: 'yaml-loader', | ||
19 | + }) | ||
20 | + | ||
21 | + return config | ||
22 | + }, | ||
23 | +} |
1 | { | 1 | { |
2 | "name": "@graphql-community/web", | 2 | "name": "@graphql-community/web", |
3 | - "version": "1.0.0", | 3 | + "version": "0.1.0", |
4 | + "author": "", | ||
5 | + "license": "MIT", | ||
4 | "scripts": { | 6 | "scripts": { |
5 | "dev": "next", | 7 | "dev": "next", |
6 | "build": "next build", | 8 | "build": "next build", |
9 | + "test": "jest", | ||
7 | "start": "next start" | 10 | "start": "next start" |
8 | }, | 11 | }, |
9 | "dependencies": { | 12 | "dependencies": { |
10 | - "@apollo/client": "3.1.1", | 13 | + "@graphql-community/shared": "1.0.0", |
11 | - "deepmerge": "^4.2.2", | 14 | + "@apollo/client": "^3.1.3", |
12 | - "lodash": "4.17.20", | 15 | + "@graphql-tools/load-files": "6.0.18", |
13 | - "graphql": "^15.3.0", | 16 | + "@graphql-tools/merge": "6.0.18", |
17 | + "@graphql-tools/schema": "6.0.18", | ||
18 | + "apollo-server-micro": "^2.16.1", | ||
19 | + "graphql": "15.3.0", | ||
14 | "next": "latest", | 20 | "next": "latest", |
15 | - "prop-types": "^15.6.2", | 21 | + "react": "^16.13.1", |
16 | - "react": "^16.7.0", | 22 | + "react-dom": "^16.13.1" |
17 | - "react-dom": "^16.7.0" | ||
18 | }, | 23 | }, |
19 | - "license": "MIT" | 24 | + "devDependencies": { |
25 | + "@graphql-codegen/cli": "^1.17.8", | ||
26 | + "@graphql-codegen/plugin-helpers": "^1.17.8", | ||
27 | + "@graphql-codegen/typescript": "^1.17.8", | ||
28 | + "@graphql-codegen/typescript-operations": "^1.17.8", | ||
29 | + "@graphql-codegen/typescript-react-apollo": "^2.0.6", | ||
30 | + "@graphql-codegen/typescript-resolvers": "^1.17.8", | ||
31 | + "@types/react": "^16.9.46", | ||
32 | + "@types/react-dom": "^16.9.8", | ||
33 | + "@types/react-test-renderer": "16.9.3", | ||
34 | + "babel-jest": "26.3.0", | ||
35 | + "graphql-let": "0.x", | ||
36 | + "graphql-tag": "2.11.0", | ||
37 | + "jest": "26.4.0", | ||
38 | + "react-test-renderer": "16.13.1", | ||
39 | + "typescript": "^3.9.7", | ||
40 | + "yaml-loader": "0.6.0" | ||
41 | + } | ||
20 | } | 42 | } | ... | ... |
project/packages/web/pages/_app.js
deleted
100644 → 0
1 | -import { ApolloProvider } from '@apollo/client' | ||
2 | -import { useApollo } from '../lib/apolloClient' | ||
3 | - | ||
4 | -export default function App({ Component, pageProps }) { | ||
5 | - const apolloClient = useApollo(pageProps) | ||
6 | - | ||
7 | - return ( | ||
8 | - <ApolloProvider client={apolloClient}> | ||
9 | - <Component {...pageProps} /> | ||
10 | - </ApolloProvider> | ||
11 | - ) | ||
12 | -} |
project/packages/web/pages/_app.tsx
0 → 100644
1 | +import { AppProps } from "next/app"; | ||
2 | +import { ApolloProvider } from "@apollo/client"; | ||
3 | +import { useApollo } from "../lib/apollo"; | ||
4 | + | ||
5 | +export default function App({ Component, pageProps }: AppProps) { | ||
6 | + const apolloClient = useApollo(pageProps); | ||
7 | + | ||
8 | + return ( | ||
9 | + <ApolloProvider client={apolloClient}> | ||
10 | + <Component {...pageProps} /> | ||
11 | + </ApolloProvider> | ||
12 | + ); | ||
13 | +} |
project/packages/web/pages/about.js
deleted
100644 → 0
1 | -import App from '../components/App' | ||
2 | -import Header from '../components/Header' | ||
3 | - | ||
4 | -const AboutPage = () => ( | ||
5 | - <App> | ||
6 | - <Header /> | ||
7 | - <article> | ||
8 | - <h1>The Idea Behind This Example</h1> | ||
9 | - <p> | ||
10 | - <a href="https://www.apollographql.com/client/">Apollo</a> is a GraphQL | ||
11 | - client that allows you to easily query the exact data you need from a | ||
12 | - GraphQL server. In addition to fetching and mutating data, Apollo | ||
13 | - analyzes your queries and their results to construct a client-side cache | ||
14 | - of your data, which is kept up to date as further queries and mutations | ||
15 | - are run, fetching more results from the server. | ||
16 | - </p> | ||
17 | - <p> | ||
18 | - In this simple example, we integrate Apollo seamlessly with{' '} | ||
19 | - <a href="https://github.com/vercel/next.js">Next</a> by calling{' '} | ||
20 | - <a href="https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation"> | ||
21 | - getStaticProps | ||
22 | - </a>{' '} | ||
23 | - at our Page component. This approach lets us opt out of getInitialProps | ||
24 | - and let us use all the niceties provided by{' '} | ||
25 | - <a href="https://github.com/vercel/next.js">Next</a>. | ||
26 | - </p> | ||
27 | - <p> | ||
28 | - On initial page load, while on the server and inside{' '} | ||
29 | - <a href="https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation"> | ||
30 | - getStaticProps | ||
31 | - </a> | ||
32 | - , we fetch the query used to get the list of posts. At the point in | ||
33 | - which the query promise resolves, our Apollo Client store is completely | ||
34 | - initialized. Then we serve the initial HTML with the fetched data and | ||
35 | - hydrate Apollo in the browser. | ||
36 | - </p> | ||
37 | - <p> | ||
38 | - This example relies on <a href="http://graph.cool">graph.cool</a> for | ||
39 | - its GraphQL backend. | ||
40 | - </p> | ||
41 | - </article> | ||
42 | - </App> | ||
43 | -) | ||
44 | - | ||
45 | -export default AboutPage |
project/packages/web/pages/about.tsx
0 → 100644
1 | -import App from '../components/App' | ||
2 | -import InfoBox from '../components/InfoBox' | ||
3 | -import Header from '../components/Header' | ||
4 | -import Submit from '../components/Submit' | ||
5 | -import PostList from '../components/PostList' | ||
6 | - | ||
7 | -const ClientOnlyPage = (props) => ( | ||
8 | - <App> | ||
9 | - <Header /> | ||
10 | - <InfoBox> | ||
11 | - ℹ️ This page shows how to use Apollo only in the client. If you{' '} | ||
12 | - <a href="/client-only">reload</a> this page, you will see a loader since | ||
13 | - Apollo didn't fetch any data on the server. This is useful when the page | ||
14 | - doesn't have SEO requirements or blocking data fetching requirements. | ||
15 | - </InfoBox> | ||
16 | - <Submit /> | ||
17 | - <PostList /> | ||
18 | - </App> | ||
19 | -) | ||
20 | - | ||
21 | -export default ClientOnlyPage |
project/packages/web/pages/index.js
deleted
100644 → 0
1 | -import App from '../components/App' | ||
2 | -import InfoBox from '../components/InfoBox' | ||
3 | -import Header from '../components/Header' | ||
4 | -import Submit from '../components/Submit' | ||
5 | -import PostList, { | ||
6 | - ALL_POSTS_QUERY, | ||
7 | - allPostsQueryVars, | ||
8 | -} from '../components/PostList' | ||
9 | -import { initializeApollo, addApolloState } from '../lib/apolloClient' | ||
10 | - | ||
11 | -const IndexPage = () => ( | ||
12 | - <App> | ||
13 | - <Header /> | ||
14 | - <InfoBox>ℹ️ This page shows how to use SSG with Apollo.</InfoBox> | ||
15 | - <Submit /> | ||
16 | - <PostList /> | ||
17 | - </App> | ||
18 | -) | ||
19 | - | ||
20 | -export async function getStaticProps() { | ||
21 | - const apolloClient = initializeApollo() | ||
22 | - | ||
23 | - await apolloClient.query({ | ||
24 | - query: ALL_POSTS_QUERY, | ||
25 | - variables: allPostsQueryVars, | ||
26 | - }) | ||
27 | - | ||
28 | - return addApolloState(apolloClient, { | ||
29 | - props: {}, | ||
30 | - revalidate: 1, | ||
31 | - }) | ||
32 | -} | ||
33 | - | ||
34 | -export default IndexPage |
project/packages/web/pages/index.tsx
0 → 100644
1 | +import { GetPostInput, Post } from "@graphql-community/shared"; | ||
2 | +import { useQuery, gql } from "@apollo/client"; | ||
3 | + | ||
4 | +const GET_SOME_POST_QUERY = gql` | ||
5 | + query GetSomePosts($getSomePostInput: GetPostInput!) { | ||
6 | + getSomePosts(input: $getSomePostInput) { | ||
7 | + author | ||
8 | + category | ||
9 | + } | ||
10 | + } | ||
11 | +`; | ||
12 | + | ||
13 | +const Index = () => { | ||
14 | + const { data, error } = useQuery< | ||
15 | + { getSomePosts: Post[] }, | ||
16 | + { getSomePostInput: GetPostInput } | ||
17 | + >(GET_SOME_POST_QUERY, { | ||
18 | + variables: { | ||
19 | + getSomePostInput: { | ||
20 | + id: 1, | ||
21 | + }, | ||
22 | + }, | ||
23 | + }); | ||
24 | + if (error) console.log(JSON.stringify(error, null, 2)); | ||
25 | + | ||
26 | + return ( | ||
27 | + <> | ||
28 | + <div>index </div> | ||
29 | + <div>{data?.getSomePosts[0].author}</div> | ||
30 | + <div>{data?.getSomePosts[0].category}</div> | ||
31 | + </> | ||
32 | + ); | ||
33 | +}; | ||
34 | + | ||
35 | +export default Index; |
project/packages/web/pages/ssr.js
deleted
100644 → 0
1 | -import App from '../components/App' | ||
2 | -import InfoBox from '../components/InfoBox' | ||
3 | -import Header from '../components/Header' | ||
4 | -import Submit from '../components/Submit' | ||
5 | -import PostList, { | ||
6 | - ALL_POSTS_QUERY, | ||
7 | - allPostsQueryVars, | ||
8 | -} from '../components/PostList' | ||
9 | -import { initializeApollo, addApolloState } from '../lib/apolloClient' | ||
10 | - | ||
11 | -const SSRPage = () => ( | ||
12 | - <App> | ||
13 | - <Header /> | ||
14 | - <InfoBox>ℹ️ This page shows how to use SSR with Apollo.</InfoBox> | ||
15 | - <Submit /> | ||
16 | - <PostList /> | ||
17 | - </App> | ||
18 | -) | ||
19 | - | ||
20 | -export async function getServerSideProps() { | ||
21 | - const apolloClient = initializeApollo() | ||
22 | - | ||
23 | - await apolloClient.query({ | ||
24 | - query: ALL_POSTS_QUERY, | ||
25 | - variables: allPostsQueryVars, | ||
26 | - }) | ||
27 | - | ||
28 | - return addApolloState(apolloClient, { | ||
29 | - props: {}, | ||
30 | - }) | ||
31 | -} | ||
32 | - | ||
33 | -export default SSRPage |
1 | +// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
2 | + | ||
3 | +exports[`Index renders the html we want 1`] = ` | ||
4 | +<div> | ||
5 | + You're signed in as | ||
6 | + Baa | ||
7 | + and you're | ||
8 | + Healthy | ||
9 | + . Go to the | ||
10 | + | ||
11 | + <a | ||
12 | + href="/about" | ||
13 | + onClick={[Function]} | ||
14 | + onMouseEnter={[Function]} | ||
15 | + > | ||
16 | + about | ||
17 | + </a> | ||
18 | + | ||
19 | + page. | ||
20 | + <div> | ||
21 | + <input | ||
22 | + onChange={[Function]} | ||
23 | + placeholder="your new name..." | ||
24 | + type="text" | ||
25 | + /> | ||
26 | + <input | ||
27 | + onClick={[Function]} | ||
28 | + type="button" | ||
29 | + value="change" | ||
30 | + /> | ||
31 | + </div> | ||
32 | +</div> | ||
33 | +`; |
project/packages/web/test/index.test.tsx
0 → 100644
1 | +import { InMemoryCache, gql } from '@apollo/client' | ||
2 | +import React from 'react' | ||
3 | +import Index from '../pages' | ||
4 | +import renderer from 'react-test-renderer' | ||
5 | +import { MockedProvider } from '@apollo/client/testing' | ||
6 | + | ||
7 | +const cache = new InMemoryCache() | ||
8 | +cache.writeQuery({ | ||
9 | + query: gql` | ||
10 | + query Viewer { | ||
11 | + viewer { | ||
12 | + id | ||
13 | + name | ||
14 | + status | ||
15 | + } | ||
16 | + } | ||
17 | + `, | ||
18 | + data: { | ||
19 | + viewer: { | ||
20 | + __typename: 'User', | ||
21 | + id: 'Baa', | ||
22 | + name: 'Baa', | ||
23 | + status: 'Healthy', | ||
24 | + }, | ||
25 | + }, | ||
26 | +}) | ||
27 | + | ||
28 | +describe('Index', () => { | ||
29 | + it('renders the html we want', async () => { | ||
30 | + const component = renderer.create( | ||
31 | + <MockedProvider cache={cache}> | ||
32 | + <Index /> | ||
33 | + </MockedProvider> | ||
34 | + ) | ||
35 | + expect(component.toJSON()).toMatchSnapshot() | ||
36 | + }) | ||
37 | +}) |
project/packages/web/tsconfig.json
0 → 100644
1 | +{ | ||
2 | + "compilerOptions": { | ||
3 | + "allowJs": true, | ||
4 | + "esModuleInterop": true, | ||
5 | + "forceConsistentCasingInFileNames": true, | ||
6 | + "isolatedModules": true, | ||
7 | + "jsx": "preserve", | ||
8 | + "lib": [ | ||
9 | + "dom", | ||
10 | + "es2017" | ||
11 | + ], | ||
12 | + "module": "esnext", | ||
13 | + "moduleResolution": "node", | ||
14 | + "noEmit": true, | ||
15 | + "noFallthroughCasesInSwitch": true, | ||
16 | + "noUnusedLocals": true, | ||
17 | + "noUnusedParameters": true, | ||
18 | + "resolveJsonModule": true, | ||
19 | + "skipLibCheck": true, | ||
20 | + "target": "esnext", | ||
21 | + "strict": false | ||
22 | + }, | ||
23 | + "exclude": [ | ||
24 | + "node_modules" | ||
25 | + ], | ||
26 | + "include": [ | ||
27 | + "**/*.ts", | ||
28 | + "**/*.tsx" | ||
29 | + ] | ||
30 | +} |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment