From 2f0154dc8ca99a81072cc9bedfeab739ce7e5dca Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 13 Jul 2024 18:48:23 +0200 Subject: [PATCH 1/5] Make this reusable. --- tests/mu-plugins/mu-plugin.php | 15 +++++++++++++++ tests/output/font-collection.php | 11 ++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/tests/mu-plugins/mu-plugin.php b/tests/mu-plugins/mu-plugin.php index 9cb2e23..70c20b3 100644 --- a/tests/mu-plugins/mu-plugin.php +++ b/tests/mu-plugins/mu-plugin.php @@ -104,6 +104,21 @@ function save_rest_array( array $data, string $dir ) : void { } } +function save_external_schema( string $url, string $name ) : void { + $target = dirname( ABSPATH ) . "/external-schemas/{$name}.json"; + $schema = download_url( $url ); + + if ( is_wp_error( $schema ) ) { + throw new \Exception( "Failed to download external {$name} schema." ); + } + + $renamed = rename( $schema, $target ); + + if ( ! $renamed ) { + throw new \Exception( "Failed to rename external {$name} schema." ); + } +} + /** * Helper function for performing an internal REST API request and returning its response data. * diff --git a/tests/output/font-collection.php b/tests/output/font-collection.php index 254d1f5..8c1c558 100644 --- a/tests/output/font-collection.php +++ b/tests/output/font-collection.php @@ -8,10 +8,7 @@ $data, ], 'font-collections' ); -$font_collection_schema = download_url( 'https://schemas.wp.org/trunk/font-collection.json' ); - -if ( is_wp_error( $font_collection_schema ) ) { - throw new \Exception( 'Failed to download font-collection schema.' ); -} - -rename( $font_collection_schema, dirname( ABSPATH ) . '/external-schemas/font-collection.json' ); +save_external_schema( + 'https://schemas.wp.org/trunk/font-collection.json', + 'font-collection' +); From cac943982355ce4c6ccdd8d88d0ac1ee7459bee0 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 13 Jul 2024 18:48:43 +0200 Subject: [PATCH 2/5] Docs. --- CONTRIBUTING.md | 4 ++-- packages/wp-types/readme.md | 12 ++++++------ readme.md | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 15c452e..17cdfdd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,7 +45,7 @@ The WordPress REST API response doesn't fully adhere to the JSON schema spec, so - Start by copying an existing file such as `post.php` which is for `/wp/v2/posts` - The command should perform one or more REST API requests to the endpoint and pass the responses to the `save_rest_array()` function which saves them as JSON during the tests * Run `composer run test` to validate and test the schemas. -* Run `npm run build-wp-types` and check the output of `packages/wp-types/index.ts`. +* Check the output of `packages/wp-types/index.ts`. * Add documentation for the schema in both `readme.md` and `packages/wp-types/readme.md`. ## Creating a PHP object schema @@ -69,7 +69,7 @@ The schema for a PHP object is created using the docblocks from its class proper - Start by copying an existing file such as `error.php` - The file should pass an array of one or more objects of this type to the `save_object_array()` function which saves it as JSON during the tests * Run `composer run test` to validate and test the schemas. -* Run `npm run build-wp-types` and check the output of `packages/wp-types/index.ts`. +* Check the output of `packages/wp-types/index.ts`. * Add documentation for the schema in both `readme.md` and `packages/wp-types/readme.md`. ## Updating schemas for a new WordPress release diff --git a/packages/wp-types/readme.md b/packages/wp-types/readme.md index 89e6ce8..7321812 100644 --- a/packages/wp-types/readme.md +++ b/packages/wp-types/readme.md @@ -52,12 +52,12 @@ Route | Schema /wp/v2/categories/{id} | `WP_REST_API_Category` /wp/v2/comments | `WP_REST_API_Comments` /wp/v2/comments/{id} | `WP_REST_API_Comment` -/wp/v2/wp/v2/font-collections | `WP_REST_API_Font_Collections` -/wp/v2/wp/v2/font-collections/{slug} | `WP_REST_API_Font_Collection` -/wp/v2/wp/v2/font-families | Todo -/wp/v2/wp/v2/font-families/{id}/ | Todo -/wp/v2/wp/v2/font-families/{id}/font-faces | Todo -/wp/v2/wp/v2/font-families/{id}/font-faces/{id} | Todo +/wp/v2/font-collections | `WP_REST_API_Font_Collections` +/wp/v2/font-collections/{slug} | `WP_REST_API_Font_Collection` +/wp/v2/font-families | `WP_REST_API_Font_Families` +/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/{parent}/revisions | Todo /wp/v2/global-styles/{parent}/revisions/{id} | Todo diff --git a/readme.md b/readme.md index 7a7eb2d..2c8217a 100644 --- a/readme.md +++ b/readme.md @@ -56,12 +56,12 @@ Route | Schema /wp/v2/categories/{id} | `WP_REST_API_Category` /wp/v2/comments | `WP_REST_API_Comments` /wp/v2/comments/{id} | `WP_REST_API_Comment` -/wp/v2/wp/v2/font-collections | `WP_REST_API_Font_Collections` -/wp/v2/wp/v2/font-collections/{slug} | `WP_REST_API_Font_Collection` -/wp/v2/wp/v2/font-families | Todo -/wp/v2/wp/v2/font-families/{id}/ | Todo -/wp/v2/wp/v2/font-families/{id}/font-faces | Todo -/wp/v2/wp/v2/font-families/{id}/font-faces/{id} | Todo +/wp/v2/font-collections | `WP_REST_API_Font_Collections` +/wp/v2/font-collections/{slug} | `WP_REST_API_Font_Collection` +/wp/v2/font-families | `WP_REST_API_Font_Families` +/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/{parent}/revisions | Todo /wp/v2/global-styles/{parent}/revisions/{id} | Todo From 2bd2a2cfd77db42232e34079c6043b42321c9961 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 13 Jul 2024 18:50:13 +0200 Subject: [PATCH 3/5] Add a schema for the font families REST API endpoints. --- schema.json | 8 ++ .../rest-api/collections/font-families.json | 19 +++++ schemas/rest-api/font-family.json | 81 +++++++++++++++++++ tests/output/fonts.php | 55 +++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 schemas/rest-api/collections/font-families.json create mode 100644 schemas/rest-api/font-family.json create mode 100644 tests/output/fonts.php diff --git a/schema.json b/schema.json index e8b19f7..52a2de3 100644 --- a/schema.json +++ b/schema.json @@ -86,6 +86,12 @@ "Font_Collections": { "$ref": "schemas/rest-api/collections/font-collections.json" }, + "Font_Family": { + "$ref": "schemas/rest-api/font-family.json" + }, + "Font_Families": { + "$ref": "schemas/rest-api/collections/font-families.json" + }, "Post": { "$ref": "schemas/rest-api/post.json" }, @@ -209,6 +215,8 @@ "Comments", "Font_Collection", "Font_Collections", + "Font_Family", + "Font_Families", "Post", "Posts", "Page", diff --git a/schemas/rest-api/collections/font-families.json b/schemas/rest-api/collections/font-families.json new file mode 100644 index 0000000..7a1a895 --- /dev/null +++ b/schemas/rest-api/collections/font-families.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-07/hyper-schema#", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/font-families.json", + "title": "WP_REST_API_Font_Families", + "description": "A collection of font family objects in a REST API context.", + "type": "array", + "items": { + "$ref": "../font-family.json" + }, + "links": [ + { + "rel": "self", + "href": "/wp/v2/font-families", + "targetSchema": { + "$ref": "#" + } + } + ] +} diff --git a/schemas/rest-api/font-family.json b/schemas/rest-api/font-family.json new file mode 100644 index 0000000..7e9893c --- /dev/null +++ b/schemas/rest-api/font-family.json @@ -0,0 +1,81 @@ +{ + "$schema": "http://json-schema.org/draft-07/hyper-schema#", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/font-family.json", + "title": "WP_REST_API_Font_Family", + "description": "A font family object in a REST API context.", + "$comment": "See also https://schemas.wp.org/trunk/font-family.json", + "type": "object", + "required": [ + "id", + "theme_json_version", + "font_faces", + "font_family_settings", + "_links" + ], + "properties": { + "id": { + "readOnly": true, + "description": "Unique identifier for the font family.", + "type": "integer" + }, + "theme_json_version": { + "description": "Version of the theme.json schema used for the typography settings.", + "type": "integer" + }, + "font_faces": { + "description": "The IDs of the child font faces in the font family.", + "type": "array", + "items": { + "type": "integer" + } + }, + "font_family_settings": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "fontFamily": { + "type": "string" + }, + "preview": { + "type": "string", + "format": "uri" + } + } + }, + "_links": { + "$ref": "properties/object-links.json" + } + }, + "links": [ + { + "rel": "self", + "href": "/wp/v2/font-families/{id}", + "hrefSchema": { + "properties": { + "id": { + "$ref": "#/properties/id" + } + } + }, + "targetSchema": { + "$ref": "#" + } + }, + { + "rel": "collection", + "href": "/wp/v2/font-families", + "targetSchema": { + "type": "array", + "items": { + "$ref": "#" + } + } + } + ], + "additionalProperties": false +} diff --git a/tests/output/fonts.php b/tests/output/fonts.php new file mode 100644 index 0000000..dce4736 --- /dev/null +++ b/tests/output/fonts.php @@ -0,0 +1,55 @@ + 'Chakra Petch', + 'fontFamily' => '"Chakra Petch", sans-serif', + 'slug' => 'chakra-petch', + 'preview' => 'https://s.w.org/images/fonts/17.7/previews/chakra-petch/chakra-petch.svg', +]; +$family_response = get_rest_response( + 'POST', + '/wp/v2/font-families', + [ + 'font_family_settings' => json_encode( $family_payload ), + ] +); +$family_id = $family_response->data['id']; + +// Add a font face to the font family: +$face_payload = [ + 'src' => content_url( 'uploads/fonts/example.woff2' ), + 'fontWeight' => '600', + 'fontStyle' => 'normal', + 'fontFamily' => 'Chakra Petch', + 'preview' => 'https://s.w.org/images/fonts/17.7/previews/chakra-petch/chakra-petch-600-normal.svg', +]; +$face_response = get_rest_response( + 'POST', + "/wp/v2/font-families/{$family_id}/font-faces", + [ + 'font_face_settings' => json_encode( $face_payload ), + ] +); +$face_id = $face_response->data['id']; + +// Get the font families: +$data = get_rest_response( 'GET', '/wp/v2/font-families' ); + +save_rest_array( [ + $data, +], 'font-families' ); + +// Get the faces for the font family: +$data = get_rest_response( 'GET', "/wp/v2/font-families/{$family_id}/font-faces" ); + +save_rest_array( [ + $data, +], 'font-faces' ); + +save_external_schema( + 'https://schemas.wp.org/trunk/theme.json', + 'font-family' +); From cee61be6dd0ca8dd5e2e7c5ffa622222aec68aa3 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 14 Jul 2024 17:52:08 +0200 Subject: [PATCH 4/5] Introduce schemas for font families and font faces. --- composer.json | 1 + packages/wp-types/index.ts | 107 +++++++++++++++ schema.json | 8 ++ schemas/rest-api/collections/font-faces.json | 10 ++ schemas/rest-api/font-collection.json | 8 +- schemas/rest-api/font-face.json | 136 +++++++++++++++++++ schemas/rest-api/font-family.json | 13 +- tests/external-schemas/font-collection.json | 29 +++- tests/external-schemas/font-face.json | 95 +++++++++++++ tests/mu-plugins/mu-plugin.php | 41 +++++- tests/output/fonts.php | 6 +- 11 files changed, 437 insertions(+), 17 deletions(-) create mode 100644 schemas/rest-api/collections/font-faces.json create mode 100644 schemas/rest-api/font-face.json create mode 100644 tests/external-schemas/font-face.json diff --git a/composer.json b/composer.json index 0ebe16a..3985824 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "require-dev": { "ext-sqlite3": "*", "ext-pdo_sqlite": "*", + "ergebnis/json-printer": "^3.5", "johnbillion/args": "1.7.0", "roots/wordpress-core-installer": "^1.0.0", "roots/wordpress-full": "6.6-RC3", diff --git a/packages/wp-types/index.ts b/packages/wp-types/index.ts index 74c89ec..3cc8c36 100644 --- a/packages/wp-types/index.ts +++ b/packages/wp-types/index.ts @@ -40,6 +40,14 @@ export type WP_REST_API_Comments = WP_REST_API_Comment[]; * A collection of font collection objects in a REST API context. */ export type WP_REST_API_Font_Collections = WP_REST_API_Font_Collection[]; +/** + * A collection of font family objects in a REST API context. + */ +export type WP_REST_API_Font_Families = WP_REST_API_Font_Family[]; +/** + * A collection of font face objects in a REST API context. + */ +export type WP_REST_API_Font_Faces = WP_REST_API_Font_Face[]; /** * A collection of post objects in a REST API context. */ @@ -144,6 +152,10 @@ export interface WP { Comments: WP_REST_API_Comments; Font_Collection: WP_REST_API_Font_Collection; Font_Collections: WP_REST_API_Font_Collections; + Font_Family: WP_REST_API_Font_Family; + Font_Families: WP_REST_API_Font_Families; + Font_Face: WP_REST_API_Font_Face; + Font_Faces: WP_REST_API_Font_Faces; Post: WP_REST_API_Post; Posts: WP_REST_API_Posts; Page: WP_REST_API_Page; @@ -1977,10 +1989,13 @@ export interface WP_REST_API_Font_Collection { * CSS unicode-range value. */ unicodeRange?: string; + [k: string]: unknown; }[]; preview?: string; + [k: string]: unknown; }; categories?: string[]; + [k: string]: unknown; }[]; /** * The categories for the font collection. @@ -1988,10 +2003,102 @@ export interface WP_REST_API_Font_Collection { categories: { name: string; slug: string; + [k: string]: unknown; }[]; _links: WP_REST_API_Object_Links; [k: string]: unknown; } +/** + * A font family object in a REST API context. + */ +export interface WP_REST_API_Font_Family { + /** + * Unique identifier for the font family. + */ + id: number; + /** + * Version of the theme.json schema used for the typography settings. + */ + theme_json_version: number; + /** + * The IDs of the child font faces in the font family. + */ + font_faces: number[]; + font_family_settings: { + name?: string; + slug?: string; + fontFamily?: string; + preview?: string; + [k: string]: unknown; + }; + _links: WP_REST_API_Object_Links; + /** + * The embedded representation of relations. Only present when the '_embed' query parameter is set. + */ + _embedded?: { + /** + * The associated font faces. + */ + font_faces?: unknown[]; + [k: string]: unknown; + }; + [k: string]: unknown; +} +/** + * A font face object in a REST API context. + */ +export interface WP_REST_API_Font_Face { + /** + * Unique identifier for the font face. + */ + id: number; + /** + * Version of the theme.json schema used for the typography settings. + */ + theme_json_version: number; + /** + * The ID for the parent font family of the font face. + */ + parent: number; + /** + * font-face declaration in theme.json format. + */ + font_face_settings: { + /** + * Unique identifier for the font family. + */ + id?: number; + /** + * Version of the theme.json schema used for the typography settings. + */ + theme_json_version?: number; + /** + * The IDs of the child font faces in the font family. + */ + font_faces?: number[]; + font_family_settings?: { + name?: string; + slug?: string; + fontFamily?: string; + preview?: string; + [k: string]: unknown; + }; + _links?: WP_REST_API_Object_Links; + /** + * The embedded representation of relations. Only present when the '_embed' query parameter is set. + */ + _embedded?: { + /** + * The associated font faces. + */ + font_faces?: unknown[]; + [k: string]: unknown; + }; + [k: string]: unknown; + }; + _links: WP_REST_API_Object_Links; + [k: string]: unknown; +} /** * A post object in a REST API context. */ diff --git a/schema.json b/schema.json index 52a2de3..a07a8cb 100644 --- a/schema.json +++ b/schema.json @@ -92,6 +92,12 @@ "Font_Families": { "$ref": "schemas/rest-api/collections/font-families.json" }, + "Font_Face": { + "$ref": "schemas/rest-api/font-face.json" + }, + "Font_Faces": { + "$ref": "schemas/rest-api/collections/font-faces.json" + }, "Post": { "$ref": "schemas/rest-api/post.json" }, @@ -217,6 +223,8 @@ "Font_Collections", "Font_Family", "Font_Families", + "Font_Face", + "Font_Faces", "Post", "Posts", "Page", diff --git a/schemas/rest-api/collections/font-faces.json b/schemas/rest-api/collections/font-faces.json new file mode 100644 index 0000000..caef5e7 --- /dev/null +++ b/schemas/rest-api/collections/font-faces.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-07/hyper-schema#", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/font-faces.json", + "title": "WP_REST_API_Font_Faces", + "description": "A collection of font face objects in a REST API context.", + "type": "array", + "items": { + "$ref": "../font-face.json" + } +} diff --git a/schemas/rest-api/font-collection.json b/schemas/rest-api/font-collection.json index 9f97fc7..99046a8 100644 --- a/schemas/rest-api/font-collection.json +++ b/schemas/rest-api/font-collection.json @@ -148,7 +148,7 @@ "type": "string" } }, - "additionalProperties": false + "additionalProperties": true } }, "preview": { @@ -156,7 +156,7 @@ "format": "uri" } }, - "additionalProperties": false + "additionalProperties": true }, "categories": { "type": "array", @@ -165,7 +165,7 @@ } } }, - "additionalProperties": false + "additionalProperties": true } }, "categories": { @@ -185,7 +185,7 @@ "type": "string" } }, - "additionalProperties": false + "additionalProperties": true } }, "_links": { diff --git a/schemas/rest-api/font-face.json b/schemas/rest-api/font-face.json new file mode 100644 index 0000000..a6a2f9a --- /dev/null +++ b/schemas/rest-api/font-face.json @@ -0,0 +1,136 @@ +{ + "$schema": "http://json-schema.org/draft-07/hyper-schema#", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/font-face.json", + "title": "WP_REST_API_Font_Face", + "description": "A font face object in a REST API context.", + "$comment": "See also https://schemas.wp.org/trunk/font-face.json", + "type": "object", + "required": [ + "id", + "theme_json_version", + "parent", + "font_face_settings", + "_links" + ], + "properties": { + "id": { + "readOnly": true, + "description": "Unique identifier for the font face.", + "type": "integer" + }, + "theme_json_version": { + "description": "Version of the theme.json schema used for the typography settings.", + "type": "integer" + }, + "parent": { + "description": "The ID for the parent font family of the font face.", + "type": "integer" + }, + "font_face_settings": { + "description": "font-face declaration in theme.json format.", + "type": "object", + "properties": { + "id": { + "readOnly": true, + "description": "Unique identifier for the font family.", + "type": "integer" + }, + "theme_json_version": { + "description": "Version of the theme.json schema used for the typography settings.", + "type": "integer" + }, + "font_faces": { + "description": "The IDs of the child font faces in the font family.", + "type": "array", + "items": { + "type": "integer" + } + }, + "font_family_settings": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "fontFamily": { + "type": "string" + }, + "preview": { + "type": "string", + "format": "uri" + } + } + }, + "_links": { + "$ref": "properties/object-links.json" + }, + "_embedded": { + "description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.", + "type": "object", + "properties": { + "font_faces": { + "description": "The associated font faces.", + "type": "array" + } + } + } + } + }, + "_links": { + "$ref": "properties/object-links.json" + } + }, + "links": [ + { + "rel": "self", + "href": "/wp/v2/font-families/{parent}/font-faces/{id}", + "hrefSchema": { + "properties": { + "parent": { + "$ref": "#/properties/parent" + }, + "id": { + "$ref": "#/properties/id" + } + } + }, + "targetSchema": { + "$ref": "#" + } + }, + { + "rel": "collection", + "href": "/wp/v2/font-families/{parent}/font-faces", + "hrefSchema": { + "properties": { + "parent": { + "$ref": "#/properties/parent" + } + } + }, + "targetSchema": { + "type": "array", + "items": { + "$ref": "#" + } + } + }, + { + "rel": "parent", + "href": "/wp/v2/font-families/{parent}", + "hrefSchema": { + "properties": { + "parent": { + "$ref": "#/properties/parent" + } + } + }, + "targetSchema": { + "$ref": "font-family.json" + } + } + ] +} diff --git a/schemas/rest-api/font-family.json b/schemas/rest-api/font-family.json index 7e9893c..4b5cd3f 100644 --- a/schemas/rest-api/font-family.json +++ b/schemas/rest-api/font-family.json @@ -49,6 +49,16 @@ }, "_links": { "$ref": "properties/object-links.json" + }, + "_embedded": { + "description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.", + "type": "object", + "properties": { + "font_faces": { + "description": "The associated font faces.", + "type": "array" + } + } } }, "links": [ @@ -76,6 +86,5 @@ } } } - ], - "additionalProperties": false + ] } diff --git a/tests/external-schemas/font-collection.json b/tests/external-schemas/font-collection.json index e52455b..05f4657 100644 --- a/tests/external-schemas/font-collection.json +++ b/tests/external-schemas/font-collection.json @@ -37,7 +37,13 @@ "description": "CSS font-display value.", "type": "string", "default": "fallback", - "enum": [ "auto", "block", "fallback", "swap", "optional" ] + "enum": [ + "auto", + "block", + "fallback", + "swap", + "optional" + ] }, "src": { "description": "Paths or URLs to the font files.", @@ -91,7 +97,10 @@ "type": "string" } }, - "required": [ "fontFamily", "src" ], + "required": [ + "fontFamily", + "src" + ], "additionalProperties": false } }, @@ -138,7 +147,11 @@ } } }, - "required": [ "name", "fontFamily", "slug" ], + "required": [ + "name", + "fontFamily", + "slug" + ], "additionalProperties": false }, "categories": { @@ -149,11 +162,15 @@ } } }, - "required": [ "font_family_settings" ], + "required": [ + "font_family_settings" + ], "additionalProperties": false } } }, "additionalProperties": false, - "required": [ "font_families" ] -} + "required": [ + "font_families" + ] +} \ No newline at end of file diff --git a/tests/external-schemas/font-face.json b/tests/external-schemas/font-face.json new file mode 100644 index 0000000..757e0e4 --- /dev/null +++ b/tests/external-schemas/font-face.json @@ -0,0 +1,95 @@ +{ + "type": "object", + "properties": { + "fontFamily": { + "description": "CSS font-family value.", + "type": "string", + "default": "" + }, + "fontStyle": { + "description": "CSS font-style value.", + "type": "string", + "default": "normal" + }, + "fontWeight": { + "description": "List of available font weights, separated by a space.", + "default": "400", + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "fontDisplay": { + "description": "CSS font-display value.", + "type": "string", + "default": "fallback", + "enum": [ + "auto", + "block", + "fallback", + "swap", + "optional" + ] + }, + "src": { + "description": "Paths or URLs to the font files.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "default": [] + }, + "fontStretch": { + "description": "CSS font-stretch value.", + "type": "string" + }, + "ascentOverride": { + "description": "CSS ascent-override value.", + "type": "string" + }, + "descentOverride": { + "description": "CSS descent-override value.", + "type": "string" + }, + "fontVariant": { + "description": "CSS font-variant value.", + "type": "string" + }, + "fontFeatureSettings": { + "description": "CSS font-feature-settings value.", + "type": "string" + }, + "fontVariationSettings": { + "description": "CSS font-variation-settings value.", + "type": "string" + }, + "lineGapOverride": { + "description": "CSS line-gap-override value.", + "type": "string" + }, + "sizeAdjust": { + "description": "CSS size-adjust value.", + "type": "string" + }, + "unicodeRange": { + "description": "CSS unicode-range value.", + "type": "string" + } + }, + "required": [ + "fontFamily", + "src" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/tests/mu-plugins/mu-plugin.php b/tests/mu-plugins/mu-plugin.php index 70c20b3..8743452 100644 --- a/tests/mu-plugins/mu-plugin.php +++ b/tests/mu-plugins/mu-plugin.php @@ -2,6 +2,8 @@ namespace WPJsonSchemas; +use Ergebnis\Json\Printer; + use WP_CLI; use WP_REST_Request; use WP_REST_Response; @@ -14,6 +16,8 @@ return; } +require_once dirname( __DIR__, 2 ) . '/vendor/autoload.php'; + set_error_handler( function( int $errno, string $errstr, string $errfile = '', int $errline = 0 ) : bool { // This is an @-suppressed error: if ( ! ( error_reporting() & $errno ) ) { @@ -104,7 +108,7 @@ function save_rest_array( array $data, string $dir ) : void { } } -function save_external_schema( string $url, string $name ) : void { +function save_external_schema( string $url, string $name, array $path = [] ) : void { $target = dirname( ABSPATH ) . "/external-schemas/{$name}.json"; $schema = download_url( $url ); @@ -112,10 +116,39 @@ function save_external_schema( string $url, string $name ) : void { throw new \Exception( "Failed to download external {$name} schema." ); } - $renamed = rename( $schema, $target ); + $file = file_get_contents( $schema ); + + if ( ! $file ) { + throw new \Exception( "Failed to open {$name} schema file." ); + } + + $data = json_decode( $file, true ); + + if ( ! $data ) { + throw new \Exception( "Failed to parse external {$name} schema." ); + } + + foreach ( $path as $key ) { + if ( isset( $data[ $key ] ) ) { + $data = $data[ $key ]; + } else { + throw new \Exception( "Failed to find path {$key} in external {$name} schema." ); + } + } + + $json = json_encode( $data, JSON_PRETTY_PRINT ^ JSON_UNESCAPED_SLASHES ); + + $printer = new Printer\Printer(); + + $json = $printer->print( + $json, + "\t", + ); + + $result = file_put_contents( $target, $json ); - if ( ! $renamed ) { - throw new \Exception( "Failed to rename external {$name} schema." ); + if ( ! $result ) { + throw new \Exception( "Failed to save external {$name} schema." ); } } diff --git a/tests/output/fonts.php b/tests/output/fonts.php index dce4736..89fe94e 100644 --- a/tests/output/fonts.php +++ b/tests/output/fonts.php @@ -51,5 +51,9 @@ save_external_schema( 'https://schemas.wp.org/trunk/theme.json', - 'font-family' + 'font-face', + [ + 'definitions', + 'fontFace', + ] ); From 3431d6c14eecf8e7a7e862f831ccde93d75f5e2b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 14 Jul 2024 18:42:10 +0200 Subject: [PATCH 5/5] DRY. --- packages/wp-types/index.ts | 164 +++++++++--------- schemas/rest-api/font-collection.json | 127 +------------- schemas/rest-api/font-face.json | 19 +- schemas/rest-api/font-family.json | 19 +- schemas/rest-api/properties/font-face.json | 99 +++++++++++ .../properties/font-family-settings.json | 38 ++++ 6 files changed, 229 insertions(+), 237 deletions(-) create mode 100644 schemas/rest-api/properties/font-face.json create mode 100644 schemas/rest-api/properties/font-family-settings.json diff --git a/packages/wp-types/index.ts b/packages/wp-types/index.ts index 3cc8c36..0adfa8a 100644 --- a/packages/wp-types/index.ts +++ b/packages/wp-types/index.ts @@ -1924,78 +1924,8 @@ export interface WP_REST_API_Font_Collection { * The font families for the font collection. */ font_families: { - font_family_settings: { - name: string; - fontFamily: string; - slug: string; - fontFace?: { - /** - * URL to a preview image of the font. - */ - preview?: string; - /** - * CSS font-family value. - */ - fontFamily: string; - /** - * CSS font-style value. - */ - fontStyle?: string; - /** - * List of available font weights, separated by a space. - */ - fontWeight?: string | number; - /** - * CSS font-display value. - */ - fontDisplay?: "auto" | "block" | "fallback" | "swap" | "optional"; - /** - * Paths or URLs to the font files. - */ - src: string | string[]; - /** - * CSS font-stretch value. - */ - fontStretch?: string; - /** - * CSS ascent-override value. - */ - ascentOverride?: string; - /** - * CSS descent-override value. - */ - descentOverride?: string; - /** - * CSS font-variant value. - */ - fontVariant?: string; - /** - * CSS font-feature-settings value. - */ - fontFeatureSettings?: string; - /** - * CSS font-variation-settings value. - */ - fontVariationSettings?: string; - /** - * CSS line-gap-override value. - */ - lineGapOverride?: string; - /** - * CSS size-adjust value. - */ - sizeAdjust?: string; - /** - * CSS unicode-range value. - */ - unicodeRange?: string; - [k: string]: unknown; - }[]; - preview?: string; - [k: string]: unknown; - }; + font_family_settings: WP_Font_Family_Settings; categories?: string[]; - [k: string]: unknown; }[]; /** * The categories for the font collection. @@ -2003,11 +1933,85 @@ export interface WP_REST_API_Font_Collection { categories: { name: string; slug: string; - [k: string]: unknown; }[]; _links: WP_REST_API_Object_Links; [k: string]: unknown; } +/** + * Font family settings. + */ +export interface WP_Font_Family_Settings { + name: string; + fontFamily: string; + slug: string; + fontFace?: WP_Font_Face[]; + preview?: string; +} +/** + * A font face. + */ +export interface WP_Font_Face { + /** + * URL to a preview image of the font. + */ + preview?: string; + /** + * CSS font-family value. + */ + fontFamily: string; + /** + * CSS font-style value. + */ + fontStyle?: string; + /** + * List of available font weights, separated by a space. + */ + fontWeight?: string | number; + /** + * CSS font-display value. + */ + fontDisplay?: "auto" | "block" | "fallback" | "swap" | "optional"; + /** + * Paths or URLs to the font files. + */ + src: string | string[]; + /** + * CSS font-stretch value. + */ + fontStretch?: string; + /** + * CSS ascent-override value. + */ + ascentOverride?: string; + /** + * CSS descent-override value. + */ + descentOverride?: string; + /** + * CSS font-variant value. + */ + fontVariant?: string; + /** + * CSS font-feature-settings value. + */ + fontFeatureSettings?: string; + /** + * CSS font-variation-settings value. + */ + fontVariationSettings?: string; + /** + * CSS line-gap-override value. + */ + lineGapOverride?: string; + /** + * CSS size-adjust value. + */ + sizeAdjust?: string; + /** + * CSS unicode-range value. + */ + unicodeRange?: string; +} /** * A font family object in a REST API context. */ @@ -2024,13 +2028,7 @@ export interface WP_REST_API_Font_Family { * The IDs of the child font faces in the font family. */ font_faces: number[]; - font_family_settings: { - name?: string; - slug?: string; - fontFamily?: string; - preview?: string; - [k: string]: unknown; - }; + font_family_settings: WP_Font_Family_Settings; _links: WP_REST_API_Object_Links; /** * The embedded representation of relations. Only present when the '_embed' query parameter is set. @@ -2076,13 +2074,7 @@ export interface WP_REST_API_Font_Face { * The IDs of the child font faces in the font family. */ font_faces?: number[]; - font_family_settings?: { - name?: string; - slug?: string; - fontFamily?: string; - preview?: string; - [k: string]: unknown; - }; + font_family_settings?: WP_Font_Family_Settings; _links?: WP_REST_API_Object_Links; /** * The embedded representation of relations. Only present when the '_embed' query parameter is set. diff --git a/schemas/rest-api/font-collection.json b/schemas/rest-api/font-collection.json index 99046a8..37aa8b5 100644 --- a/schemas/rest-api/font-collection.json +++ b/schemas/rest-api/font-collection.json @@ -37,126 +37,11 @@ ], "properties": { "font_family_settings": { - "type": "object", - "required": [ - "name", - "fontFamily", - "slug" - ], - "properties": { - "name": { - "type": "string" - }, - "fontFamily": { - "type": "string" - }, - "slug": { - "type": "string" - }, - "fontFace": { - "type": "array", - "items": { - "type": "object", - "required": [ - "src", - "fontFamily" - ], - "properties": { - "preview": { - "description": "URL to a preview image of the font.", - "type": "string", - "format": "uri" - }, - "fontFamily": { - "description": "CSS font-family value.", - "type": "string" - }, - "fontStyle": { - "description": "CSS font-style value.", - "type": "string" - }, - "fontWeight": { - "description": "List of available font weights, separated by a space.", - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "fontDisplay": { - "description": "CSS font-display value.", - "type": "string", - "enum": [ - "auto", - "block", - "fallback", - "swap", - "optional" - ] - }, - "src": { - "description": "Paths or URLs to the font files.", - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "fontStretch": { - "description": "CSS font-stretch value.", - "type": "string" - }, - "ascentOverride": { - "description": "CSS ascent-override value.", - "type": "string" - }, - "descentOverride": { - "description": "CSS descent-override value.", - "type": "string" - }, - "fontVariant": { - "description": "CSS font-variant value.", - "type": "string" - }, - "fontFeatureSettings": { - "description": "CSS font-feature-settings value.", - "type": "string" - }, - "fontVariationSettings": { - "description": "CSS font-variation-settings value.", - "type": "string" - }, - "lineGapOverride": { - "description": "CSS line-gap-override value.", - "type": "string" - }, - "sizeAdjust": { - "description": "CSS size-adjust value.", - "type": "string" - }, - "unicodeRange": { - "description": "CSS unicode-range value.", - "type": "string" - } - }, - "additionalProperties": true - } - }, - "preview": { - "type": "string", - "format": "uri" + "oneOf": [ + { + "$ref": "properties/font-family-settings.json" } - }, - "additionalProperties": true + ] }, "categories": { "type": "array", @@ -165,7 +50,7 @@ } } }, - "additionalProperties": true + "additionalProperties": false } }, "categories": { @@ -185,7 +70,7 @@ "type": "string" } }, - "additionalProperties": true + "additionalProperties": false } }, "_links": { diff --git a/schemas/rest-api/font-face.json b/schemas/rest-api/font-face.json index a6a2f9a..a118a60 100644 --- a/schemas/rest-api/font-face.json +++ b/schemas/rest-api/font-face.json @@ -47,22 +47,11 @@ } }, "font_family_settings": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "slug": { - "type": "string" - }, - "fontFamily": { - "type": "string" - }, - "preview": { - "type": "string", - "format": "uri" + "oneOf": [ + { + "$ref": "properties/font-family-settings.json" } - } + ] }, "_links": { "$ref": "properties/object-links.json" diff --git a/schemas/rest-api/font-family.json b/schemas/rest-api/font-family.json index 4b5cd3f..f8c5414 100644 --- a/schemas/rest-api/font-family.json +++ b/schemas/rest-api/font-family.json @@ -30,22 +30,11 @@ } }, "font_family_settings": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "slug": { - "type": "string" - }, - "fontFamily": { - "type": "string" - }, - "preview": { - "type": "string", - "format": "uri" + "oneOf": [ + { + "$ref": "properties/font-family-settings.json" } - } + ] }, "_links": { "$ref": "properties/object-links.json" diff --git a/schemas/rest-api/properties/font-face.json b/schemas/rest-api/properties/font-face.json new file mode 100644 index 0000000..2587799 --- /dev/null +++ b/schemas/rest-api/properties/font-face.json @@ -0,0 +1,99 @@ +{ + "$schema": "http://json-schema.org/draft-07/hyper-schema#", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/font-face.json", + "title": "WP_Font_Face", + "description": "A font face.", + "type": "object", + "required": [ + "src", + "fontFamily" + ], + "properties": { + "preview": { + "description": "URL to a preview image of the font.", + "type": "string", + "format": "uri" + }, + "fontFamily": { + "description": "CSS font-family value.", + "type": "string" + }, + "fontStyle": { + "description": "CSS font-style value.", + "type": "string" + }, + "fontWeight": { + "description": "List of available font weights, separated by a space.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "fontDisplay": { + "description": "CSS font-display value.", + "type": "string", + "enum": [ + "auto", + "block", + "fallback", + "swap", + "optional" + ] + }, + "src": { + "description": "Paths or URLs to the font files.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "fontStretch": { + "description": "CSS font-stretch value.", + "type": "string" + }, + "ascentOverride": { + "description": "CSS ascent-override value.", + "type": "string" + }, + "descentOverride": { + "description": "CSS descent-override value.", + "type": "string" + }, + "fontVariant": { + "description": "CSS font-variant value.", + "type": "string" + }, + "fontFeatureSettings": { + "description": "CSS font-feature-settings value.", + "type": "string" + }, + "fontVariationSettings": { + "description": "CSS font-variation-settings value.", + "type": "string" + }, + "lineGapOverride": { + "description": "CSS line-gap-override value.", + "type": "string" + }, + "sizeAdjust": { + "description": "CSS size-adjust value.", + "type": "string" + }, + "unicodeRange": { + "description": "CSS unicode-range value.", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/schemas/rest-api/properties/font-family-settings.json b/schemas/rest-api/properties/font-family-settings.json new file mode 100644 index 0000000..d66ee7d --- /dev/null +++ b/schemas/rest-api/properties/font-family-settings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-07/hyper-schema#", + "$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/font-family-settings.json", + "title": "WP_Font_Family_Settings", + "description": "Font family settings.", + "type": "object", + "required": [ + "name", + "fontFamily", + "slug" + ], + "properties": { + "name": { + "type": "string" + }, + "fontFamily": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "fontFace": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "./font-face.json" + } + ] + } + }, + "preview": { + "type": "string", + "format": "uri" + } + }, + "additionalProperties": false +}