diff --git a/.changeset/config.json b/.changeset/config.json
index 7545ab65f..4e897c6f7 100644
--- a/.changeset/config.json
+++ b/.changeset/config.json
@@ -3,7 +3,6 @@
"changelog": "@changesets/cli/changelog",
"commit": false,
"linked": [
- ["@faustjs/core", "@faustjs/next", "@faustjs/react"],
["@faustwp/core", "@faustwp/cli"]
],
"privatePackages": {
@@ -14,10 +13,7 @@
"baseBranch": "canary",
"updateInternalDependencies": "patch",
"ignore": [
- "@faustjs/next-headless-getting-started",
- "@faustwp/getting-started-example",
- "@faustwp/app-router-example",
- "@faustwp/block-support-example"
+ "@faustwp/getting-started-example"
],
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"onlyUpdatePeerDependentsWhenOutOfRange": true
diff --git a/.changeset/tasty-walls-thank.md b/.changeset/tasty-walls-thank.md
new file mode 100644
index 000000000..a988baa93
--- /dev/null
+++ b/.changeset/tasty-walls-thank.md
@@ -0,0 +1,5 @@
+---
+'@faustwp/wordpress-plugin': minor
+---
+
+Added new filter `faustwp_public_redirect_status_code`, allowing WordPress plugins and themes to choose the [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) to use when generating redirects when the [enable public route redirects](https://faustjs.org/docs/faustwp/settings#enabling-public-route-redirects) setting is active.
diff --git a/.changeset/three-singers-roll.md b/.changeset/three-singers-roll.md
new file mode 100644
index 000000000..579cf86e7
--- /dev/null
+++ b/.changeset/three-singers-roll.md
@@ -0,0 +1,39 @@
+---
+'@faustwp/experimental-app-router': minor
+---
+
+---
+
+## '@faustwp/experimental-app-router': minor
+
+Update @faustwp/experimental-app-router to account for next 15 changes to cookies and update NextResponse import
+
+Notable changes:
+
+- Adding await to all cookies requests as per Next documentation: https://nextjs.org/docs/app/api-reference/functions/cookies
+
+```
+import { cookies } from 'next/headers'
+
+export default async function Page() {
+ const cookieStore = await cookies()
+ const theme = cookieStore.get('theme')
+ return '...'
+}
+```
+
+- Files changed:
+
+ - packages/experimental-app-router/src/server-actions/logoutAction.ts
+ - packages/experimental-app-router/src/server-actions/utils/setRefreshToken.ts
+ - packages/experimental-app-router/src/server/auth/fetchTokens.ts
+ - packages/experimental-app-router/src/server/routeHandler/tokenHandler.ts
+
+- Updated Next App Router example to use latest next version and React 19 RC.
+- Updated Example Login form using React 19s useActionState
+- Updated Awaiting of params for Next 15
+- Files Changed:
+ - examples/next/app-router/app/login/page.tsx
+ - examples/next/app-router/package.json
+ - examples/next/app-router/[slug]hasPreviewProps.ts (made async)
+ - examples/next/app-router/[slug]page.tsx
diff --git a/.eslintrc.js b/.eslintrc.js
index 52572114f..17b03ce28 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -31,6 +31,10 @@ module.exports = {
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
'@typescript-eslint/unbound-method': 0,
'@typescript-eslint/no-explicit-any': 0,
+ '@typescript-eslint/no-unsafe-call': 0,
+ '@typescript-eslint/no-unsafe-return': 0,
+ '@typescript-eslint/no-unsafe-argument': 0,
+ '@typescript-eslint/restrict-template-expressions': 0,
'no-void': 0,
'import/named': 0,
'import/no-extraneous-dependencies': [
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index d5712a4c0..375657b8c 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,4 +1,4 @@
# Code Owners
-* @wpengine/merlin
+* @wpengine/headless-open-source
-# jira:[18721] is where issues related to this repository should be ticketed
\ No newline at end of file
+# jira:[18721] is where issues related to this repository should be ticketed
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 14457190f..000000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-name: '🐛 Bug Report'
-about: Create a report to help us improve
-title: 'Bug: '
-labels: 'Status: Unconfirmed'
----
-
-
-
-## Environment
-- `@faustwp/core` version:
-- `@faustwp/cli` version:
-- `@faustwp/blocks` version:
-- `@faustwp/block-editor-utils` version:
-- WordPress version:
-- Browser, OS, and other relevant software versions:
-
-## Description
-
-
-## Steps to Reproduce
-
-
-## Expected vs. Actual Behavior
-
-
-## Reproducible Demo
-
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 000000000..23eb208c7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,66 @@
+name: Bug report
+description: Report a bug in Faust
+body:
+ - type: markdown
+ attributes:
+ value: >-
+ Thank you for taking the time to report a possible bug!
+
+ Please remember, a bug report is _not the place to ask questions_. You can
+ use [Discord](https://discord.gg/J2khkF9XYK) for that, or start a topic in [GitHub
+ Discussions](https://github.com/wpengine/faustjs/discussions).
+ - type: textarea
+ attributes:
+ label: Description
+ description: >-
+ Please write a brief description of the bug, including what you expected and what actually happened.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Steps to reproduce
+ description: >-
+ Please list all the steps needed to reproduce the bug in an *isolated* way (e.g. a clonable GitHub repository, or a Faust.js snippet that works on a clean environment ).
+ placeholder: >-
+ 1. Clone the `faustwp-getting-started` example project
+ 2. Navigate to the `wp-templates/single.js` Faust template
+ 3. Result show X but should be Y
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Additional context
+ description: >-
+ Add any other context about the problem here, such as screenshots, error logs, etc.
+ - type: input
+ attributes:
+ label: "@faustwp/core Version"
+ validations:
+ required: true
+ - type: input
+ attributes:
+ label: "@faustwp/cli Version"
+ validations:
+ required: true
+ - type: input
+ attributes:
+ label: FaustWP Plugin Version
+ validations:
+ required: true
+ - type: input
+ attributes:
+ label: WordPress Version
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Additional environment details
+ description: Additional Faust.js packages and their versions (@faustwp/blocks, @faustwp/experimental-app-router, etc), PHP version, Hosting Platform, etc.
+ - type: checkboxes
+ attributes:
+ label: Please confirm that you have searched existing issues in the repo.
+ description: >-
+ You can do this by searching https://github.com/wpengine/faustjs/issues.
+ options:
+ - label: 'Yes'
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..ffbfea418
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,8 @@
+blank_issues_enabled: false
+contact_links:
+ - name: General Help Request
+ url: https://github.com/wpengine/faustjs/discussions
+ about: For general questions and help requests, create a new topic in GitHub Discussions
+ - name: Headless WordPress Discord Community
+ url: https://discord.gg/J2khkF9XYK
+ about: Ask questions, discuss features, and meet new people in the Headless WordPress Discord community
diff --git a/.github/actions/release-plugin/action.yml b/.github/actions/release-plugin/action.yml
index 8655a8c68..4bb0fd7c3 100644
--- a/.github/actions/release-plugin/action.yml
+++ b/.github/actions/release-plugin/action.yml
@@ -1,22 +1,41 @@
-name: 'WordPress Plugin Deploy'
-description: 'Deploy to the WordPress Plugin Repository'
-author: '10up'
+name: 'Plugin Deploy'
+description: 'Upload zip file to releases tab'
branding:
icon: 'upload-cloud'
color: 'blue'
-inputs:
- generate-zip:
- description: 'Generate package zip file?'
- default: false
+
outputs:
zip-path:
description: 'Path to zip file'
- value: ${{ steps.deploy.outputs.zip-path }}
+ value: ${{ steps.zip.outputs.zip-path }}
+
runs:
using: 'composite'
steps:
- - id: deploy
- env:
- INPUT_GENERATE_ZIP: ${{ inputs.generate-zip }}
- run: ${{ github.action_path }}/deploy.sh
+ - id: prepare
+ name: Prepare Environment
+ run: |
+ sudo apt-get update && sudo apt-get install zip rsync -y
+ - id: zip
+ name: Zip Plugin (optional)
+ run: |
+ # Create dist folder and copy files while excluding .distignore items
+ mkdir -p dist
+ rsync -av --exclude-from="${{ env.PLUGIN_DIR }}/.distignore" ${{ env.PLUGIN_DIR }}/ dist/${{ env.SLUG }}
+
+ # Zip the plugin directory
+ zip_file="faustwp-${{ env.VERSION }}.zip"
+ zip -r $zip_file dist/${{ env.SLUG }}
+
+ # Save zip path to output
+ echo "::set-output name=zip-path::$PWD/$zip_file"
shell: bash
+
+ - id: upload
+ name: Upload Zip File to Release
+ uses: softprops/action-gh-release@v2
+ with:
+ repo_token: ${{ secrets.GITHUB_TOKEN }}
+ files: ${{ steps.zip.outputs.zip-path }} # Updated to use zip-path output
+ asset_name: faustwp-${{ env.VERSION }}.zip # Set asset name to the correct versioned name
+ overwrite: true
\ No newline at end of file
diff --git a/.github/actions/release-plugin/deploy.sh b/.github/actions/release-plugin/deploy.sh
deleted file mode 100755
index bff08c7d2..000000000
--- a/.github/actions/release-plugin/deploy.sh
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/bin/bash
-
-# Note that this does not use pipefail
-# because if the grep later doesn't match any deleted files,
-# which is likely the majority case,
-# it does not exit with a 0, and I only care about the final exit.
-set -eo
-
-# Ensure SVN username and password are set
-# IMPORTANT: while secrets are encrypted and not viewable in the GitHub UI,
-# they are by necessity provided as plaintext in the context of the Action,
-# so do not echo or use debug mode unless you want your secrets exposed!
-if [[ -z "$SVN_USERNAME" ]]; then
- echo "Set the SVN_USERNAME secret"
- exit 1
-fi
-
-if [[ -z "$SVN_PASSWORD" ]]; then
- echo "Set the SVN_PASSWORD secret"
- exit 1
-fi
-
-# Require the PLUGIN_DIR environment variable to be set
-if [[ -z "$PLUGIN_DIR" ]]; then
- echo "Set the PLUGIN_DIR environment variable"
- exit 1
-fi
-echo "ℹ︎ PLUGIN_DIR is $PLUGIN_DIR"
-
-# Allow some ENV variables to be customized
-if [[ -z "$SLUG" ]]; then
- SLUG=${GITHUB_REPOSITORY#*/}
-fi
-echo "ℹ︎ SLUG is $SLUG"
-
-# Does it even make sense for VERSION to be editable in a workflow definition?
-if [[ -z "$VERSION" ]]; then
- VERSION="${GITHUB_REF#refs/tags/}"
- VERSION="${VERSION#@faustwp/wordpress-plugin@}" # Strip the @faustwp/wordpress-plugin@ prefix from the version
-fi
-echo "ℹ︎ VERSION is $VERSION"
-
-if [[ -z "$ASSETS_DIR" ]]; then
- ASSETS_DIR=".wordpress-org"
-fi
-echo "ℹ︎ ASSETS_DIR is $ASSETS_DIR"
-
-SVN_URL="https://plugins.svn.wordpress.org/${SLUG}/"
-SVN_DIR="${HOME}/svn-${SLUG}"
-
-# Checkout just trunk and assets for efficiency
-# Tagging will be handled on the SVN level
-echo "➤ Checking out .org repository..."
-svn checkout --depth immediates "$SVN_URL" "$SVN_DIR"
-cd "$SVN_DIR"
-svn update --set-depth infinity assets
-svn update --set-depth infinity trunk
-
-echo "➤ Copying files..."
-if [[ -e "$GITHUB_WORKSPACE/$PLUGIN_DIR/.distignore" ]]; then
- echo "ℹ︎ Using .distignore"
- # Copy from PLUGIN_DIR to /trunk, excluding dotorg assets
- # The --delete flag will delete anything in destination that no longer exists in source
- rsync -rc --exclude-from="$GITHUB_WORKSPACE/$PLUGIN_DIR/.distignore" "$GITHUB_WORKSPACE/$PLUGIN_DIR/" trunk/ --delete --delete-excluded
-else
- rsync -rc "$GITHUB_WORKSPACE/$PLUGIN_DIR/" trunk --delete --delete-excluded
-fi
-
-# Copy dotorg assets to /assets
-if [[ -d "$GITHUB_WORKSPACE/$PLUGIN_DIR/$ASSETS_DIR/" ]]; then
- rsync -rc "$GITHUB_WORKSPACE/$PLUGIN_DIR/$ASSETS_DIR/" assets/ --delete
-else
- echo "ℹ︎ No assets directory found; skipping asset copy"
-fi
-
-# Add everything and commit to SVN
-# The force flag ensures we recurse into subdirectories even if they are already added
-# Suppress stdout in favor of svn status later for readability
-echo "➤ Preparing files..."
-svn add . --force > /dev/null
-
-# SVN delete all deleted files
-# Also suppress stdout here
-svn status | grep '^\!' | sed 's/! *//' | xargs -I% svn rm %@ > /dev/null
-
-# Copy tag locally to make this a single commit
-echo "➤ Copying tag..."
-svn cp "trunk" "tags/$VERSION"
-
-# Fix screenshots getting force downloaded when clicking them
-# https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/
-svn propset svn:mime-type image/png assets/*.png || true
-svn propset svn:mime-type image/jpeg assets/*.jpg || true
-
-svn status
-
-echo "➤ Committing files..."
-svn commit -m "Update to version $VERSION from GitHub" --no-auth-cache --non-interactive --username "$SVN_USERNAME" --password "$SVN_PASSWORD"
-
-if $INPUT_GENERATE_ZIP; then
- echo "Generating zip file..."
- cd "$SVN_DIR/trunk" || exit
- zip -r "${GITHUB_WORKSPACE}/${PLUGIN_DIR}/${SLUG}.zip" .
- echo "::set-output name=zip-path::${GITHUB_WORKSPACE}/${PLUGIN_DIR}/${SLUG}.zip"
- echo "✓ Zip file generated!"
-fi
-
-echo "✓ Plugin deployed!"
diff --git a/.github/workflows/audit-dependencies.yml b/.github/workflows/audit-dependencies.yml
deleted file mode 100644
index 9682d5af1..000000000
--- a/.github/workflows/audit-dependencies.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: Audit Dependencies
-
-on: pull_request
-
-jobs:
- audit_dependencies:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- - name: Audit for vulnerabilities
- run: npx audit-ci@^6 --config ./audit-ci.jsonc
diff --git a/.github/workflows/build-legacy-docs.yml b/.github/workflows/build-legacy-docs.yml
deleted file mode 100644
index 22924f369..000000000
--- a/.github/workflows/build-legacy-docs.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: Build Legacy Docs Site
-
-on:
- pull_request:
- paths:
- - 'internal/legacy.faustjs.org/**'
-
-jobs:
- build_legacy_docs:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: ./internal/legacy.faustjs.org
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
- with:
- node-version: '18'
- - run: npm ci
- - run: npm run build
diff --git a/.github/workflows/e2e-next-example.yml b/.github/workflows/e2e-next-example.yml
deleted file mode 100644
index 80ad47c0d..000000000
--- a/.github/workflows/e2e-next-example.yml
+++ /dev/null
@@ -1,73 +0,0 @@
-name: E2E Test
-
-on:
- pull_request:
- paths-ignore:
- - '**/*.md'
-
-jobs:
- e2e-test-next-getting-started-example:
- name: (legacy) Next Getting Started Example on Node ${{ matrix.node }}
- runs-on: ubuntu-latest
- env:
- PR_REPO: ${{github.event.pull_request.head.repo.full_name}}
- PR_BRANCH: ${{github.event.pull_request.head.ref}}
- strategy:
- matrix:
- node: ['16', '18', '20']
- defaults:
- run:
- working-directory: ./
- steps:
- - name: checkout
- uses: actions/checkout@v3
- - name: setup node
- uses: actions/setup-node@v3
- with:
- node-version: ${{ matrix.node }}
- # Get the PR branch so we can pull the correct Next.js example path
- - name: echo current pr branch name
- run: |
- echo $PR_BRANCH
- # Get the PR repo so we can pull the correct Next.js example path
- - name: echo current pr repo
- run: |
- echo $PR_REPO
- # Install the Faust.js Next getting started example via npx create next app
- # and use the PR branch to pull the correct example URL
- - name: npx create next app
- run: |
- npx create-next-app@13 \
- -e https://github.com/${PR_REPO}/tree/${PR_BRANCH} \
- --example-path examples/next/getting-started \
- --use-npm \
- e2e-app
- - name: install and build packages
- working-directory: ./
- run: |
- npm ci
- npm run build
- # To ensure PR changes are tested accurately, we replace the
- # faust node_modules downloaded from NPM with the faust packages
- # built in the previous step
- # TODO: It would be nice to use symlink or npm link here, but upon
- # writing this they do not function as expected on GH actions
- - name: replace downloaded registry faust packages with local build
- run: |
- rm -rf e2e-app/node_modules/@faustjs/core
- rm -rf e2e-app/node_modules/@faustjs/next
- cp -r packages/core e2e-app/node_modules/@faustjs/core
- cp -r packages/next e2e-app/node_modules/@faustjs/next
- - name: copy env
- working-directory: e2e-app
- run: |
- cp .env.local.sample .env.local
- # Generate the schema to ensure no type collisions
- - name: Generate Schema
- working-directory: e2e-app
- run: |
- npm run generate
- - name: Build
- working-directory: e2e-app
- run: |
- npm run build
diff --git a/.github/workflows/e2e-next-faustwp-example.yml b/.github/workflows/e2e-next-faustwp-example.yml
index 4aed8b02e..8d868a283 100644
--- a/.github/workflows/e2e-next-faustwp-example.yml
+++ b/.github/workflows/e2e-next-faustwp-example.yml
@@ -1,4 +1,4 @@
-name: E2E Test
+name: E2E Test Packages
on:
pull_request:
@@ -6,23 +6,23 @@ on:
- '**/*.md'
jobs:
- e2e-test-next-getting-started-example:
+ e2e-test-faustwp-getting-started-example:
name: (faustwp) Next Getting Started Example on Node ${{ matrix.node }}
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
env:
PR_REPO: ${{github.event.pull_request.head.repo.full_name}}
PR_BRANCH: ${{github.event.pull_request.head.ref}}
strategy:
matrix:
- node: ['16', '18', '20']
+ node: ['18', '20', '22']
defaults:
run:
working-directory: ./
steps:
- name: checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: setup node
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
# Get the PR branch so we can pull the correct Next.js example path
diff --git a/.github/workflows/e2e-nightly-build.yml b/.github/workflows/e2e-nightly-build.yml
index 0f2bfc59f..8483c42fa 100644
--- a/.github/workflows/e2e-nightly-build.yml
+++ b/.github/workflows/e2e-nightly-build.yml
@@ -1,4 +1,4 @@
-name: E2E Nightly Test
+name: E2E Test Packages (Nightly)
on:
workflow_run:
@@ -9,19 +9,19 @@ on:
jobs:
e2e-nightly-test:
name: E2E app on Node ${{ matrix.node }}
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
strategy:
matrix:
- node: ['16', '18', '20']
+ node: ['18', '20', '22']
defaults:
run:
working-directory: ./
steps:
- name: checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: setup node
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
diff --git a/.github/workflows/e2e-test-plugin.yml b/.github/workflows/e2e-test-plugin.yml
deleted file mode 100644
index 69ecb7bd3..000000000
--- a/.github/workflows/e2e-test-plugin.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-name: E2E Test Plugin
-
-on:
- pull_request:
- paths-ignore:
- - '**/*.md'
-
-jobs:
- e2e_test_plugin:
- timeout-minutes: 10
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v3
- - name: Setup Node
- uses: actions/setup-node@v3
- with:
- node-version: '16'
- - name: Install NPM Deps
- run: |
- npm ci
- npm run build
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: '8.1'
- coverage: pcov
- ini-values: pcov.directory=includes
- - name: Setup Frontend
- run: |
- NEXT_PUBLIC_WORDPRESS_URL=http://localhost:8080 FAUSTWP_SECRET_KEY=00000000-0000-4000-8000-000000000001 npm run dev:next:getting-started &
- - name: Composer install
- working-directory: plugins/faustwp
- run: composer install --prefer-dist --no-progress --no-interaction --no-suggest
- - name: Setup Containers
- working-directory: plugins/faustwp
- run: docker-compose up -d
- - name: Sleep 15 seconds
- run: sleep 15
- - name: Maybe upgrade WP DB
- working-directory: plugins/faustwp
- run: docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) wp core update-db --allow-root
- - name: Init Testing Environment
- working-directory: plugins/faustwp
- run: docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) init-testing-environment.sh
- - name: Install WP GraphQL
- working-directory: plugins/faustwp
- run: |
- docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) wp plugin install wp-graphql --activate --allow-root
- - name: Setup testing data
- working-directory: plugins/faustwp
- run: |
- docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) wp db export tests/_data/dump.sql --allow-root
- - name: Copy env file
- working-directory: plugins/faustwp
- run: cp .env.testing.example .env.testing
- - name: Run Acceptance tests
- working-directory: plugins/faustwp
- run: vendor/bin/codecept run acceptance
- - name: Run API tests
- working-directory: plugins/faustwp
- run: vendor/bin/codecept run api
- - name: Upload Test Output
- uses: actions/upload-artifact@v2
- if: failure()
- with:
- name: failed-test-output
- path: ${{ github.workspace }}/plugins/faustwp/tests/_output
diff --git a/.github/workflows/experimental-app-router.yml b/.github/workflows/experimental-app-router.yml
index ae3a7dfc5..e94876808 100644
--- a/.github/workflows/experimental-app-router.yml
+++ b/.github/workflows/experimental-app-router.yml
@@ -8,16 +8,16 @@ jobs:
name: "Build and Test Experimental App Router on Node.js ${{ matrix.node }} ${{ matrix.os }}"
strategy:
matrix:
- os: ['ubuntu-latest']
- node: ['18', '20']
+ os: ['ubuntu-22.04']
+ node: ['18', '20', '22']
permissions:
checks: write
pull-requests: write
runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node }}
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
diff --git a/.github/workflows/lint-packages.yml b/.github/workflows/lint-packages.yml
index 6da241597..390c1526d 100644
--- a/.github/workflows/lint-packages.yml
+++ b/.github/workflows/lint-packages.yml
@@ -7,12 +7,12 @@ on:
jobs:
lint_packages:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
with:
- node-version: '16'
+ node-version: '18'
- run: npm ci
- run: npm run build
- run: npm run lint
diff --git a/.github/workflows/lint-plugin.yml b/.github/workflows/lint-plugin.yml
index 1b7857705..78bc0bca3 100644
--- a/.github/workflows/lint-plugin.yml
+++ b/.github/workflows/lint-plugin.yml
@@ -7,10 +7,10 @@ on:
jobs:
lint_plugin:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
diff --git a/.github/workflows/nextjs-bundle-analysis.yml b/.github/workflows/nextjs-bundle-analysis.yml
index a22ef403a..3a43bc6fe 100644
--- a/.github/workflows/nextjs-bundle-analysis.yml
+++ b/.github/workflows/nextjs-bundle-analysis.yml
@@ -7,6 +7,8 @@ name: 'Next.js Bundle Analysis'
on:
pull_request:
+ branches-ignore:
+ - 'main'
push:
branches:
- 'canary'
@@ -25,12 +27,12 @@ jobs:
'examples/next/faustwp-getting-started',
]
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Install Node.js
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: 18
@@ -63,7 +65,7 @@ jobs:
npm pkg set nextBundleAnalysis.budget=358400 nextBundleAnalysis.budgetPercentIncreaseRed=20 nextBundleAnalysis.showDetails=true --json
- name: Restore next build
- uses: actions/cache@v3
+ uses: actions/cache@v4
id: restore-build-cache
env:
cache-name: cache-next-build
@@ -85,13 +87,13 @@ jobs:
run: npx -p nextjs-bundle-analysis report
- name: Upload bundle analysis report for this PR
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: bundle
path: ${{ matrix.next-dir }}/.next/analyze/__bundle_analysis.json
- name: Download bundle analysis report for base branch
- uses: dawidd6/action-download-artifact@v2
+ uses: dawidd6/action-download-artifact@v6
if: success() && github.event.number
with:
workflow: nextjs-bundle-analysis.yml
@@ -115,7 +117,7 @@ jobs:
echo EOF >> $GITHUB_OUTPUT
- name: Find Comment
- uses: peter-evans/find-comment@v2
+ uses: peter-evans/find-comment@v3
if: success() && github.event.number
id: fc
with:
@@ -123,14 +125,16 @@ jobs:
body-includes: ''
- name: Create Comment
- uses: peter-evans/create-or-update-comment@v2
+ uses: peter-evans/create-or-update-comment@v4
+ continue-on-error: true
if: success() && github.event.number && steps.fc.outputs.comment-id == 0
with:
issue-number: ${{ github.event.number }}
body: ${{ steps.get-comment-body.outputs.body }}
- name: Update Comment
- uses: peter-evans/create-or-update-comment@v2
+ uses: peter-evans/create-or-update-comment@v4
+ continue-on-error: true
if: success() && github.event.number && steps.fc.outputs.comment-id != 0
with:
issue-number: ${{ github.event.number }}
diff --git a/.github/workflows/nightly-releases.yml b/.github/workflows/nightly-releases.yml
index 9903a5ebd..e995a2c98 100644
--- a/.github/workflows/nightly-releases.yml
+++ b/.github/workflows/nightly-releases.yml
@@ -23,15 +23,15 @@ on:
jobs:
release_nightly_canary:
name: Release Nightly Canary
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
steps:
- name: Checkout repo
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js 18.x
- uses: actions/setup-node@master
+ uses: actions/setup-node@v4
with:
node-version: 18.x
diff --git a/.github/workflows/notify-discord.yml b/.github/workflows/notify-discord.yml
index 46a0ca007..a2b936b9a 100644
--- a/.github/workflows/notify-discord.yml
+++ b/.github/workflows/notify-discord.yml
@@ -12,7 +12,7 @@ on:
jobs:
release_plugin:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
steps:
- name: Discord Notification
env:
@@ -33,6 +33,6 @@ jobs:
]
}
]
- uses: Ilshidur/action-discord@0c4b27844ba47cb1c7bee539c8eead5284ce9fa9
+ uses: Ilshidur/action-discord@0.3.2
with:
args: '${{ github.ref_name }} has been released!'
diff --git a/.github/workflows/release-packages.yml b/.github/workflows/release-packages.yml
index 03575ee34..48e79b14d 100644
--- a/.github/workflows/release-packages.yml
+++ b/.github/workflows/release-packages.yml
@@ -7,17 +7,17 @@ on:
jobs:
release_packages:
- name: Release Packages
- runs-on: ubuntu-latest
+ name: Release Packages
+ runs-on: ubuntu-22.04
steps:
- name: Checkout Repo
- uses: actions/checkout@master
+ uses: actions/checkout@v4
with:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0
- name: Setup Node.js 18.x
- uses: actions/setup-node@master
+ uses: actions/setup-node@v4
with:
node-version: 18.x
@@ -52,12 +52,8 @@ jobs:
# Then deploy the WordPress plugin
# https://github.com/changesets/action#outputs
if: steps.changesets.outputs.published && contains(steps.changesets.outputs.publishedPackages, '"@faustwp/wordpress-plugin"')
- # Use a variant of 10up/action-wordpress-plugin-deploy that allows us to specify a PLUGIN_DIR
- # to support our monorepo structure.
uses: ./.github/actions/release-plugin
env:
- SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
- SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
PLUGIN_DIR: plugins/faustwp
SLUG: faustwp
VERSION: ${{ env.PLUGIN_VERSION }}
diff --git a/.github/workflows/release-plugin.yml b/.github/workflows/release-plugin.yml
deleted file mode 100644
index a58325864..000000000
--- a/.github/workflows/release-plugin.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: Deploy to WordPress.org
-on:
- push:
- tags:
- - "@faustwp/wordpress-plugin@*"
-jobs:
- release_plugin:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@master
- - name: WordPress Plugin Deploy
- # Use a variant of 10up/action-wordpress-plugin-deploy that allows us to specify a PLUGIN_DIR
- # to support our monorepo structure.
- uses: ./.github/actions/release-plugin
- env:
- SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
- SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
- PLUGIN_DIR: plugins/faustwp
- SLUG: faustwp
diff --git a/.github/workflows/sonarqube-scan.yml b/.github/workflows/sonarqube-scan.yml
index 592119b50..7dc3d8220 100644
--- a/.github/workflows/sonarqube-scan.yml
+++ b/.github/workflows/sonarqube-scan.yml
@@ -14,7 +14,7 @@ jobs:
if: github.repository_owner == 'wpengine'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0
diff --git a/.github/workflows/test-plugin.yml b/.github/workflows/test-plugin.yml
deleted file mode 100644
index 9fccdb951..000000000
--- a/.github/workflows/test-plugin.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: Test Plugin
-
-on:
- pull_request:
- paths-ignore:
- - '**/*.md'
-
-jobs:
- test_plugin:
- name: WordPress ${{ matrix.wordpress }}
- runs-on: ubuntu-latest
- strategy:
- matrix:
- wordpress: ['6.3', '6.4']
- steps:
- - name: Checkout
- uses: actions/checkout@v3
- - name: Create Docker Containers
- working-directory: ./plugins/faustwp
- run: docker-compose up -d
- - name: Sleep 15 seconds
- run: sleep 15
- - name: Setup testing framework
- working-directory: ./plugins/faustwp
- run: docker exec -e COVERAGE=1 -e WP_VERSION=${{ matrix.wordpress}} $(docker-compose ps -q wordpress) init-testing-environment.sh
- - name: Install and activate WP GraphQL
- working-directory: ./plugins/faustwp
- run: docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) wp plugin install wp-graphql --activate --allow-root
- - name: Install Dependencies
- working-directory: ./plugins/faustwp
- run: docker exec -e COVERAGE=1 -e WP_VERSION=${{ matrix.wordpress}} -w /var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) composer install
- - name: Run unit tests
- working-directory: ./plugins/faustwp
- run: docker exec -e COVERAGE=1 -e WP_VERSION=${{ matrix.wordpress}} -w /var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) composer test
diff --git a/.github/workflows/test-packages.yml b/.github/workflows/unit-test-packages.yml
similarity index 84%
rename from .github/workflows/test-packages.yml
rename to .github/workflows/unit-test-packages.yml
index 751810551..8c2aba598 100644
--- a/.github/workflows/test-packages.yml
+++ b/.github/workflows/unit-test-packages.yml
@@ -6,20 +6,20 @@ on:
- '**/*.md'
jobs:
- test_packages:
+ unit-test_packages:
name: "Test packages on Node.js ${{ matrix.node }} ${{ matrix.os }}"
strategy:
matrix:
- os: ['ubuntu-latest']
- node: ['16', '18', '20']
+ os: ['ubuntu-22.04']
+ node: ['18', '20', '22']
permissions:
checks: write
pull-requests: write
runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node }}
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
diff --git a/.github/workflows/unit-test-plugin-nightly.yml b/.github/workflows/unit-test-plugin-nightly.yml
new file mode 100644
index 000000000..95f3da426
--- /dev/null
+++ b/.github/workflows/unit-test-plugin-nightly.yml
@@ -0,0 +1,50 @@
+name: Unit Test Plugin / WordPress Nightly
+
+on:
+ pull_request:
+ paths-ignore:
+ - '**/*.md'
+
+jobs:
+ unit_test_plugin:
+ runs-on: ubuntu-22.04
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Create Docker Containers
+ working-directory: ./plugins/faustwp
+ run: |
+ docker compose build \
+ --build-arg WP_VERSION=6.5
+ docker compose up -d
+
+ - name: Wait for db
+ run: |
+ while ! mysqladmin ping --host=127.0.0.1 --port=33066 --password=$MYSQL_ROOT_PASSWORD --silent; do
+ sleep 1
+ done
+
+ - name: Setup testing framework
+ working-directory: ./plugins/faustwp
+ run: docker exec -e COVERAGE=1 $(docker compose ps -q wordpress) init-testing-environment.sh
+
+ - name: Ensure Correct WordPress version
+ working-directory: ./plugins/faustwp
+ run: |
+ docker exec -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) wp core version --allow-root
+ docker exec -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) wp core upgrade --version=nightly --force --allow-root
+ docker exec -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) wp core version --allow-root
+
+ - name: Install and activate WP GraphQL
+ working-directory: ./plugins/faustwp
+ run: docker exec -e COVERAGE=1 -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) wp plugin install wp-graphql --activate --allow-root
+
+ - name: Install Dependencies
+ working-directory: ./plugins/faustwp
+ run: docker exec -e COVERAGE=1 -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) composer install
+
+ - name: Run unit tests
+ working-directory: ./plugins/faustwp
+ run: docker exec -e COVERAGE=1 -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) composer test
diff --git a/.github/workflows/unit-test-plugin.yml b/.github/workflows/unit-test-plugin.yml
new file mode 100644
index 000000000..1b16961e5
--- /dev/null
+++ b/.github/workflows/unit-test-plugin.yml
@@ -0,0 +1,48 @@
+name: Unit Test Plugin
+
+on:
+ pull_request:
+ paths-ignore:
+ - '**/*.md'
+
+jobs:
+ unit_test_plugin:
+ name: WordPress ${{ matrix.wordpress }}
+ runs-on: ubuntu-22.04
+ strategy:
+ matrix:
+ wordpress: [ '6.5', '6.4', '6.3', '6.2', '6.1' ]
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Create Docker Containers
+ env:
+ WP_VERSION: ${{ matrix.wordpress }}
+ working-directory: ./plugins/faustwp
+ run: |
+ docker compose build \
+ --build-arg WP_VERSION=${{ matrix.wordpress }}
+ docker compose up -d
+
+ - name: Wait for db
+ run: |
+ while ! mysqladmin ping --host=127.0.0.1 --port=33066 --password=$MYSQL_ROOT_PASSWORD --silent; do
+ sleep 1
+ done
+
+ - name: Setup testing framework
+ working-directory: ./plugins/faustwp
+ run: docker exec -e COVERAGE=1 $(docker compose ps -q wordpress) init-testing-environment.sh
+
+ - name: Install and activate WP GraphQL
+ working-directory: ./plugins/faustwp
+ run: docker exec -e COVERAGE=1 -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) wp plugin install wp-graphql --activate --allow-root
+
+ - name: Install Dependencies
+ working-directory: ./plugins/faustwp
+ run: docker exec -e COVERAGE=1 -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) composer install
+
+ - name: Run unit tests
+ working-directory: ./plugins/faustwp
+ run: docker exec -e COVERAGE=1 -w /var/www/html/wp-content/plugins/faustwp $(docker compose ps -q wordpress) composer test
diff --git a/.gitignore b/.gitignore
index 4eb2de83e..0ecd42389 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,7 +9,8 @@ process.yml
.env
.env.*
!.env.local.sample
-.docusaurus
build/
-examples/next/getting-started/package-lock.json
faustjs.code-workspace
+
+# Ignore the WordPress source where used by various development environments
+wordpress/
diff --git a/.nvmrc b/.nvmrc
index 7fd023741..3f430af82 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v16.15.0
+v18
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..b68f9294a
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+opensource@wpengine.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index 915f4ba1f..8dc6c5571 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -9,9 +9,10 @@ There are many ways to [contribute](/CONTRIBUTING.md) to this project.
## Project Structure
-- `/internal/website` - faustjs.org
- `/packages` - NPM packages
+- `/examples` - Example projects
- `/plugins` - WordPress Plugins
+- `/scripts` - Packaging scripts
### NPM Packages
@@ -71,7 +72,7 @@ composer run docker:start
If desired, you may specify the WP_VERSION you'd like to run tests against:
```sh
-WP_VERSION=5.5 composer run docker:start
+WP_VERSION=6.4.2 composer run docker:start
```
Once the containers are up, set up the test framework. If you want to enable code coverage reporting, make sure you provide the `COVERAGE=1` environment variable as a parameter:
@@ -83,13 +84,13 @@ docker-compose exec -e COVERAGE=1 wordpress init-testing-environment.sh
Install and activate WP GraphQL:
```sh
-docker-compose exec --workdir=/var/www/html/wp-content/plugins/faustwp --user=www-data wordpress wp plugin install wp-graphql --activate
+docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) wp plugin install wp-graphql --activate --allow-root
```
Run the unit tests:
```sh
-docker-compose exec -w /var/www/html/wp-content/plugins/faustwp wordpress composer test
+docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) composer test
```
Finally, to remove the containers:
@@ -131,14 +132,15 @@ FAUST_SECRET_KEY=00000000-0000-4000-8000-000000000001
### 3. WordPress Setup
1. Leave the node server running and open a new shell.
-1. Move into the FaustWP plugin directory `plugins/faustwp`.
-1. Run `composer install` if you haven't already.
-1. Prepare a test WordPress site.
+2. Move into the FaustWP plugin directory `plugins/faustwp`.
+3. Run `composer install` if you haven't already.
+4. Prepare a test WordPress site.
1. Run `docker-compose up -d --build`. If building for the first time, it could take some time to download and build the images.
- 1. Run `docker-compose exec --workdir=/var/www/html/wp-content/plugins/faustwp --user=www-data wordpress wp plugin install wp-graphql --activate`
- 1. Run `docker-compose exec --workdir=/var/www/html/wp-content/plugins/faustwp --user=www-data wordpress wp db export tests/_data/dump.sql`
-1. Copy `.env.testing.example` to `.env.testing`.
-1. Run `vendor/bin/codecept run acceptance` to start the end-2-end tests.
+ 2. Run `docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) wp plugin install wp-graphql --activate --allow-root`
+ 3. Run `docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) wp core update-db --allow-root `
+ 4. Run `docker exec --workdir=/var/www/html/wp-content/plugins/faustwp $(docker-compose ps -q wordpress) wp db export tests/_data/dump.sql --allow-root`
+5. Copy `.env.testing.example` to `.env.testing`.
+6. Run `vendor/bin/codecept run acceptance` to start the end-2-end tests.
### Browser testing documentation
@@ -147,23 +149,12 @@ FAUST_SECRET_KEY=00000000-0000-4000-8000-000000000001
- [WPBrowser](https://wpbrowser.wptestkit.dev/)
- WordPress framework wrapping Codeception for browser testing WordPress.
-## Documentation
-
-The documentation site uses [Docusaurus](https://docusaurus.io/). Content lives primarily in MDX files under `internal/website/docs`. The following commands will get you up and running with a local copy of the docs.
-
-```sh
-npm run docs:install # Install docs dependencies
-npm run docs:build # Build the docs
-npm run docs # Serve the site on http://localhost:3000
-```
-
## Git Workflows
We have three notable branches:
- `canary` - This branch has the latest changes
- `main` - This branch is used to deploy changes to [faustjs.org](https://faustjs.org)
-- `site-dev` - This branch is used to deploy to the staging site
### Code Changes/Feature Workflow
@@ -178,23 +169,6 @@ We use the [feature branch workflow](https://www.atlassian.com/git/tutorials/com
**Note**: We use Squash and Merge when merging pull requests into the `canary` branch.
-### Staging Site Deployment
-
-When your feature branch includes changes to the documentation website, it's helpful to include a live preview link in the PR description. The [staging site](https://hcixzyt38dn5ak04xxcqc36lf.js.wpenginepowered.com/) is used for this purpose. You can deploy your changes to the staging site using the following steps:
-
-- Checkout and switch to the `site-dev` branch.
-- Merge your feature branch into `site-dev`.
-- Push your merge commit to `site-dev`.
-- Within about 10 minutes, the docs changes from your feature branch should be visible on the [staging site](https://hcixzyt38dn5ak04xxcqc36lf.js.wpenginepowered.com/).
-
-### Prod Site Deployment
-
-The docs on faustjs.org are automatically built on pushes to `main`. Updating the docs on `main` will update faustjs.org within 10 minutes.
-
-After a successful release, a PR from `canary` to `main` is automatically created. Review and merge this PR to update faustjs.org.
-
-**Important**: Be sure to use the "Create a merge commit" option, and not "Squash and merge", as this can lead to [merge conflicts](https://medium.com/@guilhermerios/the-agony-and-the-ecstasy-of-git-squash-7f91c8da20af).
-
## Deployment
Developers with full GitHub repository access can create public releases. We use [Changesets](https://github.com/atlassian/changesets) to automate the versioning and deployment process for all of our packages and plugins.
@@ -216,9 +190,9 @@ When you are ready to release, you should first create the new package and plugi
- [ ] The plugin's readme.txt changelog has been updated with the latest 3 versions (Plugin versioning only)
3. Approve, then "Squash and merge" the "Version Packages" PR into `canary`.
-### Publishing the @faustjs packages
+### Publishing the @faustwp packages
-The @faustjs packages are automatically published to NPM through a GitHub action once the "Version Packages" PR is merged.
+The @faustwp packages are automatically published to NPM through a GitHub action once the "Version Packages" PR is merged.
### Publishing the FaustWP plugin
@@ -226,11 +200,35 @@ Once the "Version Packages" PR is merged, create a new release on GitHub with a
Once deployed, the updated packages and plugin will be visible here:
-- https://www.npmjs.com/package/@faustjs/core
-- https://www.npmjs.com/package/@faustjs/react
-- https://www.npmjs.com/package/@faustjs/next
+- https://www.npmjs.com/package/@faustwp/core
+- https://www.npmjs.com/package/@faustwp/cli
+- https://www.npmjs.com/package/@faustwp/experimental-app-router
+- https://www.npmjs.com/package/@faustwp/block-editor-utils
+- https://www.npmjs.com/package/@faustwp/blocks
- https://plugins.trac.wordpress.org/browser/faustwp/tags
-### Update the docs
+### Working with the Monorepo
+
+This section offers guidance for developers working within the monorepo environment, which utilizes npm for package management.
+
+#### Navigation:
+
+- Use your terminal or IDE to navigate the file structure.
+- To locate a specific project, navigate to its directory within the packages folder. For example, `cd packages/faustwp-core` would take you to the `faustwp-core` project directory.
+
+#### Building and Deploying:
+
+- We use npm for managing dependencies and running build scripts.
+- Individual projects often have their own package.json file with project-specific scripts for building and deploying. You can run these scripts using commands like `npm run build` or `npm run test` within the project directory (e.g., `packages/faustwp-core`).
+- Refer to the project's README file or internal documentation for specific build and deploy instructions.
+ For deploying the entire monorepo, there might be a top-level build script which you can invoke with `npm run build`.
+
+#### Additional Considerations:
+
+Use the `--workspaces` or `-w` flag to run a specific script command of a specified workspace. For example:
+
+```bash
+$ npm run build -w examples/next/faustwp-getting-started
+```
-After a release, remember to update the docs using the [Prod Site Deployment](#prod-site-deployment) process outlined above.
+It runs the `build` npm script for the `faustwp-getting-started` example project.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..22dbdd401
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,37 @@
+# Security Policy
+
+## Supported Versions
+
+The following versions of this project are currently being supported with security updates.
+
+| Version | Supported |
+| ------- | ------------------ |
+| 1.3.1 | :white_check_mark: |
+| <1.3.0 | :x: |
+
+WP Engine takes the security of our software and services seriously, including all
+of the open-source code repositories managed through our
+[WP Engine organization](https://github.com/wpengine).
+
+## Reporting Security Issues
+
+If you believe you have found a security vulnerability in any Alley-owned
+repository, please report it to us via email at opensource@wpengine.com.
+
+**Please do not report security vulnerabilities through public GitHub issues,
+discussions, or pull requests.**
+
+Please include as much of the information listed below as you can to help us
+better understand and resolve the issue:
+
+- The type of issue (e.g., buffer overflow, SQL injection, or cross-site
+ scripting).
+- Full paths of the source file(s) related to the manifestation of the issue.
+- The location of the affected source code (tag/branch/commit or direct URL).
+- Any special configuration required to reproduce the issue.
+- Step-by-step instructions to reproduce the issue.
+- Proof-of-concept or exploit code (if possible).
+- Impact of the issue, including how an attacker might exploit the issue.
+
+This information will help us triage your report more quickly. Thank you for
+helping us keep WP Engine and our users safe!
diff --git a/examples/next/app-router/app/[slug]/hasPreviewProps.ts b/examples/next/app-router/app/[slug]/hasPreviewProps.ts
index 090ca6bb1..10dbad9e4 100644
--- a/examples/next/app-router/app/[slug]/hasPreviewProps.ts
+++ b/examples/next/app-router/app/[slug]/hasPreviewProps.ts
@@ -1,3 +1,6 @@
-export function hasPreviewProps(props: any) {
- return props?.searchParams?.preview === 'true' && !!props?.searchParams?.p;
+export async function hasPreviewProps(props: any) {
+ const { searchParams } = await props;
+ const { preview, p } = await searchParams;
+
+ return preview === 'true' && !!p;
}
diff --git a/examples/next/app-router/app/[slug]/page.tsx b/examples/next/app-router/app/[slug]/page.tsx
index 80fd253a4..8b51163e6 100644
--- a/examples/next/app-router/app/[slug]/page.tsx
+++ b/examples/next/app-router/app/[slug]/page.tsx
@@ -4,8 +4,11 @@ import { hasPreviewProps } from './hasPreviewProps';
import { PleaseLogin } from '@/components/please-login';
export default async function Page(props) {
- const isPreview = hasPreviewProps(props);
- const id = isPreview ? props.searchParams.p : props.params.slug;
+ const { searchParams, params } = await props;
+ const { slug } = await params;
+ const { p } = await searchParams;
+ const isPreview = await hasPreviewProps(props);
+ const id = isPreview ? p : slug;
let client = isPreview ? await getAuthClient() : await getClient();
diff --git a/examples/next/app-router/app/login/page.tsx b/examples/next/app-router/app/login/page.tsx
index 945aaeeda..2da2c4979 100644
--- a/examples/next/app-router/app/login/page.tsx
+++ b/examples/next/app-router/app/login/page.tsx
@@ -1,19 +1,10 @@
'use client';
-import { useFormState, useFormStatus } from 'react-dom';
import { loginAction } from './action';
-
-function SubmitButton() {
- const status = useFormStatus();
- return (
-
- );
-}
+import { useActionState } from 'react';
export default function Page() {
- const [state, formAction] = useFormState(loginAction, {});
+ const [state, formAction, isPending] = useActionState(loginAction, {});
return (
<>
@@ -30,7 +21,9 @@ export default function Page() {
-
+
{state.error && (
diff --git a/examples/next/faustwp-getting-started/faust.config.js b/examples/next/faustwp-getting-started/faust.config.js
index 891294488..8233c5d1f 100644
--- a/examples/next/faustwp-getting-started/faust.config.js
+++ b/examples/next/faustwp-getting-started/faust.config.js
@@ -7,7 +7,7 @@ import possibleTypes from './possibleTypes.json';
**/
export default setConfig({
templates,
- experimentalPlugins: [],
+ plugins: [],
experimentalToolbar: true,
possibleTypes,
});
diff --git a/examples/next/faustwp-getting-started/next.config.js b/examples/next/faustwp-getting-started/next.config.js
index 671f1eca0..b886fe7ab 100644
--- a/examples/next/faustwp-getting-started/next.config.js
+++ b/examples/next/faustwp-getting-started/next.config.js
@@ -1,4 +1,5 @@
const { withFaust, getWpHostname } = require('@faustwp/core');
+const { createSecureHeaders } = require('next-secure-headers');
/**
* @type {import('next').NextConfig}
@@ -15,4 +16,9 @@ module.exports = withFaust({
locales: ['en'],
defaultLocale: 'en',
},
+ async headers() {
+ return [{ source: '/:path*', headers: createSecureHeaders({
+ xssProtection: false
+ }) }];
+ },
});
diff --git a/examples/next/faustwp-getting-started/package.json b/examples/next/faustwp-getting-started/package.json
index b949c17bd..56dfbbe3e 100644
--- a/examples/next/faustwp-getting-started/package.json
+++ b/examples/next/faustwp-getting-started/package.json
@@ -10,20 +10,23 @@
"start": "faust start"
},
"dependencies": {
- "@apollo/client": "^3.6.6",
- "@faustwp/cli": "^2.0.0",
- "@faustwp/core": "^2.1.2",
- "@wordpress/base-styles": "^4.36.0",
- "@wordpress/block-library": "^7.19.0",
- "classnames": "^2.3.1",
- "graphql": "^16.6.0",
- "next": "^12.1.6",
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
- "sass": "^1.54.9"
+ "@apollo/client": "^3.10.4",
+ "@faustwp/cli": "^3.1.1",
+ "@faustwp/core": "^3.1.0",
+ "@wordpress/base-styles": "^5.10.0",
+ "@wordpress/block-library": "^9.10.0",
+ "classnames": "^2.5.1",
+ "graphql": "^16.8.1",
+ "next": "^14.2.15",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "sass": "^1.77.3"
+ },
+ "devDependencies": {
+ "next-secure-headers": "^2.2.0"
},
"engines": {
- "node": ">=16",
+ "node": ">=18",
"npm": ">=8"
}
}
diff --git a/examples/next/getting-started/.env.local.sample b/examples/next/getting-started/.env.local.sample
deleted file mode 100644
index d2b613710..000000000
--- a/examples/next/getting-started/.env.local.sample
+++ /dev/null
@@ -1,5 +0,0 @@
-# Your WordPress site URL
-NEXT_PUBLIC_WORDPRESS_URL=https://headlessfw.wpengine.com
-
-# Plugin secret found in WordPress Settings->Headless
-FAUSTWP_SECRET_KEY=YOUR_PLUGIN_SECRET
diff --git a/examples/next/getting-started/.eslintrc b/examples/next/getting-started/.eslintrc
deleted file mode 100644
index 15b1ed91a..000000000
--- a/examples/next/getting-started/.eslintrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "next"
-}
diff --git a/examples/next/getting-started/.gitignore b/examples/next/getting-started/.gitignore
deleted file mode 100644
index b886ae8b4..000000000
--- a/examples/next/getting-started/.gitignore
+++ /dev/null
@@ -1,37 +0,0 @@
-# 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*
-
-# dotenv files
-.env
-.env.test
-.env.production
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
-
-# vercel
-.vercel
diff --git a/examples/next/getting-started/README.md b/examples/next/getting-started/README.md
deleted file mode 100644
index c35fe2ec6..000000000
--- a/examples/next/getting-started/README.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# Next.js Headless WordPress Getting Started Example
-
-⚠️ TRY THE NEW FAUST: This Example project uses the old version of Faust. We will only be providing ongoing support for critical bugs and vulnerabilities with this version. If you intended to use the new version of Faust, please follow this [getting started guide](https://faustjs.org/docs/getting-started). Read the [following announcement](https://faustjs.org/blog/sprint-22-update) that explains the re-release of Faust.js.
-
-## Setup
-
-See the [setup steps](https://github.com/wpengine/faustjs#quick-start).
-
-## Run it
-
-```bash
-npm install
-npm run dev
-```
-
-[http://localhost:3000]()
diff --git a/examples/next/getting-started/gqty.config.js b/examples/next/getting-started/gqty.config.js
deleted file mode 100644
index 7f253230d..000000000
--- a/examples/next/getting-started/gqty.config.js
+++ /dev/null
@@ -1,30 +0,0 @@
-require('dotenv-flow').config();
-
-/**
- * @type {import("@gqty/cli").GQtyConfig}
- */
-const config = {
- react: false,
- scalarTypes: { DateTime: 'string' },
- introspection: {
- endpoint: `${process.env.NEXT_PUBLIC_WORDPRESS_URL}/graphql`,
- headers: {},
- },
- destination: './src/client/index.ts',
- subscriptions: false,
- javascriptOutput: false,
-};
-
-console.log(`Using "${config.introspection.endpoint}" to generate schema...`);
-console.log(
- '**********************************************************************',
-);
-console.log(`* ✨ There is a new version of Faust ✨. *
-* If you are still using the this version, and you wish to migrate, *
-* take a look at our migration guide at *
-* https://faustjs.org/docs/migrationPath/overview *`);
-console.log(
- '**********************************************************************',
-);
-
-module.exports = config;
diff --git a/examples/next/getting-started/next-env.d.ts b/examples/next/getting-started/next-env.d.ts
deleted file mode 100644
index 4f11a03dc..000000000
--- a/examples/next/getting-started/next-env.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-///
-///
-
-// NOTE: This file should not be edited
-// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/examples/next/getting-started/next.config.js b/examples/next/getting-started/next.config.js
deleted file mode 100644
index 85e4a431c..000000000
--- a/examples/next/getting-started/next.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-const { withFaust } = require('@faustjs/next');
-
-/**
- * @type {import('next').NextConfig}
- **/
-module.exports = withFaust();
diff --git a/examples/next/getting-started/package.json b/examples/next/getting-started/package.json
deleted file mode 100644
index 4565a6090..000000000
--- a/examples/next/getting-started/package.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "@faustjs/next-headless-getting-started",
- "version": "0.1.0",
- "private": true,
- "engines": {
- "node": ">=14.0.0",
- "npm": ">=6.0.0"
- },
- "scripts": {
- "dev": "next dev",
- "build": "next build",
- "start": "next start",
- "clean": "rimraf .next node_modules",
- "lint": "next lint",
- "generate": "gqty generate",
- "wpe-build": "next build"
- },
- "dependencies": {
- "@faustjs/core": "^0.15.13",
- "@faustjs/next": "^0.15.13",
- "next": "^12.2.4",
- "normalize.css": "^8.0.1",
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
- "sass": "^1.54.0",
- "sharp": "^0.32.6"
- },
- "devDependencies": {
- "@gqty/cli": "^3.1.0",
- "@types/node": "^17.0.17",
- "@types/react": "^17.0.34",
- "@types/react-dom": "^17.0.11",
- "dotenv-flow": "3.2.0",
- "eslint": "^8.4.1",
- "eslint-config-next": "^12.0.7",
- "rimraf": "^3.0.2",
- "typescript": "^4.5.2"
- }
-}
diff --git a/examples/next/getting-started/public/favicon.ico b/examples/next/getting-started/public/favicon.ico
deleted file mode 100644
index 851e88c43..000000000
Binary files a/examples/next/getting-started/public/favicon.ico and /dev/null differ
diff --git a/examples/next/getting-started/public/images/headless_hero_background.jpg b/examples/next/getting-started/public/images/headless_hero_background.jpg
deleted file mode 100644
index 4248eb22a..000000000
Binary files a/examples/next/getting-started/public/images/headless_hero_background.jpg and /dev/null differ
diff --git a/examples/next/getting-started/src/client/index.ts b/examples/next/getting-started/src/client/index.ts
deleted file mode 100644
index b8a67429b..000000000
--- a/examples/next/getting-started/src/client/index.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * GQTY: You can safely modify this file and Query Fetcher based on your needs
- */
-import type { IncomingMessage } from 'http';
-import { getClient } from '@faustjs/next';
-import {
- generatedSchema,
- scalarsEnumsHash,
- GeneratedSchema,
- SchemaObjectTypes,
- SchemaObjectTypesNames,
-} from './schema.generated';
-
-export const client = getClient<
- GeneratedSchema,
- SchemaObjectTypesNames,
- SchemaObjectTypes
->({
- schema: generatedSchema,
- scalarsEnumsHash,
-});
-
-export function serverClient(req: IncomingMessage) {
- return getClient({
- schema: generatedSchema,
- scalarsEnumsHash,
- context: req,
- });
-}
-
-export * from './schema.generated';
diff --git a/examples/next/getting-started/src/client/schema.generated.ts b/examples/next/getting-started/src/client/schema.generated.ts
deleted file mode 100644
index 7badff6ad..000000000
--- a/examples/next/getting-started/src/client/schema.generated.ts
+++ /dev/null
@@ -1,20793 +0,0 @@
-/**
- * GQTY AUTO-GENERATED CODE: PLEASE DO NOT MODIFY MANUALLY
- */
-
-import { SchemaUnionsKey } from 'gqty';
-
-export type Maybe = T | null;
-export type InputMaybe = Maybe;
-export type Exact = {
- [K in keyof T]: T[K];
-};
-export type MakeOptional = Omit & {
- [SubKey in K]?: Maybe;
-};
-export type MakeMaybe = Omit & {
- [SubKey in K]: Maybe;
-};
-/** All built-in and custom scalars, mapped to their actual values */
-export interface Scalars {
- ID: string;
- String: string;
- Boolean: boolean;
- Int: number;
- Float: number;
-}
-
-/** What rating to display avatars up to. Accepts 'G', 'PG', 'R', 'X', and are judged in that order. Default is the value of the 'avatar_rating' option */
-export enum AvatarRatingEnum {
- /** Indicates a G level avatar rating level. */
- G = 'G',
- /** Indicates a PG level avatar rating level. */
- PG = 'PG',
- /** Indicates an R level avatar rating level. */
- R = 'R',
- /** Indicates an X level avatar rating level. */
- X = 'X',
-}
-
-/** The Type of Identifier used to fetch a single resource. Default is ID. */
-export enum CategoryIdType {
- /** The Database ID for the node */
- DATABASE_ID = 'DATABASE_ID',
- /** The hashed Global ID */
- ID = 'ID',
- /** The name of the node */
- NAME = 'NAME',
- /** Url friendly name of the node */
- SLUG = 'SLUG',
- /** The URI for the node */
- URI = 'URI',
-}
-
-/** Arguments for filtering the CategoryToCategoryConnection connection */
-export interface CategoryToCategoryConnectionWhereArgs {
- /** Unique cache key to be produced when this query is stored in an object cache. Default is 'core'. */
- cacheDomain?: InputMaybe;
- /** Term ID to retrieve child terms of. If multiple taxonomies are passed, $child_of is ignored. Default 0. */
- childOf?: InputMaybe;
- /** True to limit results to terms that have no children. This parameter has no effect on non-hierarchical taxonomies. Default false. */
- childless?: InputMaybe;
- /** Retrieve terms where the description is LIKE the input value. Default empty. */
- descriptionLike?: InputMaybe;
- /** Array of term ids to exclude. If $include is non-empty, $exclude is ignored. Default empty array. */
- exclude?: InputMaybe>>;
- /** Array of term ids to exclude along with all of their descendant terms. If $include is non-empty, $exclude_tree is ignored. Default empty array. */
- excludeTree?: InputMaybe>>;
- /** Whether to hide terms not assigned to any posts. Accepts true or false. Default false */
- hideEmpty?: InputMaybe;
- /** Whether to include terms that have non-empty descendants (even if $hide_empty is set to true). Default true. */
- hierarchical?: InputMaybe;
- /** Array of term ids to include. Default empty array. */
- include?: InputMaybe>>;
- /** Array of names to return term(s) for. Default empty. */
- name?: InputMaybe>>;
- /** Retrieve terms where the name is LIKE the input value. Default empty. */
- nameLike?: InputMaybe;
- /** Array of object IDs. Results will be limited to terms associated with these objects. */
- objectIds?: InputMaybe>>;
- /** Direction the connection should be ordered in */
- order?: InputMaybe;
- /** Field(s) to order terms by. Defaults to 'name'. */
- orderby?: InputMaybe;
- /** Whether to pad the quantity of a term's children in the quantity of each term's "count" object variable. Default false. */
- padCounts?: InputMaybe;
- /** Parent term ID to retrieve direct-child terms of. Default empty. */
- parent?: InputMaybe;
- /** Search criteria to match terms. Will be SQL-formatted with wildcards before and after. Default empty. */
- search?: InputMaybe;
- /** Array of slugs to return term(s) for. Default empty. */
- slug?: InputMaybe>>;
- /** Array of term taxonomy IDs, to match when querying terms. */
- termTaxonomId?: InputMaybe>>;
- /** Array of term taxonomy IDs, to match when querying terms. */
- termTaxonomyId?: InputMaybe>>;
- /** Whether to prime meta caches for matched terms. Default true. */
- updateTermMetaCache?: InputMaybe;
-}
-
-/** Arguments for filtering the CategoryToContentNodeConnection connection */
-export interface CategoryToContentNodeConnectionWhereArgs {
- /** The Types of content to filter */
- contentTypes?: InputMaybe>>;
- /** Filter the connection based on dates */
- dateQuery?: InputMaybe;
- /** True for objects with passwords; False for objects without passwords; null for all objects with or without passwords */
- hasPassword?: InputMaybe;
- /** Specific database ID of the object */
- id?: InputMaybe;
- /** Array of IDs for the objects to retrieve */
- in?: InputMaybe>>;
- /** Get objects with a specific mimeType property */
- mimeType?: InputMaybe;
- /** Slug / post_name of the object */
- name?: InputMaybe;
- /** Specify objects to retrieve. Use slugs */
- nameIn?: InputMaybe>>;
- /** Specify IDs NOT to retrieve. If this is used in the same query as "in", it will be ignored */
- notIn?: InputMaybe>>;
- /** What parameter to use to order the objects by. */
- orderby?: InputMaybe>>;
- /** Use ID to return only children. Use 0 to return only top-level items */
- parent?: InputMaybe;
- /** Specify objects whose parent is in an array */
- parentIn?: InputMaybe>>;
- /** Specify posts whose parent is not in an array */
- parentNotIn?: InputMaybe>>;
- /** Show posts with a specific password. */
- password?: InputMaybe;
- /** Show Posts based on a keyword search */
- search?: InputMaybe;
- /** Retrieve posts where post status is in an array. */
- stati?: InputMaybe>>;
- /** Show posts with a specific status. */
- status?: InputMaybe;
- /** Title of the object */
- title?: InputMaybe;
-}
-
-/** Arguments for filtering the CategoryToPostConnection connection */
-export interface CategoryToPostConnectionWhereArgs {
- /** The user that's connected as the author of the object. Use the userId for the author object. */
- author?: InputMaybe;
- /** Find objects connected to author(s) in the array of author's userIds */
- authorIn?: InputMaybe>>;
- /** Find objects connected to the author by the author's nicename */
- authorName?: InputMaybe;
- /** Find objects NOT connected to author(s) in the array of author's userIds */
- authorNotIn?: InputMaybe>>;
- /** Category ID */
- categoryId?: InputMaybe;
- /** Array of category IDs, used to display objects from one category OR another */
- categoryIn?: InputMaybe>>;
- /** Use Category Slug */
- categoryName?: InputMaybe;
- /** Array of category IDs, used to display objects from one category OR another */
- categoryNotIn?: InputMaybe>>;
- /** Filter the connection based on dates */
- dateQuery?: InputMaybe;
- /** True for objects with passwords; False for objects without passwords; null for all objects with or without passwords */
- hasPassword?: InputMaybe;
- /** Specific database ID of the object */
- id?: InputMaybe;
- /** Array of IDs for the objects to retrieve */
- in?: InputMaybe>>;
- /** Get objects with a specific mimeType property */
- mimeType?: InputMaybe;
- /** Slug / post_name of the object */
- name?: InputMaybe;
- /** Specify objects to retrieve. Use slugs */
- nameIn?: InputMaybe>>;
- /** Specify IDs NOT to retrieve. If this is used in the same query as "in", it will be ignored */
- notIn?: InputMaybe>>;
- /** What parameter to use to order the objects by. */
- orderby?: InputMaybe>>;
- /** Use ID to return only children. Use 0 to return only top-level items */
- parent?: InputMaybe;
- /** Specify objects whose parent is in an array */
- parentIn?: InputMaybe>>;
- /** Specify posts whose parent is not in an array */
- parentNotIn?: InputMaybe>>;
- /** Show posts with a specific password. */
- password?: InputMaybe;
- /** Show Posts based on a keyword search */
- search?: InputMaybe;
- /** Retrieve posts where post status is in an array. */
- stati?: InputMaybe>>;
- /** Show posts with a specific status. */
- status?: InputMaybe;
- /** Tag Slug */
- tag?: InputMaybe;
- /** Use Tag ID */
- tagId?: InputMaybe;
- /** Array of tag IDs, used to display objects from one tag OR another */
- tagIn?: InputMaybe>>;
- /** Array of tag IDs, used to display objects from one tag OR another */
- tagNotIn?: InputMaybe>>;
- /** Array of tag slugs, used to display objects from one tag AND another */
- tagSlugAnd?: InputMaybe>>;
- /** Array of tag slugs, used to include objects in ANY specified tags */
- tagSlugIn?: InputMaybe>>;
- /** Title of the object */
- title?: InputMaybe;
-}
-
-/** The Type of Identifier used to fetch a single comment node. Default is "ID". To be used along with the "id" field. */
-export enum CommentNodeIdTypeEnum {
- /** Identify a resource by the Database ID. */
- DATABASE_ID = 'DATABASE_ID',
- /** Identify a resource by the (hashed) Global ID. */
- ID = 'ID',
-}
-
-/** The status of the comment object. */
-export enum CommentStatusEnum {
- /** Comments with the Approved status */
- APPROVE = 'APPROVE',
- /** Comments with the Unapproved status */
- HOLD = 'HOLD',
- /** Comments with the Spam status */
- SPAM = 'SPAM',
- /** Comments with the Trash status */
- TRASH = 'TRASH',
-}
-
-/** Arguments for filtering the CommentToCommentConnection connection */
-export interface CommentToCommentConnectionWhereArgs {
- /** Comment author email address. */
- authorEmail?: InputMaybe;
- /** Array of author IDs to include comments for. */
- authorIn?: InputMaybe>>;
- /** Array of author IDs to exclude comments for. */
- authorNotIn?: InputMaybe>>;
- /** Comment author URL. */
- authorUrl?: InputMaybe;
- /** Array of comment IDs to include. */
- commentIn?: InputMaybe>>;
- /** Array of IDs of users whose unapproved comments will be returned by the query regardless of status. */
- commentNotIn?: InputMaybe>>;
- /** Include comments of a given type. */
- commentType?: InputMaybe;
- /** Include comments from a given array of comment types. */
- commentTypeIn?: InputMaybe>>;
- /** Exclude comments from a given array of comment types. */
- commentTypeNotIn?: InputMaybe;
- /** Content object author ID to limit results by. */
- contentAuthor?: InputMaybe>>;
- /** Array of author IDs to retrieve comments for. */
- contentAuthorIn?: InputMaybe>>;
- /** Array of author IDs *not* to retrieve comments for. */
- contentAuthorNotIn?: InputMaybe>>;
- /** Limit results to those affiliated with a given content object ID. */
- contentId?: InputMaybe;
- /** Array of content object IDs to include affiliated comments for. */
- contentIdIn?: InputMaybe>>;
- /** Array of content object IDs to exclude affiliated comments for. */
- contentIdNotIn?: InputMaybe>>;
- /** Content object name (i.e. slug ) to retrieve affiliated comments for. */
- contentName?: InputMaybe;
- /** Content Object parent ID to retrieve affiliated comments for. */
- contentParent?: InputMaybe;
- /** Array of content object statuses to retrieve affiliated comments for. Pass 'any' to match any value. */
- contentStatus?: InputMaybe>>;
- /** Content object type or array of types to retrieve affiliated comments for. Pass 'any' to match any value. */
- contentType?: InputMaybe>>;
- /** Array of IDs or email addresses of users whose unapproved comments will be returned by the query regardless of $status. Default empty */
- includeUnapproved?: InputMaybe>>;
- /** Karma score to retrieve matching comments for. */
- karma?: InputMaybe;
- /** The cardinality of the order of the connection */
- order?: InputMaybe;
- /** Field to order the comments by. */
- orderby?: InputMaybe;
- /** Parent ID of comment to retrieve children of. */
- parent?: InputMaybe;
- /** Array of parent IDs of comments to retrieve children for. */
- parentIn?: InputMaybe>>;
- /** Array of parent IDs of comments *not* to retrieve children for. */
- parentNotIn?: InputMaybe>>;
- /** Search term(s) to retrieve matching comments for. */
- search?: InputMaybe;
- /** Comment status to limit results by. */
- status?: InputMaybe;
- /** Include comments for a specific user ID. */
- userId?: InputMaybe;
-}
-
-/** Arguments for filtering the CommentToParentCommentConnection connection */
-export interface CommentToParentCommentConnectionWhereArgs {
- /** Comment author email address. */
- authorEmail?: InputMaybe;
- /** Array of author IDs to include comments for. */
- authorIn?: InputMaybe>>;
- /** Array of author IDs to exclude comments for. */
- authorNotIn?: InputMaybe>>;
- /** Comment author URL. */
- authorUrl?: InputMaybe;
- /** Array of comment IDs to include. */
- commentIn?: InputMaybe>>;
- /** Array of IDs of users whose unapproved comments will be returned by the query regardless of status. */
- commentNotIn?: InputMaybe>>;
- /** Include comments of a given type. */
- commentType?: InputMaybe;
- /** Include comments from a given array of comment types. */
- commentTypeIn?: InputMaybe>>;
- /** Exclude comments from a given array of comment types. */
- commentTypeNotIn?: InputMaybe;
- /** Content object author ID to limit results by. */
- contentAuthor?: InputMaybe>>;
- /** Array of author IDs to retrieve comments for. */
- contentAuthorIn?: InputMaybe>>;
- /** Array of author IDs *not* to retrieve comments for. */
- contentAuthorNotIn?: InputMaybe>>;
- /** Limit results to those affiliated with a given content object ID. */
- contentId?: InputMaybe;
- /** Array of content object IDs to include affiliated comments for. */
- contentIdIn?: InputMaybe>>;
- /** Array of content object IDs to exclude affiliated comments for. */
- contentIdNotIn?: InputMaybe>>;
- /** Content object name (i.e. slug ) to retrieve affiliated comments for. */
- contentName?: InputMaybe;
- /** Content Object parent ID to retrieve affiliated comments for. */
- contentParent?: InputMaybe;
- /** Array of content object statuses to retrieve affiliated comments for. Pass 'any' to match any value. */
- contentStatus?: InputMaybe>>;
- /** Content object type or array of types to retrieve affiliated comments for. Pass 'any' to match any value. */
- contentType?: InputMaybe>>;
- /** Array of IDs or email addresses of users whose unapproved comments will be returned by the query regardless of $status. Default empty */
- includeUnapproved?: InputMaybe>>;
- /** Karma score to retrieve matching comments for. */
- karma?: InputMaybe;
- /** The cardinality of the order of the connection */
- order?: InputMaybe;
- /** Field to order the comments by. */
- orderby?: InputMaybe;
- /** Parent ID of comment to retrieve children of. */
- parent?: InputMaybe;
- /** Array of parent IDs of comments to retrieve children for. */
- parentIn?: InputMaybe>>;
- /** Array of parent IDs of comments *not* to retrieve children for. */
- parentNotIn?: InputMaybe>>;
- /** Search term(s) to retrieve matching comments for. */
- search?: InputMaybe;
- /** Comment status to limit results by. */
- status?: InputMaybe;
- /** Include comments for a specific user ID. */
- userId?: InputMaybe;
-}
-
-/** Options for ordering the connection */
-export enum CommentsConnectionOrderbyEnum {
- /** Order by browser user agent of the commenter. */
- COMMENT_AGENT = 'COMMENT_AGENT',
- /** Order by approval status of the comment. */
- COMMENT_APPROVED = 'COMMENT_APPROVED',
- /** Order by name of the comment author. */
- COMMENT_AUTHOR = 'COMMENT_AUTHOR',
- /** Order by e-mail of the comment author. */
- COMMENT_AUTHOR_EMAIL = 'COMMENT_AUTHOR_EMAIL',
- /** Order by IP address of the comment author. */
- COMMENT_AUTHOR_IP = 'COMMENT_AUTHOR_IP',
- /** Order by URL address of the comment author. */
- COMMENT_AUTHOR_URL = 'COMMENT_AUTHOR_URL',
- /** Order by the comment contents. */
- COMMENT_CONTENT = 'COMMENT_CONTENT',
- /** Order by date/time timestamp of the comment. */
- COMMENT_DATE = 'COMMENT_DATE',
- /** Order by GMT timezone date/time timestamp of the comment. */
- COMMENT_DATE_GMT = 'COMMENT_DATE_GMT',
- /** Order by the globally unique identifier for the comment object */
- COMMENT_ID = 'COMMENT_ID',
- /** Order by the array list of comment IDs listed in the where clause. */
- COMMENT_IN = 'COMMENT_IN',
- /** Order by the comment karma score. */
- COMMENT_KARMA = 'COMMENT_KARMA',
- /** Order by the comment parent ID. */
- COMMENT_PARENT = 'COMMENT_PARENT',
- /** Order by the post object ID. */
- COMMENT_POST_ID = 'COMMENT_POST_ID',
- /** Order by the the type of comment, such as 'comment', 'pingback', or 'trackback'. */
- COMMENT_TYPE = 'COMMENT_TYPE',
- /** Order by the user ID. */
- USER_ID = 'USER_ID',
-}
-
-/** The Type of Identifier used to fetch a single resource. Default is ID. */
-export enum ContentNodeIdTypeEnum {
- /** Identify a resource by the Database ID. */
- DATABASE_ID = 'DATABASE_ID',
- /** Identify a resource by the (hashed) Global ID. */
- ID = 'ID',
- /** Identify a resource by the URI. */
- URI = 'URI',
-}
-
-/** Allowed Content Types */
-export enum ContentTypeEnum {
- /** The Type of Content object */
- ATTACHMENT = 'ATTACHMENT',
- /** The Type of Content object */
- PAGE = 'PAGE',
- /** The Type of Content object */
- POST = 'POST',
-}
-
-/** The Type of Identifier used to fetch a single Content Type node. To be used along with the "id" field. Default is "ID". */
-export enum ContentTypeIdTypeEnum {
- /** The globally unique ID */
- ID = 'ID',
- /** The name of the content type. */
- NAME = 'NAME',
-}
-
-/** Arguments for filtering the ContentTypeToContentNodeConnection connection */
-export interface ContentTypeToContentNodeConnectionWhereArgs {
- /** The Types of content to filter */
- contentTypes?: InputMaybe>>;
- /** Filter the connection based on dates */
- dateQuery?: InputMaybe;
- /** True for objects with passwords; False for objects without passwords; null for all objects with or without passwords */
- hasPassword?: InputMaybe;
- /** Specific database ID of the object */
- id?: InputMaybe;
- /** Array of IDs for the objects to retrieve */
- in?: InputMaybe>>;
- /** Get objects with a specific mimeType property */
- mimeType?: InputMaybe;
- /** Slug / post_name of the object */
- name?: InputMaybe;
- /** Specify objects to retrieve. Use slugs */
- nameIn?: InputMaybe>>;
- /** Specify IDs NOT to retrieve. If this is used in the same query as "in", it will be ignored */
- notIn?: InputMaybe>>;
- /** What parameter to use to order the objects by. */
- orderby?: InputMaybe>>;
- /** Use ID to return only children. Use 0 to return only top-level items */
- parent?: InputMaybe;
- /** Specify objects whose parent is in an array */
- parentIn?: InputMaybe>>;
- /** Specify posts whose parent is not in an array */
- parentNotIn?: InputMaybe>>;
- /** Show posts with a specific password. */
- password?: InputMaybe;
- /** Show Posts based on a keyword search */
- search?: InputMaybe;
- /** Retrieve posts where post status is in an array. */
- stati?: InputMaybe>>;
- /** Show posts with a specific status. */
- status?: InputMaybe;
- /** Title of the object */
- title?: InputMaybe;
-}
-
-/** Allowed Content Types of the Category taxonomy. */
-export enum ContentTypesOfCategoryEnum {
- /** The Type of Content object */
- POST = 'POST',
-}
-
-/** Allowed Content Types of the PostFormat taxonomy. */
-export enum ContentTypesOfPostFormatEnum {
- /** The Type of Content object */
- POST = 'POST',
-}
-
-/** Allowed Content Types of the Tag taxonomy. */
-export enum ContentTypesOfTagEnum {
- /** The Type of Content object */
- POST = 'POST',
-}
-
-/** Input for the createCategory mutation. */
-export interface CreateCategoryInput {
- /** The slug that the category will be an alias of */
- aliasOf?: InputMaybe;
- /** This is an ID that can be passed to a mutation by the client to track the progress of mutations and catch possible duplicate mutation submissions. */
- clientMutationId?: InputMaybe;
- /** The description of the category object */
- description?: InputMaybe;
- /** The name of the category object to mutate */
- name: Scalars['String'];
- /** The ID of the category that should be set as the parent */
- parentId?: InputMaybe;
- /** If this argument exists then the slug will be checked to see if it is not an existing valid term. If that check succeeds (it is not a valid term), then it is added and the term id is given. If it fails, then a check is made to whether the taxonomy is hierarchical and the parent argument is not empty. If the second check succeeds, the term will be inserted and the term id will be given. If the slug argument is empty, then it will be calculated from the term name. */
- slug?: InputMaybe;
-}
-
-/** Input for the createComment mutation. */
-export interface CreateCommentInput {
- /** The approval status of the comment. */
- approved?: InputMaybe;
- /** The name of the comment's author. */
- author?: InputMaybe;
- /** The email of the comment's author. */
- authorEmail?: InputMaybe;
- /** The url of the comment's author. */
- authorUrl?: InputMaybe;
- /** This is an ID that can be passed to a mutation by the client to track the progress of mutations and catch possible duplicate mutation submissions. */
- clientMutationId?: InputMaybe;
- /** The database ID of the post object the comment belongs to. */
- commentOn?: InputMaybe;
- /** Content of the comment. */
- content?: InputMaybe;
- /** The date of the object. Preferable to enter as year/month/day ( e.g. 01/31/2017 ) as it will rearrange date as fit if it is not specified. Incomplete dates may have unintended results for example, "2017" as the input will use current date with timestamp 20:17 */
- date?: InputMaybe;
- /** Parent comment ID of current comment. */
- parent?: InputMaybe;
- /** The approval status of the comment */
- status?: InputMaybe;
- /** Type of comment. */
- type?: InputMaybe;
-}
-
-/** Input for the createMediaItem mutation. */
-export interface CreateMediaItemInput {
- /** Alternative text to display when mediaItem is not displayed */
- altText?: InputMaybe;
- /** The userId to assign as the author of the mediaItem */
- authorId?: InputMaybe;
- /** The caption for the mediaItem */
- caption?: InputMaybe;
- /** This is an ID that can be passed to a mutation by the client to track the progress of mutations and catch possible duplicate mutation submissions. */
- clientMutationId?: InputMaybe;
- /** The comment status for the mediaItem */
- commentStatus?: InputMaybe;
- /** The date of the mediaItem */
- date?: InputMaybe;
- /** The date (in GMT zone) of the mediaItem */
- dateGmt?: InputMaybe;
- /** Description of the mediaItem */
- description?: InputMaybe;
- /** The file name of the mediaItem */
- filePath?: InputMaybe;
- /** The file type of the mediaItem */
- fileType?: InputMaybe;
- /** The ID of the parent object */
- parentId?: InputMaybe;
- /** The ping status for the mediaItem */
- pingStatus?: InputMaybe;
- /** The slug of the mediaItem */
- slug?: InputMaybe;
- /** The status of the mediaItem */
- status?: InputMaybe;
- /** The title of the mediaItem */
- title?: InputMaybe;
-}
-
-/** Input for the createPage mutation. */
-export interface CreatePageInput {
- /** The userId to assign as the author of the object */
- authorId?: InputMaybe;
- /** This is an ID that can be passed to a mutation by the client to track the progress of mutations and catch possible duplicate mutation submissions. */
- clientMutationId?: InputMaybe;
- /** The comment status for the object */
- commentStatus?: InputMaybe;
- /** The content of the object */
- content?: InputMaybe;
- /** The date of the object. Preferable to enter as year/month/day (e.g. 01/31/2017) as it will rearrange date as fit if it is not specified. Incomplete dates may have unintended results for example, "2017" as the input will use current date with timestamp 20:17 */
- date?: InputMaybe;
- /** A field used for ordering posts. This is typically used with nav menu items or for special ordering of hierarchical content types. */
- menuOrder?: InputMaybe;
- /** The ID of the parent object */
- parentId?: InputMaybe;
- /** The password used to protect the content of the object */
- password?: InputMaybe;
- /** The slug of the object */
- slug?: InputMaybe;
- /** The status of the object */
- status?: InputMaybe;
- /** The title of the object */
- title?: InputMaybe;
-}
-
-/** Input for the createPostFormat mutation. */
-export interface CreatePostFormatInput {
- /** The slug that the post_format will be an alias of */
- aliasOf?: InputMaybe;
- /** This is an ID that can be passed to a mutation by the client to track the progress of mutations and catch possible duplicate mutation submissions. */
- clientMutationId?: InputMaybe;
- /** The description of the post_format object */
- description?: InputMaybe;
- /** The name of the post_format object to mutate */
- name: Scalars['String'];
- /** If this argument exists then the slug will be checked to see if it is not an existing valid term. If that check succeeds (it is not a valid term), then it is added and the term id is given. If it fails, then a check is made to whether the taxonomy is hierarchical and the parent argument is not empty. If the second check succeeds, the term will be inserted and the term id will be given. If the slug argument is empty, then it will be calculated from the term name. */
- slug?: InputMaybe;
-}
-
-/** Input for the createPost mutation. */
-export interface CreatePostInput {
- /** The userId to assign as the author of the object */
- authorId?: InputMaybe;
- /** Set connections between the post and categories */
- categories?: InputMaybe;
- /** This is an ID that can be passed to a mutation by the client to track the progress of mutations and catch possible duplicate mutation submissions. */
- clientMutationId?: InputMaybe;
- /** The comment status for the object */
- commentStatus?: InputMaybe;
- /** The content of the object */
- content?: InputMaybe;
- /** The date of the object. Preferable to enter as year/month/day (e.g. 01/31/2017) as it will rearrange date as fit if it is not specified. Incomplete dates may have unintended results for example, "2017" as the input will use current date with timestamp 20:17 */
- date?: InputMaybe;
- /** The excerpt of the object */
- excerpt?: InputMaybe;
- /** A field used for ordering posts. This is typically used with nav menu items or for special ordering of hierarchical content types. */
- menuOrder?: InputMaybe;
- /** The password used to protect the content of the object */
- password?: InputMaybe;
- /** The ping status for the object */
- pingStatus?: InputMaybe;
- /** URLs that have been pinged. */
- pinged?: InputMaybe>>;
- /** Set connections between the post and postFormats */
- postFormats?: InputMaybe;
- /** The slug of the object */
- slug?: InputMaybe;
- /** The status of the object */
- status?: InputMaybe;
- /** Set connections between the post and tags */
- tags?: InputMaybe;
- /** The title of the object */
- title?: InputMaybe;
- /** URLs queued to be pinged. */
- toPing?: InputMaybe>>;
-}
-
-/** Input for the createTag mutation. */
-export interface CreateTagInput {
- /** The slug that the post_tag will be an alias of */
- aliasOf?: InputMaybe;
- /** This is an ID that can be passed to a mutation by the client to track the progress of mutations and catch possible duplicate mutation submissions. */
- clientMutationId?: InputMaybe;
- /** The description of the post_tag object */
- description?: InputMaybe;
- /** The name of the post_tag object to mutate */
- name: Scalars['String'];
- /** If this argument exists then the slug will be checked to see if it is not an existing valid term. If that check succeeds (it is not a valid term), then it is added and the term id is given. If it fails, then a check is made to whether the taxonomy is hierarchical and the parent argument is not empty. If the second check succeeds, the term will be inserted and the term id will be given. If the slug argument is empty, then it will be calculated from the term name. */
- slug?: InputMaybe;
-}
-
-/** Input for the createUser mutation. */
-export interface CreateUserInput {
- /** User's AOL IM account. */
- aim?: InputMaybe;
- /** This is an ID that can be passed to a mutation by the client to track the progress of mutations and catch possible duplicate mutation submissions. */
- clientMutationId?: InputMaybe;
- /** A string containing content about the user. */
- description?: InputMaybe;
- /** A string that will be shown on the site. Defaults to user's username. It is likely that you will want to change this, for both appearance and security through obscurity (that is if you dont use and delete the default admin user). */
- displayName?: InputMaybe;
- /** A string containing the user's email address. */
- email?: InputMaybe;
- /** The user's first name. */
- firstName?: InputMaybe;
- /** User's Jabber account. */
- jabber?: InputMaybe;
- /** The user's last name. */
- lastName?: InputMaybe;
- /** User's locale. */
- locale?: InputMaybe;
- /** A string that contains a URL-friendly name for the user. The default is the user's username. */
- nicename?: InputMaybe;
- /** The user's nickname, defaults to the user's username. */
- nickname?: InputMaybe;
- /** A string that contains the plain text password for the user. */
- password?: InputMaybe;
- /** The date the user registered. Format is Y-m-d H:i:s. */
- registered?: InputMaybe;
- /** A string for whether to enable the rich editor or not. False if not empty. */
- richEditing?: InputMaybe;
- /** An array of roles to be assigned to the user. */
- roles?: InputMaybe>>;
- /** A string that contains the user's username for logging in. */
- username: Scalars['String'];
- /** A string containing the user's URL for the user's web site. */
- websiteUrl?: InputMaybe;
- /** User's Yahoo IM account. */
- yim?: InputMaybe;
-}
-
-/** Date values */
-export interface DateInput {
- /** Day of the month (from 1 to 31) */
- day?: InputMaybe;
- /** Month number (from 1 to 12) */
- month?: InputMaybe;
- /** 4 digit year (e.g. 2017) */
- year?: InputMaybe;
-}
-
-/** Filter the connection based on input */
-export interface DateQueryInput {
- /** Nodes should be returned after this date */
- after?: InputMaybe;
- /** Nodes should be returned before this date */
- before?: InputMaybe;
- /** Column to query against */
- column?: InputMaybe;
- /** For after/before, whether exact value should be matched or not */
- compare?: InputMaybe