diff --git a/packages/wp-types/index.ts b/packages/wp-types/index.ts index 6eabbee..7c8e965 100644 --- a/packages/wp-types/index.ts +++ b/packages/wp-types/index.ts @@ -136,6 +136,32 @@ export type WP_REST_API_Navigation_Menu = WP_REST_API_Partial_Post_Common; * A collection of navigation menu objects in a REST API context. */ export type WP_REST_API_Navigation_Menus = WP_REST_API_Navigation_Menu[]; +/** + * A collection of global styles variations in a REST API context. + */ +export type WP_REST_API_Global_Style_Variations = { + /** + * Version number of the global styles variation. + */ + version: number; + /** + * Global styles. + */ + styles?: { + [k: string]: unknown; + }; + /** + * Global settings. + */ + settings?: { + [k: string]: unknown; + }; + /** + * Title of the global styles variation. + */ + title: string; + [k: string]: unknown; +}[]; /** * A collection of media attachment objects in a REST API context. */ @@ -246,6 +272,9 @@ export interface WP { Pages: WP_REST_API_Pages; Navigation_Menu: WP_REST_API_Navigation_Menu; Navigation_Menus: WP_REST_API_Navigation_Menus; + Global_Style_Variation: WP_REST_API_Global_Style_Variation; + Global_Style_Variations: WP_REST_API_Global_Style_Variations; + Global_Style_Config: WP_REST_API_Global_Style_Config; Attachment: WP_REST_API_Attachment; Attachments: WP_REST_API_Attachments; Block: WP_REST_API_Block; @@ -2377,6 +2406,63 @@ interface WP_REST_API_Partial_Post_Excerpt { protected: boolean; }; } +/** + * A global styles variation item in a REST API context. + */ +export interface WP_REST_API_Global_Style_Variation { + /** + * ID of global styles variation. + */ + id: number; + /** + * Global styles. + */ + styles: { + [k: string]: unknown; + }; + /** + * Global settings. + */ + settings: { + [k: string]: unknown; + }; + /** + * Title of the global styles variation. + */ + title: + | string + | { + /** + * Title for the global styles variation, as it exists in the database. + */ + raw?: string; + /** + * HTML title for the post, transformed for display. + */ + rendered?: string; + }; + _links: WP_REST_API_Object_Links; + [k: string]: unknown; +} +/** + * A theme's global style config in a REST API context. + */ +export interface WP_REST_API_Global_Style_Config { + /** + * Global styles. + */ + styles: { + [k: string]: unknown; + }; + /** + * Global settings. + */ + settings: { + [k: string]: unknown; + }; + _links: WP_REST_API_Object_Links; + [k: string]: unknown; +} /** * A media attachment object in a REST API context. */ diff --git a/packages/wp-types/readme.md b/packages/wp-types/readme.md index 19d30dc..b3f9615 100644 --- a/packages/wp-types/readme.md +++ b/packages/wp-types/readme.md @@ -58,11 +58,11 @@ Route | Schema /wp/v2/font-families/{id}/ | `WP_REST_API_Font_Family` /wp/v2/font-families/{parent}/font-faces | `WP_REST_API_Font_Faces` /wp/v2/font-families/{parent}/font-faces/{id} | `WP_REST_API_Font_Face` -/wp/v2/global-styles/{id} | Todo +/wp/v2/global-styles/{id} | `WP_REST_API_Global_Style_Variation` /wp/v2/global-styles/{parent}/revisions | Todo /wp/v2/global-styles/{parent}/revisions/{id} | Todo -/wp/v2/global-styles/themes/{stylesheet}/variations | Todo -/wp/v2/global-styles/themes/{stylesheet} | Todo +/wp/v2/global-styles/themes/{stylesheet}/variations | `WP_REST_API_Global_Style_Variations` +/wp/v2/global-styles/themes/{stylesheet} | `WP_REST_API_Global_Style_Config` /wp/v2/media | `WP_REST_API_Attachments` /wp/v2/media/{id} | `WP_REST_API_Attachment` /wp/v2/media/{id}/edit | Todo diff --git a/readme.md b/readme.md index fba4f85..4b71cc0 100644 --- a/readme.md +++ b/readme.md @@ -62,11 +62,11 @@ Route | Schema /wp/v2/font-families/{id}/ | `WP_REST_API_Font_Family` /wp/v2/font-families/{parent}/font-faces | `WP_REST_API_Font_Faces` /wp/v2/font-families/{parent}/font-faces/{id} | `WP_REST_API_Font_Face` -/wp/v2/global-styles/{id} | Todo +/wp/v2/global-styles/{id} | `WP_REST_API_Global_Style_Variation` /wp/v2/global-styles/{parent}/revisions | Todo /wp/v2/global-styles/{parent}/revisions/{id} | Todo -/wp/v2/global-styles/themes/{stylesheet}/variations | Todo -/wp/v2/global-styles/themes/{stylesheet} | Todo +/wp/v2/global-styles/themes/{stylesheet}/variations | `WP_REST_API_Global_Style_Variations` +/wp/v2/global-styles/themes/{stylesheet} | `WP_REST_API_Global_Style_Config` /wp/v2/media | `WP_REST_API_Attachments` /wp/v2/media/{id} | `WP_REST_API_Attachment` /wp/v2/media/{id}/edit | Todo diff --git a/schema.json b/schema.json index 27f4f82..ee255f1 100644 --- a/schema.json +++ b/schema.json @@ -116,6 +116,15 @@ "Navigation_Menus": { "$ref": "schemas/rest-api/collections/navigation.json" }, + "Global_Style_Variation": { + "$ref": "schemas/rest-api/global-style-variation.json" + }, + "Global_Style_Variations": { + "$ref": "schemas/rest-api/collections/global-style-variations.json" + }, + "Global_Style_Config": { + "$ref": "schemas/rest-api/global-style-config.json" + }, "Attachment": { "$ref": "schemas/rest-api/attachment.json" }, @@ -255,6 +264,9 @@ "Pages", "Navigation_Menu", "Navigation_Menus", + "Global_Style_Variation", + "Global_Style_Variations", + "Global_Style_Config", "Attachment", "Attachments", "Block_Directory_Item", diff --git a/schemas/rest-api/collections/global-style-variations.json b/schemas/rest-api/collections/global-style-variations.json new file mode 100644 index 0000000..a750803 --- /dev/null +++ b/schemas/rest-api/collections/global-style-variations.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/global-style-variations.json", + "title": "WP_REST_API_Global_Style_Variations", + "description": "A collection of global styles variations in a REST API context.", + "type": "array", + "items": { + "$comment": "These items are not the same shape as a single global styles variation object.", + "type": "object", + "required": [ + "version", + "title" + ], + "properties": { + "version": { + "description": "Version number of the global styles variation.", + "type": "integer" + }, + "styles": { + "description": "Global styles.", + "type": "object" + }, + "settings": { + "description": "Global settings.", + "type": "object" + }, + "title": { + "description": "Title of the global styles variation.", + "type": "string" + } + } + }, + "links": [ + { + "rel": "self", + "href": "/wp/v2/global-styles/themes/{theme}/variations", + "hrefSchema": { + "properties": { + "id": { + "type": "string" + } + } + }, + "targetSchema": { + "$ref": "#" + } + } + ] +} diff --git a/schemas/rest-api/global-style-config.json b/schemas/rest-api/global-style-config.json new file mode 100644 index 0000000..fdbc9e8 --- /dev/null +++ b/schemas/rest-api/global-style-config.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/global-style-config.json", + "title": "WP_REST_API_Global_Style_Config", + "description": "A theme's global style config in a REST API context.", + "type": "object", + "required": [ + "styles", + "settings", + "_links" + ], + "properties": { + "styles": { + "description": "Global styles.", + "type": "object" + }, + "settings": { + "description": "Global settings.", + "type": "object" + }, + "_links": { + "$ref": "properties/object-links.json" + } + }, + "links": [ + { + "rel": "self", + "href": "/wp/v2/global-styles/themes/{theme}", + "hrefSchema": { + "properties": { + "id": { + "type": "string" + } + } + }, + "targetSchema": { + "$ref": "#" + } + } + ] +} diff --git a/schemas/rest-api/global-style-variation.json b/schemas/rest-api/global-style-variation.json new file mode 100644 index 0000000..104b848 --- /dev/null +++ b/schemas/rest-api/global-style-variation.json @@ -0,0 +1,83 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/hyper-schema", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/global-style-variation.json", + "title": "WP_REST_API_Global_Style_Variation", + "description": "A global styles variation item in a REST API context.", + "type": "object", + "required": [ + "id", + "styles", + "settings", + "title", + "_links" + ], + "properties": { + "id": { + "description": "ID of global styles variation.", + "type": "integer" + }, + "styles": { + "description": "Global styles.", + "type": "object" + }, + "settings": { + "description": "Global settings.", + "type": "object" + }, + "title": { + "description": "Title of the global styles variation.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "raw": { + "description": "Title for the global styles variation, as it exists in the database.", + "type": "string" + }, + "rendered": { + "description": "HTML title for the post, transformed for display.", + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "_links": { + "$ref": "properties/object-links.json" + } + }, + "links": [ + { + "rel": "self", + "href": "/wp/v2/global-styles/{id}", + "hrefSchema": { + "properties": { + "id": { + "$ref": "#/properties/id" + } + } + }, + "targetSchema": { + "$ref": "#" + } + }, + { + "rel": "collection", + "href": "/wp/v2/global-styles/themes/{theme}/variations", + "hrefSchema": { + "properties": { + "id": { + "type": "string" + } + } + }, + "targetSchema": { + "$ref": "collections/global-style-variations.json" + } + } + ] +} diff --git a/tests/bin/test.sh b/tests/bin/test.sh index 261541b..cc9a9cb 100755 --- a/tests/bin/test.sh +++ b/tests/bin/test.sh @@ -70,3 +70,7 @@ for file in schemas/rest-api/collections/*.json do validate_schema "$file" done + +# Validation for REST API entities that don't have a collection: +validate_schema schemas/rest-api/global-style-variation.json +validate_schema schemas/rest-api/global-style-config.json diff --git a/tests/mu-plugins/mu-plugin.php b/tests/mu-plugins/mu-plugin.php index a5d9f5b..37a4941 100644 --- a/tests/mu-plugins/mu-plugin.php +++ b/tests/mu-plugins/mu-plugin.php @@ -106,12 +106,16 @@ function save_object_array( array $data, string $dir ) : void { * @param WP_REST_Response[] $data Array of responses to a REST API request. * @param string $dir The directory to save the files. */ -function save_rest_array( array $data, string $dir ) : void { +function save_rest_array( array $data, string $dir, bool $single = false ) : void { if ( empty( $data ) ) { throw new \Exception( "No REST API data to save for {$dir}." ); } - $dir = dirname( ABSPATH ) . '/data/rest-api/collections/' . $dir; + if ( $single ) { + $dir = dirname( ABSPATH ) . '/data/rest-api/' . $dir; + } else { + $dir = dirname( ABSPATH ) . '/data/rest-api/collections/' . $dir; + } if ( ! file_exists( $dir ) ) { mkdir( $dir, 0777, true ); diff --git a/tests/output/post.php b/tests/output/post.php index 35a2281..ad59f7c 100644 --- a/tests/output/post.php +++ b/tests/output/post.php @@ -2,6 +2,10 @@ namespace WPJsonSchemas; +$theme = wp_get_theme(); +$theme_name = $theme->get_stylesheet(); +$theme_dir = $theme->get_stylesheet_directory(); + $parent_post = wp_insert_post( [ 'post_type' => 'post', 'post_title' => 'Post Title', @@ -58,6 +62,27 @@ 'post_status' => 'publish', ] ); +$global_style_ids = []; + +foreach ( glob( $theme_dir . '/styles/*.json' ) as $variation ) { + $json = file_get_contents( $variation ); + $data = json_decode( $json, true ); + + $data['isGlobalStylesUserThemeJSON'] = true; + $data['version'] = \WP_Theme_JSON::LATEST_SCHEMA; + + $global_style_ids[] = wp_insert_post( [ + 'post_type' => 'wp_global_styles', + 'post_title' => ' Style Variation: ' . basename( $variation ), + 'post_content' => addslashes( json_encode( $data, JSON_UNESCAPED_SLASHES ) ), + 'post_status' => 'publish', + ] ); +} + +if ( empty( $global_style_ids ) ) { + throw new \Exception( 'No global style variations found' ); +} + $posts = get_posts( [ 'posts_per_page' => -1, 'post_status' => 'any', @@ -68,6 +93,7 @@ save_object_array( $posts, 'post' ); +// Generate REST API responses for all post types foreach ( [ 'posts', 'pages', 'blocks', 'navigation' ] as $type ) { $view_data = get_rest_response( 'GET', "/wp/v2/{$type}", [ 'context' => 'view', @@ -88,3 +114,54 @@ $empty_response, ], $type ); } + +$global_style_data = []; + +foreach ( $global_style_ids as $id ) { + // Generate REST API responses for each of the single global style variations + $global_style_data[] = get_rest_response( 'GET', "/wp/v2/global-styles/{$id}", [ + 'context' => 'view', + ] ); + $global_style_data[] = get_rest_response( 'GET', "/wp/v2/global-styles/{$id}", [ + 'context' => 'edit', + ] ); +} + +save_rest_array( + $global_style_data, + 'global-style-variation', + true, +); + +// Generate REST API responses for the global style variations collection +$view_data = get_rest_response( 'GET', "/wp/v2/global-styles/themes/{$theme_name}/variations", [ + 'context' => 'view', +] ); +$edit_data = get_rest_response( 'GET', "/wp/v2/global-styles/themes/{$theme_name}/variations", [ + 'context' => 'edit', +] ); + +save_rest_array( + [ + $view_data, + $edit_data, + ], + 'global-style-variations', +); + +// Generate REST API responses for the theme global style config +$view_data = get_rest_response( 'GET', "/wp/v2/global-styles/themes/{$theme_name}", [ + 'context' => 'view', +] ); +$edit_data = get_rest_response( 'GET', "/wp/v2/global-styles/themes/{$theme_name}", [ + 'context' => 'edit', +] ); + +save_rest_array( + [ + $view_data, + $edit_data, + ], + 'global-style-config', + true, +);