From f22214daeb2fad4b2f0274c795605d4f5143299c Mon Sep 17 00:00:00 2001 From: setsun Date: Tue, 11 Jul 2023 20:29:51 -0400 Subject: [PATCH] boilerplate for a graphql server --- apps/portfolio/package.json | 2 +- apps/portfolio/src/app/api/graphql/route.ts | 65 +++++++ packages/scripts/src/generate-previews.ts | 5 +- pnpm-lock.yaml | 203 ++++++++++++++++++-- 4 files changed, 251 insertions(+), 24 deletions(-) create mode 100644 apps/portfolio/src/app/api/graphql/route.ts diff --git a/apps/portfolio/package.json b/apps/portfolio/package.json index e0b3ee28..f1210c90 100644 --- a/apps/portfolio/package.json +++ b/apps/portfolio/package.json @@ -24,7 +24,7 @@ "classnames": "^2.3.2", "database": "workspace:*", "graphql": "^16.7.1", - "graphql-request": "^6.1.0", + "graphql-yoga": "^4.0.3", "lodash.clamp": "^4.0.3", "next": "^13.4.9", "react": "^18.2.0", diff --git a/apps/portfolio/src/app/api/graphql/route.ts b/apps/portfolio/src/app/api/graphql/route.ts new file mode 100644 index 00000000..1f03d6eb --- /dev/null +++ b/apps/portfolio/src/app/api/graphql/route.ts @@ -0,0 +1,65 @@ +import { client } from "database"; +import { NextResponse } from "next/server"; +import { createYoga, createSchema } from "graphql-yoga"; + +const typeDefs = /* GraphQL */ ` + type User { + id: String! + name: String + email: String + createdAt: Int + updatedAt: Int + } + + type Post { + id: String! + title: String! + content: String + published: Boolean! + author: User + authorId: String + } + + type Query { + listPosts: [Post!]! + getPostById(id: String): Post + } +`; + +const resolvers = { + Query: { + listPosts: async () => { + return await client.post.findMany({ + where: { published: true }, + include: { + author: true, + }, + }); + }, + getPostById: async (_parent, args: { id: string }) => { + return await client.post.findUnique({ + where: { + id: args.id, + }, + include: { + author: true, + }, + }); + }, + }, +}; + +const { handleRequest } = createYoga({ + schema: createSchema({ + typeDefs, + resolvers, + }), + + // While using Next.js file convention for routing, we need to configure Yoga to use the correct endpoint + graphqlEndpoint: "/api/graphql", + + // Yoga needs to know how to create a valid Next response + fetchAPI: { Response: NextResponse }, +}); + +export { handleRequest as GET, handleRequest as POST }; diff --git a/packages/scripts/src/generate-previews.ts b/packages/scripts/src/generate-previews.ts index e9fc2460..e99077ca 100644 --- a/packages/scripts/src/generate-previews.ts +++ b/packages/scripts/src/generate-previews.ts @@ -33,9 +33,6 @@ async function generatePreviews() { // Set screen size await page.setViewport({ width: 1200, height: 700 }); - // Configure the navigation timeout - await page.setDefaultNavigationTimeout(0); - for (let pageNumber of PAGE_NUMBERS) { await page.goto(`https://setsun.xyz/visualizers/${pageNumber}`, { waitUntil: "networkidle0", @@ -56,4 +53,4 @@ async function generatePreviews() { // run logic (async () => { await generatePreviews(); -})(); \ No newline at end of file +})(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 132aec40..ea857a76 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,9 +71,9 @@ importers: graphql: specifier: ^16.7.1 version: 16.7.1 - graphql-request: - specifier: ^6.1.0 - version: 6.1.0(graphql@16.7.1) + graphql-yoga: + specifier: ^4.0.3 + version: 4.0.3(graphql@16.7.1) lodash.clamp: specifier: ^4.0.3 version: 4.0.3 @@ -2902,6 +2902,21 @@ packages: react: 18.2.0 dev: true + /@envelop/core@4.0.0: + resolution: {integrity: sha512-6usEZO86hWT0ZajAbhOX0QXlV++lrlEmu8br6KQVvyXOxttiHADIibgfzb3GtSI7RnnJDnrcRb7Jynv6Lca3iQ==} + engines: {node: '>=16.0.0'} + dependencies: + '@envelop/types': 4.0.0 + tslib: 2.6.0 + dev: false + + /@envelop/types@4.0.0: + resolution: {integrity: sha512-dmBK16VVfKCkqYYemvE+gt1cPBP0d9CbYO4yjNhSSYy9K+w6+Lw48wOLK238mSR339PNAvwj/JW/qzNy2llggA==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + /@esbuild/android-arm64@0.17.19: resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} @@ -3452,6 +3467,56 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@graphql-tools/executor@1.1.0(graphql@16.7.1): + resolution: {integrity: sha512-+1wmnaUHETSYxiK/ELsT60x584Rw3QKBB7F/7fJ83HKPnLifmE2Dm/K9Eyt6L0Ppekf1jNUbWBpmBGb8P5hAeg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/utils': 10.0.3(graphql@16.7.1) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.7.1) + '@repeaterjs/repeater': 3.0.4 + graphql: 16.7.1 + tslib: 2.6.0 + value-or-promise: 1.0.12 + dev: false + + /@graphql-tools/merge@9.0.0(graphql@16.7.1): + resolution: {integrity: sha512-J7/xqjkGTTwOJmaJQJ2C+VDBDOWJL3lKrHJN4yMaRLAJH3PosB7GiPRaSDZdErs0+F77sH2MKs2haMMkywzx7Q==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/utils': 10.0.3(graphql@16.7.1) + graphql: 16.7.1 + tslib: 2.6.0 + dev: false + + /@graphql-tools/schema@10.0.0(graphql@16.7.1): + resolution: {integrity: sha512-kf3qOXMFcMs2f/S8Y3A8fm/2w+GaHAkfr3Gnhh2LOug/JgpY/ywgFVxO3jOeSpSEdoYcDKLcXVjMigNbY4AdQg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/merge': 9.0.0(graphql@16.7.1) + '@graphql-tools/utils': 10.0.3(graphql@16.7.1) + graphql: 16.7.1 + tslib: 2.6.0 + value-or-promise: 1.0.12 + dev: false + + /@graphql-tools/utils@10.0.3(graphql@16.7.1): + resolution: {integrity: sha512-6uO41urAEIs4sXQT2+CYGsUTkHkVo/2MpM/QjoHj6D6xoEF2woXHBpdAVi0HKIInDwZqWgEYOwIFez0pERxa1Q==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.7.1) + dset: 3.1.2 + graphql: 16.7.1 + tslib: 2.6.0 + dev: false + /@graphql-typed-document-node/core@3.2.0(graphql@16.7.1): resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} peerDependencies: @@ -3460,6 +3525,31 @@ packages: graphql: 16.7.1 dev: false + /@graphql-yoga/logger@1.0.0: + resolution: {integrity: sha512-JYoxwnPggH2BfO+dWlWZkDeFhyFZqaTRGLvFhy+Pjp2UxitEW6nDrw+pEDw/K9tJwMjIFMmTT9VfTqrnESmBHg==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.0 + dev: false + + /@graphql-yoga/subscription@4.0.0: + resolution: {integrity: sha512-0qsN/BPPZNMoC2CZ8i+P6PgiJyHh1H35aKDt37qARBDaIOKDQuvEOq7+4txUKElcmXi7DYFo109FkhSQoEajrg==} + engines: {node: '>=16.0.0'} + dependencies: + '@graphql-yoga/typed-event-target': 2.0.0 + '@repeaterjs/repeater': 3.0.4 + '@whatwg-node/events': 0.1.1 + tslib: 2.6.0 + dev: false + + /@graphql-yoga/typed-event-target@2.0.0: + resolution: {integrity: sha512-oA/VGxGmaSDym1glOHrltw43qZsFwLLjBwvh57B79UKX/vo3+UQcRgOyE44c5RP7DCYjkrC2tuArZmb6jCzysw==} + engines: {node: '>=16.0.0'} + dependencies: + '@repeaterjs/repeater': 3.0.4 + tslib: 2.6.0 + dev: false + /@humanwhocodes/config-array@0.11.10: resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} engines: {node: '>=10.10.0'} @@ -4423,6 +4513,10 @@ packages: use-asset: 1.0.4(react@18.2.0) dev: false + /@repeaterjs/repeater@3.0.4: + resolution: {integrity: sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==} + dev: false + /@rollup/pluginutils@4.2.1: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -5812,6 +5906,38 @@ packages: - supports-color dev: true + /@whatwg-node/events@0.1.1: + resolution: {integrity: sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==} + engines: {node: '>=16.0.0'} + dev: false + + /@whatwg-node/fetch@0.9.8: + resolution: {integrity: sha512-PA7pIw22WYtMladTEVCq2EObUI9yFFLqgLHp4dK6w7iEVr5VRE6S2V+8XKFPdTxR8UowK8rYqrkzfuXxTOn23A==} + engines: {node: '>=16.0.0'} + dependencies: + '@whatwg-node/node-fetch': 0.4.7 + urlpattern-polyfill: 9.0.0 + dev: false + + /@whatwg-node/node-fetch@0.4.7: + resolution: {integrity: sha512-hoH1HrLkMi5EFd+R8NqmAFHDj2v8731vnz9A+Brn3RSBDGpJxJrqa0LLHlBaZciAIdf+9z+wfErOKfa+s/EdgA==} + engines: {node: '>=16.0.0'} + dependencies: + '@whatwg-node/events': 0.1.1 + busboy: 1.6.0 + fast-querystring: 1.1.2 + fast-url-parser: 1.1.3 + tslib: 2.6.0 + dev: false + + /@whatwg-node/server@0.9.2: + resolution: {integrity: sha512-W8CzF9Lvu/AKE+HFmKmTwJZ91G+zPmn0zjsl47hjcY5y0/kZqkCqwB86c0y8rRf8+bV5hJ2ChDK8otN0y6fzng==} + engines: {node: '>=16.0.0'} + dependencies: + '@whatwg-node/fetch': 0.9.8 + tslib: 2.6.0 + dev: false + /@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.17.19): resolution: {integrity: sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==} engines: {node: '>=14.15.0'} @@ -6794,14 +6920,6 @@ packages: /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - /cross-fetch@3.1.8: - resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} - dependencies: - node-fetch: 2.6.12 - transitivePeerDependencies: - - encoding - dev: false - /cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} dependencies: @@ -7380,6 +7498,11 @@ packages: resolution: {integrity: sha512-+3NaRjWktb5r61ZFoDejlykPEFKT5N/LkbXsaddlw6xNSXBanUYpFc2AXXpbJDilPHazcSreU/DpQIaxfX0NfQ==} dev: false + /dset@3.1.2: + resolution: {integrity: sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==} + engines: {node: '>=4'} + dev: false + /duplexify@3.7.1: resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} dependencies: @@ -8194,6 +8317,10 @@ packages: - supports-color dev: false + /fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + dev: false + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -8217,6 +8344,18 @@ packages: /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + /fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + dependencies: + fast-decode-uri-component: 1.0.1 + dev: false + + /fast-url-parser@1.1.3: + resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} + dependencies: + punycode: 1.4.1 + dev: false + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: @@ -8741,16 +8880,24 @@ packages: /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - /graphql-request@6.1.0(graphql@16.7.1): - resolution: {integrity: sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==} + /graphql-yoga@4.0.3(graphql@16.7.1): + resolution: {integrity: sha512-MP+v+yxCqM3lXg95vaA+kXjyRvyRxHUlgZryTecN7ugzEEnyQKKu8JBXA4ziEuLi3liRriyjCAyV4pqFzhHujA==} + engines: {node: '>=16.0.0'} peerDependencies: - graphql: 14 - 16 - dependencies: - '@graphql-typed-document-node/core': 3.2.0(graphql@16.7.1) - cross-fetch: 3.1.8 + graphql: ^15.2.0 || ^16.0.0 + dependencies: + '@envelop/core': 4.0.0 + '@graphql-tools/executor': 1.1.0(graphql@16.7.1) + '@graphql-tools/schema': 10.0.0(graphql@16.7.1) + '@graphql-tools/utils': 10.0.3(graphql@16.7.1) + '@graphql-yoga/logger': 1.0.0 + '@graphql-yoga/subscription': 4.0.0 + '@whatwg-node/fetch': 0.9.8 + '@whatwg-node/server': 0.9.2 + dset: 3.1.2 graphql: 16.7.1 - transitivePeerDependencies: - - encoding + lru-cache: 10.0.0 + tslib: 2.6.0 dev: false /graphql@16.7.1: @@ -9857,6 +10004,11 @@ packages: dependencies: js-tokens: 4.0.0 + /lru-cache@10.0.0: + resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==} + engines: {node: 14 || >=16.14} + dev: false + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: @@ -11140,6 +11292,10 @@ packages: pump: 2.0.1 dev: true + /punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + dev: false + /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} @@ -13111,6 +13267,10 @@ packages: dependencies: punycode: 2.3.0 + /urlpattern-polyfill@9.0.0: + resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==} + dev: false + /use-asset@1.0.4(react@18.2.0): resolution: {integrity: sha512-7/hqDrWa0iMnCoET9W1T07EmD4Eg/Wmoj/X8TGBc++ECRK4m5yTsjP4O6s0yagbxfqIOuUkIxe2/sA+VR2GxZA==} peerDependencies: @@ -13205,6 +13365,11 @@ packages: spdx-expression-parse: 3.0.1 dev: true + /value-or-promise@1.0.12: + resolution: {integrity: sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==} + engines: {node: '>=12'} + dev: false + /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'}