diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml index 59b4e71bce5b3..75cac601fbbb8 100644 --- a/.github/workflows/build_test_deploy.yml +++ b/.github/workflows/build_test_deploy.yml @@ -873,6 +873,7 @@ jobs: - build - build-wasm - build-native + - build-native-freebsd env: NPM_TOKEN: ${{ secrets.NPM_TOKEN_ELEVATED }} steps: @@ -1303,6 +1304,66 @@ jobs: name: next-swc-binaries path: packages/next-swc/native/next-swc.*.node + build-native-freebsd: + if: ${{ needs.build.outputs.isRelease == 'true' }} + needs: build + name: stable - x86_64-unknown-freebsd - node@16 + runs-on: macos-10.15 + steps: + - name: tune mac network + run: sudo sysctl -w net.link.generic.system.hwcksum_tx=0 && sudo sysctl -w net.link.generic.system.hwcksum_rx=0 + - uses: actions/checkout@v3 + - name: Delete useless files + run: | + rm -rf bench + rm -rf docs + rm -rf errors + rm -rf examples + rm -rf scripts + rm -rf test + - name: Build + id: build + uses: vmactions/freebsd-vm@v0.1.6 + env: + DEBUG: napi:* + RUSTUP_HOME: /usr/local/rustup + CARGO_HOME: /usr/local/cargo + RUSTUP_IO_THREADS: 1 + # Disable LTO, or the lld may crash with OOM + CARGO_PROFILE_RELEASE_LTO: false + with: + envs: DEBUG RUSTUP_HOME CARGO_HOME RUSTUP_IO_THREADS CARGO_PROFILE_RELEASE_LTO NAPI_CLI_VERSION TURBO_VERSION RUST_TOOLCHAIN + usesh: true + mem: 6000 + prepare: | + pkg install -y curl node14 + curl -qL https://www.npmjs.com/install.sh | sh + npm install -g yarn + curl https://sh.rustup.rs -sSf --output rustup.sh + sh rustup.sh -y --profile minimal --default-toolchain stable + export PATH="/usr/local/cargo/bin:$PATH" + echo "~~~~ rustc --version ~~~~" + rustc --version + echo "~~~~ node -v ~~~~" + node -v + run: | + export PATH="/usr/local/cargo/bin:$PATH" + pwd + ls -lah + whoami + env + freebsd-version + npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}" "turbo@${TURBO_VERSION}" + yarn --cwd packages/next-swc build-native --release --target x86_64-unknown-freebsd + rm -rf node_modules + rm -rf packages/next-swc/target + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: next-swc-binaries + path: packages/next-swc/native/next-swc.*.node + if-no-files-found: error + build-wasm: needs: build if: ${{ needs.build.outputs.isRelease == 'true' }} diff --git a/docs/basic-features/pages.md b/docs/basic-features/pages.md index 76bda662b3f16..cff5bdbc6aaee 100644 --- a/docs/basic-features/pages.md +++ b/docs/basic-features/pages.md @@ -64,6 +64,7 @@ You can also use **Client-side Rendering** along with Static Generation or Serve
  • GraphCMS Example (Demo)
  • Kontent Example (Demo)
  • Builder.io Example (Demo)
  • +
  • TinaCMS Example (Demo)
  • Static Tweet (Demo)
  • diff --git a/errors/swc-disabled.md b/errors/swc-disabled.md index ce026dd0e882e..277aaf374d838 100644 --- a/errors/swc-disabled.md +++ b/errors/swc-disabled.md @@ -13,3 +13,16 @@ Many of the integrations with external libraries that currently require custom B - Emotion In order to prioritize transforms that will help you adopt SWC please provide your `.babelrc` on [the feedback thread](https://github.com/vercel/next.js/discussions/30174). + +#### Possible Ways to Fix It + +If you want to use SWC despite the presence of a `.babelrc` file you can force it in your `next.config.js` file. + +```js +// next.config.js +module.exports = { + experimental: { + forceSwcTransforms: true, + }, +} +``` diff --git a/examples/blog-starter/README.md b/examples/blog-starter/README.md index 1744d7d375671..a8799d814324f 100644 --- a/examples/blog-starter/README.md +++ b/examples/blog-starter/README.md @@ -33,6 +33,7 @@ Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_mediu - [Kontent](/examples/cms-kontent) - [Umbraco Heartcore](/examples/cms-umbraco-heartcore) - [Builder.io](/examples/cms-builder-io) +- [TinaCMS](/examples/cms-tina/) ## How to use diff --git a/examples/cms-tina/.tina/__generated__/_graphql.json b/examples/cms-tina/.tina/__generated__/_graphql.json index 4f7ac4cfe7efc..e0b0c4a215b4d 100644 --- a/examples/cms-tina/.tina/__generated__/_graphql.json +++ b/examples/cms-tina/.tina/__generated__/_graphql.json @@ -3,10 +3,7 @@ "definitions": [ { "kind": "ScalarTypeDefinition", - "name": { - "kind": "Name", - "value": "Reference" - }, + "name": { "kind": "Name", "value": "Reference" }, "description": { "kind": "StringValue", "value": "References another document, used as a foreign key" @@ -15,80 +12,50 @@ }, { "kind": "ScalarTypeDefinition", - "name": { - "kind": "Name", - "value": "JSON" - }, - "description": { - "kind": "StringValue", - "value": "" - }, + "name": { "kind": "Name", "value": "JSON" }, + "description": { "kind": "StringValue", "value": "" }, "directives": [] }, { "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "SystemInfo" - }, + "name": { "kind": "Name", "value": "SystemInfo" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "filename" - }, + "name": { "kind": "Name", "value": "filename" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "basename" - }, + "name": { "kind": "Name", "value": "basename" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "breadcrumbs" - }, + "name": { "kind": "Name", "value": "breadcrumbs" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "excludeExtension" - }, + "name": { "kind": "Name", "value": "excludeExtension" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Boolean" - } + "name": { "kind": "Name", "value": "Boolean" } } } ], @@ -100,10 +67,7 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } } @@ -111,91 +75,61 @@ }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "path" - }, + "name": { "kind": "Name", "value": "path" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "relativePath" - }, + "name": { "kind": "Name", "value": "relativePath" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "extension" - }, + "name": { "kind": "Name", "value": "extension" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "template" - }, + "name": { "kind": "Name", "value": "template" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "collection" - }, + "name": { "kind": "Name", "value": "collection" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Collection" - } + "name": { "kind": "Name", "value": "Collection" } } } } @@ -205,80 +139,53 @@ "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "PageInfo" - }, + "name": { "kind": "Name", "value": "PageInfo" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "hasPreviousPage" - }, + "name": { "kind": "Name", "value": "hasPreviousPage" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Boolean" - } + "name": { "kind": "Name", "value": "Boolean" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "hasNextPage" - }, + "name": { "kind": "Name", "value": "hasNextPage" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Boolean" - } + "name": { "kind": "Name", "value": "Boolean" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "startCursor" - }, + "name": { "kind": "Name", "value": "startCursor" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "endCursor" - }, + "name": { "kind": "Name", "value": "endCursor" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } } @@ -286,32 +193,20 @@ }, { "kind": "InterfaceTypeDefinition", - "description": { - "kind": "StringValue", - "value": "" - }, - "name": { - "kind": "Name", - "value": "Node" - }, + "description": { "kind": "StringValue", "value": "" }, + "name": { "kind": "Name", "value": "Node" }, "interfaces": [], "directives": [], "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "id" - }, + "name": { "kind": "Name", "value": "id" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "ID" - } + "name": { "kind": "Name", "value": "ID" } } } } @@ -319,83 +214,41 @@ }, { "kind": "InterfaceTypeDefinition", - "description": { - "kind": "StringValue", - "value": "" - }, - "name": { - "kind": "Name", - "value": "Document" - }, + "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" - }, + "name": { "kind": "Name", "value": "id" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "ID" - } + "name": { "kind": "Name", "value": "ID" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "form" - }, + "name": { "kind": "Name", "value": "_sys" }, "arguments": [], "type": { - "kind": "NonNullType", - "type": { - "kind": "NamedType", - "name": { - "kind": "Name", - "value": "JSON" - } - } + "kind": "NamedType", + "name": { "kind": "Name", "value": "SystemInfo" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "values" - }, + "name": { "kind": "Name", "value": "_values" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "JSON" - } + "name": { "kind": "Name", "value": "JSON" } } } } @@ -407,28 +260,31 @@ "kind": "StringValue", "value": "A relay-compliant pagination connection" }, - "name": { - "kind": "Name", - "value": "Connection" - }, + "name": { "kind": "Name", "value": "Connection" }, "interfaces": [], "directives": [], "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "totalCount" - }, + "name": { "kind": "Name", "value": "totalCount" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Float" - } + "name": { "kind": "Name", "value": "Float" } + } + } + }, + { + "kind": "FieldDefinition", + "name": { "kind": "Name", "value": "pageInfo" }, + "arguments": [], + "type": { + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "PageInfo" } } } } @@ -438,50 +294,53 @@ "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "Query" - }, + "name": { "kind": "Name", "value": "Query" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "getCollection" - }, + "name": { "kind": "Name", "value": "getOptimizedQuery" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "collection" - }, + "name": { "kind": "Name", "value": "queryString" }, "type": { - "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "String" } } } } ], + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "String" } + } + }, + { + "kind": "FieldDefinition", + "name": { "kind": "Name", "value": "collection" }, + "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" - } + "name": { "kind": "Name", "value": "Collection" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "getCollections" - }, + "name": { "kind": "Name", "value": "collections" }, "arguments": [], "type": { "kind": "NonNullType", @@ -491,10 +350,7 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Collection" - } + "name": { "kind": "Name", "value": "Collection" } } } } @@ -502,23 +358,14 @@ }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "node" - }, + "name": { "kind": "Name", "value": "node" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "id" - }, + "name": { "kind": "Name", "value": "id" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } ], @@ -526,46 +373,28 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Node" - } + "name": { "kind": "Name", "value": "Node" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "getDocument" - }, + "name": { "kind": "Name", "value": "document" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "collection" - }, + "name": { "kind": "Name", "value": "collection" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "relativePath" - }, + "name": { "kind": "Name", "value": "relativePath" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } ], @@ -573,74 +402,20 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentNode" - } + "name": { "kind": "Name", "value": "DocumentNode" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "getDocumentList" - }, + "name": { "kind": "Name", "value": "posts" }, "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" - }, + "name": { "kind": "Name", "value": "relativePath" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Float" - } + "name": { "kind": "Name", "value": "String" } } } ], @@ -648,125 +423,52 @@ "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" - } + "name": { "kind": "Name", "value": "Posts" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "getPostsDocument" - }, + "name": { "kind": "Name", "value": "postsConnection" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "relativePath" - }, + "name": { "kind": "Name", "value": "before" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } - } - } - ], - "type": { - "kind": "NonNullType", - "type": { - "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsDocument" + "name": { "kind": "Name", "value": "String" } } - } - } - }, - { - "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "getPostsList" - }, - "arguments": [ + }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "before" - }, + "name": { "kind": "Name", "value": "after" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "after" - }, + "name": { "kind": "Name", "value": "first" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "Float" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "first" - }, + "name": { "kind": "Name", "value": "last" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Float" - } + "name": { "kind": "Name", "value": "Float" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "last" - }, + "name": { "kind": "Name", "value": "sort" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Float" - } + "name": { "kind": "Name", "value": "String" } } } ], @@ -774,10 +476,7 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsConnection" - } + "name": { "kind": "Name", "value": "PostsConnection" } } } } @@ -787,39 +486,27 @@ "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "DocumentConnectionEdges" - }, + "name": { "kind": "Name", "value": "DocumentConnectionEdges" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "cursor" - }, + "name": { "kind": "Name", "value": "cursor" }, "arguments": [], "type": { - "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "node" - }, + "name": { "kind": "Name", "value": "node" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentNode" - } + "name": { "kind": "Name", "value": "DocumentNode" } } } ] @@ -829,66 +516,45 @@ "interfaces": [ { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Connection" - } + "name": { "kind": "Name", "value": "Connection" } } ], "directives": [], - "name": { - "kind": "Name", - "value": "DocumentConnection" - }, + "name": { "kind": "Name", "value": "DocumentConnection" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "pageInfo" - }, + "name": { "kind": "Name", "value": "pageInfo" }, "arguments": [], "type": { - "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PageInfo" + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "PageInfo" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "totalCount" - }, + "name": { "kind": "Name", "value": "totalCount" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Float" - } + "name": { "kind": "Name", "value": "Float" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "edges" - }, + "name": { "kind": "Name", "value": "edges" }, "arguments": [], "type": { "kind": "ListType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentConnectionEdges" - } + "name": { "kind": "Name", "value": "DocumentConnectionEdges" } } } } @@ -898,207 +564,137 @@ "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "Collection" - }, + "name": { "kind": "Name", "value": "Collection" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "name" - }, + "name": { "kind": "Name", "value": "name" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "slug" - }, + "name": { "kind": "Name", "value": "slug" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "label" - }, + "name": { "kind": "Name", "value": "label" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "path" - }, + "name": { "kind": "Name", "value": "path" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "format" - }, + "name": { "kind": "Name", "value": "format" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "matches" - }, + "name": { "kind": "Name", "value": "matches" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "templates" - }, + "name": { "kind": "Name", "value": "templates" }, "arguments": [], "type": { "kind": "ListType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "JSON" - } + "name": { "kind": "Name", "value": "JSON" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "fields" - }, + "name": { "kind": "Name", "value": "fields" }, "arguments": [], "type": { "kind": "ListType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "JSON" - } + "name": { "kind": "Name", "value": "JSON" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "documents" - }, + "name": { "kind": "Name", "value": "documents" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "before" - }, + "name": { "kind": "Name", "value": "before" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "after" - }, + "name": { "kind": "Name", "value": "after" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "first" - }, + "name": { "kind": "Name", "value": "first" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Float" - } + "name": { "kind": "Name", "value": "Float" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "last" - }, + "name": { "kind": "Name", "value": "last" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Float" - } + "name": { "kind": "Name", "value": "Float" } + } + }, + { + "kind": "InputValueDefinition", + "name": { "kind": "Name", "value": "sort" }, + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "String" } } } ], @@ -1106,10 +702,7 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentConnection" - } + "name": { "kind": "Name", "value": "DocumentConnection" } } } } @@ -1117,58 +710,34 @@ }, { "kind": "UnionTypeDefinition", - "name": { - "kind": "Name", - "value": "DocumentNode" - }, + "name": { "kind": "Name", "value": "DocumentNode" }, "directives": [], "types": [ - { - "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsDocument" - } - } + { "kind": "NamedType", "name": { "kind": "Name", "value": "Posts" } } ] }, { "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "PostsAuthor" - }, + "name": { "kind": "Name", "value": "PostsAuthor" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "name" - }, + "name": { "kind": "Name", "value": "name" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "picture" - }, + "name": { "kind": "Name", "value": "picture" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } ] @@ -1177,273 +746,124 @@ "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "PostsOgImage" - }, + "name": { "kind": "Name", "value": "PostsOgImage" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "url" - }, + "name": { "kind": "Name", "value": "url" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } ] }, { "kind": "ObjectTypeDefinition", - "interfaces": [], + "interfaces": [ + { "kind": "NamedType", "name": { "kind": "Name", "value": "Node" } }, + { "kind": "NamedType", "name": { "kind": "Name", "value": "Document" } } + ], "directives": [], - "name": { - "kind": "Name", - "value": "Posts" - }, + "name": { "kind": "Name", "value": "Posts" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "title" - }, + "name": { "kind": "Name", "value": "title" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "excerpt" - }, + "name": { "kind": "Name", "value": "excerpt" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "coverImage" - }, + "name": { "kind": "Name", "value": "coverImage" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "date" - }, + "name": { "kind": "Name", "value": "date" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "author" - }, + "name": { "kind": "Name", "value": "author" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsAuthor" - } + "name": { "kind": "Name", "value": "PostsAuthor" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "ogImage" - }, + "name": { "kind": "Name", "value": "ogImage" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsOgImage" - } + "name": { "kind": "Name", "value": "PostsOgImage" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "body" - }, + "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" - } - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "data" - }, + "name": { "kind": "Name", "value": "id" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Posts" - } + "name": { "kind": "Name", "value": "ID" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "form" - }, + "name": { "kind": "Name", "value": "_sys" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "JSON" - } + "name": { "kind": "Name", "value": "SystemInfo" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "values" - }, + "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" - } + "name": { "kind": "Name", "value": "JSON" } } } } @@ -1453,39 +873,27 @@ "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "PostsConnectionEdges" - }, + "name": { "kind": "Name", "value": "PostsConnectionEdges" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "cursor" - }, + "name": { "kind": "Name", "value": "cursor" }, "arguments": [], "type": { - "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "node" - }, + "name": { "kind": "Name", "value": "node" }, "arguments": [], "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsDocument" - } + "name": { "kind": "Name", "value": "Posts" } } } ] @@ -1495,66 +903,45 @@ "interfaces": [ { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Connection" - } + "name": { "kind": "Name", "value": "Connection" } } ], "directives": [], - "name": { - "kind": "Name", - "value": "PostsConnection" - }, + "name": { "kind": "Name", "value": "PostsConnection" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "pageInfo" - }, + "name": { "kind": "Name", "value": "pageInfo" }, "arguments": [], "type": { - "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PageInfo" + "kind": "NonNullType", + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "PageInfo" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "totalCount" - }, + "name": { "kind": "Name", "value": "totalCount" }, "arguments": [], "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "Float" - } + "name": { "kind": "Name", "value": "Float" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "edges" - }, + "name": { "kind": "Name", "value": "edges" }, "arguments": [], "type": { "kind": "ListType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsConnectionEdges" - } + "name": { "kind": "Name", "value": "PostsConnectionEdges" } } } } @@ -1564,64 +951,40 @@ "kind": "ObjectTypeDefinition", "interfaces": [], "directives": [], - "name": { - "kind": "Name", - "value": "Mutation" - }, + "name": { "kind": "Name", "value": "Mutation" }, "fields": [ { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "addPendingDocument" - }, + "name": { "kind": "Name", "value": "addPendingDocument" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "collection" - }, + "name": { "kind": "Name", "value": "collection" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "relativePath" - }, + "name": { "kind": "Name", "value": "relativePath" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "template" - }, + "name": { "kind": "Name", "value": "template" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } ], @@ -1629,65 +992,41 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentNode" - } + "name": { "kind": "Name", "value": "DocumentNode" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "updateDocument" - }, + "name": { "kind": "Name", "value": "updateDocument" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "collection" - }, + "name": { "kind": "Name", "value": "collection" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "relativePath" - }, + "name": { "kind": "Name", "value": "relativePath" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "params" - }, + "name": { "kind": "Name", "value": "params" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentMutation" - } + "name": { "kind": "Name", "value": "DocumentMutation" } } } } @@ -1696,65 +1035,73 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentNode" - } + "name": { "kind": "Name", "value": "DocumentNode" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "createDocument" - }, + "name": { "kind": "Name", "value": "deleteDocument" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "collection" - }, + "name": { "kind": "Name", "value": "collection" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" + "name": { "kind": "Name", "value": "String" } + } + }, + { + "kind": "InputValueDefinition", + "name": { "kind": "Name", "value": "relativePath" }, + "type": { + "kind": "NonNullType", + "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": "createDocument" }, + "arguments": [ + { + "kind": "InputValueDefinition", + "name": { "kind": "Name", "value": "collection" }, + "type": { + "kind": "NamedType", + "name": { "kind": "Name", "value": "String" } + } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "relativePath" - }, + "name": { "kind": "Name", "value": "relativePath" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "params" - }, + "name": { "kind": "Name", "value": "params" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentMutation" - } + "name": { "kind": "Name", "value": "DocumentMutation" } } } } @@ -1763,51 +1110,33 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "DocumentNode" - } + "name": { "kind": "Name", "value": "DocumentNode" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "updatePostsDocument" - }, + "name": { "kind": "Name", "value": "updatePosts" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "relativePath" - }, + "name": { "kind": "Name", "value": "relativePath" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "params" - }, + "name": { "kind": "Name", "value": "params" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsMutation" - } + "name": { "kind": "Name", "value": "PostsMutation" } } } } @@ -1816,51 +1145,33 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsDocument" - } + "name": { "kind": "Name", "value": "Posts" } } } }, { "kind": "FieldDefinition", - "name": { - "kind": "Name", - "value": "createPostsDocument" - }, + "name": { "kind": "Name", "value": "createPosts" }, "arguments": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "relativePath" - }, + "name": { "kind": "Name", "value": "relativePath" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "params" - }, + "name": { "kind": "Name", "value": "params" }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsMutation" - } + "name": { "kind": "Name", "value": "PostsMutation" } } } } @@ -1869,10 +1180,7 @@ "kind": "NonNullType", "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsDocument" - } + "name": { "kind": "Name", "value": "Posts" } } } } @@ -1880,190 +1188,112 @@ }, { "kind": "InputObjectTypeDefinition", - "name": { - "kind": "Name", - "value": "DocumentMutation" - }, + "name": { "kind": "Name", "value": "DocumentMutation" }, "fields": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "posts" - }, + "name": { "kind": "Name", "value": "posts" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsMutation" - } + "name": { "kind": "Name", "value": "PostsMutation" } } } ] }, { "kind": "InputObjectTypeDefinition", - "name": { - "kind": "Name", - "value": "PostsAuthorMutation" - }, + "name": { "kind": "Name", "value": "PostsAuthorMutation" }, "fields": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "name" - }, + "name": { "kind": "Name", "value": "name" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "picture" - }, + "name": { "kind": "Name", "value": "picture" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } ] }, { "kind": "InputObjectTypeDefinition", - "name": { - "kind": "Name", - "value": "PostsOgImageMutation" - }, + "name": { "kind": "Name", "value": "PostsOgImageMutation" }, "fields": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "url" - }, + "name": { "kind": "Name", "value": "url" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } ] }, { "kind": "InputObjectTypeDefinition", - "name": { - "kind": "Name", - "value": "PostsMutation" - }, + "name": { "kind": "Name", "value": "PostsMutation" }, "fields": [ { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "title" - }, + "name": { "kind": "Name", "value": "title" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "excerpt" - }, + "name": { "kind": "Name", "value": "excerpt" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "coverImage" - }, + "name": { "kind": "Name", "value": "coverImage" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "date" - }, + "name": { "kind": "Name", "value": "date" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "author" - }, + "name": { "kind": "Name", "value": "author" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsAuthorMutation" - } + "name": { "kind": "Name", "value": "PostsAuthorMutation" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "ogImage" - }, + "name": { "kind": "Name", "value": "ogImage" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "PostsOgImageMutation" - } + "name": { "kind": "Name", "value": "PostsOgImageMutation" } } }, { "kind": "InputValueDefinition", - "name": { - "kind": "Name", - "value": "body" - }, + "name": { "kind": "Name", "value": "body" }, "type": { "kind": "NamedType", - "name": { - "kind": "Name", - "value": "String" - } + "name": { "kind": "Name", "value": "String" } } } ] diff --git a/examples/cms-tina/.tina/__generated__/_lookup.json b/examples/cms-tina/.tina/__generated__/_lookup.json index 6e651b843207f..fadf5763d98ab 100644 --- a/examples/cms-tina/.tina/__generated__/_lookup.json +++ b/examples/cms-tina/.tina/__generated__/_lookup.json @@ -4,22 +4,19 @@ "resolveType": "multiCollectionDocumentList", "collections": ["posts"] }, - "Node": { - "type": "Node", - "resolveType": "nodeDocument" - }, + "Node": { "type": "Node", "resolveType": "nodeDocument" }, "DocumentNode": { "type": "DocumentNode", "resolveType": "multiCollectionDocument", "createDocument": "create", "updateDocument": "update" }, - "PostsDocument": { - "type": "PostsDocument", + "Posts": { + "type": "Posts", "resolveType": "collectionDocument", "collection": "posts", - "createPostsDocument": "create", - "updatePostsDocument": "update" + "createPosts": "create", + "updatePosts": "update" }, "PostsConnection": { "type": "PostsConnection", diff --git a/examples/cms-tina/.tina/__generated__/_schema.json b/examples/cms-tina/.tina/__generated__/_schema.json index 46e9b5f5c4c12..6b80f8e6a9754 100644 --- a/examples/cms-tina/.tina/__generated__/_schema.json +++ b/examples/cms-tina/.tina/__generated__/_schema.json @@ -1,9 +1,9 @@ { "version": { - "fullVersion": "0.59.7", + "fullVersion": "0.60.1", "major": "0", - "minor": "59", - "patch": "7" + "minor": "60", + "patch": "1" }, "meta": {}, "collections": [ @@ -75,9 +75,7 @@ "label": "Blog Post Body", "name": "body", "isBody": true, - "ui": { - "component": "textarea" - }, + "ui": { "component": "textarea" }, "namespace": ["posts", "body"] } ], diff --git a/examples/cms-tina/.tina/__generated__/queries.gql b/examples/cms-tina/.tina/__generated__/queries.gql index 949e4040d5e9a..325b842bed1ca 100644 --- a/examples/cms-tina/.tina/__generated__/queries.gql +++ b/examples/cms-tina/.tina/__generated__/queries.gql @@ -1,6 +1,6 @@ -query getPostsDocument($relativePath: String!) { - getPostsDocument(relativePath: $relativePath) { - sys { +query posts($relativePath: String!) { + posts(relativePath: $relativePath) { + _sys { filename basename breadcrumbs @@ -9,19 +9,17 @@ query getPostsDocument($relativePath: String!) { extension } id - data { - ...PostsParts - } + ...PostsParts } } -query getPostsList { - getPostsList { +query postsConnection { + postsConnection { totalCount edges { node { id - sys { + _sys { filename basename breadcrumbs @@ -29,9 +27,7 @@ query getPostsList { relativePath extension } - data { - ...PostsParts - } + ...PostsParts } } } diff --git a/examples/cms-tina/.tina/__generated__/schema.gql b/examples/cms-tina/.tina/__generated__/schema.gql index 42acbd89517d4..74600380d73ee 100644 --- a/examples/cms-tina/.tina/__generated__/schema.gql +++ b/examples/cms-tina/.tina/__generated__/schema.gql @@ -38,10 +38,9 @@ interface Node { """ interface Document { - sys: SystemInfo id: ID! - form: JSON! - values: JSON! + _sys: SystemInfo + _values: JSON! } """ @@ -49,36 +48,32 @@ A relay-compliant pagination connection """ interface Connection { totalCount: Float! + pageInfo: PageInfo! } type Query { - getCollection(collection: String): Collection! - getCollections: [Collection!]! + getOptimizedQuery(queryString: String!): String + collection(collection: String): Collection! + collections: [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( + document(collection: String, relativePath: String): DocumentNode! + posts(relativePath: String): Posts! + postsConnection( before: String after: String first: Float last: Float + sort: String ): PostsConnection! } type DocumentConnectionEdges { - cursor: String + cursor: String! node: DocumentNode } type DocumentConnection implements Connection { - pageInfo: PageInfo + pageInfo: PageInfo! totalCount: Float! edges: [DocumentConnectionEdges] } @@ -97,10 +92,11 @@ type Collection { after: String first: Float last: Float + sort: String ): DocumentConnection! } -union DocumentNode = PostsDocument +union DocumentNode = Posts type PostsAuthor { name: String @@ -111,7 +107,7 @@ type PostsOgImage { url: String } -type Posts { +type Posts implements Node & Document { title: String excerpt: String coverImage: String @@ -119,24 +115,18 @@ type Posts { author: PostsAuthor ogImage: PostsOgImage body: String -} - -type PostsDocument implements Node & Document { id: ID! - sys: SystemInfo! - data: Posts! - form: JSON! - values: JSON! - dataJSON: JSON! + _sys: SystemInfo! + _values: JSON! } type PostsConnectionEdges { - cursor: String - node: PostsDocument + cursor: String! + node: Posts } type PostsConnection implements Connection { - pageInfo: PageInfo + pageInfo: PageInfo! totalCount: Float! edges: [PostsConnectionEdges] } @@ -152,19 +142,14 @@ type Mutation { relativePath: String! params: DocumentMutation! ): DocumentNode! + deleteDocument(collection: String, relativePath: String!): DocumentNode! createDocument( collection: String relativePath: String! params: DocumentMutation! ): DocumentNode! - updatePostsDocument( - relativePath: String! - params: PostsMutation! - ): PostsDocument! - createPostsDocument( - relativePath: String! - params: PostsMutation! - ): PostsDocument! + updatePosts(relativePath: String!, params: PostsMutation!): Posts! + createPosts(relativePath: String!, params: PostsMutation!): Posts! } input DocumentMutation { diff --git a/examples/cms-tina/.tina/__generated__/types.ts b/examples/cms-tina/.tina/__generated__/types.ts index bf78adacfbc9f..4c0551771cea7 100644 --- a/examples/cms-tina/.tina/__generated__/types.ts +++ b/examples/cms-tina/.tina/__generated__/types.ts @@ -1,6 +1,12 @@ //@ts-nocheck // DO NOT MODIFY THIS FILE. This file is automatically generated by Tina -import { gql } from 'tinacms' +export function gql(strings: TemplateStringsArray, ...args: string[]): string { + let str = '' + strings.forEach((string, i) => { + str += string + (args[i] || '') + }) + return str +} export type Maybe = T | null export type InputMaybe = Maybe export type Exact = { @@ -53,30 +59,33 @@ export type Node = { } export type Document = { - sys?: Maybe id: Scalars['ID'] - form: Scalars['JSON'] - values: Scalars['JSON'] + _sys?: Maybe + _values: Scalars['JSON'] } /** A relay-compliant pagination connection */ export type Connection = { totalCount: Scalars['Float'] + pageInfo: PageInfo } export type Query = { __typename?: 'Query' - getCollection: Collection - getCollections: Array + getOptimizedQuery?: Maybe + collection: Collection + collections: Array node: Node - getDocument: DocumentNode - getDocumentList: DocumentConnection - getDocumentFields: Scalars['JSON'] - getPostsDocument: PostsDocument - getPostsList: PostsConnection + document: DocumentNode + posts: Posts + postsConnection: PostsConnection +} + +export type QueryGetOptimizedQueryArgs = { + queryString: Scalars['String'] } -export type QueryGetCollectionArgs = { +export type QueryCollectionArgs = { collection?: InputMaybe } @@ -84,38 +93,32 @@ export type QueryNodeArgs = { id?: InputMaybe } -export type QueryGetDocumentArgs = { +export type QueryDocumentArgs = { collection?: InputMaybe relativePath?: InputMaybe } -export type QueryGetDocumentListArgs = { - before?: InputMaybe - after?: InputMaybe - first?: InputMaybe - last?: InputMaybe -} - -export type QueryGetPostsDocumentArgs = { +export type QueryPostsArgs = { relativePath?: InputMaybe } -export type QueryGetPostsListArgs = { +export type QueryPostsConnectionArgs = { before?: InputMaybe after?: InputMaybe first?: InputMaybe last?: InputMaybe + sort?: InputMaybe } export type DocumentConnectionEdges = { __typename?: 'DocumentConnectionEdges' - cursor?: Maybe + cursor: Scalars['String'] node?: Maybe } export type DocumentConnection = Connection & { __typename?: 'DocumentConnection' - pageInfo?: Maybe + pageInfo: PageInfo totalCount: Scalars['Float'] edges?: Maybe>> } @@ -138,9 +141,10 @@ export type CollectionDocumentsArgs = { after?: InputMaybe first?: InputMaybe last?: InputMaybe + sort?: InputMaybe } -export type DocumentNode = PostsDocument +export type DocumentNode = Posts export type PostsAuthor = { __typename?: 'PostsAuthor' @@ -153,37 +157,30 @@ export type 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 & +export type Posts = Node & Document & { - __typename?: 'PostsDocument' + __typename?: 'Posts' + title?: Maybe + excerpt?: Maybe + coverImage?: Maybe + date?: Maybe + author?: Maybe + ogImage?: Maybe + body?: Maybe id: Scalars['ID'] - sys: SystemInfo - data: Posts - form: Scalars['JSON'] - values: Scalars['JSON'] - dataJSON: Scalars['JSON'] + _sys: SystemInfo + _values: Scalars['JSON'] } export type PostsConnectionEdges = { __typename?: 'PostsConnectionEdges' - cursor?: Maybe - node?: Maybe + cursor: Scalars['String'] + node?: Maybe } export type PostsConnection = Connection & { __typename?: 'PostsConnection' - pageInfo?: Maybe + pageInfo: PageInfo totalCount: Scalars['Float'] edges?: Maybe>> } @@ -192,9 +189,10 @@ export type Mutation = { __typename?: 'Mutation' addPendingDocument: DocumentNode updateDocument: DocumentNode + deleteDocument: DocumentNode createDocument: DocumentNode - updatePostsDocument: PostsDocument - createPostsDocument: PostsDocument + updatePosts: Posts + createPosts: Posts } export type MutationAddPendingDocumentArgs = { @@ -209,18 +207,23 @@ export type MutationUpdateDocumentArgs = { params: DocumentMutation } +export type MutationDeleteDocumentArgs = { + collection?: InputMaybe + relativePath: Scalars['String'] +} + export type MutationCreateDocumentArgs = { collection?: InputMaybe relativePath: Scalars['String'] params: DocumentMutation } -export type MutationUpdatePostsDocumentArgs = { +export type MutationUpdatePostsArgs = { relativePath: Scalars['String'] params: PostsMutation } -export type MutationCreatePostsDocumentArgs = { +export type MutationCreatePostsArgs = { relativePath: Scalars['String'] params: PostsMutation } @@ -263,16 +266,21 @@ export type PostsPartsFragment = { ogImage?: { __typename: 'PostsOgImage'; url?: string | null } | null } -export type GetPostsDocumentQueryVariables = Exact<{ +export type PostsQueryVariables = Exact<{ relativePath: Scalars['String'] }> -export type GetPostsDocumentQuery = { +export type PostsQuery = { __typename?: 'Query' - getPostsDocument: { - __typename?: 'PostsDocument' + posts: { + __typename?: 'Posts' id: string - sys: { + title?: string | null + excerpt?: string | null + coverImage?: string | null + date?: string | null + body?: string | null + _sys: { __typename?: 'SystemInfo' filename: string basename: string @@ -281,36 +289,33 @@ export type GetPostsDocumentQuery = { 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 - } + 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 PostsConnectionQueryVariables = Exact<{ [key: string]: never }> -export type GetPostsListQuery = { +export type PostsConnectionQuery = { __typename?: 'Query' - getPostsList: { + postsConnection: { __typename?: 'PostsConnection' totalCount: number edges?: Array<{ __typename?: 'PostsConnectionEdges' node?: { - __typename?: 'PostsDocument' + __typename?: 'Posts' id: string - sys: { + title?: string | null + excerpt?: string | null + coverImage?: string | null + date?: string | null + body?: string | null + _sys: { __typename?: 'SystemInfo' filename: string basename: string @@ -319,20 +324,12 @@ export type GetPostsListQuery = { 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 - } + author?: { + __typename: 'PostsAuthor' + name?: string | null + picture?: string | null + } | null + ogImage?: { __typename: 'PostsOgImage'; url?: string | null } | null } | null } | null> | null } @@ -356,10 +353,10 @@ export const PostsPartsFragmentDoc = gql` body } ` -export const GetPostsDocumentDocument = gql` - query getPostsDocument($relativePath: String!) { - getPostsDocument(relativePath: $relativePath) { - sys { +export const PostsDocument = gql` + query posts($relativePath: String!) { + posts(relativePath: $relativePath) { + _sys { filename basename breadcrumbs @@ -368,21 +365,19 @@ export const GetPostsDocumentDocument = gql` extension } id - data { - ...PostsParts - } + ...PostsParts } } ${PostsPartsFragmentDoc} ` -export const GetPostsListDocument = gql` - query getPostsList { - getPostsList { +export const PostsConnectionDocument = gql` + query postsConnection { + postsConnection { totalCount edges { node { id - sys { + _sys { filename basename breadcrumbs @@ -390,9 +385,7 @@ export const GetPostsListDocument = gql` relativePath extension } - data { - ...PostsParts - } + ...PostsParts } } } @@ -406,46 +399,44 @@ export type Requester = ( ) => Promise export function getSdk(requester: Requester) { return { - getPostsDocument( - variables: GetPostsDocumentQueryVariables, + posts( + variables: PostsQueryVariables, options?: C ): Promise<{ - data: GetPostsDocumentQuery - variables: GetPostsDocumentQueryVariables + data: PostsQuery + variables: PostsQueryVariables query: string }> { return requester< - { - data: GetPostsDocumentQuery - variables: GetPostsDocumentQueryVariables - query: string - }, - GetPostsDocumentQueryVariables - >(GetPostsDocumentDocument, variables, options) + { data: PostsQuery; variables: PostsQueryVariables; query: string }, + PostsQueryVariables + >(PostsDocument, variables, options) }, - getPostsList( - variables?: GetPostsListQueryVariables, + postsConnection( + variables?: PostsConnectionQueryVariables, options?: C ): Promise<{ - data: GetPostsListQuery - variables: GetPostsListQueryVariables + data: PostsConnectionQuery + variables: PostsConnectionQueryVariables query: string }> { return requester< { - data: GetPostsListQuery - variables: GetPostsListQueryVariables + data: PostsConnectionQuery + variables: PostsConnectionQueryVariables query: string }, - GetPostsListQueryVariables - >(GetPostsListDocument, variables, options) + PostsConnectionQueryVariables + >(PostsConnectionDocument, variables, options) }, } } export type Sdk = ReturnType // TinaSDK generated code -import { staticRequest } from 'tinacms' +import { createClient } from 'tinacms/dist/client' +const client = createClient({ url: 'http://localhost:4001/graphql' }) + const requester: (doc: any, vars?: any, options?: any) => Promise = async ( doc, vars, @@ -453,7 +444,7 @@ const requester: (doc: any, vars?: any, options?: any) => Promise = async ( ) => { let data = {} try { - data = await staticRequest({ + data = await client.request({ query: doc, variables: vars, }) @@ -463,7 +454,7 @@ const requester: (doc: any, vars?: any, options?: any) => Promise = async ( console.warn(e) } - return { data, query: doc, variables: vars || {} } + return { data: data?.data, query: doc, variables: vars || {} } } /** diff --git a/examples/cms-tina/.tina/schema.ts b/examples/cms-tina/.tina/schema.ts index 12f738c64a264..1b7d0332a80c8 100644 --- a/examples/cms-tina/.tina/schema.ts +++ b/examples/cms-tina/.tina/schema.ts @@ -1,6 +1,6 @@ import { defineSchema, defineConfig } from 'tinacms' -export default defineSchema({ +const schema = defineSchema({ collections: [ { label: 'Blog Posts', @@ -69,7 +69,7 @@ export default defineSchema({ }, ], }) - +export default schema // Your tina config // ============== const branch = 'main' @@ -82,6 +82,7 @@ const apiURL = export const tinaConfig = defineConfig({ apiURL, + schema, cmsCallback: (cms) => { // add your CMS callback code here (if you want) diff --git a/examples/cms-tina/README.md b/examples/cms-tina/README.md index 2375425abf49a..2e01fee19e5cd 100644 --- a/examples/cms-tina/README.md +++ b/examples/cms-tina/README.md @@ -5,6 +5,10 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas > 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). +## Demo + +### [https://cms-tina-example.vercel.app/](https://cms-tina-example.vercel.app/) + ### Related examples - [WordPress](/examples/cms-wordpress) @@ -30,9 +34,9 @@ Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packag ```bash npx create-next-app --example cms-tina cms-tina-app # or -yarn create next-app --example cms-ghost cms-tina-app +yarn create next-app --example cms-tina cms-tina-app # or -pnpm create next-app -- --example cms-ghost cms-tina-app +pnpm create next-app -- --example cms-tina cms-tina-app ``` ### Setp 1. Run Next.js in development mode @@ -76,4 +80,4 @@ Then [import to Vercel](https://vercel.com/import/git?utm_source=github&utm_medi **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. +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://cms-tina-example.vercel.app/ diff --git a/examples/cms-tina/package.json b/examples/cms-tina/package.json index 4ab85e58294ad..dd9d204a04f76 100644 --- a/examples/cms-tina/package.json +++ b/examples/cms-tina/package.json @@ -9,7 +9,7 @@ "tina-start": "yarn tinacms server:start -c \"next start\"" }, "dependencies": { - "@tinacms/cli": "^0.60.8", + "@tinacms/cli": "^0.60.16", "classnames": "2.3.1", "date-fns": "2.28.0", "gray-matter": "4.0.3", @@ -19,7 +19,7 @@ "remark": "14.0.2", "remark-html": "15.0.1", "styled-components": "^5.3.3", - "tinacms": "^0.66.7" + "tinacms": "^0.68.4" }, "devDependencies": { "autoprefixer": "^10.4.2", diff --git a/examples/with-geist-ui/.gitignore b/examples/with-geist-ui/.gitignore new file mode 100644 index 0000000000000..1437c53f70bc2 --- /dev/null +++ b/examples/with-geist-ui/.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/with-geist-ui/README.md b/examples/with-geist-ui/README.md new file mode 100644 index 0000000000000..04f20dd2b6348 --- /dev/null +++ b/examples/with-geist-ui/README.md @@ -0,0 +1,21 @@ +# Example app with [geist-ui](https://github.com/geist-org/geist-ui) and TypeScript + +This example features how to use [geist-ui](https://github.com/geist-org/geist-ui) as the component library within a Next.js app with TypeScript. + +## Deploy your own + +Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-geist-ui) + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-geist-ui&project-name=with-geist-ui&repository-name=with-geist-ui) + +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 with-geist-ui with-geist-ui-app +# or +yarn create next-app --example with-geist-ui with-geist-ui-app +# or +pnpm create next-app -- --example with-geist-ui with-geist-ui-app +``` + +Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). diff --git a/examples/with-geist-ui/next-env.d.ts b/examples/with-geist-ui/next-env.d.ts new file mode 100644 index 0000000000000..4f11a03dc6cc3 --- /dev/null +++ b/examples/with-geist-ui/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/examples/with-geist-ui/package.json b/examples/with-geist-ui/package.json new file mode 100644 index 0000000000000..81de156c6e85f --- /dev/null +++ b/examples/with-geist-ui/package.json @@ -0,0 +1,22 @@ +{ + "private": true, + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "@geist-ui/core": "latest", + "@geist-ui/icons": "1.0.1", + "next": "latest", + "react": "^18.1.0", + "react-dom": "^18.1.0" + }, + "devDependencies": { + "@types/node": "^17.0.29", + "@types/react": "^18.0.8", + "eslint": "8.14.0", + "eslint-config-next": "12.1.5", + "typescript": "^4.5.4" + } +} diff --git a/examples/with-geist-ui/pages/_app.tsx b/examples/with-geist-ui/pages/_app.tsx new file mode 100644 index 0000000000000..906b974c8092c --- /dev/null +++ b/examples/with-geist-ui/pages/_app.tsx @@ -0,0 +1,12 @@ +import type { AppProps } from 'next/app' +import { GeistProvider, CssBaseline } from '@geist-ui/core' + +function MyApp({ Component, pageProps }: AppProps) { + return ( + + + + + ) +} +export default MyApp diff --git a/examples/with-geist-ui/pages/_document.js b/examples/with-geist-ui/pages/_document.js new file mode 100644 index 0000000000000..8ff3141143ca0 --- /dev/null +++ b/examples/with-geist-ui/pages/_document.js @@ -0,0 +1,33 @@ +import Document, { Html, Head, Main, NextScript } from 'next/document' +import { CssBaseline } from '@geist-ui/core' + +class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx) + const styles = CssBaseline.flush() + + return { + ...initialProps, + styles: ( + <> + {initialProps.styles} + {styles} + + ), + } + } + + render() { + return ( + + + +
    + + + + ) + } +} + +export default MyDocument diff --git a/examples/with-geist-ui/pages/index.tsx b/examples/with-geist-ui/pages/index.tsx new file mode 100644 index 0000000000000..8808b14d3a9e1 --- /dev/null +++ b/examples/with-geist-ui/pages/index.tsx @@ -0,0 +1,87 @@ +import Head from 'next/head' +import { + Page, + Text, + Image, + Display, + Button, + Grid, + Spacer, +} from '@geist-ui/core' +import { Github } from '@geist-ui/icons' + +const gh = 'https://github.com/geist-org/geist-ui' +const docs = 'https://geist-ui.dev' + +export default function Home() { + const redirect = (url: string) => window.open(url) + + return ( +
    + + Geist UI with NextJS + + + + + Example repository of{' '} + + Next.js + {' '} + &{' '} + + + G + + + e + + + i + + + s + + + t + + + UI. + + {' '} + + } + > + geist ui banner + + + + + + + + + + + +
    + ) +} diff --git a/examples/with-geist-ui/public/geist-banner.png b/examples/with-geist-ui/public/geist-banner.png new file mode 100644 index 0000000000000..cf7a3facab671 Binary files /dev/null and b/examples/with-geist-ui/public/geist-banner.png differ diff --git a/examples/with-geist-ui/tsconfig.json b/examples/with-geist-ui/tsconfig.json new file mode 100644 index 0000000000000..99710e857874f --- /dev/null +++ b/examples/with-geist-ui/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/examples/with-jest/package.json b/examples/with-jest/package.json index 23e5d9ed94c85..c637cdf07f343 100644 --- a/examples/with-jest/package.json +++ b/examples/with-jest/package.json @@ -2,7 +2,6 @@ "private": true, "scripts": { "dev": "next dev", - "lint": "next lint", "build": "next build", "start": "next start", "test": "jest --watch", @@ -18,10 +17,6 @@ "@testing-library/react": "12.1.2", "@testing-library/user-event": "13.5.0", "@types/react": "17.0.38", - "babel-jest": "27.4.5", - "eslint": "8.5.0", - "eslint-config-next": "latest", - "eslint-plugin-testing-library": "5.0.1", "jest": "27.4.5", "typescript": "4.5.4" } diff --git a/lerna.json b/lerna.json index 880c0a0e8da54..93df0379f9d92 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "12.1.7-canary.3" + "version": "12.1.7-canary.4" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 18fdd35955372..0edbe59fe1e5e 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index fbeceda394bcf..28bab914ea400 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "description": "ESLint configuration used by NextJS.", "main": "index.js", "license": "MIT", @@ -9,7 +9,7 @@ "directory": "packages/eslint-config-next" }, "dependencies": { - "@next/eslint-plugin-next": "12.1.7-canary.3", + "@next/eslint-plugin-next": "12.1.7-canary.4", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.21.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 65fe921bfd010..a3ac4713caf9e 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "description": "ESLint plugin for NextJS.", "main": "lib/index.js", "license": "MIT", diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 79a04b70c1f04..4610e37da79d1 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 58e08ac058fc3..741e784ba4fee 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index b96189e397aad..222b6b4cff32d 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 91dcfed36eaa7..f32f77db3ef85 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 83a9bb9025422..19bc24fcf61f3 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 5dc7ebe0f285a..c869e21e06eca 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 822faad5c3050..d3e2c5df47d8a 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/crates/napi/npm/freebsd-x64/README.md b/packages/next-swc/crates/napi/npm/freebsd-x64/README.md new file mode 100644 index 0000000000000..8a9ba18e17b4d --- /dev/null +++ b/packages/next-swc/crates/napi/npm/freebsd-x64/README.md @@ -0,0 +1,3 @@ +# `@next/swc-freebsd-x64` + +This is the **x86_64-unknown-freebsd** binary for `@next/swc` diff --git a/packages/next-swc/crates/napi/npm/freebsd-x64/package.json b/packages/next-swc/crates/napi/npm/freebsd-x64/package.json new file mode 100644 index 0000000000000..d76208230f26d --- /dev/null +++ b/packages/next-swc/crates/napi/npm/freebsd-x64/package.json @@ -0,0 +1,18 @@ +{ + "name": "@next/swc-freebsd-x64", + "version": "0.0.0", + "os": [ + "freebsd" + ], + "cpu": [ + "x64" + ], + "main": "next-swc.freebsd-x64.node", + "files": [ + "next-swc.freebsd-x64.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 7849d35af03f7..ed19425ac4e75 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "private": true, "scripts": { "build-native": "napi build --platform --cargo-name next_swc_napi native", diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 187ac67d8218f..882861acee4ba 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -1523,6 +1523,10 @@ export default async function build( featureName: 'experimental/optimizeCss', invocationCount: config.experimental.optimizeCss ? 1 : 0, }, + { + featureName: 'experimental/nextScriptWorkers', + invocationCount: config.experimental.nextScriptWorkers ? 1 : 0, + }, { featureName: 'optimizeFonts', invocationCount: config.optimizeFonts ? 1 : 0, diff --git a/packages/next/build/jest/jest.ts b/packages/next/build/jest/jest.ts index d456c54a34440..844afc8e22308 100644 --- a/packages/next/build/jest/jest.ts +++ b/packages/next/build/jest/jest.ts @@ -84,10 +84,6 @@ export default function nextJest(options: { dir?: string } = {}) { ...resolvedJestConfig, moduleNameMapper: { - // Custom config will be able to override the default mappings - // moduleNameMapper is matched top to bottom hence why this has to be before Next.js internal rules - ...(resolvedJestConfig.moduleNameMapper || {}), - // Handle CSS imports (with CSS modules) // https://jestjs.io/docs/webpack#mocking-css-modules '^.+\\.module\\.(css|sass|scss)$': @@ -97,9 +93,17 @@ export default function nextJest(options: { dir?: string } = {}) { '^.+\\.(css|sass|scss)$': require.resolve('./__mocks__/styleMock.js'), // Handle image imports - '^.+\\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$': require.resolve( + '^.+\\.(png|jpg|jpeg|gif|webp|avif|ico|bmp)$': require.resolve( `./__mocks__/fileMock.js` ), + + // Keep .svg to it's own rule to make overriding easy + '^.+\\.(svg)$': require.resolve(`./__mocks__/fileMock.js`), + + // custom config comes last to ensure the above rules are matched, + // fixes the case where @pages/(.*) -> src/pages/$! doesn't break + // CSS/image mocks + ...(resolvedJestConfig.moduleNameMapper || {}), }, testPathIgnorePatterns: [ // Don't look for tests in node_modules diff --git a/packages/next/build/output/log.ts b/packages/next/build/output/log.ts index 9220fe1834e36..bbf520da350d7 100644 --- a/packages/next/build/output/log.ts +++ b/packages/next/build/output/log.ts @@ -10,30 +10,30 @@ export const prefixes = { trace: chalk.magenta('trace') + ' -', } -export function wait(...message: string[]) { +export function wait(...message: any[]) { console.log(prefixes.wait, ...message) } -export function error(...message: string[]) { +export function error(...message: any[]) { console.error(prefixes.error, ...message) } -export function warn(...message: string[]) { +export function warn(...message: any[]) { console.warn(prefixes.warn, ...message) } -export function ready(...message: string[]) { +export function ready(...message: any[]) { console.log(prefixes.ready, ...message) } -export function info(...message: string[]) { +export function info(...message: any[]) { console.log(prefixes.info, ...message) } -export function event(...message: string[]) { +export function event(...message: any[]) { console.log(prefixes.event, ...message) } -export function trace(...message: string[]) { +export function trace(...message: any[]) { console.log(prefixes.trace, ...message) } diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 2078041106ae1..c225847ae8de0 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -412,7 +412,7 @@ export default async function getBaseWebpackConfig( const distDir = path.join(dir, config.distDir) - let useSWCLoader = !babelConfigFile + let useSWCLoader = !babelConfigFile || config.experimental.forceSwcTransforms let SWCBinaryTarget: [Feature, boolean] | undefined = undefined if (useSWCLoader) { // TODO: we do not collect wasm target yet @@ -915,9 +915,8 @@ export default async function getBaseWebpackConfig( }, } - const rscCodeCondition = { + const serverComponentCodeCondition = { test: serverComponentsRegex, - // only apply to the pages as the begin process of rsc loaders include: [dir, /next[\\/]dist[\\/]pages/], } @@ -1216,7 +1215,7 @@ export default async function getBaseWebpackConfig( ? [ // RSC server compilation loaders { - ...rscCodeCondition, + ...serverComponentCodeCondition, use: { loader: 'next-flight-server-loader', }, @@ -1225,7 +1224,7 @@ export default async function getBaseWebpackConfig( : [ // RSC client compilation loaders { - ...rscCodeCondition, + ...serverComponentCodeCondition, use: { loader: 'next-flight-server-loader', options: { @@ -1595,8 +1594,12 @@ export default async function getBaseWebpackConfig( }, }), hasServerComponents && - isClient && - new FlightManifestPlugin({ dev, pageExtensions: rawPageExtensions }), + !isClient && + new FlightManifestPlugin({ + dev, + pageExtensions: rawPageExtensions, + isEdgeServer, + }), !dev && isClient && new TelemetryPlugin( diff --git a/packages/next/build/webpack/loaders/next-flight-server-loader.ts b/packages/next/build/webpack/loaders/next-flight-server-loader.ts index 2dd7cde2fb12e..83c4ac670f883 100644 --- a/packages/next/build/webpack/loaders/next-flight-server-loader.ts +++ b/packages/next/build/webpack/loaders/next-flight-server-loader.ts @@ -3,8 +3,8 @@ import { builtinModules } from 'module' import { parse } from '../../swc' import { buildExports, - createClientComponentFilter, - createServerComponentFilter, + clientComponentRegex, + serverComponentRegex, isNextBuiltinClientComponent, } from './utils' @@ -25,15 +25,11 @@ async function parseModuleInfo({ resourcePath, source, isClientCompilation, - isServerComponent, - isClientComponent, resolver, }: { resourcePath: string source: string isClientCompilation: boolean - isServerComponent: (name: string) => boolean - isClientComponent: (name: string) => boolean resolver: (req: string) => Promise }): Promise<{ source: string @@ -71,10 +67,10 @@ async function parseModuleInfo({ } function addClientImport(path: string) { - if (isServerComponent(path) || hasFlightLoader(path, 'server')) { + if (serverComponentRegex.test(path) || hasFlightLoader(path, 'server')) { // If it's a server component, we recursively import its dependencies. imports.push(path) - } else if (isClientComponent(path)) { + } else if (clientComponentRegex.test(path)) { // Client component. imports.push(path) } else { @@ -102,7 +98,7 @@ async function parseModuleInfo({ if (!isClientCompilation) { // Server compilation for .server.js. - if (isServerComponent(importSource)) { + if (serverComponentRegex.test(importSource)) { continue } @@ -111,7 +107,7 @@ async function parseModuleInfo({ node.source.span.start - beginPos ) - if (isClientComponent(importSource)) { + if (clientComponentRegex.test(importSource)) { transformedSource += importDeclarations transformedSource += JSON.stringify( `next-flight-client-loader!${importSource}` @@ -210,12 +206,10 @@ export default async function transformSource( throw new Error('Expected source to have been transformed to a string.') } - const isServerComponent = createServerComponentFilter() - const isClientComponent = createClientComponentFilter() const hasAppliedFlightServerLoader = this.loaders.some((loader: any) => { return hasFlightLoader(loader.path, 'server') }) - const isServerExt = isServerComponent(resourcePath) + const isServerExt = serverComponentRegex.test(resourcePath) if (!isClientCompilation) { // We only apply the loader to server components, or shared components that @@ -235,8 +229,6 @@ export default async function transformSource( resourcePath, source, isClientCompilation, - isServerComponent, - isClientComponent, resolver, }) diff --git a/packages/next/build/webpack/loaders/next-view-loader.ts b/packages/next/build/webpack/loaders/next-view-loader.ts index 1f4ca331584fb..4374b9ff3673c 100644 --- a/packages/next/build/webpack/loaders/next-view-loader.ts +++ b/packages/next/build/webpack/loaders/next-view-loader.ts @@ -22,18 +22,34 @@ async function resolveLayoutPathsByPage({ }) { const layoutPaths = new Map() const parts = pagePath.split('/') + const isNewRootLayout = + parts[1]?.length > 2 && parts[1]?.startsWith('(') && parts[1]?.endsWith(')') - for (let i = 1; i < parts.length; i++) { + for (let i = parts.length; i >= 0; i--) { const pathWithoutSlashLayout = parts.slice(0, i).join('/') - const layoutPath = `${pathWithoutSlashLayout}/layout` - - const resolvedLayoutPath = await resolve(layoutPath) + if (!pathWithoutSlashLayout) { + continue + } + const layoutPath = `${pathWithoutSlashLayout}/layout` + let resolvedLayoutPath = await resolve(layoutPath) let urlPath = pathToUrlPath(pathWithoutSlashLayout) + // if we are in a new root views/(root) and a custom root layout was + // not provided or a root layout views/layout is not present, we use + // a default root layout to provide the html/body tags + const isCustomRootLayout = isNewRootLayout && i === 2 + + if ((isCustomRootLayout || i === 1) && !resolvedLayoutPath) { + resolvedLayoutPath = await resolve('next/dist/lib/views-layout') + } layoutPaths.set(urlPath, resolvedLayoutPath) - } + // if we're in a new root layout don't add the top-level view/layout + if (isCustomRootLayout) { + break + } + } return layoutPaths } @@ -84,7 +100,7 @@ const nextViewLoader: webpack.LoaderDefinitionFunction<{ // Add page itself to the list of components componentsCode.push( `'${pathToUrlPath(pagePath).replace( - new RegExp(`/page\\.+(${extensions.join('|')})$`), + new RegExp(`/page+(${extensions.join('|')})$`), '' // use require so that we can bust the require cache )}': () => require('${pagePath}')` diff --git a/packages/next/build/webpack/loaders/utils.ts b/packages/next/build/webpack/loaders/utils.ts index ba2c478b8af9a..d6e113f1f93cd 100644 --- a/packages/next/build/webpack/loaders/utils.ts +++ b/packages/next/build/webpack/loaders/utils.ts @@ -24,25 +24,18 @@ export function buildExports(moduleExports: any, isESM: boolean) { return ret } -export const createClientComponentFilter = () => { - // Special cases for Next.js APIs that are considered as client components: - // - .client.[ext] - // - next built-in client components - // - .[imageExt] - const regex = new RegExp( - '(' + - `\\.client(\\.(${defaultJsFileExtensions.join('|')}))?|` + - `next/(${nextClientComponents.join('|')})(\\.js)?|` + - `\\.(${imageExtensions.join('|')})` + - ')$' - ) - - return (importSource: string) => regex.test(importSource) -} +// Special cases for Next.js APIs that are considered as client components: +// - .client.[ext] +// - next built-in client components +// - .[imageExt] +export const clientComponentRegex = new RegExp( + '(' + + `\\.client(\\.(${defaultJsFileExtensions.join('|')}))?|` + + `next/(${nextClientComponents.join('|')})(\\.js)?|` + + `\\.(${imageExtensions.join('|')})` + + ')$' +) -export const createServerComponentFilter = () => { - const regex = new RegExp( - `\\.server(\\.(${defaultJsFileExtensions.join('|')}))?$` - ) - return (importSource: string) => regex.test(importSource) -} +export const serverComponentRegex = new RegExp( + `\\.server(\\.(${defaultJsFileExtensions.join('|')}))?$` +) diff --git a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts index 73c82d8b7d322..1dea744726659 100644 --- a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts @@ -7,7 +7,7 @@ import { webpack, sources } from 'next/dist/compiled/webpack/webpack' import { MIDDLEWARE_FLIGHT_MANIFEST } from '../../../shared/lib/constants' -import { createClientComponentFilter } from '../loaders/utils' +import { clientComponentRegex } from '../loaders/utils' // This is the module that will be used to anchor all client references to. // I.e. it will have all the client files as async deps from this point on. @@ -19,20 +19,25 @@ import { createClientComponentFilter } from '../loaders/utils' type Options = { dev: boolean pageExtensions: string[] + isEdgeServer: boolean } const PLUGIN_NAME = 'FlightManifestPlugin' -const isClientComponent = createClientComponentFilter() +let edgeFlightManifest = {} +let nodeFlightManifest = {} + export class FlightManifestPlugin { dev: boolean = false pageExtensions: string[] + isEdgeServer: boolean constructor(options: Options) { if (typeof options.dev === 'boolean') { this.dev = options.dev } this.pageExtensions = options.pageExtensions + this.isEdgeServer = options.isEdgeServer } apply(compiler: any) { @@ -72,9 +77,14 @@ export class FlightManifestPlugin { // TODO: Hook into deps instead of the target module. // That way we know by the type of dep whether to include. // It also resolves conflicts when the same module is in multiple chunks. - if (!resource || !isClientComponent(resource)) { + if ( + !resource || + !clientComponentRegex.test(resource) || + !clientComponentRegex.test(id) + ) { return } + const moduleExports: any = manifest[resource] || {} const exportsInfo = compilation.moduleGraph.getExportsInfo(mod) @@ -107,10 +117,13 @@ export class FlightManifestPlugin { for (const mod of chunkModules) { let modId = compilation.chunkGraph.getModuleId(mod) - // remove resource query on production - if (typeof modId === 'string') { - modId = modId.split('?')[0] - } + if (typeof modId !== 'string') continue + + // Remove resource queries. + modId = modId.split('?')[0] + // Remove the loader prefix. + modId = modId.split('next-flight-client-loader.js!')[1] || modId + recordModule(modId, chunk, mod) // If this is a concatenation, register each child to the parent ID. if (mod.modules) { @@ -124,8 +137,19 @@ export class FlightManifestPlugin { // With switchable runtime, we need to emit the manifest files for both // runtimes. - const file = `server/${MIDDLEWARE_FLIGHT_MANIFEST}` - const json = JSON.stringify(manifest) + if (this.isEdgeServer) { + edgeFlightManifest = manifest + } else { + nodeFlightManifest = manifest + } + const mergedManifest = { + ...nodeFlightManifest, + ...edgeFlightManifest, + } + const file = + (!this.dev && !this.isEdgeServer ? '../' : '') + + MIDDLEWARE_FLIGHT_MANIFEST + const json = JSON.stringify(mergedManifest) assets[file + '.js'] = new sources.RawSource('self.__RSC_MANIFEST=' + json) assets[file + '.json'] = new sources.RawSource(json) diff --git a/packages/next/export/worker.ts b/packages/next/export/worker.ts index e8db5c26e4671..28eab497d3bdc 100644 --- a/packages/next/export/worker.ts +++ b/packages/next/export/worker.ts @@ -221,8 +221,13 @@ export default async function exportPage({ // extension of `.slug]` const pageExt = isDynamic ? '' : extname(page) const pathExt = isDynamic ? '' : extname(path) + + // force output 404.html for backwards compat + if (path === '/404.html') { + htmlFilename = path + } // Make sure page isn't a folder with a dot in the name e.g. `v1.2` - if (pageExt !== pathExt && pathExt !== '') { + else if (pageExt !== pathExt && pathExt !== '') { const isBuiltinPaths = ['/500', '/404'].some( (p) => p === path || p === path + '.html' ) diff --git a/packages/next/jest.js b/packages/next/jest.js index c0451a2246bd7..adeca0379d659 100644 --- a/packages/next/jest.js +++ b/packages/next/jest.js @@ -1,4 +1 @@ -function interopDefault(mod) { - return mod.default || mod -} -module.exports = interopDefault(require('./dist/build/jest/jest')) +module.exports = require('./dist/build/jest/jest') diff --git a/packages/next/lib/patch-incorrect-lockfile.ts b/packages/next/lib/patch-incorrect-lockfile.ts index 470e67e6e9632..02026779bd737 100644 --- a/packages/next/lib/patch-incorrect-lockfile.ts +++ b/packages/next/lib/patch-incorrect-lockfile.ts @@ -87,7 +87,7 @@ export async function patchIncorrectLockfile(dir: string) { await promises.writeFile( lockfilePath, - JSON.stringify(lockfileParsed, null, 2) + `${JSON.stringify(lockfileParsed, null, 2)}\n` ) Log.warn( 'Lockfile was successfully patched, please run "npm install" to ensure @next/swc dependencies are downloaded' diff --git a/packages/next/package.json b/packages/next/package.json index eaf1cc902a3db..b406cb2c2570e 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "12.1.7-canary.3", + "version": "12.1.7-canary.4", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -69,7 +69,7 @@ ] }, "dependencies": { - "@next/env": "12.1.7-canary.3", + "@next/env": "12.1.7-canary.4", "caniuse-lite": "^1.0.30001332", "postcss": "8.4.5", "styled-jsx": "5.0.2", @@ -118,11 +118,11 @@ "@hapi/accept": "5.0.2", "@napi-rs/cli": "2.4.4", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "12.1.7-canary.3", - "@next/polyfill-nomodule": "12.1.7-canary.3", - "@next/react-dev-overlay": "12.1.7-canary.3", - "@next/react-refresh-utils": "12.1.7-canary.3", - "@next/swc": "12.1.7-canary.3", + "@next/polyfill-module": "12.1.7-canary.4", + "@next/polyfill-nomodule": "12.1.7-canary.4", + "@next/react-dev-overlay": "12.1.7-canary.4", + "@next/react-refresh-utils": "12.1.7-canary.4", + "@next/swc": "12.1.7-canary.4", "@peculiar/webcrypto": "1.3.1", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index 37070426f4291..4fd42d56f9138 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -1629,7 +1629,7 @@ export default abstract class Server { return null } - if (isSSG) { + if (isSSG && !this.minimalMode) { // set x-nextjs-cache header to match the header // we set for the image-optimizer res.setHeader( diff --git a/packages/next/server/config-shared.ts b/packages/next/server/config-shared.ts index 8b1c10c8581d4..b9221879b03e6 100644 --- a/packages/next/server/config-shared.ts +++ b/packages/next/server/config-shared.ts @@ -135,6 +135,7 @@ export interface ExperimentalConfig { } > swcTraceProfiling?: boolean + forceSwcTransforms?: boolean } /** @@ -505,6 +506,7 @@ export const defaultConfig: NextConfig = { layoutRaw: false, remotePatterns: [], }, + forceSwcTransforms: false, }, } diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index 7a5c28597ddd6..91222ebabe7d5 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -693,7 +693,7 @@ export default class DevServer extends Server { ) { let usedOriginalStack = false - if (isError(err) && err.name && err.stack && err.message) { + if (isError(err) && err.stack) { try { const frames = parseStack(err.stack!) const frame = frames[0] @@ -751,11 +751,11 @@ export default class DevServer extends Server { if (!usedOriginalStack) { if (type === 'warning') { - Log.warn(err + '') + Log.warn(err) } else if (type) { - Log.error(`${type}:`, err + '') + Log.error(`${type}:`, err) } else { - Log.error(err + '') + Log.error(err) } } } diff --git a/packages/next/server/node-web-streams-helper.ts b/packages/next/server/node-web-streams-helper.ts index 6dc7e46ce0e3c..353ccb3f70d99 100644 --- a/packages/next/server/node-web-streams-helper.ts +++ b/packages/next/server/node-web-streams-helper.ts @@ -1,5 +1,9 @@ import { nonNullable } from '../lib/non-nullable' +export type ReactReadableStream = ReadableStream & { + allReady?: Promise | undefined +} + export function readableStreamTee( readable: ReadableStream ): [ReadableStream, ReadableStream] { @@ -138,29 +142,24 @@ export function renderToInitialStream({ }: { ReactDOMServer: any element: React.ReactElement -}): Promise< - ReadableStream & { - allReady?: Promise - } -> { +}): Promise { return ReactDOMServer.renderToReadableStream(element) } -export async function continueFromInitialStream({ - suffix, - dataStream, - generateStaticHTML, - flushEffectHandler, - renderStream, -}: { - suffix?: string - dataStream?: ReadableStream - generateStaticHTML: boolean - flushEffectHandler?: () => string - renderStream: ReadableStream & { - allReady?: Promise +export async function continueFromInitialStream( + renderStream: ReactReadableStream, + { + suffix, + dataStream, + generateStaticHTML, + flushEffectHandler, + }: { + suffix?: string + dataStream?: ReadableStream + generateStaticHTML: boolean + flushEffectHandler?: () => string } -}): Promise> { +): Promise> { const closeTag = '' const suffixUnclosed = suffix ? suffix.split(closeTag)[0] : null @@ -198,12 +197,11 @@ export async function renderToStream({ flushEffectHandler?: () => string }): Promise> { const renderStream = await renderToInitialStream({ ReactDOMServer, element }) - return continueFromInitialStream({ + return continueFromInitialStream(renderStream, { suffix, dataStream, generateStaticHTML, flushEffectHandler, - renderStream, }) } diff --git a/packages/next/server/render.tsx b/packages/next/server/render.tsx index ca0b4c5111b36..fb2e9f9e3639f 100644 --- a/packages/next/server/render.tsx +++ b/packages/next/server/render.tsx @@ -20,6 +20,7 @@ import type { FontManifest } from './font-utils' import type { LoadComponentsReturnType, ManifestItem } from './load-components' import type { GetServerSideProps, GetStaticProps, PreviewData } from '../types' import type { UnwrapPromise } from '../lib/coalesced-function' +import type { ReactReadableStream } from './node-web-streams-helper' import React from 'react' import { createFromReadableStream } from 'next/dist/compiled/react-server-dom-webpack' @@ -1340,11 +1341,11 @@ export async function renderToHTML( } } - async function documentInitialProps( + async function loadDocumentInitialProps( renderShell?: ( _App: AppType, _Component: NextComponentType - ) => Promise + ) => Promise ) { const renderPage: RenderPage = ( options: ComponentsEnhancer = {} @@ -1373,11 +1374,13 @@ export async function renderToHTML( enhanceComponents(options, App, Component) if (renderShell) { - return renderShell(EnhancedApp, EnhancedComponent).then(() => { - // When using concurrent features, we don't have or need the full - // html so it's fine to return nothing here. - return { html: '', head } - }) + return renderShell(EnhancedApp, EnhancedComponent).then( + async (stream) => { + const forwardStream = readableStreamTee(stream)[1] + const html = await streamToString(forwardStream) + return { html, head } + } + ) } const html = ReactDOMServer.renderToString( @@ -1438,9 +1441,9 @@ export async function renderToHTML( if (!process.env.__NEXT_REACT_ROOT) { // Enabling react legacy rendering mode: __NEXT_REACT_ROOT = false if (Document.getInitialProps) { - const documentInitialPropsRes = await documentInitialProps() - if (documentInitialPropsRes === null) return null - const { docProps, documentCtx } = documentInitialPropsRes + const documentInitialProps = await loadDocumentInitialProps() + if (documentInitialProps === null) return null + const { docProps, documentCtx } = documentInitialProps return { bodyResult: (suffix: string) => @@ -1473,80 +1476,75 @@ export async function renderToHTML( } } else { // Enabling react concurrent rendering mode: __NEXT_REACT_ROOT = true - let renderStream: ReadableStream & { - allReady?: Promise | undefined - } - const renderShell = async ( EnhancedApp: AppType, EnhancedComponent: NextComponentType ) => { const content = renderContent(EnhancedApp, EnhancedComponent) - renderStream = await renderToInitialStream({ + return await renderToInitialStream({ ReactDOMServer, element: content, }) } - const bodyResult = async (suffix: string) => { - // this must be called inside bodyResult so appWrappers is - // up to date when `wrapApp` is called - - const flushEffectHandler = (): string => { - const allFlushEffects = [ - styledJsxFlushEffect, - ...(flushEffects || []), - ] - const flushed = ReactDOMServer.renderToString( - <> - {allFlushEffects.map((flushEffect, i) => ( - {flushEffect()} - ))} - - ) - return flushed - } + const createBodyResult = + (initialStream: ReactReadableStream) => (suffix: string) => { + // this must be called inside bodyResult so appWrappers is + // up to date when `wrapApp` is called + const flushEffectHandler = (): string => { + const allFlushEffects = [ + styledJsxFlushEffect, + ...(flushEffects || []), + ] + const flushed = ReactDOMServer.renderToString( + <> + {allFlushEffects.map((flushEffect, i) => ( + {flushEffect()} + ))} + + ) + return flushed + } - // Handle static data for server components. - async function generateStaticFlightDataIfNeeded() { - if (serverComponentsPageDataTransformStream) { - // If it's a server component with the Node.js runtime, we also - // statically generate the page data. - let data = '' - - const readable = serverComponentsPageDataTransformStream.readable - const reader = readable.getReader() - const textDecoder = new TextDecoder() - - while (true) { - const { done, value } = await reader.read() - if (done) { - break + // Handle static data for server components. + async function generateStaticFlightDataIfNeeded() { + if (serverComponentsPageDataTransformStream) { + // If it's a server component with the Node.js runtime, we also + // statically generate the page data. + let data = '' + + const readable = serverComponentsPageDataTransformStream.readable + const reader = readable.getReader() + const textDecoder = new TextDecoder() + + while (true) { + const { done, value } = await reader.read() + if (done) { + break + } + data += decodeText(value, textDecoder) } - data += decodeText(value, textDecoder) - } - ;(renderOpts as any).pageData = { - ...(renderOpts as any).pageData, - __flight__: data, + ;(renderOpts as any).pageData = { + ...(renderOpts as any).pageData, + __flight__: data, + } + return data } - return data } - } - // @TODO: A potential improvement would be to reuse the inlined - // data stream, or pass a callback inside as this doesn't need to - // be streamed. - // Do not use `await` here. - generateStaticFlightDataIfNeeded() - return await continueFromInitialStream({ - renderStream, - suffix, - dataStream: serverComponentsInlinedTransformStream?.readable, - generateStaticHTML, - flushEffectHandler, - }) - } + // @TODO: A potential improvement would be to reuse the inlined + // data stream, or pass a callback inside as this doesn't need to + // be streamed. + // Do not use `await` here. + generateStaticFlightDataIfNeeded() + return continueFromInitialStream(initialStream, { + suffix, + dataStream: serverComponentsInlinedTransformStream?.readable, + generateStaticHTML, + flushEffectHandler, + }) + } const hasDocumentGetInitialProps = !( isServerComponent || @@ -1554,16 +1552,21 @@ export async function renderToHTML( !Document.getInitialProps ) + let bodyResult: (s: string) => Promise> + // If it has getInitialProps, we will render the shell in `renderPage`. // Otherwise we do it right now. let documentInitialPropsRes: | {} - | Awaited> + | Awaited> if (hasDocumentGetInitialProps) { - documentInitialPropsRes = await documentInitialProps(renderShell) + documentInitialPropsRes = await loadDocumentInitialProps(renderShell) if (documentInitialPropsRes === null) return null + const { docProps } = documentInitialPropsRes as any + bodyResult = createBodyResult(streamFromArray([docProps.html])) } else { - await renderShell(App, Component) + const stream = await renderShell(App, Component) + bodyResult = createBodyResult(stream) documentInitialPropsRes = {} } diff --git a/packages/next/server/view-render.tsx b/packages/next/server/view-render.tsx index f304f2472ce66..68c24818978e7 100644 --- a/packages/next/server/view-render.tsx +++ b/packages/next/server/view-render.tsx @@ -19,7 +19,6 @@ import { import { FlushEffectsContext } from '../shared/lib/flush-effects' import { isDynamicRoute } from '../shared/lib/router/utils' import { tryGetPreviewData } from './api-utils/node' -import DefaultRootLayout from '../lib/views-layout' const ReactDOMServer = process.env.__NEXT_REACT_ROOT ? require('react-dom/server.browser') @@ -218,10 +217,13 @@ export async function renderToHTML( const isFlight = query.__flight__ !== undefined const flightRouterPath = isFlight ? query.__flight_router_path__ : undefined + delete query.__flight__ + delete query.__flight_router_path__ const hasConcurrentFeatures = !!runtime const pageIsDynamic = isDynamicRoute(pathname) - const components = Object.keys(ComponentMod.components) + const componentPaths = Object.keys(ComponentMod.components) + const components = componentPaths .filter((path) => { // Rendering part of the page is only allowed for flight data if (flightRouterPath) { @@ -238,6 +240,8 @@ export async function renderToHTML( return mod }) + const isSubtreeRender = components.length < componentPaths.length + // Reads of this are cached on the `req` object, so this should resolve // instantly. There's no need to pass this data down from a previous // invoke, where we'd have to consider server & serverless. @@ -247,22 +251,12 @@ export async function renderToHTML( (renderOpts as any).previewProps ) const isPreview = previewData !== false - - let WrappedComponent: any - let RootLayout: any - const dataCache = new Map() + let WrappedComponent: any for (let i = components.length - 1; i >= 0; i--) { const dataCacheKey = i.toString() const layout = components[i] - - if (i === 0) { - // top-most layout is the root layout that renders - // the html/body tags - RootLayout = layout.Component - continue - } let fetcher: any // TODO: pass a shared cache from previous getStaticProps/ @@ -313,8 +307,7 @@ export async function renderToHTML( // eslint-disable-next-line no-loop-func const lastComponent = WrappedComponent - WrappedComponent = () => { - let props: any + WrappedComponent = (props: any) => { if (fetcher) { // The data fetching was kicked off before rendering (see above) // if the data was not resolved yet the layout rendering will be suspended @@ -325,7 +318,25 @@ export async function renderToHTML( ) // Result of calling getStaticProps or getServerSideProps. If promise is not resolve yet it will suspend. const recordValue = readRecordValue(record) - props = recordValue.props + + if (props) { + props = Object.assign({}, props, recordValue.props) + } else { + props = recordValue.props + } + } + + // if this is the root layout pass children as bodyChildren prop + if (!isSubtreeRender && i === 0) { + return React.createElement(layout.Component, { + ...props, + headChildren: props.headChildren, + bodyChildren: React.createElement( + lastComponent || React.Fragment, + {}, + null + ), + }) } return React.createElement( @@ -345,14 +356,11 @@ export async function renderToHTML( // } } - // Fall back to default root layout that renders / / - if (!RootLayout) { - RootLayout = DefaultRootLayout - } - - const headChildren = buildManifest.rootMainFiles.map((src) => ( -