@smartive/graphql-magic 15.1.0 → 15.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
- # [15.1.0](https://github.com/smartive/graphql-magic/compare/v15.0.1...v15.1.0) (2024-04-03)
1
+ # [15.2.0](https://github.com/smartive/graphql-magic/compare/v15.1.1...v15.2.0) (2024-04-03)
2
2
 
3
3
 
4
4
  ### Features
5
5
 
6
- * Docs ([#153](https://github.com/smartive/graphql-magic/issues/153)) ([a827813](https://github.com/smartive/graphql-magic/commit/a8278137bf7d8b68a06d17ebeb9380071490b4c9))
6
+ * Finish tutorial ([c1b0a21](https://github.com/smartive/graphql-magic/commit/c1b0a215ed23773fd287cd5b5898f07f7c401af1))
@@ -10,59 +10,85 @@ Let's create a blog with `graphql-magic`!
10
10
 
11
11
  ### Code base
12
12
 
13
- First create a next.js website:
13
+ First create a `next.js` website:
14
14
 
15
15
  ```
16
16
  npx create-next-app@latest magic-blog --ts --app --tailwind --eslint --src
17
17
  cd magic-blog
18
18
  ```
19
19
 
20
- For some styling install `preline` and dependencies:
20
+ Replace `app/globals.css`:
21
21
 
22
22
  ```
23
- npm i preline @tailwindcss/forms
24
- ```
23
+ @tailwind base;
24
+ @tailwind components;
25
+ @tailwind utilities;
25
26
 
26
- Add `@tailwindcss/forms` to `tailwind.config.ts`:
27
+ main {
28
+ @apply w-96 mx-auto
29
+ }
27
30
 
28
- ```
29
- plugins: [
30
- require('@tailwindcss/forms'),
31
- ],
32
- ```
31
+ nav {
32
+ @apply flex items-center
33
+ }
33
34
 
34
- Replace `app/globals.css`:
35
+ h1, h2, h3, h4 {
36
+ @apply font-bold
37
+ }
35
38
 
36
- ```
37
- TODO
38
- ```
39
+ h1 {
40
+ @apply text-4xl mb-4 flex-grow
41
+ }
39
42
 
40
- Replace `app/layout.tsx`:
43
+ h2 {
44
+ @apply text-3xl mb-3
45
+ }
41
46
 
42
- ```
43
- export default function RootLayout({
44
- children,
45
- }: Readonly<{
46
- children: React.ReactNode;
47
- }>) {
48
- return (
49
- <html>
50
- <body>{children}</body>
51
- </html>
52
- );
47
+ h3 {
48
+ @apply text-2xl mb-2
49
+ }
50
+
51
+ h4 {
52
+ @apply text-xl mb-1
53
+ }
54
+
55
+ a {
56
+ @apply text-blue-500
57
+ }
58
+
59
+ article, form {
60
+ @apply mb-4 p-3 rounded-lg shadow-md border border-gray-100
61
+ }
62
+
63
+ input, textarea {
64
+ @apply border border-gray-300 w-full rounded-md p-1
65
+ }
66
+
67
+ label span {
68
+ @apply font-bold
53
69
  }
54
70
  ```
55
71
 
56
72
  Replace `app/page.tsx`:
57
73
 
58
74
  ```
59
- export default function Page() {
60
- return <div>
75
+ export default async function Home() {
76
+ return <main>
77
+ <nav>
61
78
  <h1>Magic Blog</h1>
62
- </div>
79
+ </nav>
80
+ </main>
63
81
  }
64
82
  ```
65
83
 
84
+ Start the website:
85
+
86
+ ```
87
+ npm run dev
88
+ ```
89
+
90
+ ### Install graphql-magic
91
+
66
92
  Add this setting to `next.config.mjs`:
67
93
 
68
94
  ```
@@ -79,28 +105,16 @@ Install `@smartive/graphql-magic`:
79
105
  npm install @smartive/graphql-magic
80
106
  ```
81
107
 
82
- Temporary:
83
-
84
- ```
85
- npm i @graphql-codegen/typescript-compatibility
86
- ```
87
-
88
108
  Run the gqm cli:
89
109
 
90
110
  ```
91
111
  npx gqm generate
92
112
  ```
93
113
 
94
- Start the website:
95
-
96
- ```
97
- npm run dev
98
- ```
99
-
100
114
  ### Database setup
101
115
 
102
- Adapt the database `.env` variables to connect to a postgresql instance, or create a new one.
103
- For example, to create a local instance with docker and docker-compose, create the following `docker-compose.yml`:
116
+ Let's boot a local database instance.
117
+ Create the following `docker-compose.yml`:
104
118
 
105
119
  ```
106
120
  version: '3.4'
@@ -148,10 +162,12 @@ import { getSession } from '@auth0/nextjs-auth0';
148
162
  export default async function Page() {
149
163
  const session = await getSession();
150
164
 
151
- return <div>
165
+ return <main>
166
+ <nav>
152
167
  <h1>Welcome to my Blog</h1>
153
168
  {session ? <a href="/api/auth/logout">Logout</a> : <a href="/api/auth/login">Login</a>}
154
- </div>
169
+ </nav>
170
+ </main>
155
171
  }
156
172
  ```
157
173
 
@@ -241,17 +257,21 @@ npx gqm generate
241
257
  Now, let's modify `src/app/page.tsx` so that it fetches the user from the database:
242
258
 
243
259
  ```
244
- import { GetMeQuery } from "../generated/client";
245
- import { GET_ME } from "../graphql/client/queries/get-me";
246
- import { executeGraphql } from "../graphql/execute";
260
+ import { GetMeQuery } from "@/generated/client";
261
+ import { GET_ME } from "@/graphql/client/queries/get-me";
262
+ import { executeGraphql } from "@/graphql/execute";
247
263
 
248
- export default async function Page() {
249
- const { data: { me }} = await executeGraphql<GetMeQuery>({ query: GET_ME });
264
+ export default async function Home() {
265
+ const { data: { me } } = await executeGraphql<GetMeQuery>({ query: GET_ME });
250
266
 
251
- return <div>
252
- <h1>Welcome to my Blog</h1>
253
- {me ? <div>Hello {me.username}! <a href="/api/auth/logout">Logout</a></div> : <a href="/api/auth/login">Login</a>}
254
- </div>
267
+ return (
268
+ <main>
269
+ <nav>
270
+ <h1>Blog</h1>
271
+ {me ? <span>Hello, {me.username}! <a href="/api/auth/logout"> Logout</a></span> : <a href="/api/auth/login">Login</a>}
272
+ </nav>
273
+ </main>
274
+ );
255
275
  }
256
276
  ```
257
277
 
@@ -316,7 +336,7 @@ npx env-cmd knex migrate:up
316
336
  npx gqm generate
317
337
  ```
318
338
 
319
- new get-posts
339
+ Create a new query `src/graphql/client/queries/get-posts.ts`:
320
340
 
321
341
  ```
322
342
  import { gql } from '@smartive/graphql-magic';
@@ -342,12 +362,53 @@ export const GET_POSTS = gql`
342
362
  `;
343
363
  ```
344
364
 
345
- ```
346
- {me && <CreatePost/> }
347
- <Posts/>
348
- ```
365
+ Now add all the logic to create and display posts and comments to `src/app/page.tsx`
366
+
349
367
 
350
368
  ```
369
+ import { CreateCommentMutationMutation, CreateCommentMutationMutationVariables, CreatePostMutationMutation, CreatePostMutationMutationVariables, GetMeQuery, GetPostsQuery } from "@/generated/client";
370
+ import { CREATE_COMMENT, CREATE_POST } from "@/generated/client/mutations";
371
+ import { GET_ME } from "@/graphql/client/queries/get-me";
372
+ import { GET_POSTS } from "@/graphql/client/queries/get-posts";
373
+ import { executeGraphql } from "@/graphql/execute";
374
+ import { revalidatePath } from "next/cache";
375
+
376
+ export default async function Home() {
377
+ const { data: { me } } = await executeGraphql<GetMeQuery>({ query: GET_ME });
378
+
379
+ return (
380
+ <main>
381
+ <nav>
382
+ <h1>Blog</h1>
383
+ {me ? <span>Hello, {me.username}! <a href="/api/auth/logout"> Logout</a></span> : <a href="/api/auth/login">Login</a>}
384
+ </nav>
385
+ {me && <CreatePost />}
386
+ <Posts me={me} />
387
+ </main>
388
+ );
389
+ }
390
+
391
+ async function Posts({ me }: { me: GetMeQuery['me'] }) {
392
+ const { data: { posts } } = await executeGraphql<GetPostsQuery>({ query: GET_POSTS })
393
+
394
+ return <div>
395
+ {posts.map(post => <div key={post.id}>
396
+ <article>
397
+ <h2>{post.title}</h2>
398
+ <div>by {post.createdBy.username}</div>
399
+ <p>{post.content}</p>
400
+ <h4>Comments</h4>
401
+ {post.comments.map(comment => (<div key={comment.id}>
402
+ <div>{comment.createdBy.username}</div>
403
+ <p>{comment.content}</p> by {comment.createdBy.username}
404
+ </div>)
405
+ )}
406
+ {me && <CreateComment postId={post.id} />}
407
+ </article>
408
+ </div>)}
409
+ </div>
410
+ }
411
+
351
412
  async function CreatePost() {
352
413
  async function createPost(formData: FormData) {
353
414
  'use server'
@@ -365,44 +426,20 @@ async function CreatePost() {
365
426
 
366
427
  return <form action={createPost}>
367
428
  <h2>New Post</h2>
368
- <div>
429
+ <label>
369
430
  <span>Title</span>
370
431
  <input name="title" />
371
- </div>
372
- <div>
432
+ </label>
433
+ <label>
373
434
  <span>Content</span>
374
435
  <textarea rows={5} name="content" />
375
- </div>
436
+ </label>
376
437
  <div>
377
438
  <button type="submit">Create</button>
378
439
  </div>
379
440
  </form>
380
441
  }
381
- ```
382
-
383
- ```
384
- async function Posts() {
385
- const { data: { posts } } = await executeGraphql<GetPostsQuery>({ query: GET_POSTS })
386
-
387
- return <div>
388
- {posts.map(post => <div key={post.id}>
389
- <article>
390
- <h3>{post.title}</h3>
391
- <div>{post.createdBy.username}</div>
392
- <div>{post.content}</div>
393
- {post.comments.map(comment => (<div key={comment.id}>
394
- <div>{comment.createdBy.username}</div>
395
- <p>{comment.content}</p> by {comment.createdBy.username}
396
- </div>)
397
- )}
398
- <CreateComment postId={post.id} />
399
- </article>
400
- </div>)}
401
- </div>
402
- }
403
- ```
404
442
 
405
- ```
406
443
  function CreateComment({ postId }: { postId: string }) {
407
444
  async function createComment(formData: FormData) {
408
445
  'use server'
@@ -429,3 +466,5 @@ function CreateComment({ postId }: { postId: string }) {
429
466
  </form>
430
467
  }
431
468
  ```
469
+
470
+ Now you should have a working minimal blog example!
@@ -7,11 +7,8 @@ const config: Config = {
7
7
  tagline: 'Model-first GraphQL API generator',
8
8
  favicon: 'img/favicon.ico',
9
9
 
10
- // Set the production url of your site here
11
- url: 'https://your-docusaurus-site.example.com',
12
- // Set the /<baseUrl>/ pathname under which your site is served
13
- // For GitHub pages deployment, it is often '/<projectName>/'
14
- baseUrl: '/',
10
+ url: 'https://smartive.github.io',
11
+ baseUrl: '/graphql-magic/',
15
12
 
16
13
  // GitHub pages deployment config.
17
14
  // If you aren't using GitHub pages, you don't need these.
@@ -1,5 +1,5 @@
1
- import clsx from 'clsx';
2
1
  import Heading from '@theme/Heading';
2
+ import clsx from 'clsx';
3
3
  import styles from './styles.module.css';
4
4
 
5
5
  type FeatureItem = {
@@ -10,38 +10,35 @@ type FeatureItem = {
10
10
 
11
11
  const FeatureList: FeatureItem[] = [
12
12
  {
13
- title: 'Easy to Use',
13
+ title: 'Model-first',
14
14
  Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
15
15
  description: (
16
16
  <>
17
- Docusaurus was designed from the ground up to be easily installed and
18
- used to get your website up and running quickly.
17
+ Define your model, generate everything else.
19
18
  </>
20
19
  ),
21
20
  },
22
21
  {
23
- title: 'Focus on What Matters',
22
+ title: 'CLI',
24
23
  Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
25
24
  description: (
26
25
  <>
27
- Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
28
- ahead and move your docs into the <code>docs</code> directory.
26
+ Generate things with our cli.
29
27
  </>
30
28
  ),
31
29
  },
32
30
  {
33
- title: 'Powered by React',
31
+ title: 'Brought to you by smartive',
34
32
  Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
35
33
  description: (
36
34
  <>
37
- Extend or customize your website layout by reusing React. Docusaurus can
38
- be extended while reusing the same header and footer.
35
+ We developed this as an internal tool.
39
36
  </>
40
37
  ),
41
38
  },
42
39
  ];
43
40
 
44
- function Feature({title, Svg, description}: FeatureItem) {
41
+ function Feature({ title, Svg, description }: FeatureItem) {
45
42
  return (
46
43
  <div className={clsx('col col--4')}>
47
44
  <div className="text--center">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartive/graphql-magic",
3
- "version": "15.1.0",
3
+ "version": "15.2.0",
4
4
  "description": "",
5
5
  "source": "src/index.ts",
6
6
  "type": "module",