diff --git a/examples/blog-starter/components/avatar.js b/examples/blog-starter/components/avatar.js index 2dcc7eee1069..106d1e0bba9f 100644 --- a/examples/blog-starter/components/avatar.js +++ b/examples/blog-starter/components/avatar.js @@ -1,7 +1,14 @@ +import Image from 'next/image' export default function Avatar({ name, picture }) { return (
- {name} + {name}
{name}
) diff --git a/examples/blog-starter/components/cover-image.js b/examples/blog-starter/components/cover-image.js index 04832ba5107b..d3e21d21f161 100644 --- a/examples/blog-starter/components/cover-image.js +++ b/examples/blog-starter/components/cover-image.js @@ -18,7 +18,7 @@ export default function CoverImage({ title, src, slug, height, width }) { return (
{slug ? ( - + {image} ) : ( diff --git a/examples/blog-starter/components/hero-post.js b/examples/blog-starter/components/hero-post.js index ddb182a8b716..6dc49f20a8bb 100644 --- a/examples/blog-starter/components/hero-post.js +++ b/examples/blog-starter/components/hero-post.js @@ -25,7 +25,7 @@ export default function HeroPost({

- + {title}

diff --git a/examples/blog-starter/components/post-preview.js b/examples/blog-starter/components/post-preview.js index 3e3009fa2721..712eea6e92ec 100644 --- a/examples/blog-starter/components/post-preview.js +++ b/examples/blog-starter/components/post-preview.js @@ -23,7 +23,7 @@ export default function PostPreview({ />

- + {title}

diff --git a/examples/blog-starter/package.json b/examples/blog-starter/package.json index ee9d9ba4dc95..29d3f61c590c 100644 --- a/examples/blog-starter/package.json +++ b/examples/blog-starter/package.json @@ -16,8 +16,8 @@ "remark-html": "15.0.1" }, "devDependencies": { - "autoprefixer": "^10.4.0", - "postcss": "^8.4.4", - "tailwindcss": "^3.0.1" + "autoprefixer": "^10.4.2", + "postcss": "^8.4.7", + "tailwindcss": "^3.0.23" } } diff --git a/examples/cms-tina/.gitignore b/examples/cms-tina/.gitignore new file mode 100644 index 000000000000..1437c53f70bc --- /dev/null +++ b/examples/cms-tina/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel diff --git a/examples/cms-tina/.tina/__generated__/.gitignore b/examples/cms-tina/.tina/__generated__/.gitignore new file mode 100644 index 000000000000..5baa59d64639 --- /dev/null +++ b/examples/cms-tina/.tina/__generated__/.gitignore @@ -0,0 +1 @@ +db \ No newline at end of file diff --git a/examples/cms-tina/.tina/__generated__/_graphql.json b/examples/cms-tina/.tina/__generated__/_graphql.json new file mode 100644 index 000000000000..4f7ac4cfe7ef --- /dev/null +++ b/examples/cms-tina/.tina/__generated__/_graphql.json @@ -0,0 +1,2072 @@ +{ + "kind": "Document", + "definitions": [ + { + "kind": "ScalarTypeDefinition", + "name": { + "kind": "Name", + "value": "Reference" + }, + "description": { + "kind": "StringValue", + "value": "References another document, used as a foreign key" + }, + "directives": [] + }, + { + "kind": "ScalarTypeDefinition", + "name": { + "kind": "Name", + "value": "JSON" + }, + "description": { + "kind": "StringValue", + "value": "" + }, + "directives": [] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "SystemInfo" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "filename" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "basename" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "breadcrumbs" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "excludeExtension" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Boolean" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "path" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "relativePath" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "extension" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "template" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "collection" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collection" + } + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "PageInfo" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "hasPreviousPage" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Boolean" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "hasNextPage" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Boolean" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "startCursor" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "endCursor" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + } + ] + }, + { + "kind": "InterfaceTypeDefinition", + "description": { + "kind": "StringValue", + "value": "" + }, + "name": { + "kind": "Name", + "value": "Node" + }, + "interfaces": [], + "directives": [], + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + } + ] + }, + { + "kind": "InterfaceTypeDefinition", + "description": { + "kind": "StringValue", + "value": "" + }, + "name": { + "kind": "Name", + "value": "Document" + }, + "interfaces": [], + "directives": [], + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "sys" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "SystemInfo" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "form" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "JSON" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "values" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "JSON" + } + } + } + } + ] + }, + { + "kind": "InterfaceTypeDefinition", + "description": { + "kind": "StringValue", + "value": "A relay-compliant pagination connection" + }, + "name": { + "kind": "Name", + "value": "Connection" + }, + "interfaces": [], + "directives": [], + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "totalCount" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "Query" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "getCollection" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collection" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "getCollections" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "ListType", + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Collection" + } + } + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "node" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Node" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "getDocument" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "relativePath" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentNode" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "getDocumentList" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "before" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "after" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "last" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentConnection" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "getDocumentFields" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "JSON" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "getPostsDocument" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "relativePath" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsDocument" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "getPostsList" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "before" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "after" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "last" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsConnection" + } + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "DocumentConnectionEdges" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "cursor" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "node" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentNode" + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [ + { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Connection" + } + } + ], + "directives": [], + "name": { + "kind": "Name", + "value": "DocumentConnection" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "pageInfo" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PageInfo" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "totalCount" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "edges" + }, + "arguments": [], + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentConnectionEdges" + } + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "Collection" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "name" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "slug" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "label" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "path" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "format" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "matches" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "templates" + }, + "arguments": [], + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "JSON" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "fields" + }, + "arguments": [], + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "JSON" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "documents" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "before" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "after" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "first" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "last" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentConnection" + } + } + } + } + ] + }, + { + "kind": "UnionTypeDefinition", + "name": { + "kind": "Name", + "value": "DocumentNode" + }, + "directives": [], + "types": [ + { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsDocument" + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "PostsAuthor" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "name" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "picture" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "PostsOgImage" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "url" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "Posts" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "title" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "excerpt" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "coverImage" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "date" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "author" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsAuthor" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "ogImage" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsOgImage" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "body" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [ + { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Node" + } + }, + { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Document" + } + } + ], + "directives": [], + "name": { + "kind": "Name", + "value": "PostsDocument" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "id" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "ID" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "sys" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "SystemInfo" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "data" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Posts" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "form" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "JSON" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "values" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "JSON" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "dataJSON" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "JSON" + } + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "PostsConnectionEdges" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "cursor" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "node" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsDocument" + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [ + { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Connection" + } + } + ], + "directives": [], + "name": { + "kind": "Name", + "value": "PostsConnection" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "pageInfo" + }, + "arguments": [], + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PageInfo" + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "totalCount" + }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "Float" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "edges" + }, + "arguments": [], + "type": { + "kind": "ListType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsConnectionEdges" + } + } + } + } + ] + }, + { + "kind": "ObjectTypeDefinition", + "interfaces": [], + "directives": [], + "name": { + "kind": "Name", + "value": "Mutation" + }, + "fields": [ + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "addPendingDocument" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collection" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "relativePath" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "template" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentNode" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "updateDocument" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "relativePath" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "params" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentMutation" + } + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentNode" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "createDocument" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "collection" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "relativePath" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "params" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentMutation" + } + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "DocumentNode" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "updatePostsDocument" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "relativePath" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "params" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsMutation" + } + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsDocument" + } + } + } + }, + { + "kind": "FieldDefinition", + "name": { + "kind": "Name", + "value": "createPostsDocument" + }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "relativePath" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "params" + }, + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsMutation" + } + } + } + } + ], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsDocument" + } + } + } + } + ] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "DocumentMutation" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "posts" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsMutation" + } + } + } + ] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "PostsAuthorMutation" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "name" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "picture" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "PostsOgImageMutation" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "url" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ] + }, + { + "kind": "InputObjectTypeDefinition", + "name": { + "kind": "Name", + "value": "PostsMutation" + }, + "fields": [ + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "title" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "excerpt" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "coverImage" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "date" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "author" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsAuthorMutation" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "ogImage" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "PostsOgImageMutation" + } + } + }, + { + "kind": "InputValueDefinition", + "name": { + "kind": "Name", + "value": "body" + }, + "type": { + "kind": "NamedType", + "name": { + "kind": "Name", + "value": "String" + } + } + } + ] + } + ] +} diff --git a/examples/cms-tina/.tina/__generated__/_lookup.json b/examples/cms-tina/.tina/__generated__/_lookup.json new file mode 100644 index 000000000000..6e651b843207 --- /dev/null +++ b/examples/cms-tina/.tina/__generated__/_lookup.json @@ -0,0 +1,29 @@ +{ + "DocumentConnection": { + "type": "DocumentConnection", + "resolveType": "multiCollectionDocumentList", + "collections": ["posts"] + }, + "Node": { + "type": "Node", + "resolveType": "nodeDocument" + }, + "DocumentNode": { + "type": "DocumentNode", + "resolveType": "multiCollectionDocument", + "createDocument": "create", + "updateDocument": "update" + }, + "PostsDocument": { + "type": "PostsDocument", + "resolveType": "collectionDocument", + "collection": "posts", + "createPostsDocument": "create", + "updatePostsDocument": "update" + }, + "PostsConnection": { + "type": "PostsConnection", + "resolveType": "collectionDocumentList", + "collection": "posts" + } +} diff --git a/examples/cms-tina/.tina/__generated__/_schema.json b/examples/cms-tina/.tina/__generated__/_schema.json new file mode 100644 index 000000000000..46e9b5f5c4c1 --- /dev/null +++ b/examples/cms-tina/.tina/__generated__/_schema.json @@ -0,0 +1,87 @@ +{ + "version": { + "fullVersion": "0.59.7", + "major": "0", + "minor": "59", + "patch": "7" + }, + "meta": {}, + "collections": [ + { + "label": "Blog Posts", + "name": "posts", + "path": "_posts", + "fields": [ + { + "type": "string", + "label": "Title", + "name": "title", + "namespace": ["posts", "title"] + }, + { + "type": "string", + "label": "Excerpt", + "name": "excerpt", + "namespace": ["posts", "excerpt"] + }, + { + "type": "string", + "label": "Cover Image", + "name": "coverImage", + "namespace": ["posts", "coverImage"] + }, + { + "type": "string", + "label": "Date", + "name": "date", + "namespace": ["posts", "date"] + }, + { + "type": "object", + "label": "author", + "name": "author", + "fields": [ + { + "type": "string", + "label": "Name", + "name": "name", + "namespace": ["posts", "author", "name"] + }, + { + "type": "string", + "label": "Picture", + "name": "picture", + "namespace": ["posts", "author", "picture"] + } + ], + "namespace": ["posts", "author"] + }, + { + "type": "object", + "label": "OG Image", + "name": "ogImage", + "fields": [ + { + "type": "string", + "label": "Url", + "name": "url", + "namespace": ["posts", "ogImage", "url"] + } + ], + "namespace": ["posts", "ogImage"] + }, + { + "type": "string", + "label": "Blog Post Body", + "name": "body", + "isBody": true, + "ui": { + "component": "textarea" + }, + "namespace": ["posts", "body"] + } + ], + "namespace": ["posts"] + } + ] +} diff --git a/examples/cms-tina/.tina/__generated__/frags.gql b/examples/cms-tina/.tina/__generated__/frags.gql new file mode 100644 index 000000000000..4c1472d2fce0 --- /dev/null +++ b/examples/cms-tina/.tina/__generated__/frags.gql @@ -0,0 +1,16 @@ +fragment PostsParts on Posts { + title + excerpt + coverImage + date + author { + __typename + name + picture + } + ogImage { + __typename + url + } + body +} diff --git a/examples/cms-tina/.tina/__generated__/queries.gql b/examples/cms-tina/.tina/__generated__/queries.gql new file mode 100644 index 000000000000..949e4040d5e9 --- /dev/null +++ b/examples/cms-tina/.tina/__generated__/queries.gql @@ -0,0 +1,38 @@ +query getPostsDocument($relativePath: String!) { + getPostsDocument(relativePath: $relativePath) { + sys { + filename + basename + breadcrumbs + path + relativePath + extension + } + id + data { + ...PostsParts + } + } +} + +query getPostsList { + getPostsList { + totalCount + edges { + node { + id + sys { + filename + basename + breadcrumbs + path + relativePath + extension + } + data { + ...PostsParts + } + } + } + } +} diff --git a/examples/cms-tina/.tina/__generated__/schema.gql b/examples/cms-tina/.tina/__generated__/schema.gql new file mode 100644 index 000000000000..42acbd89517d --- /dev/null +++ b/examples/cms-tina/.tina/__generated__/schema.gql @@ -0,0 +1,196 @@ +# DO NOT MODIFY THIS FILE. This file is automatically generated by Tina +""" +References another document, used as a foreign key +""" +scalar Reference + +""" + +""" +scalar JSON + +type SystemInfo { + filename: String! + basename: String! + breadcrumbs(excludeExtension: Boolean): [String!]! + path: String! + relativePath: String! + extension: String! + template: String! + collection: Collection! +} + +type PageInfo { + hasPreviousPage: Boolean! + hasNextPage: Boolean! + startCursor: String! + endCursor: String! +} + +""" + +""" +interface Node { + id: ID! +} + +""" + +""" +interface Document { + sys: SystemInfo + id: ID! + form: JSON! + values: JSON! +} + +""" +A relay-compliant pagination connection +""" +interface Connection { + totalCount: Float! +} + +type Query { + getCollection(collection: String): Collection! + getCollections: [Collection!]! + node(id: String): Node! + getDocument(collection: String, relativePath: String): DocumentNode! + getDocumentList( + before: String + after: String + first: Float + last: Float + ): DocumentConnection! + getDocumentFields: JSON! + getPostsDocument(relativePath: String): PostsDocument! + getPostsList( + before: String + after: String + first: Float + last: Float + ): PostsConnection! +} + +type DocumentConnectionEdges { + cursor: String + node: DocumentNode +} + +type DocumentConnection implements Connection { + pageInfo: PageInfo + totalCount: Float! + edges: [DocumentConnectionEdges] +} + +type Collection { + name: String! + slug: String! + label: String + path: String! + format: String + matches: String + templates: [JSON] + fields: [JSON] + documents( + before: String + after: String + first: Float + last: Float + ): DocumentConnection! +} + +union DocumentNode = PostsDocument + +type PostsAuthor { + name: String + picture: String +} + +type PostsOgImage { + url: String +} + +type Posts { + title: String + excerpt: String + coverImage: String + date: String + author: PostsAuthor + ogImage: PostsOgImage + body: String +} + +type PostsDocument implements Node & Document { + id: ID! + sys: SystemInfo! + data: Posts! + form: JSON! + values: JSON! + dataJSON: JSON! +} + +type PostsConnectionEdges { + cursor: String + node: PostsDocument +} + +type PostsConnection implements Connection { + pageInfo: PageInfo + totalCount: Float! + edges: [PostsConnectionEdges] +} + +type Mutation { + addPendingDocument( + collection: String! + relativePath: String! + template: String + ): DocumentNode! + updateDocument( + collection: String + relativePath: String! + params: DocumentMutation! + ): DocumentNode! + createDocument( + collection: String + relativePath: String! + params: DocumentMutation! + ): DocumentNode! + updatePostsDocument( + relativePath: String! + params: PostsMutation! + ): PostsDocument! + createPostsDocument( + relativePath: String! + params: PostsMutation! + ): PostsDocument! +} + +input DocumentMutation { + posts: PostsMutation +} + +input PostsAuthorMutation { + name: String + picture: String +} + +input PostsOgImageMutation { + url: String +} + +input PostsMutation { + title: String + excerpt: String + coverImage: String + date: String + author: PostsAuthorMutation + ogImage: PostsOgImageMutation + body: String +} + +schema { + query: Query + mutation: Mutation +} diff --git a/examples/cms-tina/.tina/__generated__/types.ts b/examples/cms-tina/.tina/__generated__/types.ts new file mode 100644 index 000000000000..8abb47270af4 --- /dev/null +++ b/examples/cms-tina/.tina/__generated__/types.ts @@ -0,0 +1,470 @@ +//@ts-nocheck +// DO NOT MODIFY THIS FILE. This file is automatically generated by Tina +import { gql } from 'tinacms' +export type Maybe = T | null +export type InputMaybe = Maybe +export type Exact = { + [K in keyof T]: T[K] +} +export type MakeOptional = Omit & + { [SubKey in K]?: Maybe } +export type MakeMaybe = Omit & + { [SubKey in K]: Maybe } +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: string + String: string + Boolean: boolean + Int: number + Float: number + /** References another document, used as a foreign key */ + Reference: any + JSON: any +} + +export type SystemInfo = { + __typename?: 'SystemInfo' + filename: Scalars['String'] + basename: Scalars['String'] + breadcrumbs: Array + path: Scalars['String'] + relativePath: Scalars['String'] + extension: Scalars['String'] + template: Scalars['String'] + collection: Collection +} + +export type SystemInfoBreadcrumbsArgs = { + excludeExtension?: InputMaybe +} + +export type PageInfo = { + __typename?: 'PageInfo' + hasPreviousPage: Scalars['Boolean'] + hasNextPage: Scalars['Boolean'] + startCursor: Scalars['String'] + endCursor: Scalars['String'] +} + +export type Node = { + id: Scalars['ID'] +} + +export type Document = { + sys?: Maybe + id: Scalars['ID'] + form: Scalars['JSON'] + values: Scalars['JSON'] +} + +/** A relay-compliant pagination connection */ +export type Connection = { + totalCount: Scalars['Float'] +} + +export type Query = { + __typename?: 'Query' + getCollection: Collection + getCollections: Array + node: Node + getDocument: DocumentNode + getDocumentList: DocumentConnection + getDocumentFields: Scalars['JSON'] + getPostsDocument: PostsDocument + getPostsList: PostsConnection +} + +export type QueryGetCollectionArgs = { + collection?: InputMaybe +} + +export type QueryNodeArgs = { + id?: InputMaybe +} + +export type QueryGetDocumentArgs = { + collection?: InputMaybe + relativePath?: InputMaybe +} + +export type QueryGetDocumentListArgs = { + before?: InputMaybe + after?: InputMaybe + first?: InputMaybe + last?: InputMaybe +} + +export type QueryGetPostsDocumentArgs = { + relativePath?: InputMaybe +} + +export type QueryGetPostsListArgs = { + before?: InputMaybe + after?: InputMaybe + first?: InputMaybe + last?: InputMaybe +} + +export type DocumentConnectionEdges = { + __typename?: 'DocumentConnectionEdges' + cursor?: Maybe + node?: Maybe +} + +export type DocumentConnection = Connection & { + __typename?: 'DocumentConnection' + pageInfo?: Maybe + totalCount: Scalars['Float'] + edges?: Maybe>> +} + +export type Collection = { + __typename?: 'Collection' + name: Scalars['String'] + slug: Scalars['String'] + label?: Maybe + path: Scalars['String'] + format?: Maybe + matches?: Maybe + templates?: Maybe>> + fields?: Maybe>> + documents: DocumentConnection +} + +export type CollectionDocumentsArgs = { + before?: InputMaybe + after?: InputMaybe + first?: InputMaybe + last?: InputMaybe +} + +export type DocumentNode = PostsDocument + +export type PostsAuthor = { + __typename?: 'PostsAuthor' + name?: Maybe + picture?: Maybe +} + +export type PostsOgImage = { + __typename?: 'PostsOgImage' + url?: Maybe +} + +export type Posts = { + __typename?: 'Posts' + title?: Maybe + excerpt?: Maybe + coverImage?: Maybe + date?: Maybe + author?: Maybe + ogImage?: Maybe + body?: Maybe +} + +export type PostsDocument = Node & + Document & { + __typename?: 'PostsDocument' + id: Scalars['ID'] + sys: SystemInfo + data: Posts + form: Scalars['JSON'] + values: Scalars['JSON'] + dataJSON: Scalars['JSON'] + } + +export type PostsConnectionEdges = { + __typename?: 'PostsConnectionEdges' + cursor?: Maybe + node?: Maybe +} + +export type PostsConnection = Connection & { + __typename?: 'PostsConnection' + pageInfo?: Maybe + totalCount: Scalars['Float'] + edges?: Maybe>> +} + +export type Mutation = { + __typename?: 'Mutation' + addPendingDocument: DocumentNode + updateDocument: DocumentNode + createDocument: DocumentNode + updatePostsDocument: PostsDocument + createPostsDocument: PostsDocument +} + +export type MutationAddPendingDocumentArgs = { + collection: Scalars['String'] + relativePath: Scalars['String'] + template?: InputMaybe +} + +export type MutationUpdateDocumentArgs = { + collection?: InputMaybe + relativePath: Scalars['String'] + params: DocumentMutation +} + +export type MutationCreateDocumentArgs = { + collection?: InputMaybe + relativePath: Scalars['String'] + params: DocumentMutation +} + +export type MutationUpdatePostsDocumentArgs = { + relativePath: Scalars['String'] + params: PostsMutation +} + +export type MutationCreatePostsDocumentArgs = { + relativePath: Scalars['String'] + params: PostsMutation +} + +export type DocumentMutation = { + posts?: InputMaybe +} + +export type PostsAuthorMutation = { + name?: InputMaybe + picture?: InputMaybe +} + +export type PostsOgImageMutation = { + url?: InputMaybe +} + +export type PostsMutation = { + title?: InputMaybe + excerpt?: InputMaybe + coverImage?: InputMaybe + date?: InputMaybe + author?: InputMaybe + ogImage?: InputMaybe + body?: InputMaybe +} + +export type PostsPartsFragment = { + __typename?: 'Posts' + title?: string | null + excerpt?: string | null + coverImage?: string | null + date?: string | null + body?: string | null + author?: { + __typename: 'PostsAuthor' + name?: string | null + picture?: string | null + } | null + ogImage?: { __typename: 'PostsOgImage'; url?: string | null } | null +} + +export type GetPostsDocumentQueryVariables = Exact<{ + relativePath: Scalars['String'] +}> + +export type GetPostsDocumentQuery = { + __typename?: 'Query' + getPostsDocument: { + __typename?: 'PostsDocument' + id: string + sys: { + __typename?: 'SystemInfo' + filename: string + basename: string + breadcrumbs: Array + path: string + relativePath: string + extension: string + } + data: { + __typename?: 'Posts' + title?: string | null + excerpt?: string | null + coverImage?: string | null + date?: string | null + body?: string | null + author?: { + __typename: 'PostsAuthor' + name?: string | null + picture?: string | null + } | null + ogImage?: { __typename: 'PostsOgImage'; url?: string | null } | null + } + } +} + +export type GetPostsListQueryVariables = Exact<{ [key: string]: never }> + +export type GetPostsListQuery = { + __typename?: 'Query' + getPostsList: { + __typename?: 'PostsConnection' + totalCount: number + edges?: Array<{ + __typename?: 'PostsConnectionEdges' + node?: { + __typename?: 'PostsDocument' + id: string + sys: { + __typename?: 'SystemInfo' + filename: string + basename: string + breadcrumbs: Array + path: string + relativePath: string + extension: string + } + data: { + __typename?: 'Posts' + title?: string | null + excerpt?: string | null + coverImage?: string | null + date?: string | null + body?: string | null + author?: { + __typename: 'PostsAuthor' + name?: string | null + picture?: string | null + } | null + ogImage?: { __typename: 'PostsOgImage'; url?: string | null } | null + } + } | null + } | null> | null + } +} + +export const PostsPartsFragmentDoc = gql` + fragment PostsParts on Posts { + title + excerpt + coverImage + date + author { + __typename + name + picture + } + ogImage { + __typename + url + } + body + } +` +export const GetPostsDocumentDocument = gql` + query getPostsDocument($relativePath: String!) { + getPostsDocument(relativePath: $relativePath) { + sys { + filename + basename + breadcrumbs + path + relativePath + extension + } + id + data { + ...PostsParts + } + } + } + ${PostsPartsFragmentDoc} +` +export const GetPostsListDocument = gql` + query getPostsList { + getPostsList { + totalCount + edges { + node { + id + sys { + filename + basename + breadcrumbs + path + relativePath + extension + } + data { + ...PostsParts + } + } + } + } + } + ${PostsPartsFragmentDoc} +` +export type Requester = ( + doc: DocumentNode, + vars?: V, + options?: C +) => Promise +export function getSdk(requester: Requester) { + return { + getPostsDocument( + variables: GetPostsDocumentQueryVariables, + options?: C + ): Promise<{ + data: GetPostsDocumentQuery + variables: GetPostsDocumentQueryVariables + query: string + }> { + return requester< + { + data: GetPostsDocumentQuery + variables: GetPostsDocumentQueryVariables + query: string + }, + GetPostsDocumentQueryVariables + >(GetPostsDocumentDocument, variables, options) + }, + getPostsList( + variables?: GetPostsListQueryVariables, + options?: C + ): Promise<{ + data: GetPostsListQuery + variables: GetPostsListQueryVariables + query: string + }> { + return requester< + { + data: GetPostsListQuery + variables: GetPostsListQueryVariables + query: string + }, + GetPostsListQueryVariables + >(GetPostsListDocument, variables, options) + }, + } +} +export type Sdk = ReturnType + +// TinaSDK generated code +import { staticRequest } from 'tinacms' +const requester: (doc: any, vars?: any, options?: any) => Promise = async ( + doc, + vars, + _options +) => { + let data = {} + try { + data = await staticRequest({ + query: doc, + variables: vars, + }) + } catch (e) { + // swallow errors related to document creation + console.warn('Warning: There was an error when fetching data') + console.warn(e) + } + + return { data, query: doc, variables: vars || {} } +} + +/** + * @experimental this class can be used but may change in the future + **/ +export const ExperimentalGetTinaClient = () => getSdk(requester) diff --git a/examples/cms-tina/.tina/components/TinaDynamicProvider.js b/examples/cms-tina/.tina/components/TinaDynamicProvider.js new file mode 100644 index 000000000000..5f6bd24bc870 --- /dev/null +++ b/examples/cms-tina/.tina/components/TinaDynamicProvider.js @@ -0,0 +1,15 @@ +import dynamic from 'next/dynamic' +const TinaProvider = dynamic(() => import('./TinaProvider'), { ssr: false }) +import { TinaEditProvider } from 'tinacms/dist/edit-state' + +const DynamicTina = ({ children }) => { + return ( + <> + {children}}> + {children} + + + ) +} + +export default DynamicTina diff --git a/examples/cms-tina/.tina/components/TinaProvider.js b/examples/cms-tina/.tina/components/TinaProvider.js new file mode 100644 index 000000000000..96d00b56aa8b --- /dev/null +++ b/examples/cms-tina/.tina/components/TinaProvider.js @@ -0,0 +1,14 @@ +import TinaCMS from 'tinacms' +import { tinaConfig } from '../schema.ts' + +// Importing the TinaProvider directly into your page will cause Tina to be added to the production bundle. +// Instead, import the tina/provider/index default export to have it dynamially imported in edit-moode +/** + * + * @private Do not import this directly, please import the dynamic provider instead + */ +const TinaProvider = ({ children }) => { + return {children} +} + +export default TinaProvider diff --git a/examples/cms-tina/.tina/schema.ts b/examples/cms-tina/.tina/schema.ts new file mode 100644 index 000000000000..12f738c64a26 --- /dev/null +++ b/examples/cms-tina/.tina/schema.ts @@ -0,0 +1,105 @@ +import { defineSchema, defineConfig } from 'tinacms' + +export default defineSchema({ + collections: [ + { + label: 'Blog Posts', + name: 'posts', + path: '_posts', + fields: [ + { + type: 'string', + label: 'Title', + name: 'title', + }, + { + type: 'string', + label: 'Excerpt', + name: 'excerpt', + }, + { + type: 'string', + label: 'Cover Image', + name: 'coverImage', + }, + { + type: 'string', + label: 'Date', + name: 'date', + }, + { + type: 'object', + label: 'author', + name: 'author', + fields: [ + { + type: 'string', + label: 'Name', + name: 'name', + }, + { + type: 'string', + label: 'Picture', + name: 'picture', + }, + ], + }, + { + type: 'object', + label: 'OG Image', + name: 'ogImage', + fields: [ + { + type: 'string', + label: 'Url', + name: 'url', + }, + ], + }, + { + type: 'string', + label: 'Blog Post Body', + name: 'body', + isBody: true, + ui: { + component: 'textarea', + }, + }, + ], + }, + ], +}) + +// Your tina config +// ============== +const branch = 'main' +// When working locally, hit our local filesystem. +// On a Vercel deployment, hit the Tina Cloud API +const apiURL = + process.env.NODE_ENV == 'development' + ? 'http://localhost:4001/graphql' + : `https://content.tinajs.io/content/${process.env.NEXT_PUBLIC_TINA_CLIENT_ID}/github/${branch}` + +export const tinaConfig = defineConfig({ + apiURL, + cmsCallback: (cms) => { + // add your CMS callback code here (if you want) + + // The Route Mapper + /** + * 1. Import `tinacms` and `RouteMappingPlugin` + **/ + import('tinacms').then(({ RouteMappingPlugin }) => { + /** + * 2. Define the `RouteMappingPlugin` see https://tina.io/docs/tinacms-context/#the-routemappingplugin for more details + **/ + const RouteMapping = new RouteMappingPlugin((collection, document) => { + return undefined + }) + /** + * 3. Add the `RouteMappingPlugin` to the `cms`. + **/ + cms.plugins.add(RouteMapping) + }) + }, +}) diff --git a/examples/cms-tina/README.md b/examples/cms-tina/README.md new file mode 100644 index 000000000000..6f0b3efb5d94 --- /dev/null +++ b/examples/cms-tina/README.md @@ -0,0 +1,77 @@ +# A statically generated blog example using Next.js and TinaCMS + +This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [TinaCMS](https://tina.io/) as the CMS and editor. + +> This boilerplate demonstrates a basic usage and best practices. If you are looking for a more feature rich Tina experience with contextual editing. +> check out [tina-cloud-starter](https://github.com/tinacms/tina-cloud-start/git). + +### Related examples + +- [WordPress](/examples/cms-wordpress) +- [DatoCMS](/examples/cms-datocms) +- [Sanity](/examples/cms-sanity) +- [TakeShape](/examples/cms-takeshape) +- [Prismic](/examples/cms-prismic) +- [Contentful](/examples/cms-contentful) +- [Strapi](/examples/cms-strapi) +- [Agility CMS](/examples/cms-agilitycms) +- [ButterCMS](/examples/cms-buttercms) +- [Storyblok](/examples/cms-storyblok) +- [GraphCMS](/examples/cms-graphcms) +- [Kontent](/examples/cms-kontent) +- [Umbraco Heartcore](/examples/cms-umbraco-heartcore) +- [Blog Starter](/examples/blog-starter) +- [Builder.io](/examples/cms-builder-io) + +## How to use + +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: + +```bash +npx create-next-app --example cms-tina cms-tina-app +# or +yarn create next-app --example cms-ghost cms-tina-app +``` + +### Setp 1. Run Next.js in development mode + +To get started, no configuration is needed for local development and editing. + +```bash +npm install +npm run tina-dev + +# or + +yarn install +yarn tina-dev +``` + +Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions). + +### Step 2. Editing blog posts. + +Tina is git backed and uses markdown, JSON or MDX to power websites. To enter edit mode locally you just need to visit [http://localhost:3000/admin](http://localhost:3000/admin) + +You can then select the collection "Blog Posts" and then the content you would like to edit. + +Once you hit save, Tina will use our graphQL modify the content on your filesystem. + +### Step 4. Deploy on Vercel + +You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). + +#### Deploy Your Local Project + +To deploy your local project to Vercel, push it to GitHub. Once you have pushed to GitHub, sign up for your Tina Cloud account at [https://app.tina.io/register](https://app.tina.io/register). Then follow the steps below: + +1. Select new project +2. Select Import your site +3. Follow steps to connect your GitHub repo. +4. Copy your Client ID + +Then [import to Vercel](https://vercel.com/import/git?utm_source=github&utm_medium=readme&utm_campaign=next-example). + +**Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set NEXT_PUBLIC_TINA_CLIENT_ID to the client ID above. + +Once you have successfully deployed to Vercel, go back to your Tina dashboard and under the project configuration enter the url in the Site URL(s) for example: https://tina-cms.vercel.app. diff --git a/examples/cms-tina/_posts/dynamic-routing.md b/examples/cms-tina/_posts/dynamic-routing.md new file mode 100644 index 000000000000..b6ef7a26e6ae --- /dev/null +++ b/examples/cms-tina/_posts/dynamic-routing.md @@ -0,0 +1,19 @@ +--- +title: 'Dynamic Routing and Static Generation' +excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus.' +coverImage: '/assets/blog/dynamic-routing/cover.jpg' +date: '2020-03-16T05:35:07.322Z' +author: + name: JJ Kasper + picture: '/assets/blog/authors/jj.jpeg' +ogImage: + url: '/assets/blog/dynamic-routing/cover.jpg' +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus. Praesent elementum facilisis leo vel fringilla. Congue mauris rhoncus aenean vel. Egestas sed tempus urna et pharetra pharetra massa massa ultricies. + +Venenatis cras sed felis eget velit. Consectetur libero id faucibus nisl tincidunt. Gravida in fermentum et sollicitudin ac orci phasellus egestas tellus. Volutpat consequat mauris nunc congue nisi vitae. Id aliquet risus feugiat in ante metus dictum at tempor. Sed blandit libero volutpat sed cras. Sed odio morbi quis commodo odio aenean sed adipiscing. Velit euismod in pellentesque massa placerat. Mi bibendum neque egestas congue quisque egestas diam in arcu. Nisi lacus sed viverra tellus in. Nibh cras pulvinar mattis nunc sed. Luctus accumsan tortor posuere ac ut consequat semper viverra. Fringilla ut morbi tincidunt augue interdum velit euismod. + +## Lorem Ipsum + +Tristique senectus et netus et malesuada fames ac turpis. Ridiculous mus mauris vitae ultricies leo integer malesuada nunc vel. In mollis nunc sed id semper. Egestas tellus rutrum tellus pellentesque. Phasellus vestibulum lorem sed risus ultricies tristique nulla. Quis blandit turpis cursus in hac habitasse platea dictumst quisque. Eros donec ac odio tempor orci dapibus ultrices. Aliquam sem et tortor consequat id porta nibh. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. Diam vulputate ut pharetra sit amet. Ut tellus elementum sagittis vitae et leo. Arcu non odio euismod lacinia at quis risus sed vulputate. diff --git a/examples/cms-tina/_posts/hello-world.md b/examples/cms-tina/_posts/hello-world.md new file mode 100644 index 000000000000..8d85a1df8f17 --- /dev/null +++ b/examples/cms-tina/_posts/hello-world.md @@ -0,0 +1,19 @@ +--- +title: 'Learn How to Pre-render Pages Using Static Generation with Next.js' +excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus.' +coverImage: '/assets/blog/hello-world/cover.jpg' +date: '2020-03-16T05:35:07.322Z' +author: + name: Tim Neutkens + picture: '/assets/blog/authors/tim.jpeg' +ogImage: + url: '/assets/blog/hello-world/cover.jpg' +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus. Praesent elementum facilisis leo vel fringilla. Congue mauris rhoncus aenean vel. Egestas sed tempus urna et pharetra pharetra massa massa ultricies. + +Venenatis cras sed felis eget velit. Consectetur libero id faucibus nisl tincidunt. Gravida in fermentum et sollicitudin ac orci phasellus egestas tellus. Volutpat consequat mauris nunc congue nisi vitae. Id aliquet risus feugiat in ante metus dictum at tempor. Sed blandit libero volutpat sed cras. Sed odio morbi quis commodo odio aenean sed adipiscing. Velit euismod in pellentesque massa placerat. Mi bibendum neque egestas congue quisque egestas diam in arcu. Nisi lacus sed viverra tellus in. Nibh cras pulvinar mattis nunc sed. Luctus accumsan tortor posuere ac ut consequat semper viverra. Fringilla ut morbi tincidunt augue interdum velit euismod. + +## Lorem Ipsum + +Tristique senectus et netus et malesuada fames ac turpis. Ridiculous mus mauris vitae ultricies leo integer malesuada nunc vel. In mollis nunc sed id semper. Egestas tellus rutrum tellus pellentesque. Phasellus vestibulum lorem sed risus ultricies tristique nulla. Quis blandit turpis cursus in hac habitasse platea dictumst quisque. Eros donec ac odio tempor orci dapibus ultrices. Aliquam sem et tortor consequat id porta nibh. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. Diam vulputate ut pharetra sit amet. Ut tellus elementum sagittis vitae et leo. Arcu non odio euismod lacinia at quis risus sed vulputate. diff --git a/examples/cms-tina/_posts/preview.md b/examples/cms-tina/_posts/preview.md new file mode 100644 index 000000000000..3d70ba7f99d1 --- /dev/null +++ b/examples/cms-tina/_posts/preview.md @@ -0,0 +1,19 @@ +--- +title: 'Preview Mode for Static Generation' +excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus.' +coverImage: '/assets/blog/preview/cover.jpg' +date: '2020-03-16T05:35:07.322Z' +author: + name: Joe Haddad + picture: '/assets/blog/authors/joe.jpeg' +ogImage: + url: '/assets/blog/preview/cover.jpg' +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus. Praesent elementum facilisis leo vel fringilla. Congue mauris rhoncus aenean vel. Egestas sed tempus urna et pharetra pharetra massa massa ultricies. + +Venenatis cras sed felis eget velit. Consectetur libero id faucibus nisl tincidunt. Gravida in fermentum et sollicitudin ac orci phasellus egestas tellus. Volutpat consequat mauris nunc congue nisi vitae. Id aliquet risus feugiat in ante metus dictum at tempor. Sed blandit libero volutpat sed cras. Sed odio morbi quis commodo odio aenean sed adipiscing. Velit euismod in pellentesque massa placerat. Mi bibendum neque egestas congue quisque egestas diam in arcu. Nisi lacus sed viverra tellus in. Nibh cras pulvinar mattis nunc sed. Luctus accumsan tortor posuere ac ut consequat semper viverra. Fringilla ut morbi tincidunt augue interdum velit euismod. + +## Lorem Ipsum + +Tristique senectus et netus et malesuada fames ac turpis. Ridiculous mus mauris vitae ultricies leo integer malesuada nunc vel. In mollis nunc sed id semper. Egestas tellus rutrum tellus pellentesque. Phasellus vestibulum lorem sed risus ultricies tristique nulla. Quis blandit turpis cursus in hac habitasse platea dictumst quisque. Eros donec ac odio tempor orci dapibus ultrices. Aliquam sem et tortor consequat id porta nibh. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. Diam vulputate ut pharetra sit amet. Ut tellus elementum sagittis vitae et leo. Arcu non odio euismod lacinia at quis risus sed vulputate. diff --git a/examples/cms-tina/components/alert.js b/examples/cms-tina/components/alert.js new file mode 100644 index 000000000000..b924cb097f16 --- /dev/null +++ b/examples/cms-tina/components/alert.js @@ -0,0 +1,42 @@ +import Container from './container' +import cn from 'classnames' +import { EXAMPLE_PATH } from '../lib/constants' + +export default function Alert({ preview }) { + return ( +
+ +
+ {preview ? ( + <> + This page is a preview.{' '} + + Click here + {' '} + to exit preview mode. + + ) : ( + <> + The source code for this blog is{' '} + + available on GitHub + + . + + )} +
+
+
+ ) +} diff --git a/examples/cms-tina/components/avatar.js b/examples/cms-tina/components/avatar.js new file mode 100644 index 000000000000..0ae7f66413cc --- /dev/null +++ b/examples/cms-tina/components/avatar.js @@ -0,0 +1,16 @@ +import Image from 'next/image' + +export default function Avatar({ name, picture }) { + return ( +
+ {name} +
{name}
+
+ ) +} diff --git a/examples/cms-tina/components/container.js b/examples/cms-tina/components/container.js new file mode 100644 index 000000000000..fc1c29dfb074 --- /dev/null +++ b/examples/cms-tina/components/container.js @@ -0,0 +1,3 @@ +export default function Container({ children }) { + return
{children}
+} diff --git a/examples/cms-tina/components/cover-image.js b/examples/cms-tina/components/cover-image.js new file mode 100644 index 000000000000..d3e21d21f161 --- /dev/null +++ b/examples/cms-tina/components/cover-image.js @@ -0,0 +1,29 @@ +import cn from 'classnames' +import Link from 'next/link' +import Image from 'next/image' + +export default function CoverImage({ title, src, slug, height, width }) { + const image = ( + {`Cover + ) + return ( +
+ {slug ? ( + + {image} + + ) : ( + image + )} +
+ ) +} diff --git a/examples/cms-tina/components/date-formatter.js b/examples/cms-tina/components/date-formatter.js new file mode 100644 index 000000000000..9de4f4880011 --- /dev/null +++ b/examples/cms-tina/components/date-formatter.js @@ -0,0 +1,6 @@ +import { parseISO, format } from 'date-fns' + +export default function DateFormatter({ dateString }) { + const date = parseISO(dateString) + return +} diff --git a/examples/cms-tina/components/footer.js b/examples/cms-tina/components/footer.js new file mode 100644 index 000000000000..da9eed88ec26 --- /dev/null +++ b/examples/cms-tina/components/footer.js @@ -0,0 +1,30 @@ +import Container from './container' +import { EXAMPLE_PATH } from '../lib/constants' + +export default function Footer() { + return ( + + ) +} diff --git a/examples/cms-tina/components/header.js b/examples/cms-tina/components/header.js new file mode 100644 index 000000000000..562e7e3eebb6 --- /dev/null +++ b/examples/cms-tina/components/header.js @@ -0,0 +1,12 @@ +import Link from 'next/link' + +export default function Header() { + return ( +

+ + Blog + + . +

+ ) +} diff --git a/examples/cms-tina/components/hero-post.js b/examples/cms-tina/components/hero-post.js new file mode 100644 index 000000000000..6dc49f20a8bb --- /dev/null +++ b/examples/cms-tina/components/hero-post.js @@ -0,0 +1,43 @@ +import Avatar from '../components/avatar' +import DateFormatter from '../components/date-formatter' +import CoverImage from '../components/cover-image' +import Link from 'next/link' + +export default function HeroPost({ + title, + coverImage, + date, + excerpt, + author, + slug, +}) { + return ( +
+
+ +
+
+
+

+ + {title} + +

+
+ +
+
+
+

{excerpt}

+ +
+
+
+ ) +} diff --git a/examples/cms-tina/components/intro.js b/examples/cms-tina/components/intro.js new file mode 100644 index 000000000000..048fc170a13e --- /dev/null +++ b/examples/cms-tina/components/intro.js @@ -0,0 +1,21 @@ +import { CMS_NAME } from '../lib/constants' + +export default function Intro() { + return ( +
+

+ Blog. +

+

+ A statically generated blog example using{' '} + + Next.js + {' '} + and {CMS_NAME}. +

+
+ ) +} diff --git a/examples/cms-tina/components/layout.js b/examples/cms-tina/components/layout.js new file mode 100644 index 000000000000..99d95353131e --- /dev/null +++ b/examples/cms-tina/components/layout.js @@ -0,0 +1,16 @@ +import Alert from '../components/alert' +import Footer from '../components/footer' +import Meta from '../components/meta' + +export default function Layout({ preview, children }) { + return ( + <> + +
+ +
{children}
+
+