diff --git a/2022-11-02-og-image-demo/netlify.toml b/2022-11-02-og-image-demo/netlify.toml index 61f77ff8..cd60416b 100644 --- a/2022-11-02-og-image-demo/netlify.toml +++ b/2022-11-02-og-image-demo/netlify.toml @@ -73,9 +73,24 @@ path = "/og/pokemon/p/*" function = "custom-font" path = "/og/custom-font" -# Example for dynamic-image - dynamic-image +# Example for dynamic-image ascorbic - GitHub dynamic-image ascorbic [[edge_functions]] -function = "dynamic-immge" +function = "dynamic-image" +path = "/og/dynamic-image" + +# Example for dynamic-image dthyresson - GitHub dynamic-image dthyresson +[[edge_functions]] +function = "dynamic-image" +path = "/og/dynamic-image" + +# Example for dynamic-image RedwoodJS - GitHub dynamic-image redwoodjs +[[edge_functions]] +function = "dynamic-image" +path = "/og/dynamic-image" + +# Example for dynamic-image default - dynamic-image +[[edge_functions]] +function = "dynamic-image" path = "/og/dynamic-image" # Example for Emoji - Shows emoji @@ -132,3 +147,8 @@ path = "/og/pokemon" [[edge_functions]] function = "pokemon" path = "/og/pokemon/p/*" + +# Example for GraphQL Query - Fetch all image examples via GraphQL +[[edge_functions]] +function = "graphql" +path = "/og/graphql" diff --git a/2022-11-02-og-image-demo/netlify/edge-functions/graphql.tsx b/2022-11-02-og-image-demo/netlify/edge-functions/graphql.tsx new file mode 100644 index 00000000..ef8c5ca0 --- /dev/null +++ b/2022-11-02-og-image-demo/netlify/edge-functions/graphql.tsx @@ -0,0 +1,91 @@ +import React from 'https://esm.sh/react@18.2.0' +import { ImageResponse } from 'https://deno.land/x/og_edge/mod.ts' +import { Request, Context } from 'https://edge.netlify.com' + +import { errorImage } from './lib/errors.tsx' +import { graphqlUrl } from './lib/urls.ts' + +export default async (request: Request, context: Context) => { + const graphqlQuery = `query { + redwood { + version + prismaVersion + } + images { + id + name + description + } + }` + + const variables = {} + const headers = {} + + try { + const image = await fetch(graphqlUrl(request), { + method: 'POST', + body: JSON.stringify({ + query: graphqlQuery, + variables, + headers, + }), + }) + .then((response) => { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}.`) + } + + return response.json() + }) + .then((payload) => { + const { data } = payload + + console.log(data) + + return new ImageResponse( + ( +
+

+ {data.images.length} OpenGraph Dynamic Image Generation Examples +

+ {data.images.map((image) => ( +

+ 📸 "{image.name}" 👉 {image.description} +

+ ))} +
+ ), + { + width: 1200, + height: 630, + // Supported options: 'twemoji', 'blobmoji', 'noto', 'openmoji', 'fluent', 'fluentFlat' + // Default to 'twemoji' + emoji: 'twemoji', + } + ) + }) + .catch((error) => { + console.error(error) + return errorImage + }) + + return image + } catch (e) { + console.error(e) + + return errorImage + } +} diff --git a/2022-11-02-og-image-demo/netlify/edge-functions/lib/errors.tsx b/2022-11-02-og-image-demo/netlify/edge-functions/lib/errors.tsx new file mode 100644 index 00000000..f970f656 --- /dev/null +++ b/2022-11-02-og-image-demo/netlify/edge-functions/lib/errors.tsx @@ -0,0 +1,22 @@ +import React from 'https://esm.sh/react@18.2.0' +import { ImageResponse } from 'https://deno.land/x/og_edge/mod.ts' + +export const errorImage = new ImageResponse( + ( +
+ Ooops. +
+ ) +) diff --git a/2022-11-02-og-image-demo/netlify/edge-functions/lib/urls.ts b/2022-11-02-og-image-demo/netlify/edge-functions/lib/urls.ts new file mode 100644 index 00000000..d9fcbcf7 --- /dev/null +++ b/2022-11-02-og-image-demo/netlify/edge-functions/lib/urls.ts @@ -0,0 +1,12 @@ +import { Request, Context } from 'https://edge.netlify.com' + +export const graphqlUrl = (request: Request): string => { + const { protocol, host } = new URL(request.url) + + const api = protocol + '//' + (host || 'localhost') + const requestUrl = new URL(api) + requestUrl.host = host + requestUrl.pathname = '.netlify/functions/graphql' + + return requestUrl.toString() +} diff --git a/2022-11-02-og-image-demo/netlify/edge-functions/pokemon.tsx b/2022-11-02-og-image-demo/netlify/edge-functions/pokemon.tsx index b73b36be..1d6d4533 100644 --- a/2022-11-02-og-image-demo/netlify/edge-functions/pokemon.tsx +++ b/2022-11-02-og-image-demo/netlify/edge-functions/pokemon.tsx @@ -2,25 +2,7 @@ import React from 'https://esm.sh/react@18.2.0' import { ImageResponse } from 'https://deno.land/x/og_edge/mod.ts' import { Context } from 'https://edge.netlify.com' -const errorImage = new ImageResponse( - ( -
- Ooops. -
- ) -) +import { errorImage } from './lib/errors.tsx' export default async (request: Request, context: Context) => { const DEFAULT_POKEMON = 'pikachu' diff --git a/2022-11-02-og-image-demo/scripts/seed.ts b/2022-11-02-og-image-demo/scripts/seed.ts index 20e99b4d..8b850b08 100644 --- a/2022-11-02-og-image-demo/scripts/seed.ts +++ b/2022-11-02-og-image-demo/scripts/seed.ts @@ -116,6 +116,13 @@ export default async () => { path: '/og/pokemon/p/*', src: '/og/pokemon/p/bulbasaur', }, + { + name: 'GraphQL Query', + description: 'Fetch all image examples via GraphQL', + function: 'graphql', + path: '/og/graphql', + src: '/og/graphql', + }, ] await db.image.createMany({ data }) diff --git a/2022-11-02-og-image-demo/web/src/components/Image/Image.tsx b/2022-11-02-og-image-demo/web/src/components/Image/Image.tsx index ee0b8728..f318fb81 100644 --- a/2022-11-02-og-image-demo/web/src/components/Image/Image.tsx +++ b/2022-11-02-og-image-demo/web/src/components/Image/Image.tsx @@ -1,3 +1,5 @@ +import { Link, routes } from '@redwoodjs/router' + import { PhotoIcon } from '@heroicons/react/24/solid' const Image = ({ image }) => { @@ -7,7 +9,9 @@ const Image = ({ image }) => {

{image.description}

- + + +

diff --git a/2022-11-02-og-image-demo/web/src/components/ImagesCell/ImagesCell.tsx b/2022-11-02-og-image-demo/web/src/components/ImagesCell/ImagesCell.tsx index 1aba1da6..d542e982 100644 --- a/2022-11-02-og-image-demo/web/src/components/ImagesCell/ImagesCell.tsx +++ b/2022-11-02-og-image-demo/web/src/components/ImagesCell/ImagesCell.tsx @@ -1,7 +1,6 @@ import type { ImagesQuery } from 'types/graphql' import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web' -import { Link, routes } from '@redwoodjs/router' import Image from 'src/components/Image/Image' export const QUERY = gql` @@ -29,11 +28,7 @@ export const Success = ({ images }: CellSuccessProps) => { return (

) diff --git a/2022-11-02-og-image-demo/yarn b/2022-11-02-og-image-demo/yarn new file mode 100644 index 00000000..70ffa2e2 --- /dev/null +++ b/2022-11-02-og-image-demo/yarn @@ -0,0 +1,170 @@ +◈ Netlify Dev ◈ +◈ Ignored site settings env var: DATABASE_URL (defined in .env file) +◈ Injected .env file env var: DATABASE_URL +◈ Ignored general context env var: LANG (defined in process) +◈ Injected .env file env var: TEST_DATABASE_URL +◈ Injected .env file env var: SIGN_IMAGE_SECRET +◈ Loaded function graphql http://localhost:8888/.netlify/functions/graphql. +◈ Functions server is listening on 55082 +◈ Setting up local development server +​ +──────────────────────────────────────────────────────────────── + Netlify Build +──────────────────────────────────────────────────────────────── +​ +❯ Version + @netlify/build 28.1.4 +​ +❯ Flags + {} +​ +❯ Current directory + /Users/dthyresson/Dropbox/Code/redwoodjs/redwood-office-hours-examples/2022-11-02-og-image-demo +​ +❯ Config file + /Users/dthyresson/Dropbox/Code/redwoodjs/redwood-office-hours-examples/2022-11-02-og-image-demo/netlify.toml +​ +❯ Context + dev +​ +──────────────────────────────────────────────────────────────── + 1. Run command for local development +──────────────────────────────────────────────────────────────── +​ +◈ Starting Netlify Dev with RedwoodJS +gen | Generating TypeScript definitions and GraphQL schemas... +gen | 22 files generated +​ +(dev.command completed in 5s) + + ┌─────────────────────────────────────────────────┐ + │ │ + │ ◈ Server now ready on http://localhost:8888 │ + │ │ + └─────────────────────────────────────────────────┘ + +◈ Loaded edge function custom-font +◈ Loaded edge function dynamic-image +◈ Loaded edge function emoji +◈ Loaded edge function encrypted +◈ Loaded edge function graphql +◈ Loaded edge function image-svg +◈ Loaded edge function language +◈ Loaded edge function param +◈ Loaded edge function pokemon +◈ Loaded edge function splat +◈ Loaded edge function static +◈ Loaded edge function tailwind +api | Building... Took 360 ms +api | Debugger listening on ws://127.0.0.1:18911/c453c097-b294-44a4-a299-0dd0ec5b51fb +api | For help, see: https://nodejs.org/en/docs/inspector +◈ Reloading function graphql... +◈ Reloaded function graphql +api | Starting API Server... +api | Loading server config from /Users/dthyresson/Dropbox/Code/redwoodjs/redwood-office-hours-examples/2022-11-02-og-image-demo/api/server.config.js +api | +api | 13:13:53 🌲 Configuring api side +api | 🗒 Custom +api | { +api | "options": { +api | "side": "api", +api | "_": [ +api | "api" +api | ], +api | "port": 8911, +api | "p": 8911, +api | "apiRootPath": "/", +api | "rootPath": "/", +api | "root-path": "/", +api | "api-root-path": "/", +api | "$0": "node_modules/@redwoodjs/api-server/dist/index.js" +api | } +api | } +api | Importing Server Functions...  +◈ Reloading function graphql... +◈ Reloaded function graphql +api | /graphql 348 ms +api | ...Done importing in 348 ms +api | Took 383 ms +api | API listening on http://localhost:8911/ +api | GraphQL endpoint at /graphql +api | 13:13:54 🐛 Fastify server configuration +api | 🗒 Custom +api | { +api | "requestTimeout": 15000, +api | "connectionTimeout": 0, +api | "keepAliveTimeout": 72000, +api | "maxRequestsPerSocket": 0, +api | "requestIdHeader": "request-id", +api | "requestIdLogLabel": "reqId", +api | "disableRequestLogging": false, +api | "bodyLimit": 1048576, +api | "caseSensitive": true, +api | "allowUnsafeRegex": false, +api | "ignoreTrailingSlash": false, +api | "ignoreDuplicateSlashes": false, +api | "jsonShorthand": true, +api | "maxParamLength": 100, +api | "onProtoPoisoning": "error", +api | "onConstructorPoisoning": "error", +api | "pluginTimeout": 10000, +api | "http2SessionTimeout": 72000, +api | "exposeHeadRoutes": true +api | } +api | 13:13:54 🐛 Registered plugins +api | bound root 377 ms +api | ├── bound _after 4 ms +api | ├── @fastify/url-data 0 ms +api | ├── fastify-raw-body 0 ms +api | ├── bound _after 0 ms +api | ├── bound _after 0 ms +api | ├── bound _after 0 ms +api | ├── bound _after 0 ms +api | └── bound _after 0 ms +api | +api | 13:13:54 🌲 Server listening at http://[::]:8911 +web | assets by path static/js/*.js 3.26 MiB +web | asset static/js/app.bundle.js 2.86 MiB [emitted] (name: app) 1 related asset +web | asset static/js/src_pages_HomePage_HomePage_tsx.chunk.js 187 KiB [emitted] 1 related asset +web | asset static/js/src_pages_ImagePage_ImagePage_tsx.chunk.js 167 KiB [emitted] 1 related asset +web | asset static/js/runtime-app.bundle.js 51 KiB [emitted] (name: runtime-app) 1 related asset +web | asset static/js/src_pages_NotFoundPage_NotFoundPage_tsx.chunk.js 3.49 KiB [emitted] 1 related asset +web | asset favicon.png 1.7 KiB [emitted] [from: public/favicon.png] [copied] +web | asset index.html 483 bytes [emitted] +web | asset robots.txt 24 bytes [emitted] [from: public/robots.txt] [copied] +web | Entrypoint app 2.91 MiB (2.88 MiB) = static/js/runtime-app.bundle.js 51 KiB static/js/app.bundle.js 2.86 MiB 2 auxiliary assets +web | orphan modules 729 KiB [orphan] 408 modules +web | runtime modules 34.3 KiB 19 modules +web | modules by path ../node_modules/ 2.38 MiB 871 modules +web | modules by path ./src/ 47.3 KiB +web | modules by path ./src/pages/ 8.42 KiB 4 modules +web | modules by path ./src/components/ 8.37 KiB 3 modules +web | modules by path ./src/*.tsx 3.96 KiB 2 modules +web | modules by path ./src/*.css 21.9 KiB +web | ./src/index.css 2.88 KiB [built] [code generated] +web | ../node_modules/@redwoodjs/core/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].oneOf[3].use[1]!../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].oneOf[3].use[2]!./src/index.css 19 KiB [built] [code generated] +web | modules by path ./src/lib/*.ts 2.93 KiB +web | ./src/lib/seo.ts 1.6 KiB [built] [code generated] +web | ./src/lib/netlify.ts 1.33 KiB [built] [code generated] +web | ./src/layouts/MainLayout/MainLayout.tsx 1.77 KiB [built] [code generated] +web | webpack 5.74.0 compiled successfully in 2710 ms +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 1250 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 116 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 235 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 124 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 127 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 111 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 127 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 127 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 106 ms. +Request from ::1: POST /.netlify/functions/graphql +Response with status 200 in 101 ms.