├── .nvmrc ├── packages └── wp-types │ ├── .gitignore │ ├── tests │ └── test.ts │ ├── append.ts │ ├── package.json │ └── LICENSE ├── .npmrc ├── wp-cli.yml ├── tests ├── data │ └── rest-api │ │ └── routes │ │ ├── wp-v2.json │ │ ├── oembed-1-0.json │ │ ├── wp-v2-book.json │ │ ├── wp-v2-media.json │ │ ├── wp-v2-menus.json │ │ ├── wp-v2-pages.json │ │ ├── wp-v2-posts.json │ │ ├── wp-v2-tags.json │ │ ├── wp-v2-types.json │ │ ├── wp-v2-users.json │ │ ├── wp-v2-blocks.json │ │ ├── wp-v2-comments.json │ │ ├── wp-v2-plugins.json │ │ ├── wp-v2-search.json │ │ ├── wp-v2-settings.json │ │ ├── wp-v2-sidebars.json │ │ ├── wp-v2-statuses.json │ │ ├── wp-v2-themes.json │ │ ├── wp-v2-users-me.json │ │ ├── wp-v2-widgets.json │ │ ├── oembed-1-0-embed.json │ │ ├── oembed-1-0-proxy.json │ │ ├── wp-abilities-v1.json │ │ ├── wp-v2-categories.json │ │ ├── wp-v2-menu-items.json │ │ ├── wp-v2-navigation.json │ │ ├── wp-v2-taxonomies.json │ │ ├── wp-v2-templates.json │ │ ├── wp-block-editor-v1.json │ │ ├── wp-site-health-v1.json │ │ ├── wp-v2-block-types.json │ │ ├── wp-v2-book-id.json │ │ ├── wp-v2-font-families.json │ │ ├── wp-v2-tags-id.json │ │ ├── wp-v2-widget-types.json │ │ ├── wp-v2-blocks-id.json │ │ ├── wp-v2-media-id.json │ │ ├── wp-v2-menu-locations.json │ │ ├── wp-v2-menus-id.json │ │ ├── wp-v2-pages-id.json │ │ ├── wp-v2-posts-id.json │ │ ├── wp-v2-template-parts.json │ │ ├── wp-v2-users-id.json │ │ ├── wp-v2-comments-id.json │ │ ├── wp-v2-font-collections.json │ │ ├── wp-v2-sidebars-id.json │ │ ├── wp-v2-templates-lookup.json │ │ ├── wp-v2-types-type.json │ │ ├── wp-v2-widgets-id.json │ │ ├── wp-abilities-v1-abilities.json │ │ ├── wp-abilities-v1-categories.json │ │ ├── wp-block-editor-v1-export.json │ │ ├── wp-v2-categories-id.json │ │ ├── wp-v2-media-id-edit.json │ │ ├── wp-v2-menu-items-id.json │ │ ├── wp-v2-navigation-id.json │ │ ├── wp-v2-wp-pattern-category.json │ │ ├── wp-v2-block-directory-search.json │ │ ├── wp-v2-block-patterns-patterns.json │ │ ├── wp-v2-book-id-autosaves.json │ │ ├── wp-v2-font-families-id.json │ │ ├── wp-v2-statuses-status.json │ │ ├── wp-v2-template-parts-lookup.json │ │ ├── wp-block-editor-v1-url-details.json │ │ ├── wp-v2-block-patterns-categories.json │ │ ├── wp-v2-blocks-id-autosaves.json │ │ ├── wp-v2-global-styles-id.json │ │ ├── wp-v2-pages-id-autosaves.json │ │ ├── wp-v2-posts-id-autosaves.json │ │ ├── wp-v2-taxonomies-taxonomy.json │ │ ├── wp-v2-widget-types-id.json │ │ ├── wp-site-health-v1-directory-sizes.json │ │ ├── wp-site-health-v1-tests-page-cache.json │ │ ├── wp-v2-media-id-post-process.json │ │ ├── wp-v2-pages-parent-revisions.json │ │ ├── wp-v2-pattern-directory-patterns.json │ │ ├── wp-v2-posts-parent-revisions.json │ │ ├── wp-v2-wp-pattern-category-id.json │ │ ├── wp-site-health-v1-tests-https-status.json │ │ ├── wp-v2-blocks-parent-revisions.json │ │ ├── wp-v2-font-collections-slug.json │ │ ├── wp-v2-menu-items-id-autosaves.json │ │ ├── wp-v2-menu-locations-location.json │ │ ├── wp-v2-navigation-id-autosaves.json │ │ ├── wp-v2-plugins-plugin.json │ │ ├── wp-block-editor-v1-navigation-fallback.json │ │ ├── wp-v2-block-renderer-name.json │ │ ├── wp-v2-block-types-namespace.json │ │ ├── wp-v2-navigation-parent-revisions.json │ │ ├── wp-v2-widget-types-id-encode.json │ │ ├── wp-v2-widget-types-id-render.json │ │ ├── wp-site-health-v1-tests-loopback-requests.json │ │ ├── wp-abilities-v1-abilities-name.json │ │ ├── wp-site-health-v1-tests-authorization-header.json │ │ ├── wp-site-health-v1-tests-background-updates.json │ │ ├── wp-site-health-v1-tests-dotorg-communication.json │ │ ├── wp-v2-blocks-parent-autosaves-id.json │ │ ├── wp-v2-blocks-parent-revisions-id.json │ │ ├── wp-v2-book-parent-autosaves-id.json │ │ ├── wp-v2-global-styles-parent-revisions.json │ │ ├── wp-v2-pages-parent-autosaves-id.json │ │ ├── wp-v2-pages-parent-revisions-id.json │ │ ├── wp-v2-posts-parent-autosaves-id.json │ │ ├── wp-v2-posts-parent-revisions-id.json │ │ ├── wp-abilities-v1-abilities-name-run.json │ │ ├── wp-abilities-v1-categories-slug.json │ │ ├── wp-v2-menu-items-parent-autosaves-id.json │ │ ├── wp-v2-navigation-parent-autosaves-id.json │ │ ├── wp-v2-navigation-parent-revisions-id.json │ │ ├── wp-v2-font-families-font-family-id-font-faces.json │ │ ├── wp-v2-global-styles-parent-revisions-id.json │ │ ├── wp-v2-themes-stylesheet.json │ │ ├── wp-v2-block-types-namespace-name.json │ │ ├── wp-v2-templates-id.json │ │ ├── wp-v2-users-user-id-me-application-passwords.json │ │ ├── wp-v2-template-parts-id.json │ │ ├── wp-v2-font-families-font-family-id-font-faces-id.json │ │ ├── wp-v2-templates-id-autosaves.json │ │ ├── wp-v2-users-user-id-me-application-passwords-introspect.json │ │ ├── wp-v2-global-styles-themes-stylesheet.json │ │ ├── wp-v2-templates-parent-revisions.json │ │ ├── wp-v2-users-user-id-me-application-passwords-uuid.json │ │ ├── wp-v2-global-styles-themes-stylesheet-variations.json │ │ ├── wp-v2-template-parts-id-autosaves.json │ │ ├── wp-v2-template-parts-parent-revisions.json │ │ ├── wp-v2-templates-parent-autosaves-id.json │ │ ├── wp-v2-templates-parent-revisions-id.json │ │ ├── wp-v2-template-parts-parent-autosaves-id.json │ │ └── wp-v2-template-parts-parent-revisions-id.json ├── output │ ├── site.php │ ├── network.php │ ├── role.php │ ├── search-results.php │ ├── block-template.php │ ├── block-directory-item.php │ ├── plugins.php │ ├── status.php │ ├── http.php │ ├── locale.php │ ├── post-type.php │ ├── rendered-block.php │ ├── taxonomy.php │ ├── block.php │ ├── comment.php │ ├── block-type.php │ ├── font-collection.php │ ├── block-patterns.php │ ├── settings.php │ ├── application-password.php │ ├── query.php │ ├── screen.php │ ├── themes.php │ ├── user.php │ ├── term.php │ ├── with-theme │ │ └── twentytwentyone │ │ │ └── menus.php │ ├── revision.php │ ├── templates.php │ ├── error.php │ ├── attachment.php │ ├── routes.php │ ├── fonts.php │ ├── template-parts.php │ ├── template-part-revision.php │ ├── global-styles-revision.php │ └── template-revision.php ├── bin │ ├── build-wp-types.sh │ └── test.sh ├── wp-config.php └── external-schemas │ └── font-face.json ├── .gitignore ├── schemas ├── properties │ ├── callable.json │ ├── user-cap-name.json │ ├── date-time.json │ ├── post-comment-status-name.json │ ├── comment-type-name.json │ ├── comment-status-name.json │ ├── user-role-name.json │ ├── object-filter-context.json │ ├── user-caps.json │ ├── taxonomy-name.json │ ├── post-status-name.json │ ├── post-format-name.json │ ├── error-messages.json │ ├── error-data.json │ ├── taxonomy-caps.json │ ├── post-type-name.json │ ├── taxonomy-rewrite.json │ ├── post-type-rewrite.json │ ├── post-type-caps.json │ ├── block-parsed.json │ └── user-data.json ├── rest-api │ ├── collections │ │ ├── menus.json │ │ ├── terms.json │ │ ├── menu-items.json │ │ ├── font-faces.json │ │ ├── revisions.json │ │ ├── menu-locations.json │ │ ├── template-revisions.json │ │ ├── application-passwords.json │ │ ├── global-styles-revisions.json │ │ ├── template-part-revisions.json │ │ ├── themes.json │ │ ├── templates.json │ │ ├── template-parts.json │ │ ├── pages.json │ │ ├── posts.json │ │ ├── tags.json │ │ ├── users.json │ │ ├── plugins.json │ │ ├── sidebars.json │ │ ├── blocks.json │ │ ├── comments.json │ │ ├── types.json │ │ ├── media.json │ │ ├── categories.json │ │ ├── block-types.json │ │ ├── statuses.json │ │ ├── font-families.json │ │ ├── navigation.json │ │ ├── search-results.json │ │ ├── taxonomies.json │ │ ├── block-patterns.json │ │ ├── font-collections.json │ │ ├── block-directory-items.json │ │ ├── block-pattern-categories.json │ │ ├── pattern-directory-patterns.json │ │ └── global-style-variations.json │ ├── properties │ │ ├── date-time-utc.json │ │ ├── date-time.json │ │ ├── object-links.json │ │ ├── font-family-settings.json │ │ ├── font-face.json │ │ └── http-status-code.json │ ├── revision.json │ ├── rendered-block.json │ ├── template-part-revision.json │ ├── tag.json │ ├── template-revision.json │ ├── category.json │ ├── partials │ │ ├── post │ │ │ ├── author.json │ │ │ ├── comments.json │ │ │ ├── public.json │ │ │ └── excerpt.json │ │ └── revision │ │ │ └── post-like.json │ ├── global-style-config.json │ ├── block-pattern-category.json │ ├── error.json │ ├── template-part.json │ ├── navigation-menu.json │ ├── template.json │ ├── menu-location.json │ ├── search-result.json │ ├── pattern-directory-pattern.json │ ├── application-password.json │ ├── term.json │ ├── font-family.json │ ├── global-style-variation.json │ ├── global-styles-revision.json │ ├── status.json │ ├── menu.json │ ├── block-pattern.json │ ├── block-directory-item.json │ ├── font-collection.json │ ├── post.json │ ├── font-face.json │ └── page.json ├── role.json ├── error-with-error.json ├── error-without-error.json ├── error.json ├── network.json ├── screen.json ├── user.json ├── block-template.json ├── block.json └── site.json ├── .editorconfig ├── .github └── workflows │ ├── lint-workflows.yml │ ├── test.yml │ └── deploy.yml ├── LICENSE ├── package.json └── composer.json /.nvmrc: -------------------------------------------------------------------------------- 1 | 20 2 | -------------------------------------------------------------------------------- /packages/wp-types/.gitignore: -------------------------------------------------------------------------------- 1 | index.js -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix="" 2 | ignore-scripts=true 3 | -------------------------------------------------------------------------------- /packages/wp-types/tests/test.ts: -------------------------------------------------------------------------------- 1 | import * as WP from '../index'; 2 | -------------------------------------------------------------------------------- /wp-cli.yml: -------------------------------------------------------------------------------- 1 | --- 2 | path: tests/wordpress 3 | url: example.org 4 | -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/oembed-1-0.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/oembed/1.0" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-book.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/book" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-media.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/media" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-menus.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/menus" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/pages" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-posts.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/posts" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/tags" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/types" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-users.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/users" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-blocks.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/blocks" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-comments.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/comments" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-plugins.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/plugins" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-search.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/search" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/settings" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/sidebars" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-statuses.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/statuses" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-themes.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/themes" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-users-me.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/users/me" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-widgets.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/widgets" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/oembed-1-0-embed.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/oembed/1.0/embed" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/oembed-1-0-proxy.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/oembed/1.0/proxy" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-abilities-v1.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-abilities/v1" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-categories.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/categories" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-menu-items.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/menu-items" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-navigation.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/navigation" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-taxonomies.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/taxonomies" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-templates.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/templates" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-block-editor-v1.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-block-editor/v1" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-site-health-v1.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-site-health/v1" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-block-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/block-types" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-book-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/book/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-font-families.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/font-families" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-tags-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/tags/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-widget-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/widget-types" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-blocks-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/blocks/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-media-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/media/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-menu-locations.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/menu-locations" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-menus-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/menus/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-pages-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/pages/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-posts-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/posts/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-template-parts.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/template-parts" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-users-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/users/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-comments-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/comments/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-font-collections.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/font-collections" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-sidebars-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/sidebars/(?P[\\w-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-templates-lookup.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/templates/lookup" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-types-type.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/types/(?P[\\w-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-widgets-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/widgets/(?P[\\w\\-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-abilities-v1-abilities.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-abilities/v1/abilities" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-abilities-v1-categories.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-abilities/v1/categories" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-block-editor-v1-export.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-block-editor/v1/export" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-categories-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/categories/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-media-id-edit.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/media/(?P[\\d]+)/edit" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-menu-items-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/menu-items/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-navigation-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/navigation/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-wp-pattern-category.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/wp_pattern_category" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-block-directory-search.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/block-directory/search" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-block-patterns-patterns.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/block-patterns/patterns" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-book-id-autosaves.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/book/(?P[\\d]+)/autosaves" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-font-families-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/font-families/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-statuses-status.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/statuses/(?P[\\w-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-template-parts-lookup.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/template-parts/lookup" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-block-editor-v1-url-details.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-block-editor/v1/url-details" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-block-patterns-categories.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/block-patterns/categories" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-blocks-id-autosaves.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/blocks/(?P[\\d]+)/autosaves" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-global-styles-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/global-styles/(?P[\\/\\d+]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-pages-id-autosaves.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/pages/(?P[\\d]+)/autosaves" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-posts-id-autosaves.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/posts/(?P[\\d]+)/autosaves" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-taxonomies-taxonomy.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/taxonomies/(?P[\\w-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-widget-types-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/widget-types/(?P[a-zA-Z0-9_-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-site-health-v1-directory-sizes.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-site-health/v1/directory-sizes" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-site-health-v1-tests-page-cache.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-site-health/v1/tests/page-cache" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-media-id-post-process.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/media/(?P[\\d]+)/post-process" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-pages-parent-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/pages/(?P[\\d]+)/revisions" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-pattern-directory-patterns.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/pattern-directory/patterns" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-posts-parent-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/posts/(?P[\\d]+)/revisions" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-wp-pattern-category-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/wp_pattern_category/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-site-health-v1-tests-https-status.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-site-health/v1/tests/https-status" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-blocks-parent-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/blocks/(?P[\\d]+)/revisions" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-font-collections-slug.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/font-collections/(?P[\\/\\w-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-menu-items-id-autosaves.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/menu-items/(?P[\\d]+)/autosaves" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-menu-locations-location.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/menu-locations/(?P[\\w-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-navigation-id-autosaves.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/navigation/(?P[\\d]+)/autosaves" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-plugins-plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/plugins/(?P[^.\\/]+(?:\\/[^.\\/]+)?)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-block-editor-v1-navigation-fallback.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-block-editor/v1/navigation-fallback" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-block-renderer-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/block-renderer/(?P[a-z0-9-]+/[a-z0-9-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-block-types-namespace.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/block-types/(?P[a-zA-Z0-9_-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-navigation-parent-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/navigation/(?P[\\d]+)/revisions" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-widget-types-id-encode.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/widget-types/(?P[a-zA-Z0-9_-]+)/encode" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-widget-types-id-render.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/widget-types/(?P[a-zA-Z0-9_-]+)/render" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-site-health-v1-tests-loopback-requests.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-site-health/v1/tests/loopback-requests" 3 | } -------------------------------------------------------------------------------- /tests/output/site.php: -------------------------------------------------------------------------------- 1 | [a-zA-Z0-9\\-\\/]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-site-health-v1-tests-authorization-header.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-site-health/v1/tests/authorization-header" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-site-health-v1-tests-background-updates.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-site-health/v1/tests/background-updates" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-site-health-v1-tests-dotorg-communication.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-site-health/v1/tests/dotorg-communication" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-blocks-parent-autosaves-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/blocks/(?P[\\d]+)/autosaves/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-blocks-parent-revisions-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/blocks/(?P[\\d]+)/revisions/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-book-parent-autosaves-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/book/(?P[\\d]+)/autosaves/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-global-styles-parent-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/global-styles/(?P[\\d]+)/revisions" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-pages-parent-autosaves-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/pages/(?P[\\d]+)/autosaves/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-pages-parent-revisions-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/pages/(?P[\\d]+)/revisions/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-posts-parent-autosaves-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/posts/(?P[\\d]+)/autosaves/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-posts-parent-revisions-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/posts/(?P[\\d]+)/revisions/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-abilities-v1-abilities-name-run.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-abilities/v1/abilities/(?P[a-zA-Z0-9\\-\\/]+?)/run" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-abilities-v1-categories-slug.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp-abilities/v1/categories/(?P[a-z0-9]+(?:-[a-z0-9]+)*)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-menu-items-parent-autosaves-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/menu-items/(?P[\\d]+)/autosaves/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-navigation-parent-autosaves-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/navigation/(?P[\\d]+)/autosaves/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-navigation-parent-revisions-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/navigation/(?P[\\d]+)/revisions/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/output/network.php: -------------------------------------------------------------------------------- 1 | role_objects; 6 | 7 | save_object_array( $roles, 'role' ); 8 | -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-font-families-font-family-id-font-faces.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/font-families/(?P[\\d]+)/font-faces" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-global-styles-parent-revisions-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/global-styles/(?P[\\d]+)/revisions/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-themes-stylesheet.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/themes/(?P[^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-block-types-namespace-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/block-types/(?P[a-zA-Z0-9_-]+)/(?P[a-zA-Z0-9_-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-templates-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/templates/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-users-user-id-me-application-passwords.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/users/(?P(?:[\\d]+|me))/application-passwords" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-template-parts-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/template-parts/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-font-families-font-family-id-font-faces-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/font-families/(?P[\\d]+)/font-faces/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-templates-id-autosaves.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/templates/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)/autosaves" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-users-user-id-me-application-passwords-introspect.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/users/(?P(?:[\\d]+|me))/application-passwords/introspect" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-global-styles-themes-stylesheet.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/global-styles/themes/(?P[^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-templates-parent-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/templates/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)/revisions" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-users-user-id-me-application-passwords-uuid.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/users/(?P(?:[\\d]+|me))/application-passwords/(?P[\\w\\-]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-global-styles-themes-stylesheet-variations.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/global-styles/themes/(?P[\\/\\s%\\w\\.\\(\\)\\[\\]\\@_\\-]+)/variations" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-template-parts-id-autosaves.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/template-parts/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)/autosaves" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /tests/data/* 3 | !/tests/data/rest-api 4 | /tests/data/rest-api/* 5 | !/tests/data/rest-api/routes 6 | /tests/wordpress 7 | /vendor 8 | 9 | /composer.lock 10 | -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-template-parts-parent-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/template-parts/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)/revisions" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-templates-parent-autosaves-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/templates/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)/autosaves/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-templates-parent-revisions-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/templates/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)/revisions/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-template-parts-parent-autosaves-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/template-parts/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)/autosaves/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/data/rest-api/routes/wp-v2-template-parts-parent-revisions-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "route": "/wp/v2/template-parts/(?P([^\\/:<>\\*\\?\"\\|]+(?:\\/[^\\/:<>\\*\\?\"\\|]+)?)[\\/\\w%-]+)/revisions/(?P[\\d]+)" 3 | } -------------------------------------------------------------------------------- /tests/output/search-results.php: -------------------------------------------------------------------------------- 1 | 'view', 7 | 'per_page' => 100, 8 | ] ); 9 | 10 | save_rest_array( [ 11 | $data 12 | ], 'search-results' ); 13 | -------------------------------------------------------------------------------- /tests/output/block-template.php: -------------------------------------------------------------------------------- 1 | 'block', 8 | ] ); 9 | 10 | save_rest_array( [ 11 | $data, 12 | ], 'block-directory-items' ); 13 | } 14 | -------------------------------------------------------------------------------- /tests/output/plugins.php: -------------------------------------------------------------------------------- 1 | 'edit', 7 | ] ); 8 | $view_data = get_rest_response( 'GET', '/wp/v2/plugins', [ 9 | 'context' => 'view', 10 | ] ); 11 | 12 | save_rest_array( [ 13 | $edit_data, 14 | $view_data, 15 | ], 'plugins' ); 16 | -------------------------------------------------------------------------------- /tests/output/status.php: -------------------------------------------------------------------------------- 1 | 'view', 7 | ] ); 8 | $edit_data = get_rest_response( 'GET', '/wp/v2/statuses', [ 9 | 'context' => 'edit', 10 | ] ); 11 | 12 | save_rest_array( [ 13 | $view_data, 14 | $edit_data, 15 | ], 'statuses' ); 16 | -------------------------------------------------------------------------------- /schemas/properties/user-cap-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/user-cap-name.json", 4 | "title": "WP_User_Cap_Name", 5 | "type": "string", 6 | "description": "The name of an individual primitive capability or meta capability." 7 | } 8 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/menus.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/menus.json", 4 | "title": "WP_REST_API_Menus", 5 | "description": "A collection of menus in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../menu.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/output/http.php: -------------------------------------------------------------------------------- 1 | getConstants(); 8 | $file = 'schemas/rest-api/properties/http-status-code.json'; 9 | 10 | set_schema_fields( 11 | $file, 12 | [ 13 | 'tsEnumNames' => array_keys( $constants ), 14 | 'enum' => array_values( $constants ), 15 | ] 16 | ); 17 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/terms.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/terms.json", 4 | "title": "WP_REST_API_Terms", 5 | "description": "A collection of term objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../term.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemas/properties/date-time.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/date-time.json", 4 | "title": "WP_Date_Time", 5 | "description": "Timestamp in MySQL DATETIME format (`YYYY-MM-DD hh:mm:ss`).", 6 | "type": "string", 7 | "pattern": "^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$" 8 | } 9 | -------------------------------------------------------------------------------- /schemas/properties/post-comment-status-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/post-comment-status-name.json", 4 | "title": "WP_Post_Comment_Status_Name", 5 | "type": "string", 6 | "tsEnumNames": [ 7 | "open", 8 | "closed" 9 | ], 10 | "enum": [ 11 | "open", 12 | "closed" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/menu-items.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/menu-items.json", 4 | "title": "WP_REST_API_Menu_Items", 5 | "description": "A collection of menu items in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../menu-item.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/font-faces.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/font-faces.json", 4 | "title": "WP_REST_API_Font_Faces", 5 | "description": "A collection of font face objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../font-face.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/revisions.json", 4 | "title": "WP_REST_API_Revisions", 5 | "description": "A collection of post revision objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../revision.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/output/locale.php: -------------------------------------------------------------------------------- 1 | $GLOBALS['wp_locale'], 7 | ]; 8 | 9 | $translations = array_keys( wp_get_installed_translations( 'core' )['default'] ); 10 | 11 | foreach ( $translations as $locale ) { 12 | switch_to_locale( $locale ); 13 | $locales[ $locale ] = $GLOBALS['wp_locale']; 14 | restore_previous_locale(); 15 | } 16 | 17 | save_object_array( $locales, 'locale' ); 18 | -------------------------------------------------------------------------------- /tests/output/post-type.php: -------------------------------------------------------------------------------- 1 | 'view', 11 | ] ); 12 | $edit_data = get_rest_response( 'GET', '/wp/v2/types', [ 13 | 'context' => 'edit', 14 | ] ); 15 | 16 | save_rest_array( [ 17 | $view_data, 18 | $edit_data, 19 | ], 'types' ); 20 | -------------------------------------------------------------------------------- /tests/output/rendered-block.php: -------------------------------------------------------------------------------- 1 | function( array $attributes, string $content ) : string { 9 | return '
Hello
'; 10 | }, 11 | ] 12 | ); 13 | 14 | $edit_data = get_rest_response( 'GET', '/wp/v2/block-renderer/foo/bar', [ 15 | 'context' => 'edit', 16 | ] ); 17 | 18 | save_rest_array( [ 19 | $edit_data, 20 | ], 'rendered-block' ); 21 | -------------------------------------------------------------------------------- /tests/output/taxonomy.php: -------------------------------------------------------------------------------- 1 | 'view', 11 | ] ); 12 | $edit_data = get_rest_response( 'GET', '/wp/v2/taxonomies', [ 13 | 'context' => 'edit', 14 | ] ); 15 | 16 | save_rest_array( [ 17 | $view_data, 18 | $edit_data, 19 | ], 'taxonomies' ); 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/menu-locations.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/menu-locations.json", 4 | "title": "WP_REST_API_Menu_Locations", 5 | "description": "A collection of menu locations in a REST API context.", 6 | "type": "object", 7 | "additionalProperties": { 8 | "$ref": "../menu-location.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemas/properties/comment-type-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/comment-type-name.json", 4 | "title": "WP_Comment_Type_Name", 5 | "type": "string", 6 | "tsEnumNames": [ 7 | "comment", 8 | "note", 9 | "pingback", 10 | "trackback" 11 | ], 12 | "enum": [ 13 | "comment", 14 | "note", 15 | "pingback", 16 | "trackback" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/template-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/template-revisions.json", 4 | "title": "WP_REST_API_Template_Revisions", 5 | "description": "A collection of template revision objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../template-revision.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemas/properties/comment-status-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/comment-status-name.json", 4 | "title": "WP_Comment_Status_Name", 5 | "type": "string", 6 | "tsEnumNames": [ 7 | "approved", 8 | "unapproved", 9 | "spam", 10 | "trash" 11 | ], 12 | "enum": [ 13 | "approved", 14 | "unapproved", 15 | "spam", 16 | "trash" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/application-passwords.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/application-passwords.json", 4 | "title": "WP_REST_API_Application_Passwords", 5 | "description": "A collection of user application passwords in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../application-password.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemas/rest-api/properties/date-time-utc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/date-time-utc.json", 4 | "title": "WP_REST_API_Date_Time_UTC", 5 | "description": "UTC timestamp in IETF RFC 3339 date-time format (`YYYY-MM-DDThh:mm:ss+00:00`).", 6 | "type": "string", 7 | "pattern": "^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})\\+00:00$" 8 | } 9 | -------------------------------------------------------------------------------- /schemas/rest-api/properties/date-time.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/date-time.json", 4 | "title": "WP_REST_API_Date_Time", 5 | "description": "Timestamp in IETF RFC 3339 date-time format minus the timezone identifier (`YYYY-MM-DDThh:mm:ss`).", 6 | "type": "string", 7 | "pattern": "^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})$" 8 | } 9 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/global-styles-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/global-styles-revisions.json", 4 | "title": "WP_REST_API_Global_Styles_Revisions", 5 | "description": "A collection of global styles revision objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../global-styles-revision.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemas/rest-api/revision.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/revision.json", 4 | "title": "WP_REST_API_Revision", 5 | "description": "A post revision object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "./partials/revision/common.json" 10 | }, 11 | { 12 | "$ref": "./partials/revision/post-like.json" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/template-part-revisions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/template-part-revisions.json", 4 | "title": "WP_REST_API_Template_Part_Revisions", 5 | "description": "A collection of block template part revision objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../template-part-revision.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/themes.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/themes.json", 4 | "title": "WP_REST_API_Themes", 5 | "description": "A collection of theme objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../theme.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/themes" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /schemas/properties/user-role-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/user-role-name.json", 4 | "title": "WP_User_Role_Name", 5 | "type": "string", 6 | "tsEnumNames": [ 7 | "administrator", 8 | "editor", 9 | "author", 10 | "contributor", 11 | "subscriber" 12 | ], 13 | "enum": [ 14 | "administrator", 15 | "editor", 16 | "author", 17 | "contributor", 18 | "subscriber" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/templates.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/templates.json", 4 | "title": "WP_REST_API_Templates", 5 | "description": "A collection of block template objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../template.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/templates" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/wp-types/append.ts: -------------------------------------------------------------------------------- 1 | 2 | type ValueOf = T[keyof T] 3 | 4 | /** 5 | * An enveloped REST API response (with `?_envelope`). 6 | * 7 | * @template T A REST API response type. 8 | */ 9 | export interface WP_REST_API_Envelope> { 10 | /** 11 | * The response body 12 | */ 13 | body: T; 14 | /** 15 | * The HTTP status code 16 | */ 17 | status: WP_Http_Status_Code; 18 | /** 19 | * The HTTP headers 20 | */ 21 | headers: { 22 | [k: string]: string|number; 23 | }; 24 | [k: string]: unknown; 25 | } 26 | -------------------------------------------------------------------------------- /tests/output/block.php: -------------------------------------------------------------------------------- 1 | 0, 7 | 'orderby' => 'comment_ID', 8 | 'order' => 'ASC', 9 | ] ); 10 | 11 | save_object_array( $comment, 'comment' ); 12 | 13 | $view_data = get_rest_response( 'GET', '/wp/v2/comments', [ 14 | 'context' => 'view', 15 | 'per_page' => 100, 16 | ] ); 17 | $edit_data = get_rest_response( 'GET', '/wp/v2/comments', [ 18 | 'context' => 'edit', 19 | 'per_page' => 100, 20 | ] ); 21 | 22 | save_rest_array( [ 23 | $view_data, 24 | $edit_data, 25 | ], 'comments' ); 26 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/sidebars.json", 4 | "title": "WP_REST_API_Sidebars", 5 | "description": "A collection of sidebar objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../sidebar.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/sidebars", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /schemas/properties/taxonomy-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/taxonomy-name.json", 4 | "title": "WP_Taxonomy_Name", 5 | "type": "string", 6 | "tsEnumNames": [ 7 | "category", 8 | "post_tag", 9 | "nav_menu", 10 | "post_format", 11 | "wp_template_part_area", 12 | "wp_theme" 13 | ], 14 | "enum": [ 15 | "category", 16 | "post_tag", 17 | "nav_menu", 18 | "post_format", 19 | "wp_template_part_area", 20 | "wp_theme" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/blocks.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/blocks.json", 4 | "title": "WP_REST_API_Blocks", 5 | "description": "A collection of reusable block objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../block.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/blocks", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/comments.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/comments.json", 4 | "title": "WP_REST_API_Comments", 5 | "description": "A collection of comment objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../comment.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/comments", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/output/block-type.php: -------------------------------------------------------------------------------- 1 | get_all_registered(); 9 | 10 | save_object_array( array_values( $block_types ), 'block-type' ); 11 | 12 | $view_data = get_rest_response( 'GET', '/wp/v2/block-types', [ 13 | 'context' => 'view', 14 | ] ); 15 | $edit_data = get_rest_response( 'GET', '/wp/v2/block-types', [ 16 | 'context' => 'edit', 17 | ] ); 18 | 19 | save_rest_array( [ 20 | $view_data, 21 | $edit_data, 22 | ], 'block-types' ); 23 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/types.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/types.json", 4 | "title": "WP_REST_API_Types", 5 | "description": "A collection of post type objects in a REST API context.", 6 | "type": "object", 7 | "additionalProperties": { 8 | "$ref": "../type.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/types", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/media.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/media.json", 4 | "title": "WP_REST_API_Attachments", 5 | "description": "A collection of media attachment objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../attachment.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/media", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/categories.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/categories.json", 4 | "title": "WP_REST_API_Categories", 5 | "description": "A collection of post category objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../category.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/categories", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/block-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/block-types.json", 4 | "title": "WP_REST_API_Block_Types", 5 | "description": "A collection of block type objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../block-type.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/block-types", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/statuses.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/statuses.json", 4 | "title": "WP_REST_API_Statuses", 5 | "description": "A collection of post status objects in a REST API context.", 6 | "type": "object", 7 | "additionalProperties": { 8 | "$ref": "../status.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/statuses", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/font-families.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/font-families.json", 4 | "title": "WP_REST_API_Font_Families", 5 | "description": "A collection of font family objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../font-family.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/font-families", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/navigation.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/navigation.json", 4 | "title": "WP_REST_API_Navigation_Menus", 5 | "description": "A collection of navigation menu objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../navigation-menu.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/navigation", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/search-results.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/search-results.json", 4 | "title": "WP_REST_API_Search_Results", 5 | "description": "A collection of search result objects in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$ref": "../search-result.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/search", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/taxonomies.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/taxonomies.json", 4 | "title": "WP_REST_API_Taxonomies", 5 | "description": "A collection of taxonomy objects in a REST API context.", 6 | "type": "object", 7 | "additionalProperties": { 8 | "$ref": "../taxonomy.json" 9 | }, 10 | "links": [ 11 | { 12 | "rel": "self", 13 | "href": "/wp/v2/taxonomies", 14 | "targetSchema": { 15 | "$ref": "#" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /schemas/properties/post-status-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/post-status-name.json", 4 | "title": "WP_Post_Status_Name", 5 | "type": "string", 6 | "tsEnumNames": [ 7 | "publish", 8 | "draft", 9 | "auto_draft", 10 | "inherit", 11 | "pending", 12 | "future", 13 | "trash", 14 | "private" 15 | ], 16 | "enum": [ 17 | "publish", 18 | "draft", 19 | "auto-draft", 20 | "inherit", 21 | "pending", 22 | "future", 23 | "trash", 24 | "private" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tests/output/font-collection.php: -------------------------------------------------------------------------------- 1 | 'view', 7 | ] ); 8 | $edit_data = get_rest_response( 'GET', '/wp/v2/settings', [ 9 | 'context' => 'edit', 10 | ] ); 11 | 12 | update_option( 'site_icon', 123 ); 13 | 14 | $with_site_icon = get_rest_response( 'GET', '/wp/v2/settings', [ 15 | 'context' => 'view', 16 | ] ); 17 | 18 | delete_option( 'site_icon' ); 19 | 20 | $without_site_icon = get_rest_response( 'GET', '/wp/v2/settings', [ 21 | 'context' => 'view', 22 | ] ); 23 | 24 | save_rest_array( [ 25 | $view_data, 26 | $edit_data, 27 | $with_site_icon, 28 | $without_site_icon, 29 | ], 'settings' ); 30 | -------------------------------------------------------------------------------- /schemas/properties/error-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/error-data.json", 4 | "title": "WP_Error_Data", 5 | "description": "The data for the errors contained within the error object.\n\nEach error is represented by a property keyed by the error code, and containing error data for that code. Any given error code can contain only one piece of error data, but the data can be of any type.", 6 | "oneOf": [ 7 | { 8 | "type": "object", 9 | "additionalProperties": { 10 | "tsType": "any" 11 | } 12 | }, 13 | { 14 | "$ref": "../../schema.json#/definitions/EmptyArray" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /schemas/rest-api/template-part-revision.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/template-part-revision.json", 4 | "title": "WP_REST_API_Template_Part_Revision", 5 | "description": "A block template part revision object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "./partials/template-revision/common.json" 10 | }, 11 | { 12 | "type": "object", 13 | "properties": { 14 | "area": { 15 | "description": "Where the template part is intended for use (header, footer, etc.)", 16 | "type": "string", 17 | "readOnly": true 18 | } 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/output/application-password.php: -------------------------------------------------------------------------------- 1 | 'Hello', 8 | ]; 9 | $created = \WP_Application_Passwords::create_new_application_password( $user->ID, wp_slash( $args ) ); 10 | 11 | if ( is_wp_error( $created ) ) { 12 | throw new \Exception( 'Failed to create application password: ' . $created->get_error_message() ); 13 | } 14 | 15 | $view_data = get_rest_response( 'GET', '/wp/v2/users/me/application-passwords', [ 16 | 'context' => 'view', 17 | ] ); 18 | $edit_data = get_rest_response( 'GET', '/wp/v2/users/me/application-passwords', [ 19 | 'context' => 'edit', 20 | ] ); 21 | save_rest_array( [ 22 | $view_data, 23 | $edit_data, 24 | ], 'application-passwords' ); 25 | -------------------------------------------------------------------------------- /schemas/properties/taxonomy-caps.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/taxonomy-caps.json", 4 | "title": "WP_Taxonomy_Caps", 5 | "type": "object", 6 | "description": "Taxonomy capabilities.", 7 | "required": [ 8 | "manage_terms", 9 | "edit_terms", 10 | "delete_terms", 11 | "assign_terms" 12 | ], 13 | "properties": { 14 | "manage_terms": { 15 | "$ref": "user-cap-name.json" 16 | }, 17 | "edit_terms": { 18 | "$ref": "user-cap-name.json" 19 | }, 20 | "delete_terms": { 21 | "$ref": "user-cap-name.json" 22 | }, 23 | "assign_terms": { 24 | "$ref": "user-cap-name.json" 25 | } 26 | }, 27 | "additionalProperties": false 28 | } 29 | -------------------------------------------------------------------------------- /tests/output/query.php: -------------------------------------------------------------------------------- 1 | 'post', 11 | 'posts_per_page' => 1, 12 | ] ); 13 | $queries[] = new WP_Query( [ 14 | 'post_type' => 'post', 15 | 's' => 'Hello', 16 | ] ); 17 | $queries[] = new WP_Query( [ 18 | 'post_type' => 'page', 19 | 'posts_per_page' => -1, 20 | ] ); 21 | $queries[] = new WP_Query( [ 22 | 'post_type' => 'does_not_exist', 23 | 'paged' => 7, 24 | ] ); 25 | 26 | $cats = get_terms( [ 27 | 'taxonomy' => 'category', 28 | 'number' => 1, 29 | ] ); 30 | 31 | $cat_query = new WP_Query( [ 32 | 'cat' => $cats[0]->term_id, 33 | ] ); 34 | 35 | $queries[] = $cat_query; 36 | 37 | save_object_array( $queries, 'query' ); 38 | -------------------------------------------------------------------------------- /schemas/role.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/role.json", 4 | "title": "WP_Role", 5 | "description": "Core class used to extend the user roles API.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "name", 10 | "capabilities" 11 | ], 12 | "properties": { 13 | "name": { 14 | "description": "Role name.", 15 | "anyOf": [ 16 | { 17 | "$ref": "properties/user-role-name.json" 18 | }, 19 | { 20 | "type": "string" 21 | } 22 | ] 23 | }, 24 | "capabilities": { 25 | "description": "List of capabilities the role contains.", 26 | "allOf": [ 27 | { 28 | "$ref": "properties/user-caps.json" 29 | } 30 | ] 31 | } 32 | }, 33 | "additionalProperties": false 34 | } 35 | -------------------------------------------------------------------------------- /schemas/rest-api/tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/tag.json", 4 | "title": "WP_REST_API_Tag", 5 | "description": "A post tag object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "term.json" 10 | } 11 | ], 12 | "links": [ 13 | { 14 | "rel": "self", 15 | "href": "/wp/v2/tags/{id}", 16 | "hrefSchema": { 17 | "properties": { 18 | "id": { 19 | "$ref": "term.json#/properties/id" 20 | } 21 | } 22 | }, 23 | "targetSchema": { 24 | "$ref": "#" 25 | } 26 | }, 27 | { 28 | "rel": "collection", 29 | "href": "/wp/v2/tags", 30 | "targetSchema": { 31 | "type": "array", 32 | "items": { 33 | "$ref": "#" 34 | } 35 | } 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /schemas/error-with-error.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/error-with-error.json", 4 | "title": "WP_Error_With_Error", 5 | "description": "WordPress Error class.\n\nRepresents a WP_Error object that contains at least one error.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "error_data", 10 | "errors" 11 | ], 12 | "properties": { 13 | "errors": { 14 | "description": "Stores the list of errors.", 15 | "allOf": [ 16 | { 17 | "$ref": "properties/error-messages.json" 18 | } 19 | ] 20 | }, 21 | "error_data": { 22 | "description": "Stores the list of data for error codes.", 23 | "allOf": [ 24 | { 25 | "$ref": "properties/error-data.json" 26 | } 27 | ] 28 | } 29 | }, 30 | "additionalProperties": false 31 | } 32 | -------------------------------------------------------------------------------- /schemas/rest-api/template-revision.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/template-revision.json", 4 | "title": "WP_REST_API_Template_Revision", 5 | "description": "A block template revision object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "./partials/template-revision/common.json" 10 | }, 11 | { 12 | "type": "object", 13 | "required": [ 14 | "is_custom" 15 | ], 16 | "properties": { 17 | "is_custom": { 18 | "description": "Whether the template is custom.", 19 | "type": "boolean", 20 | "readOnly": true 21 | }, 22 | "plugin": { 23 | "description": "Plugin that registered the template.", 24 | "type": "string", 25 | "readOnly": true 26 | } 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /schemas/rest-api/category.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/category.json", 4 | "title": "WP_REST_API_Category", 5 | "description": "A post category object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "term.json" 10 | } 11 | ], 12 | "links": [ 13 | { 14 | "rel": "self", 15 | "href": "/wp/v2/categories/{id}", 16 | "hrefSchema": { 17 | "properties": { 18 | "id": { 19 | "$ref": "term.json#/properties/id" 20 | } 21 | } 22 | }, 23 | "targetSchema": { 24 | "$ref": "#" 25 | } 26 | }, 27 | { 28 | "rel": "collection", 29 | "href": "/wp/v2/categories", 30 | "targetSchema": { 31 | "type": "array", 32 | "items": { 33 | "$ref": "#" 34 | } 35 | } 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /schemas/rest-api/partials/post/author.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/partials/post/author.json", 4 | "title": "WP_REST_API_Partial_Post_Author", 5 | "description": "Hello.", 6 | "type": "object", 7 | "required": [ 8 | "author" 9 | ], 10 | "properties": { 11 | "author": { 12 | "description": "The ID for the author of the post.", 13 | "allOf": [ 14 | { 15 | "$ref": "../../user.json#/properties/id" 16 | } 17 | ] 18 | } 19 | }, 20 | "links": [ 21 | { 22 | "rel": "author", 23 | "href": "/wp/v2/users/{author}", 24 | "hrefSchema": { 25 | "properties": { 26 | "author": { 27 | "$ref": "#/properties/author" 28 | } 29 | } 30 | }, 31 | "targetSchema": { 32 | "$ref": "../../user.json" 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /schemas/rest-api/properties/font-family-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/font-family-settings.json", 4 | "title": "WP_Font_Family_Settings", 5 | "description": "Font family settings.", 6 | "type": "object", 7 | "required": [ 8 | "name", 9 | "fontFamily", 10 | "slug" 11 | ], 12 | "properties": { 13 | "name": { 14 | "type": "string" 15 | }, 16 | "fontFamily": { 17 | "type": "string" 18 | }, 19 | "slug": { 20 | "type": "string" 21 | }, 22 | "fontFace": { 23 | "type": "array", 24 | "items": { 25 | "oneOf": [ 26 | { 27 | "$ref": "./font-face.json" 28 | } 29 | ] 30 | } 31 | }, 32 | "preview": { 33 | "type": "string", 34 | "format": "uri" 35 | } 36 | }, 37 | "additionalProperties": false 38 | } 39 | -------------------------------------------------------------------------------- /schemas/error-without-error.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/error-without-error.json", 4 | "title": "WP_Error_Without_Error", 5 | "description": "Empty WordPress Error class.\n\nRepresents a WP_Error object that contains no errors.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "error_data", 10 | "errors" 11 | ], 12 | "properties": { 13 | "errors": { 14 | "description": "Stores the list of errors.", 15 | "allOf": [ 16 | { 17 | "$ref": "../schema.json#/definitions/EmptyArray" 18 | } 19 | ] 20 | }, 21 | "error_data": { 22 | "description": "Stores the list of data for error codes.", 23 | "allOf": [ 24 | { 25 | "$ref": "../schema.json#/definitions/EmptyArray" 26 | } 27 | ] 28 | } 29 | }, 30 | "additionalProperties": false 31 | } 32 | -------------------------------------------------------------------------------- /schemas/rest-api/partials/post/comments.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/partials/post/comments.json", 4 | "title": "WP_REST_API_Partial_Post_Comments", 5 | "description": "Properties for post types that support comments", 6 | "type": "object", 7 | "required": [ 8 | "comment_status", 9 | "ping_status" 10 | ], 11 | "properties": { 12 | "comment_status": { 13 | "description": "Whether or not comments are open on the post.", 14 | "oneOf": [ 15 | { 16 | "$ref": "../../../properties/post-comment-status-name.json" 17 | } 18 | ] 19 | }, 20 | "ping_status": { 21 | "description": "Whether or not the post can be pinged.", 22 | "oneOf": [ 23 | { 24 | "$ref": "../../../properties/post-comment-status-name.json" 25 | } 26 | ] 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /schemas/properties/post-type-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/post-type-name.json", 4 | "title": "WP_Post_Type_Name", 5 | "type": "string", 6 | "tsEnumNames": [ 7 | "post", 8 | "page", 9 | "attachment", 10 | "revision", 11 | "nav_menu_item", 12 | "custom_css", 13 | "customize_changeset", 14 | "oembed_cache", 15 | "user_request", 16 | "wp_block", 17 | "wp_global_styles", 18 | "wp_navigation", 19 | "wp_template", 20 | "wp_template_part" 21 | ], 22 | "enum": [ 23 | "post", 24 | "page", 25 | "attachment", 26 | "revision", 27 | "nav_menu_item", 28 | "custom_css", 29 | "customize_changeset", 30 | "oembed_cache", 31 | "user_request", 32 | "wp_block", 33 | "wp_global_styles", 34 | "wp_navigation", 35 | "wp_template", 36 | "wp_template_part" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /packages/wp-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wp-types", 3 | "version": "4.69.0", 4 | "description": "TypeScript definitions of WordPress PHP objects and REST API responses.", 5 | "main": "index.js", 6 | "types": "index.ts", 7 | "files": [ 8 | "index.js", 9 | "index.ts" 10 | ], 11 | "homepage": "https://github.com/johnbillion/wp-json-schemas/tree/trunk/packages/wp-types", 12 | "funding": "https://github.com/sponsors/johnbillion", 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/johnbillion/wp-json-schemas" 16 | }, 17 | "keywords": [ 18 | "typescript", 19 | "wordpress" 20 | ], 21 | "author": "John Blackbourn", 22 | "license": "MIT", 23 | "dependencies": { 24 | "typescript": ">=4" 25 | }, 26 | "devDependencies": { 27 | "@swc/cli": "^0.6.0", 28 | "@swc/core": "^1.10.12" 29 | }, 30 | "scripts": { 31 | "build": "swc index.ts -o index.js", 32 | "prepublishOnly": "npm run build" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/output/screen.php: -------------------------------------------------------------------------------- 1 | set_parentage( 'tools.php?page=my_plugin_page' ); 9 | 10 | $post_with_parent = WP_Screen::get( 'edit.php' ); 11 | $post_with_parent->set_parentage( 'edit.php?post_type=page' ); 12 | 13 | $screens = [ 14 | WP_Screen::get( 'ajax' ), 15 | WP_Screen::get( 'customize' ), 16 | WP_Screen::get( 'dashboard-network' ), 17 | WP_Screen::get( 'dashboard-user' ), 18 | WP_Screen::get( 'dashboard' ), 19 | WP_Screen::get( 'edit-page' ), 20 | WP_Screen::get( 'edit-post' ), 21 | WP_Screen::get( 'edit.php' ), 22 | WP_Screen::get( 'edit' ), 23 | WP_Screen::get( 'front' ), 24 | WP_Screen::get( 'nav-menu.php' ), 25 | WP_Screen::get( 'tools.php' ), 26 | WP_Screen::get( 'widgets.php' ), 27 | $tools_with_parent, 28 | $post_with_parent, 29 | ]; 30 | 31 | save_object_array( $screens, 'screen' ); 32 | -------------------------------------------------------------------------------- /schemas/properties/taxonomy-rewrite.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/taxonomy-rewrite.json", 4 | "title": "WP_Taxonomy_Rewrite", 5 | "type": "object", 6 | "description": "Taxonomy rewrite rule definition.", 7 | "required": [ 8 | "with_front", 9 | "hierarchical", 10 | "ep_mask", 11 | "slug" 12 | ], 13 | "properties": { 14 | "with_front": { 15 | "description": "Should the permastruct be prepended with WP_Rewrite::$front.", 16 | "type": "boolean" 17 | }, 18 | "hierarchical": { 19 | "description": "Either hierarchical rewrite tag or not.", 20 | "type": "boolean" 21 | }, 22 | "ep_mask": { 23 | "description": "Assign an endpoint mask.", 24 | "type": "integer" 25 | }, 26 | "slug": { 27 | "description": "Customize the permastruct slug.", 28 | "type": "string" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/lint-workflows.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow 2 | 3 | name: Lint workflow files 4 | on: 5 | pull_request: 6 | paths: 7 | # Only run when changes are made to workflow files. 8 | - '.github/workflows/**' 9 | push: 10 | branches: 11 | - develop 12 | - trunk 13 | paths: 14 | # Only run when changes are made to workflow files. 15 | - '.github/workflows/**' 16 | workflow_dispatch: 17 | 18 | permissions: {} 19 | 20 | concurrency: 21 | group: ${{ github.workflow }}-${{ github.ref }} 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | lint: 26 | name: Lint 27 | permissions: 28 | security-events: write # To upload results to CodeQL 29 | actions: read # To read workflow runs 30 | contents: read # To read the repository 31 | uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-workflow-lint.yml@9a6405c89f3357947cd8f608bdc72d68fe17f4ae # v2.1.2 32 | -------------------------------------------------------------------------------- /schemas/error.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/error.json", 4 | "title": "WP_Error", 5 | "description": "WordPress Error class.\n\nContainer for checking for WordPress errors and error messages. Many core WordPress functions pass this class in the event of an error.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "error_data", 10 | "errors" 11 | ], 12 | "properties": { 13 | "errors": { 14 | "description": "Stores the list of errors.", 15 | "oneOf": [ 16 | { 17 | "$ref": "../schema.json#/definitions/EmptyArray" 18 | }, 19 | { 20 | "$ref": "properties/error-messages.json" 21 | } 22 | ] 23 | }, 24 | "error_data": { 25 | "description": "Stores the list of data for error codes.", 26 | "allOf": [ 27 | { 28 | "$ref": "properties/error-data.json" 29 | } 30 | ] 31 | } 32 | }, 33 | "additionalProperties": false 34 | } 35 | -------------------------------------------------------------------------------- /schemas/rest-api/global-style-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/global-style-config.json", 4 | "title": "WP_REST_API_Global_Style_Config", 5 | "description": "A theme's global style config in a REST API context.", 6 | "type": "object", 7 | "required": [ 8 | "styles", 9 | "settings", 10 | "_links" 11 | ], 12 | "properties": { 13 | "styles": { 14 | "description": "Global styles.", 15 | "type": "object" 16 | }, 17 | "settings": { 18 | "description": "Global settings.", 19 | "type": "object" 20 | }, 21 | "_links": { 22 | "$ref": "properties/object-links.json" 23 | } 24 | }, 25 | "links": [ 26 | { 27 | "rel": "self", 28 | "href": "/wp/v2/global-styles/themes/{theme}", 29 | "hrefSchema": { 30 | "properties": { 31 | "id": { 32 | "type": "string" 33 | } 34 | } 35 | }, 36 | "targetSchema": { 37 | "$ref": "#" 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /tests/output/themes.php: -------------------------------------------------------------------------------- 1 | 'view', 8 | ] ); 9 | $edit_data = get_rest_response( 'GET', '/wp/v2/themes', [ 10 | 'context' => 'edit', 11 | ] ); 12 | 13 | save_rest_array( [ 14 | $view_data, 15 | $edit_data, 16 | ], 'themes' ); 17 | 18 | // Generate REST API responses for individual themes 19 | $theme_data = []; 20 | 21 | // Get theme stylesheets from the collection response 22 | $view_response_data = $view_data->get_data(); 23 | 24 | foreach ( $view_response_data as $theme ) { 25 | $stylesheet = $theme['stylesheet']; 26 | 27 | // Generate REST API responses for individual theme 28 | $theme_data[] = get_rest_response( 'GET', "/wp/v2/themes/{$stylesheet}", [ 29 | 'context' => 'view', 30 | ] ); 31 | $theme_data[] = get_rest_response( 'GET', "/wp/v2/themes/{$stylesheet}", [ 32 | 'context' => 'edit', 33 | ] ); 34 | } 35 | 36 | save_rest_array( $theme_data, 'theme', true ); 37 | -------------------------------------------------------------------------------- /schemas/network.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/network.json", 4 | "title": "WP_Network", 5 | "description": "Core class used for interacting with a multisite network.", 6 | "type": "object", 7 | "required": [ 8 | "domain", 9 | "path", 10 | "cookie_domain", 11 | "site_name" 12 | ], 13 | "properties": { 14 | "domain": { 15 | "description": "Domain of the network.", 16 | "type": "string", 17 | "format": "hostname" 18 | }, 19 | "path": { 20 | "description": "Path of the network.", 21 | "type": "string", 22 | "format": "uri-reference" 23 | }, 24 | "cookie_domain": { 25 | "description": "Domain used to set cookies for this network.", 26 | "type": "string", 27 | "format": "hostname" 28 | }, 29 | "site_name": { 30 | "description": "Name of this network.\n\nNamed \"site\" vs. \"network\" for legacy reasons.", 31 | "type": "string" 32 | } 33 | }, 34 | "additionalProperties": false 35 | } 36 | -------------------------------------------------------------------------------- /schemas/rest-api/block-pattern-category.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/block-pattern-category.json", 4 | "title": "WP_REST_API_Block_Pattern_Category", 5 | "description": "A block pattern category in a REST API context.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "name", 10 | "label" 11 | ], 12 | "properties": { 13 | "name": { 14 | "description": "The category name.", 15 | "type": "string" 16 | }, 17 | "label": { 18 | "description": "The category label, in human readable format.", 19 | "type": "string" 20 | }, 21 | "description": { 22 | "description": "The category description, in human readable format.", 23 | "type": "string" 24 | } 25 | }, 26 | "links": [ 27 | { 28 | "rel": "collection", 29 | "href": "/wp/v2/block-patterns/categories", 30 | "targetSchema": { 31 | "type": "array", 32 | "items": { 33 | "$ref": "#" 34 | } 35 | } 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /tests/bin/build-wp-types.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # -e Exit immediately if a pipeline returns a non-zero status 4 | # -o pipefail Produce a failure return code if any command errors 5 | set -eo pipefail 6 | 7 | # Set additionalProperties to false for all partial schemas 8 | for file in schemas/rest-api/partials/**/*.json 9 | do 10 | jq --tab '. + { "additionalProperties": false }' "$file" > tmp && mv tmp "$file" 11 | done 12 | 13 | # Generate TypeScript types 14 | ./node_modules/.bin/json2ts -i schema.json -o packages/wp-types/index.ts --style.trailingComma=all --style.useTabs 15 | 16 | # Revert additionalProperties 17 | for file in schemas/rest-api/partials/**/*.json 18 | do 19 | jq --tab 'del(.additionalProperties)' "$file" > tmp && mv tmp "$file" 20 | done 21 | 22 | # Append append.ts to the generated types 23 | cat packages/wp-types/append.ts >> packages/wp-types/index.ts 24 | 25 | # Don't export the partial interfaces 26 | sed -i.bak 's/export interface WP_REST_API_Partial_/interface WP_REST_API_Partial_/g' packages/wp-types/index.ts 27 | rm packages/wp-types/index.ts.bak 28 | -------------------------------------------------------------------------------- /schemas/rest-api/partials/post/public.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/partials/post/public.json", 4 | "title": "WP_REST_API_Partial_Post_Public", 5 | "description": "Properties for public post types", 6 | "type": "object", 7 | "required": [ 8 | "class_list" 9 | ], 10 | "properties": { 11 | "permalink_template": { 12 | "readOnly": true, 13 | "description": "Permalink template for the post. Only present when using the 'edit' context and the post type is public.", 14 | "type": "string" 15 | }, 16 | "generated_slug": { 17 | "readOnly": true, 18 | "description": "Slug automatically generated from the post title. Only present when using the 'edit' context and the post type is public.", 19 | "type": "string" 20 | }, 21 | "class_list": { 22 | "readOnly": true, 23 | "description": "An array of the class names for the post container element.", 24 | "type": "array", 25 | "items": { 26 | "type": "string" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /schemas/properties/post-type-rewrite.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/post-type-rewrite.json", 4 | "title": "WP_Post_Type_Rewrite", 5 | "type": "object", 6 | "description": "Post type rewrite rule definition.", 7 | "required": [ 8 | "slug", 9 | "with_front", 10 | "feeds", 11 | "pages", 12 | "ep_mask" 13 | ], 14 | "properties": { 15 | "slug": { 16 | "description": "Customize the permastruct slug.", 17 | "type": "string" 18 | }, 19 | "with_front": { 20 | "description": "Whether the permastruct should be prepended with WP_Rewrite::$front.", 21 | "type": "boolean" 22 | }, 23 | "feeds": { 24 | "description": "Whether the feed permastruct should be built for this post type.", 25 | "type": "boolean" 26 | }, 27 | "pages": { 28 | "description": "Whether the permastruct should provide for pagination.", 29 | "type": "boolean" 30 | }, 31 | "ep_mask": { 32 | "description": "Endpoint mask to assign.", 33 | "type": "integer" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/output/user.php: -------------------------------------------------------------------------------- 1 | role_objects; 6 | 7 | array_map( 8 | function( \WP_Role $role ) { 9 | $args = new \Args\wp_insert_user; 10 | $args->role = $role->name; 11 | $args->user_login = sprintf( 12 | 'user-%s', 13 | $role->name 14 | ); 15 | $args->user_email = sprintf( 16 | 'user-%s@example.net', 17 | $role->name 18 | ); 19 | $args->user_pass = '123'; 20 | 21 | $user = wp_insert_user( $args->toArray() ); 22 | 23 | if ( is_wp_error( $user ) ) { 24 | throw new \Exception( $user->get_error_message() ); 25 | } 26 | }, 27 | $roles 28 | ); 29 | 30 | $users = get_users( [ 31 | 'number' => -1, 32 | 'orderby' => 'ID', 33 | 'order' => 'ASC', 34 | ] ); 35 | 36 | save_object_array( $users, 'user' ); 37 | 38 | $view_data = get_rest_response( 'GET', '/wp/v2/users', [ 39 | 'context' => 'view', 40 | 'per_page' => 100, 41 | ] ); 42 | $edit_data = get_rest_response( 'GET', '/wp/v2/users', [ 43 | 'context' => 'edit', 44 | 'per_page' => 100, 45 | ] ); 46 | 47 | save_rest_array( [ 48 | $view_data, 49 | $edit_data, 50 | ], 'users' ); 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2021 John Blackbourn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wp-json-schemas", 3 | "version": "4.69.0", 4 | "description": "JSON schemas for WordPress PHP objects and REST API responses", 5 | "main": "schema.json", 6 | "files": [ 7 | "schemas" 8 | ], 9 | "homepage": "https://github.com/johnbillion/wp-json-schemas", 10 | "funding": "https://github.com/sponsors/johnbillion", 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/johnbillion/wp-json-schemas" 14 | }, 15 | "keywords": [ 16 | "schemas", 17 | "wordpress" 18 | ], 19 | "author": "John Blackbourn", 20 | "license": "MIT", 21 | "devDependencies": { 22 | "ajv-cli": "^5.0", 23 | "ajv-formats": "^3.0", 24 | "json-schema-to-typescript": "^15.0", 25 | "typescript": ">=4" 26 | }, 27 | "scripts": { 28 | "version": "cd packages/wp-types && npm version $(node -p -e \"require('../../package.json').version\") && git add .", 29 | "test-wp-types": "tsc packages/wp-types/tests/test.ts --noEmit --strict --target es2015", 30 | "validate": "ajv compile --spec=draft2019 --strict --strict-schema=false -c ajv-formats -m tests/external-schemas/hyper-schema.json -s schema.json -r \"schemas/**/*.json\"" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/wp-types/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2021 John Blackbourn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/output/term.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'category', 8 | 'post_tag', 9 | ], 10 | 'number' => 0, 11 | 'orderby' => 'term_id', 12 | 'order' => 'ASC', 13 | ] ); 14 | 15 | save_object_array( $categories, 'term' ); 16 | 17 | $category_view_data = get_rest_response( 'GET', '/wp/v2/categories', [ 18 | 'context' => 'view', 19 | 'per_page' => 100, 20 | ] ); 21 | $category_edit_data = get_rest_response( 'GET', '/wp/v2/categories', [ 22 | 'context' => 'edit', 23 | 'per_page' => 100, 24 | ] ); 25 | 26 | $tag_view_data = get_rest_response( 'GET', '/wp/v2/tags', [ 27 | 'context' => 'view', 28 | 'per_page' => 100, 29 | ] ); 30 | $tag_edit_data = get_rest_response( 'GET', '/wp/v2/tags', [ 31 | 'context' => 'edit', 32 | 'per_page' => 100, 33 | ] ); 34 | 35 | save_rest_array( [ 36 | $category_view_data, 37 | $category_edit_data, 38 | ], 'categories' ); 39 | 40 | save_rest_array( [ 41 | $tag_view_data, 42 | $tag_edit_data, 43 | ], 'tags' ); 44 | 45 | save_rest_array( [ 46 | $category_view_data, 47 | $category_edit_data, 48 | $tag_view_data, 49 | $tag_edit_data, 50 | ], 'terms' ); 51 | -------------------------------------------------------------------------------- /schemas/rest-api/error.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/error.json", 4 | "title": "WP_REST_API_Error", 5 | "description": "A REST API error response.", 6 | "type": "object", 7 | "required": [ 8 | "code", 9 | "message", 10 | "data" 11 | ], 12 | "properties": { 13 | "code": { 14 | "description": "The error message code.", 15 | "type": "string" 16 | }, 17 | "message": { 18 | "description": "The error message text.", 19 | "type": "string" 20 | }, 21 | "data": { 22 | "description": "Extra data about the error", 23 | "type": "object", 24 | "properties": { 25 | "status": { 26 | "description": "The HTTP status code", 27 | "oneOf": [ 28 | { 29 | "$ref": "properties/http-status-code.json" 30 | } 31 | ] 32 | } 33 | } 34 | }, 35 | "additional_errors": { 36 | "description": "Additional error objects, if there are any.", 37 | "type": "array", 38 | "items": { 39 | "$ref": "error.json" 40 | } 41 | } 42 | }, 43 | "additionalProperties": false 44 | } 45 | -------------------------------------------------------------------------------- /schemas/rest-api/template-part.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/template-part.json", 4 | "title": "WP_REST_API_Template_Part", 5 | "description": "A block template part object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "./partials/template/common.json" 10 | }, 11 | { 12 | "type": "object", 13 | "properties": { 14 | "area": { 15 | "description": "Where the template part is intended for use (header, footer, etc.)", 16 | "type": "string" 17 | } 18 | } 19 | } 20 | ], 21 | "links": [ 22 | { 23 | "rel": "self", 24 | "href": "/wp/v2/template-parts/{id}", 25 | "hrefSchema": { 26 | "properties": { 27 | "id": { 28 | "$ref": "./partials/template/common.json#/properties/id" 29 | } 30 | } 31 | }, 32 | "targetSchema": { 33 | "$ref": "#" 34 | } 35 | }, 36 | { 37 | "rel": "collection", 38 | "href": "/wp/v2/template-parts", 39 | "targetSchema": { 40 | "$ref": "collections/template-parts.json" 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /schemas/rest-api/partials/post/excerpt.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/partials/post/excerpt.json", 4 | "title": "WP_REST_API_Partial_Post_Excerpt", 5 | "description": "Properties for post types that support an excerpt", 6 | "type": "object", 7 | "required": [ 8 | "excerpt" 9 | ], 10 | "properties": { 11 | "excerpt": { 12 | "description": "The excerpt for the post.", 13 | "type": "object", 14 | "required": [ 15 | "rendered", 16 | "protected" 17 | ], 18 | "properties": { 19 | "raw": { 20 | "description": "Excerpt for the post, as it exists in the database. Only present when using the 'edit' context.", 21 | "contentMediaType": "text/html", 22 | "type": "string" 23 | }, 24 | "rendered": { 25 | "readOnly": true, 26 | "description": "HTML excerpt for the post, transformed for display.", 27 | "contentMediaType": "text/html", 28 | "type": "string" 29 | }, 30 | "protected": { 31 | "readOnly": true, 32 | "description": "Whether the excerpt is protected with a password.", 33 | "type": "boolean" 34 | } 35 | }, 36 | "additionalProperties": false 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/output/with-theme/twentytwentyone/menus.php: -------------------------------------------------------------------------------- 1 | 'Home', 10 | 'menu-item-url' => home_url( '/' ), 11 | 'menu-item-status' => 'publish', 12 | ] ); 13 | wp_update_nav_menu_item( $menu_id, 0, [ 14 | 'menu-item-title' => 'About', 15 | 'menu-item-url' => home_url( '/about/' ), 16 | 'menu-item-status' => 'publish', 17 | ] ); 18 | wp_update_nav_menu_item( $menu_id, 0, [ 19 | 'menu-item-title' => 'Contact', 20 | 'menu-item-url' => home_url( '/contact/' ), 21 | 'menu-item-status' => 'publish', 22 | ] ); 23 | 24 | $locations = get_theme_mod( 'nav_menu_locations' ) ?: []; 25 | $locations['primary'] = $menu_id; 26 | set_theme_mod( 'nav_menu_locations', $locations ); 27 | 28 | foreach ( [ 'menu-locations', 'menu-items', 'menus' ] as $type ) { 29 | $view_data = get_rest_response( 'GET', "/wp/v2/{$type}", [ 30 | 'context' => 'view', 31 | 'per_page' => 100, 32 | ] ); 33 | $edit_data = get_rest_response( 'GET', "/wp/v2/{$type}", [ 34 | 'context' => 'edit', 35 | 'per_page' => 100, 36 | ] ); 37 | 38 | save_rest_array( [ 39 | $view_data, 40 | $edit_data, 41 | ], $type ); 42 | } 43 | -------------------------------------------------------------------------------- /schemas/rest-api/navigation-menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/navigation-menu.json", 4 | "title": "WP_REST_API_Navigation_Menu", 5 | "description": "A navigation menu object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "partials/post/common.json" 10 | } 11 | ], 12 | "links": [ 13 | { 14 | "rel": "self", 15 | "href": "/wp/v2/navigation/{id}", 16 | "hrefSchema": { 17 | "properties": { 18 | "id": { 19 | "$ref": "partials/post/common.json#/properties/id" 20 | } 21 | } 22 | }, 23 | "targetSchema": { 24 | "$ref": "#" 25 | } 26 | }, 27 | { 28 | "rel": "collection", 29 | "href": "/wp/v2/navigation", 30 | "targetSchema": { 31 | "type": "array", 32 | "items": { 33 | "$ref": "#" 34 | } 35 | } 36 | }, 37 | { 38 | "rel": "version-history", 39 | "href": "/wp/v2/navigation/{id}/revisions", 40 | "hrefSchema": { 41 | "properties": { 42 | "id": { 43 | "$ref": "partials/post/common.json#/properties/id" 44 | } 45 | } 46 | }, 47 | "targetSchema": { 48 | "type": "array", 49 | "items": { 50 | "$ref": "#" 51 | } 52 | } 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /schemas/rest-api/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/template.json", 4 | "title": "WP_REST_API_Template", 5 | "description": "A block template object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "./partials/template/common.json" 10 | }, 11 | { 12 | "type": "object", 13 | "required": [ 14 | "is_custom" 15 | ], 16 | "properties": { 17 | "is_custom": { 18 | "description": "Whether a template is custom.", 19 | "type": "boolean", 20 | "readOnly": true 21 | }, 22 | "plugin": { 23 | "description": "Plugin that registered the template.", 24 | "type": "string", 25 | "readOnly": true 26 | } 27 | } 28 | } 29 | ], 30 | "links": [ 31 | { 32 | "rel": "self", 33 | "href": "/wp/v2/templates/{id}", 34 | "hrefSchema": { 35 | "properties": { 36 | "id": { 37 | "$ref": "./partials/template/common.json#/properties/id" 38 | } 39 | } 40 | }, 41 | "targetSchema": { 42 | "$ref": "#" 43 | } 44 | }, 45 | { 46 | "rel": "collection", 47 | "href": "/wp/v2/templates", 48 | "targetSchema": { 49 | "$ref": "collections/templates.json" 50 | } 51 | } 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /schemas/rest-api/collections/global-style-variations.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/global-style-variations.json", 4 | "title": "WP_REST_API_Global_Style_Variations", 5 | "description": "A collection of global styles variations in a REST API context.", 6 | "type": "array", 7 | "items": { 8 | "$comment": "These items are not the same shape as a single global styles variation object.", 9 | "type": "object", 10 | "required": [ 11 | "version", 12 | "title" 13 | ], 14 | "properties": { 15 | "version": { 16 | "description": "Version number of the global styles variation.", 17 | "type": "integer" 18 | }, 19 | "styles": { 20 | "description": "Global styles.", 21 | "type": "object" 22 | }, 23 | "settings": { 24 | "description": "Global settings.", 25 | "type": "object" 26 | }, 27 | "title": { 28 | "description": "Title of the global styles variation.", 29 | "type": "string" 30 | } 31 | } 32 | }, 33 | "links": [ 34 | { 35 | "rel": "self", 36 | "href": "/wp/v2/global-styles/themes/{theme}/variations", 37 | "hrefSchema": { 38 | "properties": { 39 | "id": { 40 | "type": "string" 41 | } 42 | } 43 | }, 44 | "targetSchema": { 45 | "$ref": "#" 46 | } 47 | } 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /schemas/rest-api/menu-location.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/menu-location.json", 4 | "title": "WP_REST_API_Menu_Location", 5 | "description": "A menu location in a REST API context.", 6 | "type": "object", 7 | "required": [ 8 | "name", 9 | "description", 10 | "menu", 11 | "_links" 12 | ], 13 | "properties": { 14 | "name": { 15 | "description": "The name of the menu location.", 16 | "type": "string", 17 | "readOnly": true 18 | }, 19 | "description": { 20 | "description": "The description of the menu location.", 21 | "type": "string", 22 | "readOnly": true 23 | }, 24 | "menu": { 25 | "description": "The ID of the assigned menu.", 26 | "type": "integer", 27 | "readOnly": true 28 | }, 29 | "_links": { 30 | "$ref": "properties/object-links.json" 31 | } 32 | }, 33 | "links": [ 34 | { 35 | "rel": "self", 36 | "href": "/wp/v2/menu-locations/{name}", 37 | "hrefSchema": { 38 | "properties": { 39 | "name": { 40 | "$ref": "#/properties/name" 41 | } 42 | } 43 | }, 44 | "targetSchema": { 45 | "$ref": "#" 46 | } 47 | }, 48 | { 49 | "rel": "collection", 50 | "href": "/wp/v2/menu-locations", 51 | "targetSchema": { 52 | "type": "array", 53 | "items": { 54 | "$ref": "#" 55 | } 56 | } 57 | } 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /tests/wp-config.php: -------------------------------------------------------------------------------- 1 | 'pages', 7 | 'post' => 'posts', 8 | 'wp_block' => 'blocks', 9 | 'wp_navigation' => 'navigation', 10 | ]; 11 | $data = []; 12 | 13 | foreach ( $endpoints as $post_type => $slug ) { 14 | $id = wp_insert_post( [ 15 | 'post_type' => $post_type, 16 | 'post_title' => 'Title', 17 | 'post_content' => '

Content

', 18 | 'post_status' => 'publish', 19 | ], true ); 20 | 21 | if ( is_wp_error( $id ) ) { 22 | throw new \Exception( "Failed to create {$post_type} post for revisions: " . $id->get_error_message() ); 23 | } 24 | 25 | $update_result = wp_update_post( [ 26 | 'ID' => $id, 27 | 'post_title' => 'Hello 2', 28 | ], true ); 29 | 30 | if ( is_wp_error( $update_result ) ) { 31 | throw new \Exception( "Failed to update {$post_type} post (revision 2): " . $update_result->get_error_message() ); 32 | } 33 | 34 | $update_result = wp_update_post( [ 35 | 'ID' => $id, 36 | 'post_title' => 'Hello 3', 37 | ], true ); 38 | 39 | if ( is_wp_error( $update_result ) ) { 40 | throw new \Exception( "Failed to update {$post_type} post (revision 3): " . $update_result->get_error_message() ); 41 | } 42 | 43 | $data[] = get_rest_response( 'GET', "/wp/v2/{$slug}/{$id}/revisions", [ 44 | 'context' => 'view', 45 | 'per_page' => 100, 46 | ] ); 47 | $data[] = get_rest_response( 'GET', "/wp/v2/{$slug}/{$id}/revisions", [ 48 | 'context' => 'edit', 49 | 'per_page' => 100, 50 | ] ); 51 | } 52 | 53 | save_rest_array( $data, 'revisions' ); 54 | -------------------------------------------------------------------------------- /tests/output/templates.php: -------------------------------------------------------------------------------- 1 | 'Test Plugin Template', 10 | 'description' => 'A test template registered by a plugin', 11 | 'content' => '

This is a plugin-registered template.

', 12 | ] 13 | ); 14 | 15 | // Generate REST API responses for templates collection 16 | $view_data = get_rest_response( 'GET', '/wp/v2/templates', [ 17 | 'context' => 'view', 18 | ] ); 19 | $edit_data = get_rest_response( 'GET', '/wp/v2/templates', [ 20 | 'context' => 'edit', 21 | ] ); 22 | 23 | save_rest_array( [ 24 | $view_data, 25 | $edit_data, 26 | ], 'templates' ); 27 | 28 | // Generate REST API responses for individual templates 29 | $template_data = []; 30 | 31 | // Get template IDs from the collection response 32 | $view_response_data = $view_data->get_data(); 33 | 34 | foreach ( $view_response_data as $template ) { 35 | $id = $template['id']; 36 | 37 | // Generate REST API responses for individual template 38 | $template_data[] = get_rest_response( 'GET', "/wp/v2/templates/{$id}", [ 39 | 'context' => 'view', 40 | ] ); 41 | $template_data[] = get_rest_response( 'GET', "/wp/v2/templates/{$id}", [ 42 | 'context' => 'edit', 43 | ] ); 44 | } 45 | 46 | // Add lookup endpoint test 47 | $template_data[] = get_rest_response( 'GET', '/wp/v2/templates/lookup', [ 48 | 'slug' => 'single', 49 | ] ); 50 | 51 | save_rest_array( $template_data, 'template', true ); 52 | -------------------------------------------------------------------------------- /schemas/properties/post-type-caps.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/post-type-caps.json", 4 | "title": "WP_Post_Type_Caps", 5 | "type": "object", 6 | "description": "Post type capabilities.", 7 | "required": [ 8 | "edit_post", 9 | "read_post", 10 | "delete_post", 11 | "edit_posts", 12 | "edit_others_posts", 13 | "delete_posts", 14 | "publish_posts", 15 | "read_private_posts", 16 | "create_posts" 17 | ], 18 | "properties": { 19 | "edit_post": { 20 | "$ref": "user-cap-name.json" 21 | }, 22 | "read_post": { 23 | "$ref": "user-cap-name.json" 24 | }, 25 | "delete_post": { 26 | "$ref": "user-cap-name.json" 27 | }, 28 | "edit_posts": { 29 | "$ref": "user-cap-name.json" 30 | }, 31 | "edit_others_posts": { 32 | "$ref": "user-cap-name.json" 33 | }, 34 | "delete_posts": { 35 | "$ref": "user-cap-name.json" 36 | }, 37 | "publish_posts": { 38 | "$ref": "user-cap-name.json" 39 | }, 40 | "read_private_posts": { 41 | "$ref": "user-cap-name.json" 42 | }, 43 | "read": { 44 | "$ref": "user-cap-name.json" 45 | }, 46 | "delete_private_posts": { 47 | "$ref": "user-cap-name.json" 48 | }, 49 | "delete_published_posts": { 50 | "$ref": "user-cap-name.json" 51 | }, 52 | "delete_others_posts": { 53 | "$ref": "user-cap-name.json" 54 | }, 55 | "edit_private_posts": { 56 | "$ref": "user-cap-name.json" 57 | }, 58 | "edit_published_posts": { 59 | "$ref": "user-cap-name.json" 60 | }, 61 | "create_posts": { 62 | "$ref": "user-cap-name.json" 63 | } 64 | }, 65 | "additionalProperties": false 66 | } 67 | -------------------------------------------------------------------------------- /schemas/rest-api/search-result.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/search-result.json", 4 | "title": "WP_REST_API_Search_Result", 5 | "description": "A search result in a REST API context.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "id", 10 | "title", 11 | "url", 12 | "type", 13 | "subtype", 14 | "_links" 15 | ], 16 | "properties": { 17 | "id": { 18 | "description": "Unique identifier for the object.", 19 | "oneOf": [ 20 | { 21 | "type": "integer" 22 | }, 23 | { 24 | "type": "string" 25 | } 26 | ] 27 | }, 28 | "title": { 29 | "description": "The title for the object.", 30 | "type": "string" 31 | }, 32 | "url": { 33 | "description": "URL to the object.", 34 | "type": "string", 35 | "format": "uri" 36 | }, 37 | "type": { 38 | "description": "Object type.", 39 | "type": "string", 40 | "enum": [ 41 | "post", 42 | "term", 43 | "post-format" 44 | ] 45 | }, 46 | "subtype": { 47 | "description": "Object subtype.", 48 | "type": "string" 49 | }, 50 | "_links": { 51 | "$ref": "properties/object-links.json" 52 | }, 53 | "_embedded": { 54 | "description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.", 55 | "type": "object", 56 | "required": [ 57 | "self" 58 | ], 59 | "properties": { 60 | "self": { 61 | "description": "The search result.", 62 | "type": "array", 63 | "items": { 64 | "type": "object" 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /schemas/properties/block-parsed.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/block-parsed.json", 4 | "title": "WP_Block_Parsed", 5 | "description": "Original parsed array representation of block.", 6 | "type": "object", 7 | "required": [ 8 | "blockName", 9 | "attrs", 10 | "innerBlocks", 11 | "innerHTML", 12 | "innerContent" 13 | ], 14 | "properties": { 15 | "blockName": { 16 | "description": "Name of block.", 17 | "type": "string", 18 | "examples": [ 19 | "core/paragraph", 20 | "core/columns", 21 | "foo/bar" 22 | ] 23 | }, 24 | "attrs": { 25 | "oneOf": [ 26 | { 27 | "type": "object", 28 | "additionalProperties": { 29 | "tsType": "any" 30 | } 31 | }, 32 | { 33 | "$ref": "../../schema.json#/definitions/EmptyArray" 34 | } 35 | ] 36 | }, 37 | "innerBlocks": { 38 | "description": "List of inner blocks (of this same class).", 39 | "type": "array", 40 | "items": { 41 | "$ref": "#" 42 | } 43 | }, 44 | "innerHTML": { 45 | "description": "Resultant HTML from inside block comment delimiters after removing inner blocks.", 46 | "contentMediaType": "text/html", 47 | "type": "string" 48 | }, 49 | "innerContent": { 50 | "description": "List of string fragments and null markers where inner blocks were found.", 51 | "type": "array", 52 | "items": { 53 | "oneOf": [ 54 | { 55 | "contentMediaType": "text/html", 56 | "type": "string" 57 | }, 58 | { 59 | "type": "null" 60 | } 61 | ] 62 | } 63 | } 64 | }, 65 | "additionalProperties": false 66 | } 67 | -------------------------------------------------------------------------------- /tests/output/error.php: -------------------------------------------------------------------------------- 1 | 'value', 25 | ] 26 | ); 27 | 28 | $errors[] = new WP_Error( 29 | 'foo', 30 | 'Foo', 31 | null 32 | ); 33 | 34 | $multi_error = new WP_Error( 35 | 'foo', 36 | 'Foo' 37 | ); 38 | $multi_error->add( 39 | 'bar', 40 | 'Bar' 41 | ); 42 | $errors[] = $multi_error; 43 | 44 | $multi_code_1 = new WP_Error( 45 | 'foo', 46 | 'Foo' 47 | ); 48 | $multi_code_2 = new WP_Error( 49 | 'foo', 50 | 'Bar' 51 | ); 52 | $multi_code_1->merge_from( $multi_code_2 ); 53 | $errors[] = $multi_code_1; 54 | 55 | $errors_without_error = []; 56 | 57 | $errors_without_error[] = new WP_Error(); 58 | 59 | $all_errors = array_merge( $errors, $errors_without_error ); 60 | 61 | save_object_array( $all_errors, 'error' ); 62 | save_object_array( $errors, 'error-with-error' ); 63 | save_object_array( $errors_without_error, 'error-without-error' ); 64 | 65 | $posts = get_posts( [ 66 | 'posts_per_page' => 1, 67 | 'post_status' => 'publish', 68 | ] ); 69 | 70 | if ( empty( $posts ) ) { 71 | throw new \Exception( 'Failed to find a published post for error testing' ); 72 | } 73 | 74 | $post_id = $posts[0]->ID; 75 | 76 | $data_route_404 = get_rest_response( 'GET', '/wp/v2/bananas' ); 77 | $data_object_404 = get_rest_response( 'GET', '/wp/v2/posts/99999' ); 78 | $data_save_400 = get_rest_response( 'POST', "/wp/v2/posts/{$post_id}", [ 79 | 'slug' => false, 80 | ] ); 81 | 82 | save_rest_array( [ 83 | $data_route_404, 84 | $data_object_404, 85 | $data_save_400, 86 | ], 'error', false, true ); 87 | -------------------------------------------------------------------------------- /tests/output/attachment.php: -------------------------------------------------------------------------------- 1 | 'I am a parent', 8 | 'post_type' => 'post', 9 | ], 10 | true 11 | ); 12 | 13 | if ( is_wp_error( $parent ) ) { 14 | throw new \Exception( 'Failed to create parent post: ' . $parent->get_error_message() ); 15 | } 16 | 17 | $attachment_with_parent = wp_insert_attachment( 18 | [ 19 | 'post_title' => 'I am an attachment with a parent', 20 | ], 21 | false, 22 | $parent, 23 | true 24 | ); 25 | 26 | if ( is_wp_error( $attachment_with_parent ) ) { 27 | throw new \Exception( 'Failed to create attachment with parent: ' . $attachment_with_parent->get_error_message() ); 28 | } 29 | 30 | $attachment_without_parent = wp_insert_attachment( 31 | [ 32 | 'post_title' => 'I am an attachment without a parent', 33 | ], 34 | false, 35 | 0, 36 | true 37 | ); 38 | 39 | if ( is_wp_error( $attachment_without_parent ) ) { 40 | throw new \Exception( 'Failed to create attachment without parent: ' . $attachment_without_parent->get_error_message() ); 41 | } 42 | 43 | $attachments = get_posts( [ 44 | 'post_type' => 'attachment', 45 | 'posts_per_page' => -1, 46 | 'post_status' => 'any', 47 | 'orderby' => 'ID', 48 | 'order' => 'ASC', 49 | ] ); 50 | 51 | save_object_array( $attachments, 'attachment' ); 52 | 53 | $view_data = get_rest_response( 'GET', '/wp/v2/media', [ 54 | 'context' => 'view', 55 | 'per_page' => 100, 56 | ] ); 57 | $edit_data = get_rest_response( 'GET', '/wp/v2/media', [ 58 | 'context' => 'edit', 59 | 'per_page' => 100, 60 | ] ); 61 | 62 | $empty_response = get_rest_response( 'GET', '/wp/v2/media', [ 63 | 'search' => '1234567890', 64 | ] ); 65 | 66 | save_rest_array( [ 67 | $view_data, 68 | $edit_data, 69 | $empty_response, 70 | ], 'media' ); 71 | -------------------------------------------------------------------------------- /schemas/screen.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/screen.json", 4 | "title": "WP_Screen", 5 | "description": "Core class used to implement an admin screen API.", 6 | "type": "object", 7 | "required": [ 8 | "action", 9 | "base", 10 | "id", 11 | "is_network", 12 | "is_user", 13 | "parent_base", 14 | "parent_file", 15 | "post_type", 16 | "taxonomy", 17 | "is_block_editor" 18 | ], 19 | "properties": { 20 | "action": { 21 | "description": "Any action associated with the screen.", 22 | "type": "string" 23 | }, 24 | "base": { 25 | "description": "The base type of the screen.", 26 | "type": "string" 27 | }, 28 | "id": { 29 | "description": "The unique ID of the screen.", 30 | "type": "string" 31 | }, 32 | "is_network": { 33 | "description": "Whether the screen is in the network admin.", 34 | "type": "boolean" 35 | }, 36 | "is_user": { 37 | "description": "Whether the screen is in the user admin.", 38 | "type": "boolean" 39 | }, 40 | "parent_base": { 41 | "description": "The base menu parent.", 42 | "type": [ 43 | "string", 44 | "null" 45 | ] 46 | }, 47 | "parent_file": { 48 | "description": "The parent_file for the screen per the admin menu system.", 49 | "type": [ 50 | "string", 51 | "null" 52 | ] 53 | }, 54 | "post_type": { 55 | "description": "The post type associated with the screen, if any.", 56 | "type": "string" 57 | }, 58 | "taxonomy": { 59 | "description": "The taxonomy associated with the screen, if any.", 60 | "type": "string" 61 | }, 62 | "is_block_editor": { 63 | "description": "The help tab data associated with the screen, if any.", 64 | "type": "boolean" 65 | } 66 | }, 67 | "additionalProperties": false 68 | } 69 | -------------------------------------------------------------------------------- /schemas/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/user.json", 4 | "title": "WP_User", 5 | "description": "Core class used to implement the WP_User object.", 6 | "type": "object", 7 | "required": [ 8 | "ID", 9 | "allcaps", 10 | "cap_key", 11 | "caps", 12 | "data", 13 | "filter", 14 | "roles" 15 | ], 16 | "properties": { 17 | "ID": { 18 | "readOnly": true, 19 | "description": "The user's ID.", 20 | "type": "integer" 21 | }, 22 | "allcaps": { 23 | "description": "All capabilities the user has, including individual and role based.", 24 | "allOf": [ 25 | { 26 | "$ref": "properties/user-caps.json" 27 | } 28 | ] 29 | }, 30 | "cap_key": { 31 | "description": "User metadata option name.", 32 | "type": "string" 33 | }, 34 | "caps": { 35 | "description": "The individual capabilities the user has been given.\n\nSee the allcaps property for a complete list of caps that the user has.", 36 | "allOf": [ 37 | { 38 | "$ref": "properties/user-caps.json" 39 | } 40 | ] 41 | }, 42 | "data": { 43 | "description": "User data container.", 44 | "allOf": [ 45 | { 46 | "$ref": "properties/user-data.json" 47 | } 48 | ] 49 | }, 50 | "filter": { 51 | "description": "The filter context applied to user data fields.", 52 | "oneOf": [ 53 | { 54 | "$ref": "properties/object-filter-context.json" 55 | }, 56 | { 57 | "type": "null" 58 | } 59 | ] 60 | }, 61 | "roles": { 62 | "description": "The roles the user is part of.", 63 | "type": "array", 64 | "items": { 65 | "anyOf": [ 66 | { 67 | "$ref": "properties/user-role-name.json" 68 | }, 69 | { 70 | "type": "string" 71 | } 72 | ] 73 | } 74 | } 75 | }, 76 | "additionalProperties": false 77 | } 78 | -------------------------------------------------------------------------------- /schemas/rest-api/partials/revision/post-like.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/partials/revision/post-like.json", 4 | "title": "WP_REST_API_Partial_Revision_Post_Like", 5 | "description": "Revision properties specific to post-like content types (posts, pages, blocks, navigation)", 6 | "type": "object", 7 | "required": [ 8 | "guid", 9 | "slug" 10 | ], 11 | "properties": { 12 | "guid": { 13 | "description": "The globally unique identifier for the post.", 14 | "type": "object", 15 | "readOnly": true, 16 | "required": [ 17 | "rendered" 18 | ], 19 | "properties": { 20 | "raw": { 21 | "description": "GUID for the post, as it exists in the database. Only present when using the 'edit' context.", 22 | "type": "string", 23 | "readOnly": true 24 | }, 25 | "rendered": { 26 | "description": "GUID for the post, transformed for display.", 27 | "type": "string", 28 | "readOnly": true 29 | } 30 | }, 31 | "additionalProperties": false 32 | }, 33 | "slug": { 34 | "description": "An alphanumeric identifier for the revision unique to its type.", 35 | "type": "string" 36 | }, 37 | "excerpt": { 38 | "description": "The excerpt for the post.", 39 | "type": "object", 40 | "required": [ 41 | "rendered" 42 | ], 43 | "properties": { 44 | "raw": { 45 | "description": "Excerpt for the post, as it exists in the database. Only present when using the 'edit' context.", 46 | "contentMediaType": "text/html", 47 | "type": "string" 48 | }, 49 | "rendered": { 50 | "description": "HTML excerpt for the post, transformed for display.", 51 | "readOnly": true, 52 | "contentMediaType": "text/html", 53 | "type": "string" 54 | } 55 | }, 56 | "additionalProperties": false 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /schemas/rest-api/pattern-directory-pattern.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/pattern-directory-pattern.json", 4 | "title": "WP_REST_API_Pattern_Directory_Pattern", 5 | "description": "A pattern from the pattern directory in a REST API context.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "id", 10 | "title", 11 | "content", 12 | "categories", 13 | "keywords", 14 | "description", 15 | "viewport_width" 16 | ], 17 | "properties": { 18 | "id": { 19 | "description": "The pattern ID.", 20 | "type": "integer" 21 | }, 22 | "title": { 23 | "description": "The pattern title, in human readable format.", 24 | "type": "string" 25 | }, 26 | "content": { 27 | "description": "The pattern content.", 28 | "contentMediaType": "text/html", 29 | "type": "string" 30 | }, 31 | "categories": { 32 | "description": "The pattern category slugs.", 33 | "type": "array", 34 | "items": { 35 | "type": "string" 36 | } 37 | }, 38 | "keywords": { 39 | "description": "The pattern keywords.", 40 | "type": "array", 41 | "items": { 42 | "type": "string" 43 | } 44 | }, 45 | "description": { 46 | "description": "The pattern detailed description.", 47 | "type": "string" 48 | }, 49 | "viewport_width": { 50 | "description": "The pattern viewport width for inserter preview.", 51 | "type": "integer" 52 | }, 53 | "block_types": { 54 | "description": "Block types that the pattern is intended to be used with.", 55 | "type": "array", 56 | "items": { 57 | "type": "string" 58 | } 59 | } 60 | }, 61 | "links": [ 62 | { 63 | "rel": "collection", 64 | "href": "/wp/v2/pattern-directory/patterns", 65 | "targetSchema": { 66 | "type": "array", 67 | "items": { 68 | "$ref": "#" 69 | } 70 | } 71 | } 72 | ] 73 | } 74 | -------------------------------------------------------------------------------- /tests/output/routes.php: -------------------------------------------------------------------------------- 1 | get_data(); 6 | $namespaces = $root['namespaces']; 7 | $routes = []; 8 | 9 | foreach ( $namespaces as $namespace ) { 10 | $d = get_rest_response( 'GET', '/' . $namespace )->get_data(); 11 | $namespace_routes = array_map( function( array $data, string $route ) : array { 12 | $data['route'] = $route; 13 | return $data; 14 | }, $d['routes'], array_keys( $d['routes'] ) ); 15 | $routes = array_merge( $routes, $namespace_routes ); 16 | } 17 | 18 | $dir = 'routes'; 19 | $dir = dirname( ABSPATH ) . '/data/rest-api/' . $dir; 20 | 21 | if ( ! file_exists( $dir ) ) { 22 | mkdir( $dir, 0777, true ); 23 | } 24 | 25 | foreach ( $routes as $item ) { 26 | $i = preg_replace( '#[^a-z0-9]+#', '-', $item['route'] ); 27 | $i = preg_replace( '#\b[dsw]\b#', '', $i ); 28 | $i = str_replace( 'a-z', '', $i ); 29 | $i = str_replace( '0-9', '', $i ); 30 | $i = preg_replace( '#\-+#', '-', $i ); 31 | $i = trim( $i, '-' ); 32 | 33 | $save = [ 34 | 'route' => $item['route'], 35 | ]; 36 | 37 | $json = json_encode( $save, JSON_PRETTY_PRINT ^ JSON_UNESCAPED_SLASHES ); 38 | 39 | if ( $json === false ) { 40 | throw new \Exception( "Failed to encode JSON for route {$i}: " . json_last_error_msg() ); 41 | } 42 | 43 | $result = file_put_contents( $dir . '/' . $i . '.json', $json ); 44 | 45 | if ( $result === false ) { 46 | throw new \Exception( "Failed to write file {$dir}/{$i}.json" ); 47 | } 48 | } 49 | 50 | $all_routes = array_column( $routes, 'route' ); 51 | 52 | sort( $all_routes ); 53 | 54 | $json = json_encode( $all_routes, JSON_PRETTY_PRINT ^ JSON_UNESCAPED_SLASHES ); 55 | 56 | if ( $json === false ) { 57 | throw new \Exception( 'Failed to encode JSON for routes.json: ' . json_last_error_msg() ); 58 | } 59 | 60 | $result = file_put_contents( $dir . '/routes.json', $json ); 61 | 62 | if ( $result === false ) { 63 | throw new \Exception( "Failed to write file {$dir}/routes.json" ); 64 | } 65 | -------------------------------------------------------------------------------- /schemas/rest-api/application-password.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/application-password.json", 4 | "title": "WP_REST_API_Application_Password", 5 | "description": "A user application password in a REST API context.", 6 | "type": "object", 7 | "required": [ 8 | "uuid", 9 | "app_id", 10 | "name", 11 | "created", 12 | "last_used", 13 | "last_ip" 14 | ], 15 | "properties": { 16 | "uuid": { 17 | "description": "The unique identifier for the application password.", 18 | "type": "string", 19 | "format": "uuid", 20 | "readOnly": true 21 | }, 22 | "app_id": { 23 | "description": "A UUID provided by the application to uniquely identify it. It is recommended to use an UUID v5 with the URL or DNS namespace.", 24 | "type": "string" 25 | }, 26 | "name": { 27 | "description": "The name of the application password.", 28 | "type": "string", 29 | "minLength": 1, 30 | "pattern": ".*\\S.*" 31 | }, 32 | "password": { 33 | "description": "The generated password. Only available after adding an application.", 34 | "type": "string", 35 | "readOnly": true 36 | }, 37 | "created": { 38 | "description": "The GMT date the application password was created.", 39 | "oneOf": [ 40 | { 41 | "$ref": "properties/date-time.json" 42 | } 43 | ], 44 | "readOnly": true 45 | }, 46 | "last_used": { 47 | "description": "The GMT date the application password was last used.", 48 | "oneOf": [ 49 | { 50 | "$ref": "properties/date-time.json" 51 | }, 52 | { 53 | "type": "null" 54 | } 55 | ], 56 | "readOnly": true 57 | }, 58 | "last_ip": { 59 | "description": "The IP address the application password was last used by.", 60 | "type": [ 61 | "string", 62 | "null" 63 | ], 64 | "format": "ipv4", 65 | "readOnly": true 66 | }, 67 | "_links": { 68 | "$ref": "properties/object-links.json" 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /schemas/rest-api/term.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/term.json", 4 | "title": "WP_REST_API_Term", 5 | "description": "A taxonomy term object in a REST API context.", 6 | "type": "object", 7 | "required": [ 8 | "id", 9 | "count", 10 | "description", 11 | "link", 12 | "name", 13 | "slug", 14 | "taxonomy", 15 | "meta", 16 | "_links" 17 | ], 18 | "properties": { 19 | "id": { 20 | "readOnly": true, 21 | "description": "Unique identifier for the term.", 22 | "type": "integer" 23 | }, 24 | "count": { 25 | "readOnly": true, 26 | "description": "Number of published posts for the term.", 27 | "type": "integer" 28 | }, 29 | "description": { 30 | "description": "HTML description of the term.", 31 | "contentMediaType": "text/html", 32 | "type": "string" 33 | }, 34 | "link": { 35 | "readOnly": true, 36 | "description": "URL of the term.", 37 | "type": "string", 38 | "format": "uri" 39 | }, 40 | "name": { 41 | "description": "HTML title for the term.", 42 | "type": "string" 43 | }, 44 | "slug": { 45 | "description": "An alphanumeric identifier for the term unique to its type.", 46 | "type": "string" 47 | }, 48 | "taxonomy": { 49 | "readOnly": true, 50 | "description": "Type attribution for the term.", 51 | "anyOf": [ 52 | { 53 | "$ref": "../properties/taxonomy-name.json" 54 | }, 55 | { 56 | "type": "string" 57 | } 58 | ] 59 | }, 60 | "parent": { 61 | "description": "The parent term ID. Only present for hierarchical taxonomies.", 62 | "allOf": [ 63 | { 64 | "$ref": "#/properties/id" 65 | } 66 | ] 67 | }, 68 | "meta": { 69 | "description": "Meta fields.", 70 | "oneOf": [ 71 | { 72 | "$ref": "../../schema.json#/definitions/EmptyArray" 73 | }, 74 | { 75 | "type": "object" 76 | } 77 | ] 78 | }, 79 | "_links": { 80 | "$ref": "properties/object-links.json" 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /schemas/block-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/block-template.json", 4 | "title": "WP_Block_Template", 5 | "description": "Core class representing a block template.", 6 | "type": "object", 7 | "required": [ 8 | "type", 9 | "theme", 10 | "slug", 11 | "id", 12 | "title", 13 | "content", 14 | "description", 15 | "source", 16 | "origin", 17 | "wp_id", 18 | "status", 19 | "has_theme_file", 20 | "is_custom", 21 | "author", 22 | "plugin", 23 | "post_types", 24 | "modified", 25 | "area" 26 | ], 27 | "properties": { 28 | "type": { 29 | "type": "string" 30 | }, 31 | "theme": { 32 | "type": "string" 33 | }, 34 | "slug": { 35 | "type": "string" 36 | }, 37 | "id": { 38 | "type": "string" 39 | }, 40 | "title": { 41 | "type": "string" 42 | }, 43 | "content": { 44 | "type": "string" 45 | }, 46 | "description": { 47 | "type": "string" 48 | }, 49 | "source": { 50 | "type": "string" 51 | }, 52 | "origin": { 53 | "type": [ 54 | "string", 55 | "null" 56 | ] 57 | }, 58 | "wp_id": { 59 | "type": [ 60 | "integer", 61 | "null" 62 | ] 63 | }, 64 | "status": { 65 | "type": "string" 66 | }, 67 | "has_theme_file": { 68 | "type": "boolean" 69 | }, 70 | "is_custom": { 71 | "type": "boolean" 72 | }, 73 | "author": { 74 | "type": [ 75 | "integer", 76 | "null" 77 | ] 78 | }, 79 | "plugin": { 80 | "type": [ 81 | "string", 82 | "null" 83 | ] 84 | }, 85 | "post_types": { 86 | "type": [ 87 | "array", 88 | "null" 89 | ], 90 | "items": { 91 | "type": "string" 92 | } 93 | }, 94 | "area": { 95 | "type": [ 96 | "string", 97 | "null" 98 | ] 99 | }, 100 | "modified": { 101 | "type": [ 102 | "string", 103 | "null" 104 | ] 105 | } 106 | }, 107 | "additionalProperties": false 108 | } 109 | -------------------------------------------------------------------------------- /schemas/rest-api/font-family.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/font-family.json", 4 | "title": "WP_REST_API_Font_Family", 5 | "description": "A font family object in a REST API context.", 6 | "$comment": "See also https://schemas.wp.org/trunk/font-family.json", 7 | "type": "object", 8 | "required": [ 9 | "id", 10 | "theme_json_version", 11 | "font_faces", 12 | "font_family_settings", 13 | "_links" 14 | ], 15 | "properties": { 16 | "id": { 17 | "readOnly": true, 18 | "description": "Unique identifier for the font family.", 19 | "type": "integer" 20 | }, 21 | "theme_json_version": { 22 | "description": "Version of the theme.json schema used for the typography settings.", 23 | "type": "integer" 24 | }, 25 | "font_faces": { 26 | "description": "The IDs of the child font faces in the font family.", 27 | "type": "array", 28 | "items": { 29 | "type": "integer" 30 | } 31 | }, 32 | "font_family_settings": { 33 | "oneOf": [ 34 | { 35 | "$ref": "properties/font-family-settings.json" 36 | } 37 | ] 38 | }, 39 | "_links": { 40 | "$ref": "properties/object-links.json" 41 | }, 42 | "_embedded": { 43 | "description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.", 44 | "type": "object", 45 | "properties": { 46 | "font_faces": { 47 | "description": "The associated font faces.", 48 | "type": "array" 49 | } 50 | } 51 | } 52 | }, 53 | "links": [ 54 | { 55 | "rel": "self", 56 | "href": "/wp/v2/font-families/{id}", 57 | "hrefSchema": { 58 | "properties": { 59 | "id": { 60 | "$ref": "#/properties/id" 61 | } 62 | } 63 | }, 64 | "targetSchema": { 65 | "$ref": "#" 66 | } 67 | }, 68 | { 69 | "rel": "collection", 70 | "href": "/wp/v2/font-families", 71 | "targetSchema": { 72 | "type": "array", 73 | "items": { 74 | "$ref": "#" 75 | } 76 | } 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /schemas/rest-api/global-style-variation.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/global-style-variation.json", 4 | "title": "WP_REST_API_Global_Style_Variation", 5 | "description": "A global styles variation item in a REST API context.", 6 | "type": "object", 7 | "required": [ 8 | "id", 9 | "styles", 10 | "settings", 11 | "title", 12 | "_links" 13 | ], 14 | "properties": { 15 | "id": { 16 | "description": "ID of global styles variation.", 17 | "type": "integer" 18 | }, 19 | "styles": { 20 | "description": "Global styles.", 21 | "type": "object" 22 | }, 23 | "settings": { 24 | "description": "Global settings.", 25 | "type": "object" 26 | }, 27 | "title": { 28 | "description": "Title of the global styles variation.", 29 | "oneOf": [ 30 | { 31 | "type": "string" 32 | }, 33 | { 34 | "type": "object", 35 | "properties": { 36 | "raw": { 37 | "description": "Title for the global styles variation, as it exists in the database.", 38 | "type": "string" 39 | }, 40 | "rendered": { 41 | "description": "HTML title for the post, transformed for display.", 42 | "type": "string" 43 | } 44 | }, 45 | "additionalProperties": false 46 | } 47 | ] 48 | }, 49 | "_links": { 50 | "$ref": "properties/object-links.json" 51 | } 52 | }, 53 | "links": [ 54 | { 55 | "rel": "self", 56 | "href": "/wp/v2/global-styles/{id}", 57 | "hrefSchema": { 58 | "properties": { 59 | "id": { 60 | "$ref": "#/properties/id" 61 | } 62 | } 63 | }, 64 | "targetSchema": { 65 | "$ref": "#" 66 | } 67 | }, 68 | { 69 | "rel": "collection", 70 | "href": "/wp/v2/global-styles/themes/{theme}/variations", 71 | "hrefSchema": { 72 | "properties": { 73 | "id": { 74 | "type": "string" 75 | } 76 | } 77 | }, 78 | "targetSchema": { 79 | "$ref": "collections/global-style-variations.json" 80 | } 81 | } 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow 2 | 3 | name: Test 4 | 5 | on: 6 | push: 7 | branches: 8 | - 'develop' 9 | - 'trunk' 10 | pull_request: 11 | branches: 12 | - '**' 13 | 14 | permissions: {} 15 | 16 | jobs: 17 | validate: 18 | name: Validate Codebase 19 | runs-on: ubuntu-latest 20 | timeout-minutes: 10 21 | permissions: 22 | contents: read # To read the repository 23 | steps: 24 | - name: Checkout repository 25 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 26 | with: 27 | persist-credentials: false 28 | 29 | - name: Get Composer cache directory 30 | id: composer-cache 31 | run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" 32 | 33 | - name: Composer cache 34 | uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 35 | env: 36 | cache-name: cache-composer-dependencies 37 | with: 38 | path: ${{ steps.composer-cache.outputs.dir }} 39 | key: php-8.0-composer-${{ hashFiles('composer.json') }} 40 | 41 | - name: Set up Node 42 | uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 43 | with: 44 | node-version-file: '.nvmrc' 45 | 46 | - name: Install PHP 47 | uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2 48 | with: 49 | php-version: 8.0 50 | extensions: xmlwriter 51 | coverage: none 52 | env: 53 | fail-fast: true 54 | 55 | - name: Debugging 56 | run: | 57 | php --version 58 | php -m 59 | composer --version 60 | npm --version 61 | node --version 62 | 63 | - name: Install Node dependencies 64 | run: npm install 65 | 66 | - name: Install Composer dependencies 67 | run: composer install 68 | 69 | - name: Run tests 70 | run: composer run test 71 | 72 | - name: Check for changes 73 | run: git diff --exit-code 74 | -------------------------------------------------------------------------------- /tests/output/fonts.php: -------------------------------------------------------------------------------- 1 | 'Chakra Petch', 8 | 'fontFamily' => '"Chakra Petch", sans-serif', 9 | 'slug' => 'chakra-petch', 10 | 'preview' => 'https://s.w.org/images/fonts/17.7/previews/chakra-petch/chakra-petch.svg', 11 | ]; 12 | $family_response = get_rest_response( 13 | 'POST', 14 | '/wp/v2/font-families', 15 | [ 16 | 'font_family_settings' => json_encode( $family_payload ), 17 | ] 18 | ); 19 | 20 | if ( $family_response->is_error() ) { 21 | throw new \Exception( 'Failed to create font family: ' . $family_response->as_error()->get_error_message() ); 22 | } 23 | 24 | $family_id = $family_response->get_data()['id']; 25 | 26 | // Add a font face to the font family: 27 | $face_payload = [ 28 | 'src' => content_url( 'uploads/fonts/example.woff2' ), 29 | 'fontWeight' => '600', 30 | 'fontStyle' => 'normal', 31 | 'fontFamily' => 'Chakra Petch', 32 | 'preview' => 'https://s.w.org/images/fonts/17.7/previews/chakra-petch/chakra-petch-600-normal.svg', 33 | ]; 34 | $face_response = get_rest_response( 35 | 'POST', 36 | "/wp/v2/font-families/{$family_id}/font-faces", 37 | [ 38 | 'font_face_settings' => json_encode( $face_payload ), 39 | ] 40 | ); 41 | $face_id = $face_response->data['id']; 42 | 43 | // Get the font families: 44 | $data = get_rest_response( 'GET', '/wp/v2/font-families' ); 45 | 46 | save_rest_array( [ 47 | $data, 48 | ], 'font-families' ); 49 | 50 | // Get the faces for the font family: 51 | $data = get_rest_response( 'GET', "/wp/v2/font-families/{$family_id}/font-faces" ); 52 | 53 | save_rest_array( [ 54 | $data, 55 | ], 'font-faces' ); 56 | 57 | if ( should_refresh_external_schema( 'font-face' ) ) { 58 | $url = sprintf( 59 | 'https://raw.githubusercontent.com/WordPress/gutenberg/wp/%s/schemas/json/theme.json', 60 | ( 'dev-main' === WP_VERSION ) ? 'next' : WP_VERSION, 61 | ); 62 | 63 | save_external_schema( 64 | $url, 65 | 'font-face', 66 | [ 67 | 'definitions', 68 | 'settingsTypographyProperties', 69 | 'properties', 70 | 'typography', 71 | 'properties', 72 | 'fontFamilies', 73 | 'items', 74 | 'properties', 75 | 'fontFace', 76 | 'items', 77 | ] 78 | ); 79 | } 80 | -------------------------------------------------------------------------------- /schemas/rest-api/global-styles-revision.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/global-styles-revision.json", 4 | "title": "WP_REST_API_Global_Styles_Revision", 5 | "description": "A global styles revision object in a REST API context.", 6 | "type": "object", 7 | "required": [ 8 | "settings", 9 | "styles", 10 | "author", 11 | "date", 12 | "date_gmt", 13 | "id", 14 | "modified", 15 | "modified_gmt", 16 | "parent" 17 | ], 18 | "properties": { 19 | "settings": { 20 | "description": "Global settings for the revision.", 21 | "type": "object", 22 | "readOnly": true 23 | }, 24 | "styles": { 25 | "description": "Global styles for the revision.", 26 | "type": "object", 27 | "readOnly": true 28 | }, 29 | "author": { 30 | "description": "The ID for the author of the revision.", 31 | "type": "integer", 32 | "readOnly": true 33 | }, 34 | "date": { 35 | "description": "The date the revision was published, in the site's timezone.", 36 | "oneOf": [ 37 | { 38 | "$ref": "properties/date-time.json" 39 | } 40 | ], 41 | "readOnly": true 42 | }, 43 | "date_gmt": { 44 | "description": "The date the revision was published, as GMT.", 45 | "oneOf": [ 46 | { 47 | "$ref": "properties/date-time.json" 48 | } 49 | ], 50 | "readOnly": true 51 | }, 52 | "id": { 53 | "description": "Unique identifier for the revision.", 54 | "type": "integer", 55 | "readOnly": true 56 | }, 57 | "modified": { 58 | "description": "The date the revision was last modified, in the site's timezone.", 59 | "oneOf": [ 60 | { 61 | "$ref": "properties/date-time.json" 62 | } 63 | ], 64 | "readOnly": true 65 | }, 66 | "modified_gmt": { 67 | "description": "The date the revision was last modified, as GMT.", 68 | "oneOf": [ 69 | { 70 | "$ref": "properties/date-time.json" 71 | } 72 | ], 73 | "readOnly": true 74 | }, 75 | "parent": { 76 | "description": "The ID for the parent of the revision.", 77 | "type": "integer", 78 | "readOnly": true 79 | } 80 | }, 81 | "additionalProperties": false 82 | } 83 | -------------------------------------------------------------------------------- /tests/external-schemas/font-face.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "properties": { 4 | "fontFamily": { 5 | "description": "CSS font-family value.", 6 | "type": "string", 7 | "default": "" 8 | }, 9 | "fontStyle": { 10 | "description": "CSS font-style value.", 11 | "type": "string", 12 | "default": "normal" 13 | }, 14 | "fontWeight": { 15 | "description": "List of available font weights, separated by a space.", 16 | "oneOf": [ 17 | { 18 | "type": "string" 19 | }, 20 | { 21 | "type": "integer" 22 | } 23 | ], 24 | "default": "400" 25 | }, 26 | "fontDisplay": { 27 | "description": "CSS font-display value.", 28 | "type": "string", 29 | "enum": [ 30 | "auto", 31 | "block", 32 | "fallback", 33 | "swap", 34 | "optional" 35 | ], 36 | "default": "fallback" 37 | }, 38 | "src": { 39 | "description": "Paths or URLs to the font files.", 40 | "oneOf": [ 41 | { 42 | "type": "string" 43 | }, 44 | { 45 | "type": "array", 46 | "items": { 47 | "type": "string" 48 | } 49 | } 50 | ], 51 | "default": [] 52 | }, 53 | "fontStretch": { 54 | "description": "CSS font-stretch value.", 55 | "type": "string" 56 | }, 57 | "ascentOverride": { 58 | "description": "CSS ascent-override value.", 59 | "type": "string" 60 | }, 61 | "descentOverride": { 62 | "description": "CSS descent-override value.", 63 | "type": "string" 64 | }, 65 | "fontVariant": { 66 | "description": "CSS font-variant value.", 67 | "type": "string" 68 | }, 69 | "fontFeatureSettings": { 70 | "description": "CSS font-feature-settings value.", 71 | "type": "string" 72 | }, 73 | "fontVariationSettings": { 74 | "description": "CSS font-variation-settings value.", 75 | "type": "string" 76 | }, 77 | "lineGapOverride": { 78 | "description": "CSS line-gap-override value.", 79 | "type": "string" 80 | }, 81 | "sizeAdjust": { 82 | "description": "CSS size-adjust value.", 83 | "type": "string" 84 | }, 85 | "unicodeRange": { 86 | "description": "CSS unicode-range value.", 87 | "type": "string" 88 | } 89 | }, 90 | "required": [ 91 | "fontFamily", 92 | "src" 93 | ], 94 | "additionalProperties": false 95 | } -------------------------------------------------------------------------------- /tests/output/template-parts.php: -------------------------------------------------------------------------------- 1 | 'edit', 8 | ] ); 9 | 10 | $initial_list = $initial_data->get_data(); 11 | 12 | if ( ! empty( $initial_list ) ) { 13 | $first_template_part = $initial_list[0]; 14 | $template_part_id = $first_template_part['id']; 15 | 16 | // Update the first template-part to trigger a modified date 17 | $update_response = get_rest_response( 'POST', "/wp/v2/template-parts/{$template_part_id}", [ 18 | 'content' => $first_template_part['content']['raw'] . "\n", 19 | ] ); 20 | 21 | if ( $update_response->is_error() ) { 22 | $error = $update_response->as_error(); 23 | throw new \Exception( 'Failed to update template-part: ' . $error->get_error_message() ); 24 | } 25 | } 26 | 27 | // Generate REST API responses for template-parts collection 28 | $view_data = get_rest_response( 'GET', '/wp/v2/template-parts', [ 29 | 'context' => 'view', 30 | ] ); 31 | $edit_data = get_rest_response( 'GET', '/wp/v2/template-parts', [ 32 | 'context' => 'edit', 33 | ] ); 34 | 35 | save_rest_array( [ 36 | $view_data, 37 | $edit_data, 38 | ], 'template-parts' ); 39 | 40 | // Generate REST API responses for individual template parts 41 | $template_part_data = []; 42 | 43 | // Get template part IDs and slugs from the collection response 44 | $view_response_data = $view_data->get_data(); 45 | 46 | foreach ( $view_response_data as $template_part ) { 47 | $id = $template_part['id']; 48 | $slug = $template_part['slug']; 49 | 50 | // Generate REST API responses for individual template part 51 | $template_part_data[] = get_rest_response( 'GET', "/wp/v2/template-parts/{$id}", [ 52 | 'context' => 'view', 53 | ] ); 54 | $template_part_data[] = get_rest_response( 'GET', "/wp/v2/template-parts/{$id}", [ 55 | 'context' => 'edit', 56 | ] ); 57 | 58 | // Generate REST API response for template part lookup (fallback by slug) 59 | $template_part_data[] = get_rest_response( 'GET', '/wp/v2/template-parts/lookup', [ 60 | 'slug' => $slug, 61 | ] ); 62 | } 63 | 64 | save_rest_array( $template_part_data, 'template-part', true ); 65 | -------------------------------------------------------------------------------- /tests/output/template-part-revision.php: -------------------------------------------------------------------------------- 1 | 'edit', 9 | ] ); 10 | 11 | $template_parts_list = $template_parts_data->get_data(); 12 | 13 | if ( empty( $template_parts_list ) ) { 14 | throw new \Exception( 'Failed to fetch template parts list for revision test' ); 15 | } 16 | 17 | // Find a template-part with area header or footer 18 | $test_template_part = null; 19 | foreach ( $template_parts_list as $tp ) { 20 | if ( isset( $tp['area'] ) && in_array( $tp['area'], ['header', 'footer'], true ) ) { 21 | $test_template_part = $tp; 22 | break; 23 | } 24 | } 25 | 26 | if ( ! $test_template_part ) { 27 | $test_template_part = $template_parts_list[0]; 28 | } 29 | 30 | $template_part_id = $test_template_part['id']; 31 | 32 | // First update to create a custom version (this may not create a revision if wp_id is 0) 33 | $first_update = get_rest_response( 'POST', "/wp/v2/template-parts/{$template_part_id}", [ 34 | 'content' => $test_template_part['content']['raw'] . "\n", 35 | ] ); 36 | 37 | if ( $first_update->is_error() ) { 38 | $error = $first_update->as_error(); 39 | throw new \Exception( 'Failed to create custom template part: ' . $error->get_error_message() ); 40 | } 41 | 42 | $updated_data = $first_update->get_data(); 43 | 44 | // Second update to create a revision 45 | $second_update = get_rest_response( 'POST', "/wp/v2/template-parts/{$template_part_id}", [ 46 | 'content' => $updated_data['content']['raw'] . "\n", 47 | ] ); 48 | 49 | if ( $second_update->is_error() ) { 50 | $error = $second_update->as_error(); 51 | throw new \Exception( 'Failed to update template part: ' . $error->get_error_message() ); 52 | } 53 | 54 | // Fetch the revisions 55 | $data = []; 56 | $data[] = get_rest_response( 'GET', "/wp/v2/template-parts/{$template_part_id}/revisions", ['context' => 'view'] ); 57 | $data[] = get_rest_response( 'GET', "/wp/v2/template-parts/{$template_part_id}/revisions", ['context' => 'edit'] ); 58 | 59 | save_rest_array( $data, 'template-part-revisions' ); 60 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow 2 | 3 | name: Publish 4 | 5 | on: 6 | push: 7 | tags: 8 | - '*' 9 | 10 | permissions: {} 11 | 12 | jobs: 13 | publish-wp-json-schemas: 14 | name: Publish wp-json-schemas 15 | runs-on: ubuntu-latest 16 | permissions: 17 | contents: read # To read the repository 18 | id-token: write # OIDC token for trusted publishing 19 | environment: 20 | name: wp-json-schemas 21 | url: https://www.npmjs.com/package/wp-json-schemas 22 | timeout-minutes: 10 23 | steps: 24 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 25 | with: 26 | persist-credentials: false 27 | 28 | - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 29 | with: 30 | node-version-file: '.nvmrc' 31 | registry-url: https://registry.npmjs.org/ 32 | 33 | - name: Upgrade npm for OIDC support 34 | run: npm install -g npm@latest 35 | 36 | - name: Install dependencies 37 | run: npm install 38 | 39 | - name: Deploy to npm using trusted publishing with OIDC 40 | run: npm publish --access public 41 | 42 | publish-wp-types: 43 | name: Publish wp-types 44 | runs-on: ubuntu-latest 45 | permissions: 46 | contents: read # To read the repository 47 | id-token: write # OIDC token for trusted publishing 48 | environment: 49 | name: wp-types 50 | url: https://www.npmjs.com/package/wp-types 51 | timeout-minutes: 10 52 | steps: 53 | - name: Checkout repository 54 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 55 | with: 56 | persist-credentials: false 57 | 58 | - name: Set up Node 59 | uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 60 | with: 61 | node-version-file: '.nvmrc' 62 | registry-url: https://registry.npmjs.org/ 63 | 64 | - name: Upgrade npm for OIDC support 65 | run: npm install -g npm@latest 66 | 67 | - name: Deploy to npm using trusted publishing with OIDC 68 | run: | 69 | cd packages/wp-types 70 | npm install 71 | npm publish --access public 72 | -------------------------------------------------------------------------------- /tests/output/global-styles-revision.php: -------------------------------------------------------------------------------- 1 | sprintf( 'Custom Styles (%s)', $theme->get_stylesheet() ), 9 | 'post_content' => wp_json_encode( [ 10 | 'version' => 2, 11 | 'isGlobalStylesUserThemeJSON' => true, 12 | 'settings' => [], 13 | 'styles' => [], 14 | ] ), 15 | 'post_status' => 'publish', 16 | 'post_type' => 'wp_global_styles', 17 | 'post_name' => sprintf( 'wp-global-styles-%s', $theme->get_stylesheet() ), 18 | ] ); 19 | 20 | if ( is_wp_error( $post_id ) ) { 21 | throw new \Exception( 'Failed to create global styles post: ' . $post_id->get_error_message() ); 22 | } 23 | 24 | // Update the post to create a revision 25 | $update_result = wp_update_post( [ 26 | 'ID' => $post_id, 27 | 'post_content' => wp_json_encode( [ 28 | 'version' => 2, 29 | 'isGlobalStylesUserThemeJSON' => true, 30 | 'settings' => [ 31 | 'color' => [ 32 | 'palette' => [], 33 | ], 34 | ], 35 | 'styles' => [], 36 | ] ), 37 | ], true ); 38 | 39 | if ( is_wp_error( $update_result ) ) { 40 | throw new \Exception( 'Failed to update global styles post: ' . $update_result->get_error_message() ); 41 | } 42 | 43 | // Fetch the revisions collection via REST API 44 | $data = []; 45 | $data[] = get_rest_response( 'GET', "/wp/v2/global-styles/{$post_id}/revisions", [ 46 | 'context' => 'view', 47 | ] ); 48 | $data[] = get_rest_response( 'GET', "/wp/v2/global-styles/{$post_id}/revisions", [ 49 | 'context' => 'edit', 50 | ] ); 51 | 52 | save_rest_array( $data, 'global-styles-revisions' ); 53 | 54 | // Fetch individual revision 55 | $revisions_list = $data[0]->get_data(); 56 | 57 | $first_revision = $revisions_list[0]; 58 | $revision_id = $first_revision['id']; 59 | 60 | $single_data = []; 61 | $single_data[] = get_rest_response( 'GET', "/wp/v2/global-styles/{$post_id}/revisions/{$revision_id}", [ 62 | 'context' => 'view', 63 | ] ); 64 | $single_data[] = get_rest_response( 'GET', "/wp/v2/global-styles/{$post_id}/revisions/{$revision_id}", [ 65 | 'context' => 'edit', 66 | ] ); 67 | 68 | save_rest_array( $single_data, 'global-styles-revision', true ); 69 | -------------------------------------------------------------------------------- /schemas/properties/user-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/properties/user-data.json", 4 | "title": "WP_User_Data", 5 | "type": "object", 6 | "description": "User data container.", 7 | "properties": { 8 | "ID": { 9 | "readOnly": true, 10 | "description": "The user's ID.\n\nA numeric string, for compatibility reasons.", 11 | "type": "string" 12 | }, 13 | "deleted": { 14 | "description": "The user's deletion status. Only used on Multisite.", 15 | "enum": [ 16 | "0", 17 | "1" 18 | ] 19 | }, 20 | "display_name": { 21 | "description": "The user's full display name.", 22 | "type": "string" 23 | }, 24 | "spam": { 25 | "description": "The user's spam status. Only used on Multisite.", 26 | "enum": [ 27 | "0", 28 | "1" 29 | ] 30 | }, 31 | "user_activation_key": { 32 | "description": "The user's activation key. Be careful not to expose this in your application.", 33 | "type": "string" 34 | }, 35 | "user_email": { 36 | "description": "The user's email address.", 37 | "oneOf": [ 38 | { 39 | "type": "string", 40 | "format": "email" 41 | }, 42 | { 43 | "type": "string", 44 | "enum": [ 45 | "" 46 | ] 47 | } 48 | ] 49 | }, 50 | "user_login": { 51 | "description": "The user's login name.", 52 | "type": "string" 53 | }, 54 | "user_nicename": { 55 | "description": "The user's name as used in their author archive URL slug.", 56 | "type": "string" 57 | }, 58 | "user_pass": { 59 | "description": "The one-way hash of the user's password.", 60 | "type": "string" 61 | }, 62 | "user_registered": { 63 | "description": "The user's registration date.", 64 | "allOf": [ 65 | { 66 | "$ref": "date-time.json" 67 | } 68 | ] 69 | }, 70 | "user_status": { 71 | "description": "The user's status. This field does not appear to be used by WordPress core.", 72 | "const": "0" 73 | }, 74 | "user_url": { 75 | "description": "The user's URL.", 76 | "oneOf": [ 77 | { 78 | "type": "string", 79 | "format": "uri" 80 | }, 81 | { 82 | "type": "string", 83 | "enum": [ 84 | "" 85 | ] 86 | } 87 | ] 88 | } 89 | }, 90 | "additionalProperties": false 91 | } 92 | -------------------------------------------------------------------------------- /tests/output/template-revision.php: -------------------------------------------------------------------------------- 1 | 'Revision Test Template', 10 | 'description' => 'A template for testing revisions with plugin field', 11 | 'content' => '

Initial content.

', 12 | ] 13 | ); 14 | 15 | // Get templates and find the plugin-registered one 16 | $templates_data = get_rest_response( 'GET', '/wp/v2/templates', [ 17 | 'context' => 'edit', 18 | ] ); 19 | 20 | $templates_list = $templates_data->get_data(); 21 | 22 | if ( empty( $templates_list ) ) { 23 | throw new \Exception( 'Failed to fetch templates list for revision test' ); 24 | } 25 | 26 | // Find the plugin-registered template 27 | $plugin_template = null; 28 | foreach ( $templates_list as $template ) { 29 | if ( isset( $template['plugin'] ) && $template['plugin'] === 'wp-json-schemas' ) { 30 | $plugin_template = $template; 31 | break; 32 | } 33 | } 34 | 35 | // Fallback to first template if no plugin template found 36 | $test_template = $plugin_template ?? $templates_list[0]; 37 | $template_id = $test_template['id']; 38 | 39 | // First update to ensure wp_id exists 40 | $first_update = get_rest_response( 'POST', "/wp/v2/templates/{$template_id}", [ 41 | 'content' => $test_template['content']['raw'] . "\n", 42 | ] ); 43 | 44 | if ( $first_update->is_error() ) { 45 | $error = $first_update->as_error(); 46 | throw new \Exception( 'Failed to create custom template: ' . $error->get_error_message() ); 47 | } 48 | 49 | $updated_data = $first_update->get_data(); 50 | 51 | // Second update to create a revision 52 | $second_update = get_rest_response( 'POST', "/wp/v2/templates/{$template_id}", [ 53 | 'content' => $updated_data['content']['raw'] . "\n", 54 | ] ); 55 | 56 | if ( $second_update->is_error() ) { 57 | $error = $second_update->as_error(); 58 | throw new \Exception( 'Failed to update template: ' . $error->get_error_message() ); 59 | } 60 | 61 | // Fetch the revisions 62 | $data = []; 63 | $data[] = get_rest_response( 'GET', "/wp/v2/templates/{$template_id}/revisions", [ 64 | 'context' => 'view', 65 | ] ); 66 | $data[] = get_rest_response( 'GET', "/wp/v2/templates/{$template_id}/revisions", [ 67 | 'context' => 'edit', 68 | ] ); 69 | 70 | save_rest_array( $data, 'template-revisions' ); 71 | -------------------------------------------------------------------------------- /schemas/rest-api/status.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/status.json", 4 | "title": "WP_REST_API_Status", 5 | "description": "A post status object in a REST API context.", 6 | "readOnly": true, 7 | "type": "object", 8 | "required": [ 9 | "name", 10 | "public", 11 | "queryable", 12 | "slug", 13 | "date_floating", 14 | "_links" 15 | ], 16 | "properties": { 17 | "name": { 18 | "description": "The title for the status.", 19 | "type": "string", 20 | "readOnly": true 21 | }, 22 | "private": { 23 | "description": "Whether posts with this status should be private. Only present when using the 'edit' context.", 24 | "type": "boolean", 25 | "readOnly": true 26 | }, 27 | "protected": { 28 | "description": "Whether posts with this status should be protected. Only present when using the 'edit' context.", 29 | "type": "boolean", 30 | "readOnly": true 31 | }, 32 | "public": { 33 | "description": "Whether posts of this status should be shown in the front end of the site.", 34 | "type": "boolean", 35 | "readOnly": true 36 | }, 37 | "queryable": { 38 | "description": "Whether posts with this status should be publicly-queryable.", 39 | "type": "boolean", 40 | "readOnly": true 41 | }, 42 | "show_in_list": { 43 | "description": "Whether to include posts in the edit listing for their post type. Only present when using the 'edit' context.", 44 | "type": "boolean", 45 | "readOnly": true 46 | }, 47 | "slug": { 48 | "description": "An alphanumeric identifier for the status.", 49 | "type": "string", 50 | "readOnly": true 51 | }, 52 | "date_floating": { 53 | "description": "Whether posts of this status may have floating published dates.", 54 | "type": "boolean", 55 | "readOnly": true 56 | }, 57 | "_links": { 58 | "$ref": "properties/object-links.json" 59 | } 60 | }, 61 | "links": [ 62 | { 63 | "rel": "self", 64 | "href": "/wp/v2/statuses/{name}", 65 | "hrefSchema": { 66 | "properties": { 67 | "name": { 68 | "$ref": "#/properties/name" 69 | } 70 | } 71 | }, 72 | "targetSchema": { 73 | "$ref": "#" 74 | } 75 | }, 76 | { 77 | "rel": "collection", 78 | "href": "/wp/v2/statuses", 79 | "targetSchema": { 80 | "type": "array", 81 | "items": { 82 | "$ref": "#" 83 | } 84 | } 85 | } 86 | ] 87 | } 88 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "johnbillion/wp-json-schemas", 3 | "description": "JSON schemas for WordPress PHP objects and REST API responses", 4 | "homepage": "https://github.com/johnbillion/wp-json-schemas/", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "John Blackbourn", 9 | "homepage": "https://johnblackbourn.com/" 10 | } 11 | ], 12 | "repositories": [ 13 | { 14 | "type": "composer", 15 | "url": "https://wpackagist.org", 16 | "only": [ 17 | "wpackagist-plugin/*", 18 | "wpackagist-theme/*" 19 | ] 20 | } 21 | ], 22 | "require": { 23 | "php": "^7 || ^8" 24 | }, 25 | "require-dev": { 26 | "ext-sqlite3": "*", 27 | "ext-pdo_sqlite": "*", 28 | "ergebnis/json-printer": "^3.5", 29 | "johnbillion/args": "1.7.0", 30 | "roots/wordpress-core-installer": "^1.0.0", 31 | "roots/wordpress-full": "6.9", 32 | "wp-cli/core-command": "^2", 33 | "wp-cli/db-command": "^2", 34 | "wp-cli/language-command": "^2", 35 | "wpackagist-plugin/sqlite-database-integration": "^2.1", 36 | "wpackagist-theme/twentytwentyfour": "^1", 37 | "wpackagist-theme/twentytwentyone": "^2" 38 | }, 39 | "config": { 40 | "allow-plugins": { 41 | "composer/installers": true, 42 | "roots/wordpress-core-installer": true 43 | }, 44 | "preferred-install": "dist", 45 | "sort-packages": true 46 | }, 47 | "extra": { 48 | "installer-paths": { 49 | "tests/wordpress/wp-content/plugins/{$name}/": [ 50 | "type:wordpress-plugin" 51 | ], 52 | "tests/wordpress/wp-content/themes/{$name}/": [ 53 | "type:wordpress-theme" 54 | ] 55 | }, 56 | "wordpress-install-dir": "tests/wordpress" 57 | }, 58 | "scripts": { 59 | "test": [ 60 | "@php -r \"file_exists( 'tests/wordpress/wp-content/db.php' ) || copy( 'tests/wordpress/wp-content/plugins/sqlite-database-integration/db.copy', 'tests/wordpress/wp-content/db.php' );\"", 61 | 62 | "rm -f tests/wordpress/wp-content/database/.ht.sqlite", 63 | "wp core multisite-install --url=example.org --title=Example --admin_user=admin --admin_email=admin@example.org --skip-email", 64 | "wp language core install de_DE it_IT ar he_IL", 65 | 66 | "wp json-dump --theme=twentytwentyone", 67 | "wp json-dump", 68 | 69 | "npm run validate", 70 | "./tests/bin/build-wp-types.sh", 71 | "npm run test-wp-types", 72 | "./tests/bin/test.sh" 73 | ], 74 | "test:refresh": [ 75 | "@test -- --refresh" 76 | ] 77 | }, 78 | "funding": [ 79 | { 80 | "type": "github", 81 | "url": "https://github.com/sponsors/johnbillion" 82 | } 83 | ] 84 | } 85 | -------------------------------------------------------------------------------- /schemas/rest-api/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/menu.json", 4 | "title": "WP_REST_API_Menu", 5 | "description": "A menu in a REST API context.", 6 | "type": "object", 7 | "required": [ 8 | "id", 9 | "description", 10 | "name", 11 | "slug", 12 | "meta", 13 | "locations", 14 | "auto_add", 15 | "_links" 16 | ], 17 | "properties": { 18 | "id": { 19 | "description": "Unique identifier for the menu.", 20 | "type": "integer", 21 | "readOnly": true 22 | }, 23 | "description": { 24 | "description": "HTML description of the menu.", 25 | "type": "string" 26 | }, 27 | "name": { 28 | "description": "HTML title for the menu.", 29 | "type": "string" 30 | }, 31 | "slug": { 32 | "description": "An alphanumeric identifier for the menu unique to its type.", 33 | "type": "string" 34 | }, 35 | "meta": { 36 | "description": "Meta fields.", 37 | "oneOf": [ 38 | { 39 | "$ref": "../../schema.json#/definitions/EmptyArray" 40 | }, 41 | { 42 | "type": "object" 43 | } 44 | ] 45 | }, 46 | "locations": { 47 | "description": "The locations assigned to the menu.", 48 | "type": "array", 49 | "items": { 50 | "type": "string" 51 | } 52 | }, 53 | "auto_add": { 54 | "description": "Whether to automatically add top level pages to this menu.", 55 | "type": "boolean" 56 | }, 57 | "_links": { 58 | "$ref": "properties/object-links.json" 59 | }, 60 | "_embedded": { 61 | "description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.", 62 | "type": "object", 63 | "required": [ 64 | "wp:menu-location" 65 | ], 66 | "properties": { 67 | "wp:menu-location": { 68 | "description": "The menu locations.", 69 | "type": "array" 70 | } 71 | } 72 | } 73 | }, 74 | "links": [ 75 | { 76 | "rel": "self", 77 | "href": "/wp/v2/menus/{id}", 78 | "hrefSchema": { 79 | "properties": { 80 | "id": { 81 | "$ref": "#/properties/id" 82 | } 83 | } 84 | }, 85 | "targetSchema": { 86 | "$ref": "#" 87 | } 88 | }, 89 | { 90 | "rel": "collection", 91 | "href": "/wp/v2/menus", 92 | "targetSchema": { 93 | "type": "array", 94 | "items": { 95 | "$ref": "#" 96 | } 97 | } 98 | } 99 | ] 100 | } 101 | -------------------------------------------------------------------------------- /schemas/block.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/block.json", 4 | "title": "WP_Block", 5 | "description": "Class representing a parsed instance of a block.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "parsed_block", 10 | "name", 11 | "block_type", 12 | "context", 13 | "inner_blocks", 14 | "inner_html", 15 | "inner_content" 16 | ], 17 | "properties": { 18 | "parsed_block": { 19 | "description": "Original parsed array representation of block.", 20 | "allOf": [ 21 | { 22 | "$ref": "properties/block-parsed.json" 23 | } 24 | ] 25 | }, 26 | "name": { 27 | "description": "Name of block.", 28 | "type": "string", 29 | "examples": [ 30 | "core/paragraph", 31 | "core/columns", 32 | "foo/bar" 33 | ] 34 | }, 35 | "block_type": { 36 | "description": "Block type associated with the instance.", 37 | "allOf": [ 38 | { 39 | "$ref": "block-type.json" 40 | } 41 | ] 42 | }, 43 | "context": { 44 | "description": "Block context values.", 45 | "oneOf": [ 46 | { 47 | "type": "object" 48 | }, 49 | { 50 | "$ref": "../schema.json#/definitions/EmptyArray" 51 | } 52 | ] 53 | }, 54 | "inner_blocks": { 55 | "description": "List of inner blocks (of this same class). Note that this is always empty as it represents a WP_Block_List instance which has no public properties.", 56 | "oneOf": [ 57 | { 58 | "$ref": "../schema.json#/definitions/EmptyArray" 59 | }, 60 | { 61 | "$ref": "../schema.json#/definitions/EmptyObject" 62 | } 63 | ] 64 | }, 65 | "inner_html": { 66 | "description": "Resultant HTML from inside block comment delimiters after removing inner blocks.", 67 | "contentMediaType": "text/html", 68 | "type": "string" 69 | }, 70 | "inner_content": { 71 | "description": "List of string fragments and null markers where inner blocks were found.", 72 | "type": "array", 73 | "items": { 74 | "oneOf": [ 75 | { 76 | "contentMediaType": "text/html", 77 | "type": "string" 78 | }, 79 | { 80 | "type": "null" 81 | } 82 | ] 83 | } 84 | }, 85 | "attributes": { 86 | "description": "Attributes validated against the current block schema, populating defaulted and missing values. Lazily loaded, so not always present.", 87 | "type": "object", 88 | "additionalProperties": { 89 | "tsType": "any" 90 | } 91 | } 92 | }, 93 | "additionalProperties": false 94 | } 95 | -------------------------------------------------------------------------------- /schemas/rest-api/properties/font-face.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/font-face.json", 4 | "title": "WP_Font_Face", 5 | "description": "A font face.", 6 | "type": "object", 7 | "required": [ 8 | "src", 9 | "fontFamily" 10 | ], 11 | "properties": { 12 | "preview": { 13 | "description": "URL to a preview image of the font.", 14 | "type": "string", 15 | "format": "uri" 16 | }, 17 | "fontFamily": { 18 | "description": "CSS font-family value.", 19 | "type": "string" 20 | }, 21 | "fontStyle": { 22 | "description": "CSS font-style value.", 23 | "type": "string" 24 | }, 25 | "fontWeight": { 26 | "description": "List of available font weights, separated by a space.", 27 | "oneOf": [ 28 | { 29 | "type": "string" 30 | }, 31 | { 32 | "type": "integer" 33 | } 34 | ] 35 | }, 36 | "fontDisplay": { 37 | "description": "CSS font-display value.", 38 | "type": "string", 39 | "enum": [ 40 | "auto", 41 | "block", 42 | "fallback", 43 | "swap", 44 | "optional" 45 | ] 46 | }, 47 | "src": { 48 | "description": "Paths or URLs to the font files.", 49 | "oneOf": [ 50 | { 51 | "type": "string" 52 | }, 53 | { 54 | "type": "array", 55 | "items": { 56 | "type": "string" 57 | } 58 | } 59 | ] 60 | }, 61 | "fontStretch": { 62 | "description": "CSS font-stretch value.", 63 | "type": "string" 64 | }, 65 | "ascentOverride": { 66 | "description": "CSS ascent-override value.", 67 | "type": "string" 68 | }, 69 | "descentOverride": { 70 | "description": "CSS descent-override value.", 71 | "type": "string" 72 | }, 73 | "fontVariant": { 74 | "description": "CSS font-variant value.", 75 | "type": "string" 76 | }, 77 | "fontFeatureSettings": { 78 | "description": "CSS font-feature-settings value.", 79 | "type": "string" 80 | }, 81 | "fontVariationSettings": { 82 | "description": "CSS font-variation-settings value.", 83 | "type": "string" 84 | }, 85 | "lineGapOverride": { 86 | "description": "CSS line-gap-override value.", 87 | "type": "string" 88 | }, 89 | "sizeAdjust": { 90 | "description": "CSS size-adjust value.", 91 | "type": "string" 92 | }, 93 | "unicodeRange": { 94 | "description": "CSS unicode-range value.", 95 | "type": "string" 96 | } 97 | }, 98 | "additionalProperties": false 99 | } 100 | -------------------------------------------------------------------------------- /schemas/rest-api/block-pattern.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/block-pattern.json", 4 | "title": "WP_REST_API_Block_Pattern", 5 | "description": "A block pattern in a REST API context.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "name", 10 | "title", 11 | "content" 12 | ], 13 | "properties": { 14 | "name": { 15 | "description": "The pattern name, in namespace/pattern-name format.", 16 | "type": "string" 17 | }, 18 | "title": { 19 | "description": "The pattern title, in human readable format.", 20 | "type": "string" 21 | }, 22 | "content": { 23 | "description": "The pattern content.", 24 | "contentMediaType": "text/html", 25 | "type": "string" 26 | }, 27 | "description": { 28 | "description": "The pattern detailed description.", 29 | "type": "string" 30 | }, 31 | "viewport_width": { 32 | "description": "The pattern viewport width for inserter preview.", 33 | "type": "integer" 34 | }, 35 | "inserter": { 36 | "description": "Determines whether the pattern is visible in inserter.", 37 | "type": "boolean" 38 | }, 39 | "categories": { 40 | "description": "The pattern category slugs.", 41 | "type": "array", 42 | "items": { 43 | "type": "string" 44 | } 45 | }, 46 | "keywords": { 47 | "description": "The pattern keywords.", 48 | "type": "array", 49 | "items": { 50 | "type": "string" 51 | } 52 | }, 53 | "block_types": { 54 | "description": "Block types that the pattern is intended to be used with.", 55 | "type": "array", 56 | "items": { 57 | "type": "string" 58 | } 59 | }, 60 | "source": { 61 | "description": "Where the pattern comes from e.g. core.", 62 | "enum": [ 63 | "core", 64 | "plugin", 65 | "theme", 66 | "pattern-directory/core", 67 | "pattern-directory/theme", 68 | "pattern-directory/featured" 69 | ] 70 | }, 71 | "post_types": { 72 | "description": "An array of post types that the pattern is restricted to be used with.", 73 | "type": "array", 74 | "items": { 75 | "type": "string" 76 | } 77 | }, 78 | "template_types": { 79 | "description": "An array of template types where the pattern fits.", 80 | "type": "array", 81 | "items": { 82 | "type": "string" 83 | } 84 | } 85 | }, 86 | "links": [ 87 | { 88 | "rel": "collection", 89 | "href": "/wp/v2/block-patterns/patterns", 90 | "targetSchema": { 91 | "type": "array", 92 | "items": { 93 | "$ref": "#" 94 | } 95 | } 96 | } 97 | ] 98 | } 99 | -------------------------------------------------------------------------------- /schemas/rest-api/block-directory-item.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/block-directory-item.json", 4 | "title": "WP_REST_API_Block_Directory_Item", 5 | "description": "A block directory search result in a REST API context.", 6 | "type": "object", 7 | "readOnly": true, 8 | "required": [ 9 | "name", 10 | "title", 11 | "description", 12 | "id", 13 | "rating", 14 | "rating_count", 15 | "active_installs", 16 | "author_block_rating", 17 | "author_block_count", 18 | "author", 19 | "icon", 20 | "last_updated", 21 | "humanized_updated", 22 | "_links" 23 | ], 24 | "properties": { 25 | "name": { 26 | "description": "The block name, in namespace/block-name format.", 27 | "type": "string" 28 | }, 29 | "title": { 30 | "description": "The block title, in human readable format.", 31 | "type": "string" 32 | }, 33 | "description": { 34 | "description": "A short description of the block, in human readable format.", 35 | "type": "string" 36 | }, 37 | "id": { 38 | "description": "The block slug.", 39 | "type": "string" 40 | }, 41 | "rating": { 42 | "description": "The star rating of the block.", 43 | "type": "number" 44 | }, 45 | "rating_count": { 46 | "description": "The number of ratings.", 47 | "type": "integer" 48 | }, 49 | "active_installs": { 50 | "description": "The number sites that have activated this block.", 51 | "type": "integer" 52 | }, 53 | "author_block_rating": { 54 | "description": "The average rating of blocks published by the same author.", 55 | "type": "number" 56 | }, 57 | "author_block_count": { 58 | "description": "The number of blocks published by the same author.", 59 | "type": "integer" 60 | }, 61 | "author": { 62 | "description": "The WordPress.org username of the block author.", 63 | "type": "string" 64 | }, 65 | "icon": { 66 | "description": "The block icon.", 67 | "type": "string", 68 | "format": "uri" 69 | }, 70 | "last_updated": { 71 | "description": "The date when the block was last updated.", 72 | "type": "string" 73 | }, 74 | "humanized_updated": { 75 | "description": "The date when the block was last updated, in fuzzy human readable format.", 76 | "type": "string" 77 | }, 78 | "_links": { 79 | "$ref": "properties/object-links.json" 80 | } 81 | }, 82 | "links": [ 83 | { 84 | "rel": "collection", 85 | "href": "/wp/v2/block-directory/search", 86 | "targetSchema": { 87 | "type": "array", 88 | "items": { 89 | "$ref": "#" 90 | } 91 | } 92 | } 93 | ] 94 | } 95 | -------------------------------------------------------------------------------- /schemas/rest-api/font-collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/font-collection.json", 4 | "title": "WP_REST_API_Font_Collection", 5 | "description": "A font collection object in a REST API context.", 6 | "$comment": "See also https://schemas.wp.org/trunk/font-collection.json", 7 | "type": "object", 8 | "readOnly": true, 9 | "required": [ 10 | "slug", 11 | "name", 12 | "description", 13 | "font_families", 14 | "categories", 15 | "_links" 16 | ], 17 | "properties": { 18 | "slug": { 19 | "description": "Unique identifier for the font collection.", 20 | "type": "string" 21 | }, 22 | "name": { 23 | "description": "The name for the font collection.", 24 | "type": "string" 25 | }, 26 | "description": { 27 | "description": "The description for the font collection.", 28 | "type": "string" 29 | }, 30 | "font_families": { 31 | "description": "The font families for the font collection.", 32 | "type": "array", 33 | "items": { 34 | "type": "object", 35 | "required": [ 36 | "font_family_settings" 37 | ], 38 | "properties": { 39 | "font_family_settings": { 40 | "oneOf": [ 41 | { 42 | "$ref": "properties/font-family-settings.json" 43 | } 44 | ] 45 | }, 46 | "categories": { 47 | "type": "array", 48 | "items": { 49 | "type": "string" 50 | } 51 | } 52 | }, 53 | "additionalProperties": false 54 | } 55 | }, 56 | "categories": { 57 | "description": "The categories for the font collection.", 58 | "type": "array", 59 | "items": { 60 | "type": "object", 61 | "required": [ 62 | "name", 63 | "slug" 64 | ], 65 | "properties": { 66 | "name": { 67 | "type": "string" 68 | }, 69 | "slug": { 70 | "type": "string" 71 | } 72 | }, 73 | "additionalProperties": false 74 | } 75 | }, 76 | "_links": { 77 | "$ref": "properties/object-links.json" 78 | } 79 | }, 80 | "links": [ 81 | { 82 | "rel": "self", 83 | "href": "/wp/v2/font-collections/{slug}", 84 | "hrefSchema": { 85 | "properties": { 86 | "slug": { 87 | "$ref": "#/properties/slug" 88 | } 89 | } 90 | }, 91 | "targetSchema": { 92 | "$ref": "#" 93 | } 94 | }, 95 | { 96 | "rel": "collection", 97 | "href": "/wp/v2/font-collections", 98 | "targetSchema": { 99 | "type": "array", 100 | "items": { 101 | "$ref": "#" 102 | } 103 | } 104 | } 105 | ] 106 | } 107 | -------------------------------------------------------------------------------- /schemas/rest-api/properties/http-status-code.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/http-status-code.json", 4 | "title": "WP_Http_Status_Code", 5 | "type": "integer", 6 | "tsEnumNames": [ 7 | "HTTP_CONTINUE", 8 | "SWITCHING_PROTOCOLS", 9 | "PROCESSING", 10 | "EARLY_HINTS", 11 | "OK", 12 | "CREATED", 13 | "ACCEPTED", 14 | "NON_AUTHORITATIVE_INFORMATION", 15 | "NO_CONTENT", 16 | "RESET_CONTENT", 17 | "PARTIAL_CONTENT", 18 | "MULTI_STATUS", 19 | "IM_USED", 20 | "MULTIPLE_CHOICES", 21 | "MOVED_PERMANENTLY", 22 | "FOUND", 23 | "SEE_OTHER", 24 | "NOT_MODIFIED", 25 | "USE_PROXY", 26 | "RESERVED", 27 | "TEMPORARY_REDIRECT", 28 | "PERMANENT_REDIRECT", 29 | "BAD_REQUEST", 30 | "UNAUTHORIZED", 31 | "PAYMENT_REQUIRED", 32 | "FORBIDDEN", 33 | "NOT_FOUND", 34 | "METHOD_NOT_ALLOWED", 35 | "NOT_ACCEPTABLE", 36 | "PROXY_AUTHENTICATION_REQUIRED", 37 | "REQUEST_TIMEOUT", 38 | "CONFLICT", 39 | "GONE", 40 | "LENGTH_REQUIRED", 41 | "PRECONDITION_FAILED", 42 | "REQUEST_ENTITY_TOO_LARGE", 43 | "REQUEST_URI_TOO_LONG", 44 | "UNSUPPORTED_MEDIA_TYPE", 45 | "REQUESTED_RANGE_NOT_SATISFIABLE", 46 | "EXPECTATION_FAILED", 47 | "IM_A_TEAPOT", 48 | "MISDIRECTED_REQUEST", 49 | "UNPROCESSABLE_ENTITY", 50 | "LOCKED", 51 | "FAILED_DEPENDENCY", 52 | "TOO_EARLY", 53 | "UPGRADE_REQUIRED", 54 | "PRECONDITION_REQUIRED", 55 | "TOO_MANY_REQUESTS", 56 | "REQUEST_HEADER_FIELDS_TOO_LARGE", 57 | "UNAVAILABLE_FOR_LEGAL_REASONS", 58 | "INTERNAL_SERVER_ERROR", 59 | "NOT_IMPLEMENTED", 60 | "BAD_GATEWAY", 61 | "SERVICE_UNAVAILABLE", 62 | "GATEWAY_TIMEOUT", 63 | "HTTP_VERSION_NOT_SUPPORTED", 64 | "VARIANT_ALSO_NEGOTIATES", 65 | "INSUFFICIENT_STORAGE", 66 | "NOT_EXTENDED", 67 | "NETWORK_AUTHENTICATION_REQUIRED" 68 | ], 69 | "enum": [ 70 | 100, 71 | 101, 72 | 102, 73 | 103, 74 | 200, 75 | 201, 76 | 202, 77 | 203, 78 | 204, 79 | 205, 80 | 206, 81 | 207, 82 | 226, 83 | 300, 84 | 301, 85 | 302, 86 | 303, 87 | 304, 88 | 305, 89 | 306, 90 | 307, 91 | 308, 92 | 400, 93 | 401, 94 | 402, 95 | 403, 96 | 404, 97 | 405, 98 | 406, 99 | 407, 100 | 408, 101 | 409, 102 | 410, 103 | 411, 104 | 412, 105 | 413, 106 | 414, 107 | 415, 108 | 416, 109 | 417, 110 | 418, 111 | 421, 112 | 422, 113 | 423, 114 | 424, 115 | 425, 116 | 426, 117 | 428, 118 | 429, 119 | 431, 120 | 451, 121 | 500, 122 | 501, 123 | 502, 124 | 503, 125 | 504, 126 | 505, 127 | 506, 128 | 507, 129 | 510, 130 | 511 131 | ] 132 | } 133 | -------------------------------------------------------------------------------- /schemas/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/site.json", 4 | "title": "WP_Site", 5 | "description": "Core class used for interacting with a multisite site.", 6 | "type": "object", 7 | "required": [ 8 | "blog_id", 9 | "domain", 10 | "path", 11 | "site_id", 12 | "registered", 13 | "last_updated", 14 | "public", 15 | "archived", 16 | "mature", 17 | "spam", 18 | "deleted", 19 | "lang_id" 20 | ], 21 | "properties": { 22 | "blog_id": { 23 | "readOnly": true, 24 | "description": "Site ID.\n\nA numeric string, for compatibility reasons.", 25 | "type": "string" 26 | }, 27 | "domain": { 28 | "description": "Domain of the site.", 29 | "type": "string", 30 | "format": "hostname" 31 | }, 32 | "path": { 33 | "description": "Path of the site.", 34 | "type": "string", 35 | "format": "uri-reference" 36 | }, 37 | "site_id": { 38 | "description": "The ID of the site's parent network.\n\nNamed \"site\" vs. \"network\" for legacy reasons. An individual site's \"site\" is its network.\n\nA numeric string, for compatibility reasons.", 39 | "type": "string" 40 | }, 41 | "registered": { 42 | "description": "The date on which the site was created or registered.", 43 | "allOf": [ 44 | { 45 | "$ref": "properties/date-time.json" 46 | } 47 | ] 48 | }, 49 | "last_updated": { 50 | "description": "The date and time on which site settings were last updated.", 51 | "allOf": [ 52 | { 53 | "$ref": "properties/date-time.json" 54 | } 55 | ] 56 | }, 57 | "public": { 58 | "description": "Whether the site should be treated as public.\n\nA numeric string, for compatibility reasons.", 59 | "enum": [ 60 | "0", 61 | "1" 62 | ] 63 | }, 64 | "archived": { 65 | "description": "Whether the site should be treated as archived.\n\nA numeric string, for compatibility reasons.", 66 | "enum": [ 67 | "0", 68 | "1" 69 | ] 70 | }, 71 | "mature": { 72 | "description": "Whether the site should be treated as mature.\n\nA numeric string, for compatibility reasons.", 73 | "enum": [ 74 | "0", 75 | "1" 76 | ] 77 | }, 78 | "spam": { 79 | "description": "Whether the site should be treated as spam.\n\nA numeric string, for compatibility reasons.", 80 | "enum": [ 81 | "0", 82 | "1" 83 | ] 84 | }, 85 | "deleted": { 86 | "description": "Whether the site should be treated as deleted.\n\nA numeric string, for compatibility reasons.", 87 | "enum": [ 88 | "0", 89 | "1" 90 | ] 91 | }, 92 | "lang_id": { 93 | "description": "The language pack associated with this site.\n\nA numeric string, for compatibility reasons.", 94 | "type": "string" 95 | } 96 | }, 97 | "additionalProperties": false 98 | } 99 | -------------------------------------------------------------------------------- /schemas/rest-api/post.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/post.json", 4 | "title": "WP_REST_API_Post", 5 | "description": "A post object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "./partials/post/common.json" 10 | }, 11 | { 12 | "$ref": "./partials/post/author.json" 13 | }, 14 | { 15 | "$ref": "./partials/post/public.json" 16 | }, 17 | { 18 | "$ref": "./partials/post/comments.json" 19 | }, 20 | { 21 | "$ref": "./partials/post/excerpt.json" 22 | } 23 | ], 24 | "properties": { 25 | "_embedded": { 26 | "description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.", 27 | "type": "object", 28 | "required": [ 29 | "author" 30 | ], 31 | "properties": { 32 | "author": { 33 | "description": "The author of the post.", 34 | "type": "array" 35 | }, 36 | "replies": { 37 | "description": "The replies to the post (comments, pingbacks, trackbacks).", 38 | "type": "array" 39 | }, 40 | "wp:term": { 41 | "description": "The taxonomy terms for the post.", 42 | "type": "array" 43 | }, 44 | "wp:featuredmedia": { 45 | "description": "The featured image post.", 46 | "type": "array" 47 | }, 48 | "up": { 49 | "description": "The parent post.", 50 | "type": "array" 51 | } 52 | } 53 | } 54 | }, 55 | "links": [ 56 | { 57 | "rel": "self", 58 | "href": "/wp/v2/posts/{id}", 59 | "hrefSchema": { 60 | "properties": { 61 | "id": { 62 | "$ref": "partials/post/common.json#/properties/id" 63 | } 64 | } 65 | }, 66 | "targetSchema": { 67 | "$ref": "#" 68 | } 69 | }, 70 | { 71 | "rel": "collection", 72 | "href": "/wp/v2/posts", 73 | "targetSchema": { 74 | "type": "array", 75 | "items": { 76 | "$ref": "#" 77 | } 78 | } 79 | }, 80 | { 81 | "rel": "replies", 82 | "href": "/wp/v2/comments?post={id}", 83 | "hrefSchema": { 84 | "properties": { 85 | "id": { 86 | "$ref": "partials/post/common.json#/properties/id" 87 | } 88 | } 89 | }, 90 | "targetSchema": { 91 | "type": "array", 92 | "items": { 93 | "$ref": "comment.json" 94 | } 95 | } 96 | }, 97 | { 98 | "rel": "version-history", 99 | "href": "/wp/v2/posts/{id}/revisions", 100 | "hrefSchema": { 101 | "properties": { 102 | "id": { 103 | "$ref": "partials/post/common.json#/properties/id" 104 | } 105 | } 106 | }, 107 | "targetSchema": { 108 | "type": "array", 109 | "items": { 110 | "$ref": "#" 111 | } 112 | } 113 | } 114 | ] 115 | } 116 | -------------------------------------------------------------------------------- /schemas/rest-api/font-face.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/font-face.json", 4 | "title": "WP_REST_API_Font_Face", 5 | "description": "A font face object in a REST API context.", 6 | "$comment": "See also https://schemas.wp.org/trunk/font-face.json", 7 | "type": "object", 8 | "required": [ 9 | "id", 10 | "theme_json_version", 11 | "parent", 12 | "font_face_settings", 13 | "_links" 14 | ], 15 | "properties": { 16 | "id": { 17 | "readOnly": true, 18 | "description": "Unique identifier for the font face.", 19 | "type": "integer" 20 | }, 21 | "theme_json_version": { 22 | "description": "Version of the theme.json schema used for the typography settings.", 23 | "type": "integer" 24 | }, 25 | "parent": { 26 | "description": "The ID for the parent font family of the font face.", 27 | "type": "integer" 28 | }, 29 | "font_face_settings": { 30 | "description": "font-face declaration in theme.json format.", 31 | "type": "object", 32 | "properties": { 33 | "id": { 34 | "readOnly": true, 35 | "description": "Unique identifier for the font family.", 36 | "type": "integer" 37 | }, 38 | "theme_json_version": { 39 | "description": "Version of the theme.json schema used for the typography settings.", 40 | "type": "integer" 41 | }, 42 | "font_faces": { 43 | "description": "The IDs of the child font faces in the font family.", 44 | "type": "array", 45 | "items": { 46 | "type": "integer" 47 | } 48 | }, 49 | "font_family_settings": { 50 | "oneOf": [ 51 | { 52 | "$ref": "properties/font-family-settings.json" 53 | } 54 | ] 55 | } 56 | }, 57 | "additionalProperties": true 58 | }, 59 | "_links": { 60 | "$ref": "properties/object-links.json" 61 | } 62 | }, 63 | "links": [ 64 | { 65 | "rel": "self", 66 | "href": "/wp/v2/font-families/{parent}/font-faces/{id}", 67 | "hrefSchema": { 68 | "properties": { 69 | "parent": { 70 | "$ref": "#/properties/parent" 71 | }, 72 | "id": { 73 | "$ref": "#/properties/id" 74 | } 75 | } 76 | }, 77 | "targetSchema": { 78 | "$ref": "#" 79 | } 80 | }, 81 | { 82 | "rel": "collection", 83 | "href": "/wp/v2/font-families/{parent}/font-faces", 84 | "hrefSchema": { 85 | "properties": { 86 | "parent": { 87 | "$ref": "#/properties/parent" 88 | } 89 | } 90 | }, 91 | "targetSchema": { 92 | "type": "array", 93 | "items": { 94 | "$ref": "#" 95 | } 96 | } 97 | }, 98 | { 99 | "rel": "parent", 100 | "href": "/wp/v2/font-families/{parent}", 101 | "hrefSchema": { 102 | "properties": { 103 | "parent": { 104 | "$ref": "#/properties/parent" 105 | } 106 | } 107 | }, 108 | "targetSchema": { 109 | "$ref": "font-family.json" 110 | } 111 | } 112 | ] 113 | } 114 | -------------------------------------------------------------------------------- /schemas/rest-api/page.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", 3 | "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/page.json", 4 | "title": "WP_REST_API_Page", 5 | "description": "A page object in a REST API context.", 6 | "type": "object", 7 | "allOf": [ 8 | { 9 | "$ref": "partials/post/common.json" 10 | }, 11 | { 12 | "$ref": "./partials/post/author.json" 13 | }, 14 | { 15 | "$ref": "./partials/post/public.json" 16 | }, 17 | { 18 | "$ref": "./partials/post/comments.json" 19 | }, 20 | { 21 | "$ref": "./partials/post/excerpt.json" 22 | } 23 | ], 24 | "properties": { 25 | "_embedded": { 26 | "description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.", 27 | "type": "object", 28 | "required": [ 29 | "author" 30 | ], 31 | "properties": { 32 | "author": { 33 | "description": "The author of the page.", 34 | "type": "array" 35 | }, 36 | "replies": { 37 | "description": "The replies to the page (comments, pingbacks, trackbacks).", 38 | "type": "array" 39 | }, 40 | "wp:term": { 41 | "description": "The taxonomy terms for the page.", 42 | "type": "array" 43 | }, 44 | "wp:featuredmedia": { 45 | "description": "The featured image page.", 46 | "type": "array" 47 | }, 48 | "up": { 49 | "description": "The parent page.", 50 | "type": "array" 51 | } 52 | } 53 | } 54 | }, 55 | "links": [ 56 | { 57 | "rel": "self", 58 | "href": "/wp/v2/pages/{id}", 59 | "hrefSchema": { 60 | "properties": { 61 | "id": { 62 | "$ref": "partials/post/common.json#/properties/id" 63 | } 64 | } 65 | }, 66 | "targetSchema": { 67 | "$ref": "#" 68 | } 69 | }, 70 | { 71 | "rel": "collection", 72 | "href": "/wp/v2/pages", 73 | "targetSchema": { 74 | "type": "array", 75 | "items": { 76 | "$ref": "#" 77 | } 78 | } 79 | }, 80 | { 81 | "rel": "author", 82 | "href": "/wp/v2/users/{author}", 83 | "hrefSchema": { 84 | "properties": { 85 | "author": { 86 | "$ref": "partials/post/author.json#/properties/author" 87 | } 88 | } 89 | }, 90 | "targetSchema": { 91 | "$ref": "user.json" 92 | } 93 | }, 94 | { 95 | "rel": "replies", 96 | "href": "/wp/v2/comments?post={id}", 97 | "hrefSchema": { 98 | "properties": { 99 | "id": { 100 | "$ref": "partials/post/common.json#/properties/id" 101 | } 102 | } 103 | }, 104 | "targetSchema": { 105 | "type": "array", 106 | "items": { 107 | "$ref": "comment.json" 108 | } 109 | } 110 | }, 111 | { 112 | "rel": "version-history", 113 | "href": "/wp/v2/pages/{id}/revisions", 114 | "hrefSchema": { 115 | "properties": { 116 | "id": { 117 | "$ref": "partials/post/common.json#/properties/id" 118 | } 119 | } 120 | }, 121 | "targetSchema": { 122 | "type": "array", 123 | "items": { 124 | "$ref": "#" 125 | } 126 | } 127 | } 128 | ] 129 | } 130 | -------------------------------------------------------------------------------- /tests/bin/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # -e Exit immediately if a pipeline returns a non-zero status 4 | # -o pipefail Produce a failure return code if any command errors 5 | set -eo pipefail 6 | 7 | # Validate a schema file 8 | function validate_schema() { 9 | local file="$1" 10 | local base=${file//schemas\//} 11 | 12 | # https://github.com/ajv-validator/ajv-cli/issues/172 13 | local schemas=$(find schemas -type f -name "*.json" | grep -v "$file") 14 | local rflag="${schemas//$'\n'/ -r }" 15 | 16 | local filename=${base/.json/} 17 | 18 | ls tests/data/$filename/*.json > /dev/null 19 | ./node_modules/.bin/ajv validate --spec=draft2019 --strict --strict-schema=false -c ajv-formats -m tests/external-schemas/hyper-schema.json -r schema.json -r $rflag -s "$file" -d "tests/data/$filename/*.json" 20 | } 21 | 22 | # Modify a schema file using a jq transformation and an optional jq condition 23 | function modify_schema() { 24 | local file="$1" 25 | local changes="$2" 26 | local condition="$3" 27 | 28 | if [[ "$condition" != "" ]] 29 | then 30 | if [[ $(jq -e "$condition" "$file") == false ]] 31 | then 32 | return 33 | fi 34 | fi 35 | 36 | jq --tab "$changes" "$file" > tmp 37 | mv tmp "$file" 38 | } 39 | 40 | # Cleanup function to remove unevaluatedProperties and additionalProperties 41 | function cleanup() { 42 | for file in schemas/rest-api/*.json 43 | do 44 | if [[ "${IGNORE_FILES[*]}" =~ "${file}" ]] 45 | then 46 | continue 47 | fi 48 | modify_schema "$file" 'del(.unevaluatedProperties)' 49 | modify_schema "$file" 'del(.properties._embedded.additionalProperties)' 50 | done 51 | } 52 | 53 | # Files to ignore when disallowing additional properties 54 | IGNORE_FILES=("schemas/rest-api/error.json") 55 | 56 | # Always cleanup regardless of how the script exits 57 | trap cleanup EXIT 58 | 59 | # Validate all PHP object schemas in parallel 60 | pids=() 61 | for file in schemas/*.json 62 | do 63 | validate_schema "$file" & 64 | pids+=($!) 65 | done 66 | 67 | # Wait for all jobs and capture exit codes 68 | for pid in "${pids[@]}" 69 | do 70 | wait "$pid" || exit $? 71 | done 72 | 73 | # Disallow additional root properties in all REST API schemas (via unevaluatedProperties) 74 | # Disallow additional properties in the _embedded field in all REST API schemas 75 | for file in schemas/rest-api/*.json 76 | do 77 | if [[ "${IGNORE_FILES[*]}" =~ "${file}" ]] 78 | then 79 | continue 80 | fi 81 | modify_schema "$file" '. + { "unevaluatedProperties": false }' 82 | modify_schema "$file" '.properties._embedded += { "additionalProperties": false }' '.properties._embedded != null' 83 | done 84 | 85 | # Validation for REST API collections in parallel: 86 | pids=() 87 | for file in schemas/rest-api/collections/*.json 88 | do 89 | validate_schema "$file" & 90 | pids+=($!) 91 | done 92 | 93 | # Validation for REST API entities that don't have a directly corresponding collection: 94 | validate_schema schemas/rest-api/global-style-variation.json & 95 | pids+=($!) 96 | validate_schema schemas/rest-api/global-style-config.json & 97 | pids+=($!) 98 | 99 | # Wait for all parallel validation jobs to complete and capture exit codes 100 | for pid in "${pids[@]}" 101 | do 102 | wait "$pid" || exit $? 103 | done 104 | --------------------------------------------------------------------------------