Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
099621b
WordPress Abilities API Client
emdashcodes Sep 5, 2025
a9171c8
Fix: minor formatting issues and test fix for pagination headers
emdashcodes Sep 5, 2025
175d97c
fix: correct return type of wp_abilities_register_client_assets
emdashcodes Sep 5, 2025
507d026
fix: auto-init assets & use class pattern for registration
emdashcodes Sep 17, 2025
feeb63b
Normalize paths for asset loading
emdashcodes Sep 17, 2025
fd80174
fix: package structure, pull in rules from gutenberg for eslint and t…
emdashcodes Sep 17, 2025
f84f026
docs: Remove NPM package mention for now
emdashcodes Sep 17, 2025
4bce669
refactor: Rename listAbilities to getAbilities & update reducer naming
emdashcodes Sep 17, 2025
4181cd5
fix: Update AbilityInput type to accept any JSON value
emdashcodes Sep 17, 2025
b534119
fix: correct package.json after rebase with trunk
emdashcodes Sep 17, 2025
94664a0
fix: Use per_page=-1 instead of recursion in resolver
emdashcodes Sep 17, 2025
d44074b
update: use addQueryArgs to build GET requests
emdashcodes Sep 17, 2025
2ec5107
fix: wrap strings with @wordpress/i18n
emdashcodes Sep 17, 2025
23c85b7
fix: phpstan issues in register_assets
emdashcodes Sep 17, 2025
03d8a20
fix: additional phpstan error
emdashcodes Sep 17, 2025
ec455e6
Add client-only ability registration (#69)
emdashcodes Sep 19, 2025
ae36d5c
Do not translate thrown developer errors
emdashcodes Sep 22, 2025
e6654a3
use rimraf for cleaning files, move to root package.json
emdashcodes Sep 22, 2025
cf979db
Use correct versions for CI
emdashcodes Sep 22, 2025
caa4fd7
fix: move scripts to main package.json and prefer wp-scripts
emdashcodes Sep 22, 2025
955fb2f
Simplify client readme by linking to CONTRIBUTING.md for dev and test…
emdashcodes Sep 22, 2025
ce1de7f
align tsconfig with gutenberg
emdashcodes Sep 22, 2025
af2e2c8
fix wp-scripts build command
emdashcodes Sep 22, 2025
2a05c12
Build JS assets for the plugin zip
emdashcodes Sep 22, 2025
f697d20
allow asset class prefix
emdashcodes Sep 22, 2025
17dfa62
Optimize npm dependencies
gziolo Sep 24, 2025
a42c858
Fix Prettier config and format files accordingly
gziolo Sep 24, 2025
9536f60
Use correct ajv-draft-04 import. Remove unusued jest libs
emdashcodes Sep 24, 2025
dea7b40
Only store valid ability keys in the store
emdashcodes Sep 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
module.exports = {
root: true,
extends: [
'plugin:@wordpress/eslint-plugin/recommended',
'plugin:eslint-comments/recommended',
],
plugins: [ 'import' ],
parserOptions: {
ecmaVersion: 2021,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
project: './tsconfig.json',
},
settings: {
'import/resolver': {
typescript: {
project: './tsconfig.json',
},
},
},
env: {
browser: true,
es6: true,
node: true,
},
rules: {
// React best practices
'react/jsx-boolean-value': 'error',
'react/jsx-curly-brace-presence': [
'error',
{ props: 'never', children: 'never' },
],

// WordPress-specific rules, lifted from gutenberg
'@wordpress/dependency-group': 'error',
'@wordpress/data-no-store-string-literals': 'error',
'@wordpress/wp-global-usage': 'error',
'@wordpress/react-no-unsafe-timeout': 'error',
'@wordpress/i18n-hyphenated-range': 'error',
'@wordpress/i18n-no-flanking-whitespace': 'error',
'@wordpress/i18n-text-domain': [
'error',
{
allowedTextDomain: 'default',
},
],
'@wordpress/no-unsafe-wp-apis': 'off',
'import/default': 'error',
'import/named': 'error',
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: [
'**/*.@(spec|test).@(j|t)s?(x)',
'**/@(webpack|jest).config.@(j|t)s',
'**/scripts/**',
],
},
],
'no-restricted-imports': [
'error',
{
paths: [
{
name: 'lodash',
message: 'Please use native functionality instead.',
},
{
name: 'classnames',
message: "Please use `clsx` instead. It's a lighter and faster drop-in replacement for `classnames`.",
},
{
name: 'redux',
importNames: [ 'combineReducers' ],
message: 'Please use `combineReducers` from `@wordpress/data` instead.',
},
],
},
],
'no-restricted-syntax': [
'error',
{
selector: 'ImportDeclaration[source.value=/^@wordpress\\u002F.+\\u002F/]',
message: 'Path access on WordPress dependencies is not allowed.',
},
{
selector: 'JSXAttribute[name.name="id"][value.type="Literal"]',
message: 'Do not use string literals for IDs; use withInstanceId instead.',
},
{
selector: 'CallExpression[callee.object.name="Math"][callee.property.name="random"]',
message: 'Do not use Math.random() to generate unique IDs; use withInstanceId instead. (If you\'re not generating unique IDs: ignore this message.)',
},
],
},
overrides: [
{
files: [ '**/*.ts?(x)' ],
rules: {
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
disallowTypeAnnotations: false,
},
],
'@typescript-eslint/no-shadow': 'error',
'no-shadow': 'off',
'jsdoc/require-param': 'off',
'jsdoc/require-param-type': 'off',
'jsdoc/require-returns-type': 'off',
},
},
],
};
90 changes: 45 additions & 45 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,50 @@ name: 'Copilot Setup Steps'
# Automatically run the setup steps when they are changed to allow for easy validation, and
# allow manual testing through the repository's "Actions" tab
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml

jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-latest

permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

##
# This allows Composer dependencies to be installed using a single step.
#
# Since the tests are currently run within the Docker containers where the PHP version varies,
# the same PHP version needs to be configured for the action runner machine so that the correct
# dependency versions are installed and cached.
##
- name: Set up PHP
uses: shivammathur/setup-php@ec406be512d7077f68eed36e63f4d91bc006edc4 # v2.35.4
with:
php-version: '8.3'
coverage: none

- name: Install Composer dependencies
uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1

- name: Setup Node
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
cache: 'npm'
node-version-file: '.nvmrc'

- name: Install NPM dependencies
run: npm ci
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-latest

permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

##
# This allows Composer dependencies to be installed using a single step.
#
# Since the tests are currently run within the Docker containers where the PHP version varies,
# the same PHP version needs to be configured for the action runner machine so that the correct
# dependency versions are installed and cached.
##
- name: Set up PHP
uses: shivammathur/setup-php@ec406be512d7077f68eed36e63f4d91bc006edc4 # v2.35.4
with:
php-version: '8.3'
coverage: none

- name: Install Composer dependencies
uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1

- name: Setup Node
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
cache: 'npm'
node-version-file: '.nvmrc'

- name: Install NPM dependencies
run: npm ci
154 changes: 77 additions & 77 deletions .github/workflows/props-bot.yml
Original file line number Diff line number Diff line change
@@ -1,92 +1,92 @@
name: Props Bot

on:
# This event runs anytime a PR is (re)opened, updated, marked ready for review, or labeled.
# GitHub does not allow filtering the `labeled` event by a specific label.
# However, the logic below will short-circuit the workflow when the `props-bot` label is not the one being added.
# Note: The pull_request_target event is used instead of pull_request because this workflow needs permission to comment
# on the pull request. Because this event grants extra permissions to `GITHUB_TOKEN`, any code changes within the PR
# should be considered untrusted. See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
pull_request_target:
types:
- opened
- synchronize
- reopened
- labeled
- ready_for_review
# This event runs anytime a comment is added or deleted.
# You cannot filter this event for PR comments only.
# However, the logic below does short-circuit the workflow for issues.
issue_comment:
types:
- created
# This event will run everytime a new PR review is initially submitted.
pull_request_review:
types:
- submitted
# This event runs anytime a PR review comment is created or deleted.
pull_request_review_comment:
types:
- created
# This event runs anytime a PR is (re)opened, updated, marked ready for review, or labeled.
# GitHub does not allow filtering the `labeled` event by a specific label.
# However, the logic below will short-circuit the workflow when the `props-bot` label is not the one being added.
# Note: The pull_request_target event is used instead of pull_request because this workflow needs permission to comment
# on the pull request. Because this event grants extra permissions to `GITHUB_TOKEN`, any code changes within the PR
# should be considered untrusted. See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
pull_request_target:
types:
- opened
- synchronize
- reopened
- labeled
- ready_for_review
# This event runs anytime a comment is added or deleted.
# You cannot filter this event for PR comments only.
# However, the logic below does short-circuit the workflow for issues.
issue_comment:
types:
- created
# This event will run everytime a new PR review is initially submitted.
pull_request_review:
types:
- submitted
# This event runs anytime a PR review comment is created or deleted.
pull_request_review_comment:
types:
- created

# Cancels all previous workflow runs for pull requests that have not completed.
concurrency:
# The concurrency group contains the workflow name and the branch name for pull requests
# or the commit hash for any other events.
group: ${{ github.workflow }}-${{ contains( fromJSON( '["pull_request_target", "pull_request_review", "pull_request_review_comment"]' ), github.event_name ) && github.head_ref || github.sha }}
cancel-in-progress: true
# The concurrency group contains the workflow name and the branch name for pull requests
# or the commit hash for any other events.
group: ${{ github.workflow }}-${{ contains( fromJSON( '["pull_request_target", "pull_request_review", "pull_request_review_comment"]' ), github.event_name ) && github.head_ref || github.sha }}
cancel-in-progress: true

# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}

jobs:
# Compiles a list of props for a pull request.
#
# Performs the following steps:
# - Collects a list of contributor props and leaves a comment.
# - Removes the props-bot label, if necessary.
props-bot:
name: Generate a list of props
runs-on: ubuntu-24.04
permissions:
# The action needs permission `write` permission for PRs in order to add a comment.
pull-requests: write
contents: read
timeout-minutes: 20
# The job will run when pull requests are open, ready for review and:
# Compiles a list of props for a pull request.
#
# - A comment is added to the pull request.
# - A review is created or commented on (unless PR originates from a fork).
# - The pull request is opened, synchronized, marked ready for review, or reopened.
# - The `props-bot` label is added to the pull request.
if: |
(
github.event_name == 'issue_comment' && github.event.issue.pull_request ||
( contains( fromJSON( '["pull_request_review", "pull_request_review_comment"]' ), github.event_name ) && ! github.event.pull_request.head.repo.fork ) ||
github.event_name == 'pull_request_target' && github.event.action != 'labeled' ||
'props-bot' == github.event.label.name
) &&
( ! github.event.pull_request.draft && github.event.pull_request.state == 'open' || ! github.event.issue.draft && github.event.issue.state == 'open' )
# Performs the following steps:
# - Collects a list of contributor props and leaves a comment.
# - Removes the props-bot label, if necessary.
props-bot:
name: Generate a list of props
runs-on: ubuntu-24.04
permissions:
# The action needs permission `write` permission for PRs in order to add a comment.
pull-requests: write
contents: read
timeout-minutes: 20
# The job will run when pull requests are open, ready for review and:
#
# - A comment is added to the pull request.
# - A review is created or commented on (unless PR originates from a fork).
# - The pull request is opened, synchronized, marked ready for review, or reopened.
# - The `props-bot` label is added to the pull request.
if: |
(
github.event_name == 'issue_comment' && github.event.issue.pull_request ||
( contains( fromJSON( '["pull_request_review", "pull_request_review_comment"]' ), github.event_name ) && ! github.event.pull_request.head.repo.fork ) ||
github.event_name == 'pull_request_target' && github.event.action != 'labeled' ||
'props-bot' == github.event.label.name
) &&
( ! github.event.pull_request.draft && github.event.pull_request.state == 'open' || ! github.event.issue.draft && github.event.issue.state == 'open' )

steps:
- name: Gather a list of contributors
uses: WordPress/props-bot-action@trunk
with:
format: 'git'
steps:
- name: Gather a list of contributors
uses: WordPress/props-bot-action@trunk
with:
format: 'git'

- name: Remove the props-bot label
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: ${{ github.event.action == 'labeled' && 'props-bot' == github.event.label.name }}
with:
retries: 2
retry-exempt-status-codes: 418
script: |
github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: process.env.ISSUE_NUMBER,
name: 'props-bot'
});
env:
ISSUE_NUMBER: ${{ github.event.number }}
- name: Remove the props-bot label
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: ${{ github.event.action == 'labeled' && 'props-bot' == github.event.label.name }}
with:
retries: 2
retry-exempt-status-codes: 418
script: |
github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: process.env.ISSUE_NUMBER,
name: 'props-bot'
});
env:
ISSUE_NUMBER: ${{ github.event.number }}
Loading