├── .env.local.sample ├── .github ├── CODEOWNERS ├── assets │ └── faustjs-logo.svg └── workflows │ ├── blueprint-export-diff.yml │ ├── build.yml │ └── sonar.yml ├── .gitignore ├── .nvmrc ├── DEVELOPMENT.md ├── README.md ├── acm-blueprint.zip ├── codegen.ts ├── faust.config.js ├── next-env.d.ts ├── next.config.js ├── package.json ├── possibleTypes.json ├── screenshots ├── category-page.png ├── front-page.png ├── single-page.png └── single-post.png ├── sonar-project.properties ├── src ├── __generated__ │ ├── fragment-masking.ts │ ├── gql.ts │ ├── graphql.ts │ └── index.ts ├── components │ ├── EntryHeader.tsx │ ├── FeaturedImage.tsx │ ├── Footer.tsx │ ├── Header.tsx │ └── PostListItem.tsx ├── fragments │ └── PostListFragment.ts ├── pages │ ├── [...wordpressNode].tsx │ ├── _app.tsx │ ├── api │ │ └── faust │ │ │ └── [[...route]].tsx │ ├── example.tsx │ ├── index.tsx │ └── preview.tsx ├── queries │ ├── MenuQueries.ts │ └── SiteSettingsQuery.ts ├── styles │ ├── archive.module.css │ ├── entry-header.module.css │ ├── featured-image.module.css │ ├── footer.module.css │ ├── front-page.module.css │ ├── globals.css │ ├── header.module.css │ └── post-list-item.module.css ├── types.ts └── wp-templates │ ├── archive.tsx │ ├── front-page.tsx │ ├── index.tsx │ ├── page.tsx │ └── single.tsx └── tsconfig.json /.env.local.sample: -------------------------------------------------------------------------------- 1 | # Your WordPress site URL 2 | NEXT_PUBLIC_WORDPRESS_URL=https://faustexample.wpengine.com 3 | 4 | # Plugin secret found in WordPress Settings->Headless 5 | # FAUST_SECRET_KEY=YOUR_PLUGIN_SECRET 6 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @wpengine/headless-open-source 2 | 3 | # jira:[18721] is where issues related to this repository should be ticketed 4 | -------------------------------------------------------------------------------- /.github/assets/faustjs-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.github/workflows/blueprint-export-diff.yml: -------------------------------------------------------------------------------- 1 | name: Blueprint Export Diff 2 | on: pull_request 3 | jobs: 4 | blueprint_export_diff: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | with: 9 | fetch-depth: 0 10 | - uses: actions/setup-node@v2 11 | with: 12 | node-version: "18" 13 | - name: Check for changes 14 | id: check-for-export-changes 15 | run: echo ::set-output name=check::$(git diff --name-only origin/main --exit-code -- acm-blueprint.zip) 16 | - name: Setup 17 | if: steps.check-for-export-changes.outputs.check != 0 18 | run: | 19 | wget https://github.com/wpengine/faust-scaffold/raw/main/acm-blueprint.zip -O /tmp/acm-blueprint-base.zip 20 | unzip -j /tmp/acm-blueprint-base.zip -d /tmp/acm-blueprint-base 21 | unzip -j ./acm-blueprint.zip -d /tmp/acm-blueprint-compare 22 | - name: Create Diff 23 | if: steps.check-for-export-changes.outputs.check != 0 24 | run: | 25 | diff -ry --suppress-common-lines /tmp/acm-blueprint-base/ /tmp/acm-blueprint-compare/ || true > /tmp/diff-output.txt 26 | cat /tmp/diff-output.txt 27 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: pull_request 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | strategy: 7 | matrix: 8 | node: ["18", "20"] 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: actions/setup-node@v2 12 | with: 13 | node-version: ${{ matrix.node }} 14 | - run: npm install 15 | - run: cp .env.local.sample .env.local 16 | - run: npm run build 17 | continue-on-error: FALSE 18 | -------------------------------------------------------------------------------- /.github/workflows/sonar.yml: -------------------------------------------------------------------------------- 1 | on: 2 | # Trigger analysis when pushing in main or pull requests, and when creating 3 | # a pull request. 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | types: [opened, synchronize, reopened] 9 | 10 | name: Main Workflow 11 | jobs: 12 | sonarqube: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | with: 17 | # Disabling shallow clone is recommended for improving relevancy of reporting 18 | fetch-depth: 0 19 | - name: SonarQube Scan 20 | uses: sonarsource/sonarqube-scan-action@master 21 | env: 22 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 23 | SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} 24 | - name: SonarQube Quality Gate check 25 | uses: sonarsource/sonarqube-quality-gate-action@master 26 | # Force to fail step after specific time 27 | timeout-minutes: 5 28 | env: 29 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | package-lock.json 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | 34 | # vercel 35 | .vercel 36 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/jod 2 | -------------------------------------------------------------------------------- /DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | ## Updating the ACM Blueprint Export 4 | 5 | ### Importing 6 | 7 | 1. Create a fresh site in Local or use the FakerPress plugin to wipe your current WordPress database to a fresh install. 8 | 2. Install and activate Atlas Content Modeler. 9 | 3. From the WP CLI, run `wp acm blueprint import `. You can use the GitHub RAW URL from the repo: https://github.com/wpengine/faust-scaffold/raw/main/acm-blueprint.zip 10 | 11 | This will import the ACM Blueprint export into your WordPress database. Make any modifications as necessary. 12 | 13 | ### Exporting 14 | 15 | 1. Before exporting, make sure you have deleted any of the initial content that gets created upon a WordPress install (e.g. "Sample Page", "Hello World", any comments, etc.) 16 | 2. From the WP CLI, run `wp acm blueprint export --open --wp-options=category_base,permalink_structure,nav_menu_options,theme_mods_twentytwentytwo --post-types=nav_menu_item,post,page,testimonial,project`. This will export the site into the appropriate ACM Blueprint .zip, and also open the location where the .zip was saved. It will also export the Navigational Menus and the CPTs from the ACM models. 17 | 3. Replace the existing `acm-blueprint.zip` in the repo with the newly exported `acm-blueprint.zip` and make a PR with the changes. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![Faust.js Logo](./.github/assets/faustjs-logo.svg) Faust.js Starter Kit 2 | 3 | This repository contains a starter kit to get you up and running quickly on [WP Engine's Headless Platform](https://wpengine.com/headless-wordpress/) with a WordPress site skeleton for more advanced developers. 4 | 5 | ## For more information 6 | 7 | To get started on WP Engine's Platform please follow the docs here [https://developers.wpengine.com/docs/atlas/getting-started/create-app/](https://developers.wpengine.com/docs/atlas/getting-started/create-app/) 8 | 9 | ## Project Structure 10 | 11 | ``` 12 | ├── src/ 13 | │ ├── __generated__/ 14 | │ ├── components/ 15 | │ ├── fragments/ 16 | │ ├── pages/ 17 | │ ├── queries/ 18 | │ ├── styles/ 19 | │ └── wp-templates/ 20 | ├── DEVELOPMENT.md 21 | ├── faust.config.js 22 | ├── next.config.js 23 | ├── package.json 24 | ├── possibleTypes.json 25 | └── README.md 26 | └── screenshots 27 | ``` 28 | 29 | ## Available Commands 30 | 31 | | Command | Script | Description | 32 | | --------------- | ---------------------------------------------------------------------- | ---------------------------------- | 33 | | `dev` | `npm run generate && concurrently "faust dev" "npm run watch-codegen"` | Start dev server and watch codegen | 34 | | `build` | `faust build` | Build the project for production | 35 | | `generate` | `faust generatePossibleTypes` | Generate GraphQL possible types | 36 | | `start` | `faust start` | Start the production server | 37 | | `codegen` | `graphql-codegen` | Run GraphQL code generation | 38 | | `watch-codegen` | `graphql-codegen -w` | Watch and auto-run GraphQL codegen | 39 | | `format` | `prettier . --write` | Format code with Prettier | 40 | | `test:format` | `prettier . --check` | Check code formatting | 41 | 42 | ## Screenshots 43 | 44 |
45 | View Screenshots 46 | 47 | ![Front Page](screenshots/front-page.png) 48 | 49 | ![Category Page](screenshots/category-page.png) 50 | 51 | ![Single Page](screenshots/single-page.png) 52 | 53 | ![Single Post](screenshots/single-post.png) 54 | 55 |
56 | 57 | ## Our Community 🩵 58 | 59 | At WP Engine, we have a strong community built around headless WordPress to support you with your journey. 60 | 61 | - [Discord Headless Community Channel](https://faustjs.org/discord) 62 | - [Fortnightly Headless Community Call](https://discord.gg/headless-wordpress-836253505944813629?event=1371472220592930857) 63 | - [WP Engine's Headless Platform developer community](https://wpengine.com/builders/headless) 64 | - [WP Engine`s Builders YouTube Channel](https://www.youtube.com/@WPEngineBuilders) 65 | - [WP Engine's Headless Platform](https://wpengine.com/headless-wordpress/) 66 | - [WP Engines Headless Platform Docs](https://developers.wpengine.com/docs/atlas/overview/) 67 | 68 | ## Plugin Ecosystem 🪄 69 | 70 | - [Faust.js](https://faustjs.org) 71 | - [HWP Toolkit](https://github.com/wpengine/hwptoolkit) 72 | - [WPGraphQL](https://www.wpgraphql.com) 73 | - [WPGraphQL Content Blocks](https://github.com/wpengine/wp-graphql-content-blocks) 74 | - [WPGraphQL IDE](https://github.com/wp-graphql/wpgraphql-ide) 75 | - [WP GraphQL ACF](https://github.com/wp-graphql/wp-graphql-acf) 76 | 77 | ## Documentation 🔎 78 | 79 | > [!NOTE] 80 | > We are continuously adding new docs for [Faustjs.org](https://faustjs.org/docs) 81 | 82 | - [Faust.js Documentation](https://faustjs.org/docs/) 83 | - [Headless Platform Documentation](https://wpengine.com/headless-wordpress/) 84 | - [WPGraphQL Documentation](https://developers.wpengine.com/docs/atlas/overview/) 85 | 86 | ## Contributions 87 | 88 | ## Contributor License Agreement 89 | 90 | All external contributors to WP Engine products must have a signed Contributor License Agreement (CLA) in place before the contribution may be accepted into any WP Engine codebase. 91 | 92 | 1. [Submit your name and email](https://wpeng.in/cla/) 93 | 2. 📝 Sign the CLA emailed to you 94 | 3. 📥 Receive copy of signed CLA 95 | 96 | ❤️ Thank you for helping us fulfill our legal obligations in order to continue empowering builders through headless WordPress. 97 | -------------------------------------------------------------------------------- /acm-blueprint.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpengine/faust-scaffold-ts/575ca2f9f4dfdddf84462dbd4d6a582221053c27/acm-blueprint.zip -------------------------------------------------------------------------------- /codegen.ts: -------------------------------------------------------------------------------- 1 | import { CodegenConfig } from "@graphql-codegen/cli"; 2 | 3 | const config: CodegenConfig = { 4 | schema: "https://faustexample.wpengine.com/graphql", 5 | documents: ["src/**/*.{tsx,ts}"], 6 | generates: { 7 | "./src/__generated__/": { 8 | preset: "client", 9 | plugins: [], 10 | presetConfig: { 11 | gqlTagName: "gql", 12 | }, 13 | }, 14 | }, 15 | ignoreNoDocuments: true, 16 | }; 17 | 18 | export default config; 19 | -------------------------------------------------------------------------------- /faust.config.js: -------------------------------------------------------------------------------- 1 | import { setConfig } from "@faustwp/core"; 2 | import templates from "./src/wp-templates"; 3 | import possibleTypes from "./possibleTypes.json"; 4 | 5 | /** 6 | * @type {import('@faustwp/core').FaustConfig} 7 | **/ 8 | export default setConfig({ 9 | templates, 10 | experimentalPlugins: [], 11 | possibleTypes, 12 | }); 13 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/pages/api-reference/config/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const { withFaust, getWpHostname } = require("@faustwp/core"); 2 | 3 | /** 4 | * @type {import('next').NextConfig} 5 | **/ 6 | module.exports = withFaust({ 7 | images: { 8 | domains: ["faustexample.wpengine.com"], 9 | }, 10 | trailingSlash: true, 11 | }); 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run generate && concurrently \"faust dev\" \"npm run watch-codegen\"", 5 | "build": "faust build", 6 | "generate": "faust generatePossibleTypes", 7 | "start": "faust start", 8 | "codegen": "graphql-codegen", 9 | "watch-codegen": "graphql-codegen -w", 10 | "format": "prettier . --write", 11 | "test:format": "prettier . --check" 12 | }, 13 | "dependencies": { 14 | "@apollo/client": "^3.13.8", 15 | "@faustwp/cli": "^3.2.3", 16 | "@faustwp/core": "^3.2.3", 17 | "graphql": "^16.10.0", 18 | "next": "^15.3.1", 19 | "prettier": "^3.5.3", 20 | "react": "^19.1.0", 21 | "react-dom": "^19.1.0" 22 | }, 23 | "devDependencies": { 24 | "@graphql-codegen/cli": "^5.0.5", 25 | "@graphql-codegen/client-preset": "^4.8.0", 26 | "@parcel/watcher": "^2.5.1", 27 | "@types/node": "^22.15.2", 28 | "@types/react": "^19.1.2", 29 | "concurrently": "^9.1.2", 30 | "typescript": "^5.8.3" 31 | }, 32 | "resolutions": { 33 | "babel/runtime": "7.27.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /possibleTypes.json: -------------------------------------------------------------------------------- 1 | {"CategoryConnection":["RootQueryToCategoryConnection","CategoryToAncestorsCategoryConnection","CategoryToCategoryConnection","PostToCategoryConnection"],"Connection":["RootQueryToCategoryConnection","TermNodeToEnqueuedScriptConnection","TermNodeToEnqueuedStylesheetConnection","CategoryToAncestorsCategoryConnection","CategoryToCategoryConnection","CategoryToContentNodeConnection","ContentTypeToTaxonomyConnection","TaxonomyToContentTypeConnection","TaxonomyToTermNodeConnection","ContentTypeToContentNodeConnection","UserToCommentConnection","CommentToCommentConnection","UserToEnqueuedScriptConnection","UserToEnqueuedStylesheetConnection","UserToMediaItemConnection","HierarchicalContentNodeToContentNodeAncestorsConnection","HierarchicalContentNodeToContentNodeChildrenConnection","ContentNodeToEnqueuedScriptConnection","ContentNodeToEnqueuedStylesheetConnection","MediaItemToCommentConnection","UserToPageConnection","PageToCommentConnection","PageToRevisionConnection","UserToPostConnection","PostToPostConnection","PostToCategoryConnection","PostToCommentConnection","PostToPostFormatConnection","PostFormatToContentNodeConnection","PostFormatToPostConnection","PostToRevisionConnection","PostToTagConnection","TagToContentNodeConnection","TagToPostConnection","PostToTermNodeConnection","UserToRevisionsConnection","UserToUserRoleConnection","CategoryToPostConnection","RootQueryToCommentConnection","RootQueryToContentNodeConnection","RootQueryToContentTypeConnection","GraphqlDocumentToGraphqlDocumentConnection","GraphqlDocumentToGraphqlDocumentGroupConnection","GraphqlDocumentGroupToContentNodeConnection","GraphqlDocumentGroupToGraphqlDocumentConnection","GraphqlDocumentToTermNodeConnection","RootQueryToGraphqlDocumentGroupConnection","RootQueryToGraphqlDocumentConnection","RootQueryToMediaItemConnection","MenuToMenuItemConnection","MenuItemToMenuItemConnection","RootQueryToMenuItemConnection","RootQueryToMenuConnection","RootQueryToPageConnection","RootQueryToPluginConnection","RootQueryToPostFormatConnection","RootQueryToPostConnection","RootQueryToEnqueuedScriptConnection","RootQueryToEnqueuedStylesheetConnection","RootQueryToRevisionsConnection","RootQueryToTagConnection","RootQueryToTaxonomyConnection","RootQueryToTermNodeConnection","RootQueryToThemeConnection","RootQueryToUserRoleConnection","RootQueryToUserConnection"],"Edge":["TermNodeToEnqueuedScriptConnectionEdge","TermNodeToEnqueuedStylesheetConnectionEdge","CategoryToAncestorsCategoryConnectionEdge","CategoryToCategoryConnectionEdge","ContentNodeToContentTypeConnectionEdge","TaxonomyToContentTypeConnectionEdge","TaxonomyToTermNodeConnectionEdge","ContentTypeToTaxonomyConnectionEdge","ContentTypeToContentNodeConnectionEdge","ContentNodeToEditLockConnectionEdge","CommentToCommenterConnectionEdge","CommentToContentNodeConnectionEdge","CommentToParentCommentConnectionEdge","CommentToCommentConnectionEdge","UserToCommentConnectionEdge","UserToEnqueuedScriptConnectionEdge","UserToEnqueuedStylesheetConnectionEdge","NodeWithAuthorToUserConnectionEdge","HierarchicalContentNodeToContentNodeAncestorsConnectionEdge","HierarchicalContentNodeToContentNodeChildrenConnectionEdge","ContentNodeToEnqueuedScriptConnectionEdge","ContentNodeToEnqueuedStylesheetConnectionEdge","ContentNodeToEditLastConnectionEdge","HierarchicalContentNodeToParentContentNodeConnectionEdge","MediaItemToCommentConnectionEdge","UserToMediaItemConnectionEdge","NodeWithFeaturedImageToMediaItemConnectionEdge","NodeWithRevisionsToContentNodeConnectionEdge","PageToCommentConnectionEdge","PageToPreviewConnectionEdge","PageToRevisionConnectionEdge","UserToPageConnectionEdge","PostToPostConnectionEdge","PostToCategoryConnectionEdge","PostToCommentConnectionEdge","PostToParentConnectionEdge","PostFormatToContentNodeConnectionEdge","PostFormatToPostConnectionEdge","PostFormatToTaxonomyConnectionEdge","PostToPostFormatConnectionEdge","PostToPreviewConnectionEdge","PostToRevisionConnectionEdge","TagToContentNodeConnectionEdge","TagToPostConnectionEdge","TagToTaxonomyConnectionEdge","PostToTagConnectionEdge","PostToTermNodeConnectionEdge","UserToPostConnectionEdge","UserToRevisionsConnectionEdge","UserToUserRoleConnectionEdge","CategoryToContentNodeConnectionEdge","CategoryToParentCategoryConnectionEdge","CategoryToPostConnectionEdge","CategoryToTaxonomyConnectionEdge","RootQueryToCategoryConnectionEdge","RootQueryToCommentConnectionEdge","RootQueryToContentNodeConnectionEdge","RootQueryToContentTypeConnectionEdge","GraphqlDocumentToGraphqlDocumentConnectionEdge","GraphqlDocumentGroupToContentNodeConnectionEdge","GraphqlDocumentGroupToGraphqlDocumentConnectionEdge","GraphqlDocumentGroupToTaxonomyConnectionEdge","GraphqlDocumentToGraphqlDocumentGroupConnectionEdge","GraphqlDocumentToParentConnectionEdge","GraphqlDocumentToPreviewConnectionEdge","GraphqlDocumentToTermNodeConnectionEdge","RootQueryToGraphqlDocumentGroupConnectionEdge","RootQueryToGraphqlDocumentConnectionEdge","RootQueryToMediaItemConnectionEdge","MenuItemToMenuItemConnectionEdge","MenuItemToMenuItemLinkableConnectionEdge","MenuItemToMenuConnectionEdge","MenuToMenuItemConnectionEdge","RootQueryToMenuItemConnectionEdge","RootQueryToMenuConnectionEdge","RootQueryToPageConnectionEdge","RootQueryToPluginConnectionEdge","RootQueryToPostFormatConnectionEdge","RootQueryToPostConnectionEdge","RootQueryToEnqueuedScriptConnectionEdge","RootQueryToEnqueuedStylesheetConnectionEdge","RootQueryToRevisionsConnectionEdge","RootQueryToTagConnectionEdge","RootQueryToTaxonomyConnectionEdge","RootQueryToTermNodeConnectionEdge","RootQueryToThemeConnectionEdge","RootQueryToUserRoleConnectionEdge","RootQueryToUserConnectionEdge"],"Node":["Category","EnqueuedScript","EnqueuedStylesheet","ContentType","Taxonomy","User","Comment","MediaItem","Page","Post","PostFormat","Tag","UserRole","GraphqlDocument","GraphqlDocumentGroup","Menu","MenuItem","Plugin","Theme","CommentAuthor"],"PageInfo":["TermNodeToEnqueuedScriptConnectionPageInfo","TermNodeToEnqueuedStylesheetConnectionPageInfo","CategoryToAncestorsCategoryConnectionPageInfo","CategoryToCategoryConnectionPageInfo","TaxonomyToContentTypeConnectionPageInfo","TaxonomyToTermNodeConnectionPageInfo","ContentTypeToTaxonomyConnectionPageInfo","ContentTypeToContentNodeConnectionPageInfo","CommentToCommentConnectionPageInfo","UserToCommentConnectionPageInfo","UserToEnqueuedScriptConnectionPageInfo","UserToEnqueuedStylesheetConnectionPageInfo","HierarchicalContentNodeToContentNodeAncestorsConnectionPageInfo","HierarchicalContentNodeToContentNodeChildrenConnectionPageInfo","ContentNodeToEnqueuedScriptConnectionPageInfo","ContentNodeToEnqueuedStylesheetConnectionPageInfo","MediaItemToCommentConnectionPageInfo","UserToMediaItemConnectionPageInfo","PageToCommentConnectionPageInfo","PageToRevisionConnectionPageInfo","UserToPageConnectionPageInfo","PostToPostConnectionPageInfo","PostToCategoryConnectionPageInfo","PostToCommentConnectionPageInfo","PostFormatToContentNodeConnectionPageInfo","PostFormatToPostConnectionPageInfo","PostToPostFormatConnectionPageInfo","PostToRevisionConnectionPageInfo","TagToContentNodeConnectionPageInfo","TagToPostConnectionPageInfo","PostToTagConnectionPageInfo","PostToTermNodeConnectionPageInfo","UserToPostConnectionPageInfo","UserToRevisionsConnectionPageInfo","UserToUserRoleConnectionPageInfo","CategoryToContentNodeConnectionPageInfo","CategoryToPostConnectionPageInfo","RootQueryToCategoryConnectionPageInfo","RootQueryToCommentConnectionPageInfo","RootQueryToContentNodeConnectionPageInfo","RootQueryToContentTypeConnectionPageInfo","GraphqlDocumentToGraphqlDocumentConnectionPageInfo","GraphqlDocumentGroupToContentNodeConnectionPageInfo","GraphqlDocumentGroupToGraphqlDocumentConnectionPageInfo","GraphqlDocumentToGraphqlDocumentGroupConnectionPageInfo","GraphqlDocumentToTermNodeConnectionPageInfo","RootQueryToGraphqlDocumentGroupConnectionPageInfo","RootQueryToGraphqlDocumentConnectionPageInfo","RootQueryToMediaItemConnectionPageInfo","MenuItemToMenuItemConnectionPageInfo","MenuToMenuItemConnectionPageInfo","RootQueryToMenuItemConnectionPageInfo","RootQueryToMenuConnectionPageInfo","RootQueryToPageConnectionPageInfo","RootQueryToPluginConnectionPageInfo","RootQueryToPostFormatConnectionPageInfo","RootQueryToPostConnectionPageInfo","RootQueryToEnqueuedScriptConnectionPageInfo","RootQueryToEnqueuedStylesheetConnectionPageInfo","RootQueryToRevisionsConnectionPageInfo","RootQueryToTagConnectionPageInfo","RootQueryToTaxonomyConnectionPageInfo","RootQueryToTermNodeConnectionPageInfo","RootQueryToThemeConnectionPageInfo","RootQueryToUserRoleConnectionPageInfo","RootQueryToUserConnectionPageInfo"],"CategoryConnectionEdge":["CategoryToAncestorsCategoryConnectionEdge","CategoryToCategoryConnectionEdge","PostToCategoryConnectionEdge","CategoryToParentCategoryConnectionEdge","RootQueryToCategoryConnectionEdge"],"TermNode":["Category","PostFormat","Tag","GraphqlDocumentGroup"],"UniformResourceIdentifiable":["Category","ContentType","User","Comment","MediaItem","Page","Post","PostFormat","Tag","GraphqlDocument","GraphqlDocumentGroup"],"EnqueuedScriptConnection":["TermNodeToEnqueuedScriptConnection","UserToEnqueuedScriptConnection","ContentNodeToEnqueuedScriptConnection","RootQueryToEnqueuedScriptConnection"],"EnqueuedScriptConnectionEdge":["TermNodeToEnqueuedScriptConnectionEdge","UserToEnqueuedScriptConnectionEdge","ContentNodeToEnqueuedScriptConnectionEdge","RootQueryToEnqueuedScriptConnectionEdge"],"EnqueuedAsset":["EnqueuedScript","EnqueuedStylesheet"],"EnqueuedScriptConnectionPageInfo":["TermNodeToEnqueuedScriptConnectionPageInfo","UserToEnqueuedScriptConnectionPageInfo","ContentNodeToEnqueuedScriptConnectionPageInfo","RootQueryToEnqueuedScriptConnectionPageInfo"],"WPPageInfo":["TermNodeToEnqueuedScriptConnectionPageInfo","TermNodeToEnqueuedStylesheetConnectionPageInfo","CategoryToAncestorsCategoryConnectionPageInfo","CategoryToCategoryConnectionPageInfo","TaxonomyToContentTypeConnectionPageInfo","TaxonomyToTermNodeConnectionPageInfo","ContentTypeToTaxonomyConnectionPageInfo","ContentTypeToContentNodeConnectionPageInfo","CommentToCommentConnectionPageInfo","UserToCommentConnectionPageInfo","UserToEnqueuedScriptConnectionPageInfo","UserToEnqueuedStylesheetConnectionPageInfo","HierarchicalContentNodeToContentNodeAncestorsConnectionPageInfo","HierarchicalContentNodeToContentNodeChildrenConnectionPageInfo","ContentNodeToEnqueuedScriptConnectionPageInfo","ContentNodeToEnqueuedStylesheetConnectionPageInfo","MediaItemToCommentConnectionPageInfo","UserToMediaItemConnectionPageInfo","PageToCommentConnectionPageInfo","PageToRevisionConnectionPageInfo","UserToPageConnectionPageInfo","PostToPostConnectionPageInfo","PostToCategoryConnectionPageInfo","PostToCommentConnectionPageInfo","PostFormatToContentNodeConnectionPageInfo","PostFormatToPostConnectionPageInfo","PostToPostFormatConnectionPageInfo","PostToRevisionConnectionPageInfo","TagToContentNodeConnectionPageInfo","TagToPostConnectionPageInfo","PostToTagConnectionPageInfo","PostToTermNodeConnectionPageInfo","UserToPostConnectionPageInfo","UserToRevisionsConnectionPageInfo","UserToUserRoleConnectionPageInfo","CategoryToContentNodeConnectionPageInfo","CategoryToPostConnectionPageInfo","RootQueryToCategoryConnectionPageInfo","RootQueryToCommentConnectionPageInfo","RootQueryToContentNodeConnectionPageInfo","RootQueryToContentTypeConnectionPageInfo","GraphqlDocumentToGraphqlDocumentConnectionPageInfo","GraphqlDocumentGroupToContentNodeConnectionPageInfo","GraphqlDocumentGroupToGraphqlDocumentConnectionPageInfo","GraphqlDocumentToGraphqlDocumentGroupConnectionPageInfo","GraphqlDocumentToTermNodeConnectionPageInfo","RootQueryToGraphqlDocumentGroupConnectionPageInfo","RootQueryToGraphqlDocumentConnectionPageInfo","RootQueryToMediaItemConnectionPageInfo","MenuItemToMenuItemConnectionPageInfo","MenuToMenuItemConnectionPageInfo","RootQueryToMenuItemConnectionPageInfo","RootQueryToMenuConnectionPageInfo","RootQueryToPageConnectionPageInfo","RootQueryToPluginConnectionPageInfo","RootQueryToPostFormatConnectionPageInfo","RootQueryToPostConnectionPageInfo","RootQueryToEnqueuedScriptConnectionPageInfo","RootQueryToEnqueuedStylesheetConnectionPageInfo","RootQueryToRevisionsConnectionPageInfo","RootQueryToTagConnectionPageInfo","RootQueryToTaxonomyConnectionPageInfo","RootQueryToTermNodeConnectionPageInfo","RootQueryToThemeConnectionPageInfo","RootQueryToUserRoleConnectionPageInfo","RootQueryToUserConnectionPageInfo"],"EnqueuedStylesheetConnection":["TermNodeToEnqueuedStylesheetConnection","UserToEnqueuedStylesheetConnection","ContentNodeToEnqueuedStylesheetConnection","RootQueryToEnqueuedStylesheetConnection"],"EnqueuedStylesheetConnectionEdge":["TermNodeToEnqueuedStylesheetConnectionEdge","UserToEnqueuedStylesheetConnectionEdge","ContentNodeToEnqueuedStylesheetConnectionEdge","RootQueryToEnqueuedStylesheetConnectionEdge"],"EnqueuedStylesheetConnectionPageInfo":["TermNodeToEnqueuedStylesheetConnectionPageInfo","UserToEnqueuedStylesheetConnectionPageInfo","ContentNodeToEnqueuedStylesheetConnectionPageInfo","RootQueryToEnqueuedStylesheetConnectionPageInfo"],"DatabaseIdentifier":["Category","User","Comment","MediaItem","Page","Post","PostFormat","Tag","GraphqlDocument","GraphqlDocumentGroup","Menu","MenuItem","CommentAuthor"],"HierarchicalTermNode":["Category"],"HierarchicalNode":["Category","MediaItem","Page"],"MenuItemLinkable":["Category","Page","Post","Tag"],"CategoryConnectionPageInfo":["CategoryToAncestorsCategoryConnectionPageInfo","CategoryToCategoryConnectionPageInfo","PostToCategoryConnectionPageInfo","RootQueryToCategoryConnectionPageInfo"],"ContentNodeConnection":["CategoryToContentNodeConnection","ContentTypeToContentNodeConnection","HierarchicalContentNodeToContentNodeAncestorsConnection","HierarchicalContentNodeToContentNodeChildrenConnection","PostFormatToContentNodeConnection","TagToContentNodeConnection","UserToRevisionsConnection","RootQueryToContentNodeConnection","GraphqlDocumentGroupToContentNodeConnection","RootQueryToRevisionsConnection"],"ContentNodeConnectionEdge":["ContentTypeToContentNodeConnectionEdge","CommentToContentNodeConnectionEdge","HierarchicalContentNodeToContentNodeAncestorsConnectionEdge","HierarchicalContentNodeToContentNodeChildrenConnectionEdge","HierarchicalContentNodeToParentContentNodeConnectionEdge","NodeWithRevisionsToContentNodeConnectionEdge","PostFormatToContentNodeConnectionEdge","TagToContentNodeConnectionEdge","UserToRevisionsConnectionEdge","CategoryToContentNodeConnectionEdge","RootQueryToContentNodeConnectionEdge","GraphqlDocumentGroupToContentNodeConnectionEdge","RootQueryToRevisionsConnectionEdge"],"ContentNode":["MediaItem","Page","Post","GraphqlDocument"],"OneToOneConnection":["ContentNodeToContentTypeConnectionEdge","ContentNodeToEditLockConnectionEdge","CommentToCommenterConnectionEdge","CommentToContentNodeConnectionEdge","CommentToParentCommentConnectionEdge","NodeWithAuthorToUserConnectionEdge","ContentNodeToEditLastConnectionEdge","HierarchicalContentNodeToParentContentNodeConnectionEdge","NodeWithFeaturedImageToMediaItemConnectionEdge","NodeWithRevisionsToContentNodeConnectionEdge","PageToPreviewConnectionEdge","PostToParentConnectionEdge","PostFormatToTaxonomyConnectionEdge","PostToPreviewConnectionEdge","TagToTaxonomyConnectionEdge","CategoryToParentCategoryConnectionEdge","CategoryToTaxonomyConnectionEdge","GraphqlDocumentGroupToTaxonomyConnectionEdge","GraphqlDocumentToParentConnectionEdge","GraphqlDocumentToPreviewConnectionEdge","MenuItemToMenuItemLinkableConnectionEdge","MenuItemToMenuConnectionEdge"],"ContentTypeConnectionEdge":["ContentNodeToContentTypeConnectionEdge","TaxonomyToContentTypeConnectionEdge","RootQueryToContentTypeConnectionEdge"],"TaxonomyConnection":["ContentTypeToTaxonomyConnection","RootQueryToTaxonomyConnection"],"TaxonomyConnectionEdge":["ContentTypeToTaxonomyConnectionEdge","PostFormatToTaxonomyConnectionEdge","TagToTaxonomyConnectionEdge","CategoryToTaxonomyConnectionEdge","GraphqlDocumentGroupToTaxonomyConnectionEdge","RootQueryToTaxonomyConnectionEdge"],"ContentTypeConnection":["TaxonomyToContentTypeConnection","RootQueryToContentTypeConnection"],"ContentTypeConnectionPageInfo":["TaxonomyToContentTypeConnectionPageInfo","RootQueryToContentTypeConnectionPageInfo"],"TermNodeConnection":["TaxonomyToTermNodeConnection","PostToTermNodeConnection","GraphqlDocumentToTermNodeConnection","RootQueryToTermNodeConnection"],"TermNodeConnectionEdge":["TaxonomyToTermNodeConnectionEdge","PostToTermNodeConnectionEdge","GraphqlDocumentToTermNodeConnectionEdge","RootQueryToTermNodeConnectionEdge"],"TermNodeConnectionPageInfo":["TaxonomyToTermNodeConnectionPageInfo","PostToTermNodeConnectionPageInfo","GraphqlDocumentToTermNodeConnectionPageInfo","RootQueryToTermNodeConnectionPageInfo"],"TaxonomyConnectionPageInfo":["ContentTypeToTaxonomyConnectionPageInfo","RootQueryToTaxonomyConnectionPageInfo"],"ContentNodeConnectionPageInfo":["ContentTypeToContentNodeConnectionPageInfo","HierarchicalContentNodeToContentNodeAncestorsConnectionPageInfo","HierarchicalContentNodeToContentNodeChildrenConnectionPageInfo","PostFormatToContentNodeConnectionPageInfo","TagToContentNodeConnectionPageInfo","UserToRevisionsConnectionPageInfo","CategoryToContentNodeConnectionPageInfo","RootQueryToContentNodeConnectionPageInfo","GraphqlDocumentGroupToContentNodeConnectionPageInfo","RootQueryToRevisionsConnectionPageInfo"],"UserConnectionEdge":["ContentNodeToEditLockConnectionEdge","NodeWithAuthorToUserConnectionEdge","ContentNodeToEditLastConnectionEdge","RootQueryToUserConnectionEdge"],"Commenter":["User","CommentAuthor"],"CommentConnection":["UserToCommentConnection","CommentToCommentConnection","MediaItemToCommentConnection","PageToCommentConnection","PostToCommentConnection","RootQueryToCommentConnection"],"CommentConnectionEdge":["CommentToParentCommentConnectionEdge","CommentToCommentConnectionEdge","UserToCommentConnectionEdge","MediaItemToCommentConnectionEdge","PageToCommentConnectionEdge","PostToCommentConnectionEdge","RootQueryToCommentConnectionEdge"],"CommenterConnectionEdge":["CommentToCommenterConnectionEdge"],"CommentConnectionPageInfo":["CommentToCommentConnectionPageInfo","UserToCommentConnectionPageInfo","MediaItemToCommentConnectionPageInfo","PageToCommentConnectionPageInfo","PostToCommentConnectionPageInfo","RootQueryToCommentConnectionPageInfo"],"MediaItemConnection":["UserToMediaItemConnection","RootQueryToMediaItemConnection"],"MediaItemConnectionEdge":["UserToMediaItemConnectionEdge","NodeWithFeaturedImageToMediaItemConnectionEdge","RootQueryToMediaItemConnectionEdge"],"NodeWithTemplate":["MediaItem","Page","Post","GraphqlDocument"],"ContentTemplate":["DefaultTemplate","Template_Blank","Template_BlogAlternative"],"NodeWithTitle":["MediaItem","Page","Post","GraphqlDocument"],"NodeWithAuthor":["MediaItem","Page","Post"],"NodeWithComments":["MediaItem","Page","Post"],"HierarchicalContentNode":["MediaItem","Page"],"MediaItemConnectionPageInfo":["UserToMediaItemConnectionPageInfo","RootQueryToMediaItemConnectionPageInfo"],"PageConnection":["UserToPageConnection","PageToRevisionConnection","RootQueryToPageConnection"],"PageConnectionEdge":["PageToPreviewConnectionEdge","PageToRevisionConnectionEdge","UserToPageConnectionEdge","RootQueryToPageConnectionEdge"],"Previewable":["Page","Post"],"NodeWithContentEditor":["Page","Post","GraphqlDocument"],"NodeWithFeaturedImage":["Page","Post"],"NodeWithRevisions":["Page","Post"],"NodeWithPageAttributes":["Page"],"PageConnectionPageInfo":["PageToRevisionConnectionPageInfo","UserToPageConnectionPageInfo","RootQueryToPageConnectionPageInfo"],"PostConnection":["UserToPostConnection","PostToPostConnection","PostFormatToPostConnection","PostToRevisionConnection","TagToPostConnection","CategoryToPostConnection","RootQueryToPostConnection"],"PostConnectionEdge":["PostToPostConnectionEdge","PostToParentConnectionEdge","PostFormatToPostConnectionEdge","PostToPreviewConnectionEdge","PostToRevisionConnectionEdge","TagToPostConnectionEdge","UserToPostConnectionEdge","CategoryToPostConnectionEdge","RootQueryToPostConnectionEdge"],"NodeWithExcerpt":["Post"],"NodeWithTrackbacks":["Post"],"PostConnectionPageInfo":["PostToPostConnectionPageInfo","PostFormatToPostConnectionPageInfo","PostToRevisionConnectionPageInfo","TagToPostConnectionPageInfo","UserToPostConnectionPageInfo","CategoryToPostConnectionPageInfo","RootQueryToPostConnectionPageInfo"],"PostFormatConnection":["PostToPostFormatConnection","RootQueryToPostFormatConnection"],"PostFormatConnectionEdge":["PostToPostFormatConnectionEdge","RootQueryToPostFormatConnectionEdge"],"PostFormatConnectionPageInfo":["PostToPostFormatConnectionPageInfo","RootQueryToPostFormatConnectionPageInfo"],"TagConnection":["PostToTagConnection","RootQueryToTagConnection"],"TagConnectionEdge":["PostToTagConnectionEdge","RootQueryToTagConnectionEdge"],"TagConnectionPageInfo":["PostToTagConnectionPageInfo","RootQueryToTagConnectionPageInfo"],"UserRoleConnection":["UserToUserRoleConnection","RootQueryToUserRoleConnection"],"UserRoleConnectionEdge":["UserToUserRoleConnectionEdge","RootQueryToUserRoleConnectionEdge"],"UserRoleConnectionPageInfo":["UserToUserRoleConnectionPageInfo","RootQueryToUserRoleConnectionPageInfo"],"GraphqlDocumentConnection":["GraphqlDocumentToGraphqlDocumentConnection","GraphqlDocumentGroupToGraphqlDocumentConnection","RootQueryToGraphqlDocumentConnection"],"GraphqlDocumentConnectionEdge":["GraphqlDocumentToGraphqlDocumentConnectionEdge","GraphqlDocumentGroupToGraphqlDocumentConnectionEdge","GraphqlDocumentToParentConnectionEdge","GraphqlDocumentToPreviewConnectionEdge","RootQueryToGraphqlDocumentConnectionEdge"],"GraphqlDocumentConnectionPageInfo":["GraphqlDocumentToGraphqlDocumentConnectionPageInfo","GraphqlDocumentGroupToGraphqlDocumentConnectionPageInfo","RootQueryToGraphqlDocumentConnectionPageInfo"],"GraphqlDocumentGroupConnection":["GraphqlDocumentToGraphqlDocumentGroupConnection","RootQueryToGraphqlDocumentGroupConnection"],"GraphqlDocumentGroupConnectionEdge":["GraphqlDocumentToGraphqlDocumentGroupConnectionEdge","RootQueryToGraphqlDocumentGroupConnectionEdge"],"GraphqlDocumentGroupConnectionPageInfo":["GraphqlDocumentToGraphqlDocumentGroupConnectionPageInfo","RootQueryToGraphqlDocumentGroupConnectionPageInfo"],"MenuItemConnection":["MenuToMenuItemConnection","MenuItemToMenuItemConnection","RootQueryToMenuItemConnection"],"MenuItemConnectionEdge":["MenuItemToMenuItemConnectionEdge","MenuToMenuItemConnectionEdge","RootQueryToMenuItemConnectionEdge"],"MenuItemConnectionPageInfo":["MenuItemToMenuItemConnectionPageInfo","MenuToMenuItemConnectionPageInfo","RootQueryToMenuItemConnectionPageInfo"],"MenuItemLinkableConnectionEdge":["MenuItemToMenuItemLinkableConnectionEdge"],"MenuItemObjectUnion":["Post","Page","Category","Tag"],"MenuConnectionEdge":["MenuItemToMenuConnectionEdge","RootQueryToMenuConnectionEdge"],"MenuConnection":["RootQueryToMenuConnection"],"MenuConnectionPageInfo":["RootQueryToMenuConnectionPageInfo"],"PluginConnection":["RootQueryToPluginConnection"],"PluginConnectionEdge":["RootQueryToPluginConnectionEdge"],"PluginConnectionPageInfo":["RootQueryToPluginConnectionPageInfo"],"ThemeConnection":["RootQueryToThemeConnection"],"ThemeConnectionEdge":["RootQueryToThemeConnectionEdge"],"ThemeConnectionPageInfo":["RootQueryToThemeConnectionPageInfo"],"UserConnection":["RootQueryToUserConnection"],"UserConnectionPageInfo":["RootQueryToUserConnectionPageInfo"]} -------------------------------------------------------------------------------- /screenshots/category-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpengine/faust-scaffold-ts/575ca2f9f4dfdddf84462dbd4d6a582221053c27/screenshots/category-page.png -------------------------------------------------------------------------------- /screenshots/front-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpengine/faust-scaffold-ts/575ca2f9f4dfdddf84462dbd4d6a582221053c27/screenshots/front-page.png -------------------------------------------------------------------------------- /screenshots/single-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpengine/faust-scaffold-ts/575ca2f9f4dfdddf84462dbd4d6a582221053c27/screenshots/single-page.png -------------------------------------------------------------------------------- /screenshots/single-post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpengine/faust-scaffold-ts/575ca2f9f4dfdddf84462dbd4d6a582221053c27/screenshots/single-post.png -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=faust-scaffold-ts 2 | 3 | # relative paths to source directories. More details and properties are described 4 | # in https://docs.sonarqube.org/latest/project-administration/narrowing-the-focus/ 5 | sonar.sources=. 6 | -------------------------------------------------------------------------------- /src/__generated__/fragment-masking.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core'; 3 | import { FragmentDefinitionNode } from 'graphql'; 4 | import { Incremental } from './graphql'; 5 | 6 | 7 | export type FragmentType> = TDocumentType extends DocumentTypeDecoration< 8 | infer TType, 9 | any 10 | > 11 | ? [TType] extends [{ ' $fragmentName'?: infer TKey }] 12 | ? TKey extends string 13 | ? { ' $fragmentRefs'?: { [key in TKey]: TType } } 14 | : never 15 | : never 16 | : never; 17 | 18 | // return non-nullable if `fragmentType` is non-nullable 19 | export function useFragment( 20 | _documentNode: DocumentTypeDecoration, 21 | fragmentType: FragmentType> 22 | ): TType; 23 | // return nullable if `fragmentType` is undefined 24 | export function useFragment( 25 | _documentNode: DocumentTypeDecoration, 26 | fragmentType: FragmentType> | undefined 27 | ): TType | undefined; 28 | // return nullable if `fragmentType` is nullable 29 | export function useFragment( 30 | _documentNode: DocumentTypeDecoration, 31 | fragmentType: FragmentType> | null 32 | ): TType | null; 33 | // return nullable if `fragmentType` is nullable or undefined 34 | export function useFragment( 35 | _documentNode: DocumentTypeDecoration, 36 | fragmentType: FragmentType> | null | undefined 37 | ): TType | null | undefined; 38 | // return array of non-nullable if `fragmentType` is array of non-nullable 39 | export function useFragment( 40 | _documentNode: DocumentTypeDecoration, 41 | fragmentType: Array>> 42 | ): Array; 43 | // return array of nullable if `fragmentType` is array of nullable 44 | export function useFragment( 45 | _documentNode: DocumentTypeDecoration, 46 | fragmentType: Array>> | null | undefined 47 | ): Array | null | undefined; 48 | // return readonly array of non-nullable if `fragmentType` is array of non-nullable 49 | export function useFragment( 50 | _documentNode: DocumentTypeDecoration, 51 | fragmentType: ReadonlyArray>> 52 | ): ReadonlyArray; 53 | // return readonly array of nullable if `fragmentType` is array of nullable 54 | export function useFragment( 55 | _documentNode: DocumentTypeDecoration, 56 | fragmentType: ReadonlyArray>> | null | undefined 57 | ): ReadonlyArray | null | undefined; 58 | export function useFragment( 59 | _documentNode: DocumentTypeDecoration, 60 | fragmentType: FragmentType> | Array>> | ReadonlyArray>> | null | undefined 61 | ): TType | Array | ReadonlyArray | null | undefined { 62 | return fragmentType as any; 63 | } 64 | 65 | 66 | export function makeFragmentData< 67 | F extends DocumentTypeDecoration, 68 | FT extends ResultOf 69 | >(data: FT, _fragment: F): FragmentType { 70 | return data as FragmentType; 71 | } 72 | export function isFragmentReady( 73 | queryNode: DocumentTypeDecoration, 74 | fragmentNode: TypedDocumentNode, 75 | data: FragmentType, any>> | null | undefined 76 | ): data is FragmentType { 77 | const deferredFields = (queryNode as { __meta__?: { deferredFields: Record } }).__meta__ 78 | ?.deferredFields; 79 | 80 | if (!deferredFields) return true; 81 | 82 | const fragDef = fragmentNode.definitions[0] as FragmentDefinitionNode | undefined; 83 | const fragName = fragDef?.name?.value; 84 | 85 | const fields = (fragName && deferredFields[fragName]) || []; 86 | return fields.length > 0 && fields.every(field => data && field in data); 87 | } 88 | -------------------------------------------------------------------------------- /src/__generated__/gql.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import * as types from './graphql'; 3 | import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; 4 | 5 | /** 6 | * Map of all GraphQL operations in the project. 7 | * 8 | * This map has several performance disadvantages: 9 | * 1. It is not tree-shakeable, so it will include all operations in the project. 10 | * 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle. 11 | * 3. It does not support dead code elimination, so it will add unused operations. 12 | * 13 | * Therefore it is highly recommended to use the babel or swc plugin for production. 14 | * Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size 15 | */ 16 | type Documents = { 17 | "\n fragment HeaderGeneralSettingsFragment on GeneralSettings {\n title\n description\n }\n ": typeof types.HeaderGeneralSettingsFragmentFragmentDoc, 18 | "\n fragment PrimaryMenuItemFragment on MenuItem {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n ": typeof types.PrimaryMenuItemFragmentFragmentDoc, 19 | "\n fragment PostListFragment on Post {\n id\n title\n uri\n excerpt\n date\n featuredImage {\n node {\n sourceUrl\n altText\n }\n }\n author {\n node {\n name\n avatar {\n url\n }\n }\n }\n }\n": typeof types.PostListFragmentFragmentDoc, 20 | "\n query GetExamplePage {\n generalSettings {\n title\n description\n }\n primaryMenuItems: menuItems(where: { location: PRIMARY }) {\n nodes {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n }\n }\n": typeof types.GetExamplePageDocument, 21 | "\n query GetHeaderMenu {\n primaryMenuItems: menuItems(where: { location: PRIMARY }) {\n nodes {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n }\n }\n": typeof types.GetHeaderMenuDocument, 22 | "\n query GetSiteData {\n generalSettings {\n title\n description\n }\n }\n": typeof types.GetSiteDataDocument, 23 | "\n \n query GetArchive($uri: String!, $first: Int!, $after: String) {\n nodeByUri(uri: $uri) {\n archiveType: __typename\n ... on Category {\n name\n posts(first: $first, after: $after) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ...PostListFragment\n }\n }\n }\n ... on Tag {\n name\n posts(first: $first, after: $after) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ...PostListFragment\n }\n }\n }\n }\n }\n": typeof types.GetArchiveDocument, 24 | "\n query GetPage($databaseId: ID!, $asPreview: Boolean = false) {\n page(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {\n title\n content\n }\n }\n": typeof types.GetPageDocument, 25 | "\n query GetPost($databaseId: ID!, $asPreview: Boolean = false) {\n post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {\n title\n content\n date\n author {\n node {\n name\n }\n }\n }\n }\n": typeof types.GetPostDocument, 26 | }; 27 | const documents: Documents = { 28 | "\n fragment HeaderGeneralSettingsFragment on GeneralSettings {\n title\n description\n }\n ": types.HeaderGeneralSettingsFragmentFragmentDoc, 29 | "\n fragment PrimaryMenuItemFragment on MenuItem {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n ": types.PrimaryMenuItemFragmentFragmentDoc, 30 | "\n fragment PostListFragment on Post {\n id\n title\n uri\n excerpt\n date\n featuredImage {\n node {\n sourceUrl\n altText\n }\n }\n author {\n node {\n name\n avatar {\n url\n }\n }\n }\n }\n": types.PostListFragmentFragmentDoc, 31 | "\n query GetExamplePage {\n generalSettings {\n title\n description\n }\n primaryMenuItems: menuItems(where: { location: PRIMARY }) {\n nodes {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n }\n }\n": types.GetExamplePageDocument, 32 | "\n query GetHeaderMenu {\n primaryMenuItems: menuItems(where: { location: PRIMARY }) {\n nodes {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n }\n }\n": types.GetHeaderMenuDocument, 33 | "\n query GetSiteData {\n generalSettings {\n title\n description\n }\n }\n": types.GetSiteDataDocument, 34 | "\n \n query GetArchive($uri: String!, $first: Int!, $after: String) {\n nodeByUri(uri: $uri) {\n archiveType: __typename\n ... on Category {\n name\n posts(first: $first, after: $after) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ...PostListFragment\n }\n }\n }\n ... on Tag {\n name\n posts(first: $first, after: $after) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ...PostListFragment\n }\n }\n }\n }\n }\n": types.GetArchiveDocument, 35 | "\n query GetPage($databaseId: ID!, $asPreview: Boolean = false) {\n page(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {\n title\n content\n }\n }\n": types.GetPageDocument, 36 | "\n query GetPost($databaseId: ID!, $asPreview: Boolean = false) {\n post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {\n title\n content\n date\n author {\n node {\n name\n }\n }\n }\n }\n": types.GetPostDocument, 37 | }; 38 | 39 | /** 40 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 41 | * 42 | * 43 | * @example 44 | * ```ts 45 | * const query = gql(`query GetUser($id: ID!) { user(id: $id) { name } }`); 46 | * ``` 47 | * 48 | * The query argument is unknown! 49 | * Please regenerate the types. 50 | */ 51 | export function gql(source: string): unknown; 52 | 53 | /** 54 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 55 | */ 56 | export function gql(source: "\n fragment HeaderGeneralSettingsFragment on GeneralSettings {\n title\n description\n }\n "): (typeof documents)["\n fragment HeaderGeneralSettingsFragment on GeneralSettings {\n title\n description\n }\n "]; 57 | /** 58 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 59 | */ 60 | export function gql(source: "\n fragment PrimaryMenuItemFragment on MenuItem {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n "): (typeof documents)["\n fragment PrimaryMenuItemFragment on MenuItem {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n "]; 61 | /** 62 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 63 | */ 64 | export function gql(source: "\n fragment PostListFragment on Post {\n id\n title\n uri\n excerpt\n date\n featuredImage {\n node {\n sourceUrl\n altText\n }\n }\n author {\n node {\n name\n avatar {\n url\n }\n }\n }\n }\n"): (typeof documents)["\n fragment PostListFragment on Post {\n id\n title\n uri\n excerpt\n date\n featuredImage {\n node {\n sourceUrl\n altText\n }\n }\n author {\n node {\n name\n avatar {\n url\n }\n }\n }\n }\n"]; 65 | /** 66 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 67 | */ 68 | export function gql(source: "\n query GetExamplePage {\n generalSettings {\n title\n description\n }\n primaryMenuItems: menuItems(where: { location: PRIMARY }) {\n nodes {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query GetExamplePage {\n generalSettings {\n title\n description\n }\n primaryMenuItems: menuItems(where: { location: PRIMARY }) {\n nodes {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n }\n }\n"]; 69 | /** 70 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 71 | */ 72 | export function gql(source: "\n query GetHeaderMenu {\n primaryMenuItems: menuItems(where: { location: PRIMARY }) {\n nodes {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query GetHeaderMenu {\n primaryMenuItems: menuItems(where: { location: PRIMARY }) {\n nodes {\n id\n uri\n path\n label\n parentId\n cssClasses\n menu {\n node {\n name\n }\n }\n }\n }\n }\n"]; 73 | /** 74 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 75 | */ 76 | export function gql(source: "\n query GetSiteData {\n generalSettings {\n title\n description\n }\n }\n"): (typeof documents)["\n query GetSiteData {\n generalSettings {\n title\n description\n }\n }\n"]; 77 | /** 78 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 79 | */ 80 | export function gql(source: "\n \n query GetArchive($uri: String!, $first: Int!, $after: String) {\n nodeByUri(uri: $uri) {\n archiveType: __typename\n ... on Category {\n name\n posts(first: $first, after: $after) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ...PostListFragment\n }\n }\n }\n ... on Tag {\n name\n posts(first: $first, after: $after) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ...PostListFragment\n }\n }\n }\n }\n }\n"): (typeof documents)["\n \n query GetArchive($uri: String!, $first: Int!, $after: String) {\n nodeByUri(uri: $uri) {\n archiveType: __typename\n ... on Category {\n name\n posts(first: $first, after: $after) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ...PostListFragment\n }\n }\n }\n ... on Tag {\n name\n posts(first: $first, after: $after) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ...PostListFragment\n }\n }\n }\n }\n }\n"]; 81 | /** 82 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 83 | */ 84 | export function gql(source: "\n query GetPage($databaseId: ID!, $asPreview: Boolean = false) {\n page(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {\n title\n content\n }\n }\n"): (typeof documents)["\n query GetPage($databaseId: ID!, $asPreview: Boolean = false) {\n page(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {\n title\n content\n }\n }\n"]; 85 | /** 86 | * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. 87 | */ 88 | export function gql(source: "\n query GetPost($databaseId: ID!, $asPreview: Boolean = false) {\n post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {\n title\n content\n date\n author {\n node {\n name\n }\n }\n }\n }\n"): (typeof documents)["\n query GetPost($databaseId: ID!, $asPreview: Boolean = false) {\n post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {\n title\n content\n date\n author {\n node {\n name\n }\n }\n }\n }\n"]; 89 | 90 | export function gql(source: string) { 91 | return (documents as any)[source] ?? {}; 92 | } 93 | 94 | export type DocumentType> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never; -------------------------------------------------------------------------------- /src/__generated__/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./fragment-masking"; 2 | export * from "./gql"; -------------------------------------------------------------------------------- /src/components/EntryHeader.tsx: -------------------------------------------------------------------------------- 1 | import style from "../styles/entry-header.module.css"; 2 | 3 | type EntryHeaderProps = { 4 | title: string; 5 | date?: Date | string; 6 | author?: string; 7 | }; 8 | 9 | export default function EntryHeader({ title, date, author }: EntryHeaderProps) { 10 | return ( 11 |
12 | {title &&

{title}

} 13 | 14 | {date && author && ( 15 |
16 | By {author} on 17 |
18 | )} 19 |
20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /src/components/FeaturedImage.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import Image from "next/image"; 3 | import styles from "../styles/featured-image.module.css"; 4 | import { Post } from "../__generated__/graphql"; 5 | 6 | interface FeaturedImageProps { 7 | post: Partial; 8 | classNames?: string; 9 | uri?: string | null; 10 | title?: string; 11 | } 12 | 13 | export function FeaturedImage({ 14 | post, 15 | classNames = "h-48 my-9 relative", 16 | uri = null, 17 | title = "", 18 | }: FeaturedImageProps) { 19 | if (!post.featuredImage?.node?.sourceUrl) { 20 | return ""; 21 | } 22 | 23 | return ( 24 |
25 | {typeof uri === "string" && uri.trim() !== "" ? ( 26 | 27 | {post.featuredImage.node.altText 34 | 35 | ) : ( 36 | {post.featuredImage.node.altText 43 | )} 44 |
45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /src/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import styles from "../styles/footer.module.css"; 2 | 3 | export default function Footer() { 4 | return ( 5 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/components/Header.tsx: -------------------------------------------------------------------------------- 1 | import { gql } from "../__generated__"; 2 | import Link from "next/link"; 3 | import style from "../styles/header.module.css"; 4 | import { 5 | HeaderGeneralSettingsFragmentFragment, 6 | PrimaryMenuItemFragmentFragment, 7 | } from "../__generated__/graphql"; 8 | 9 | type HeaderProps = { 10 | siteTitle: HeaderGeneralSettingsFragmentFragment["title"]; 11 | siteDescription: HeaderGeneralSettingsFragmentFragment["description"]; 12 | menuItems: PrimaryMenuItemFragmentFragment[]; 13 | }; 14 | 15 | export default function Header({ 16 | siteTitle, 17 | siteDescription, 18 | menuItems, 19 | }: HeaderProps) { 20 | return ( 21 |
22 |
23 | 24 |

{siteTitle}

25 |

{siteDescription}

26 | 27 | 28 | 37 |
38 |
39 | ); 40 | } 41 | 42 | Header.fragments = { 43 | generalSettingsFragment: gql(` 44 | fragment HeaderGeneralSettingsFragment on GeneralSettings { 45 | title 46 | description 47 | } 48 | `), 49 | menuItemFragment: gql(` 50 | fragment PrimaryMenuItemFragment on MenuItem { 51 | id 52 | uri 53 | path 54 | label 55 | parentId 56 | cssClasses 57 | menu { 58 | node { 59 | name 60 | } 61 | } 62 | } 63 | `), 64 | }; 65 | -------------------------------------------------------------------------------- /src/components/PostListItem.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { FeaturedImage } from "./FeaturedImage"; 3 | import styles from "../styles/post-list-item.module.css"; 4 | import { Post } from "../__generated__/graphql"; 5 | 6 | interface PostListItemProps { 7 | post: Partial; 8 | } 9 | 10 | export default function PostListItem({ post }: PostListItemProps) { 11 | const { title, excerpt, uri, date } = post; 12 | 13 | return ( 14 |
15 | 22 | 23 |

24 | 25 | {title} 26 | 27 |

28 | 29 | {post.author?.node && ( 30 |
31 | by {post.author.node.name} 32 |
33 | )} 34 | 35 | 41 | 42 |
46 | 47 | 48 | Read more 49 | 50 |
51 | ); 52 | } 53 | -------------------------------------------------------------------------------- /src/fragments/PostListFragment.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "@apollo/client"; 2 | 3 | export const POST_LIST_FRAGMENT = gql` 4 | fragment PostListFragment on Post { 5 | id 6 | title 7 | uri 8 | excerpt 9 | date 10 | featuredImage { 11 | node { 12 | sourceUrl 13 | altText 14 | } 15 | } 16 | author { 17 | node { 18 | name 19 | avatar { 20 | url 21 | } 22 | } 23 | } 24 | } 25 | `; 26 | -------------------------------------------------------------------------------- /src/pages/[...wordpressNode].tsx: -------------------------------------------------------------------------------- 1 | import { getWordPressProps, WordPressTemplate } from "@faustwp/core"; 2 | import { GetStaticPaths, GetStaticProps } from "next"; 3 | import { WordPressTemplateProps } from "../types"; 4 | 5 | export default function Page(props: WordPressTemplateProps) { 6 | return ; 7 | } 8 | 9 | export const getStaticProps: GetStaticProps = (ctx) => { 10 | return getWordPressProps({ ctx }); 11 | }; 12 | 13 | export const getStaticPaths: GetStaticPaths = () => { 14 | return { 15 | paths: [], 16 | fallback: "blocking", 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import "../../faust.config"; 2 | import React from "react"; 3 | import { useRouter } from "next/router"; 4 | import { FaustProvider } from "@faustwp/core"; 5 | import "../styles/globals.css"; 6 | import { AppProps } from "next/app"; 7 | 8 | export default function MyApp({ Component, pageProps }: AppProps) { 9 | const router = useRouter(); 10 | 11 | return ( 12 | 13 | 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/api/faust/[[...route]].tsx: -------------------------------------------------------------------------------- 1 | import "../../../../faust.config"; 2 | import { apiRouter } from "@faustwp/core"; 3 | 4 | export default apiRouter; 5 | -------------------------------------------------------------------------------- /src/pages/example.tsx: -------------------------------------------------------------------------------- 1 | import { gql } from "../__generated__"; 2 | import { useQuery } from "@apollo/client"; 3 | import Head from "next/head"; 4 | import Header from "../components/Header"; 5 | import EntryHeader from "../components/EntryHeader"; 6 | import Footer from "../components/Footer"; 7 | import { getNextStaticProps } from "@faustwp/core"; 8 | import { GetStaticPropsContext } from "next"; 9 | 10 | /** 11 | * Next.js file based page example with Faust helpers. 12 | */ 13 | export default function Page() { 14 | const { data } = useQuery(Page.query); 15 | 16 | const { title: siteTitle, description: siteDescription } = 17 | data.generalSettings; 18 | const menuItems = data.primaryMenuItems.nodes; 19 | 20 | return ( 21 | <> 22 | 23 | {siteTitle} 24 | 25 | 26 |
31 | 32 |
33 | 34 |

Next.js pages are still supported!

35 |
36 | 37 |