Last active
February 9, 2022 12:43
-
-
Save adamziel/5919335be693bb45ae03019b7bcf5a96 to your computer and use it in GitHub Desktop.
Compile WordPress API JSON Schema to TypeScript type definitions for entity records
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const __ = (x) => x; | |
export const defaultEntities = [ | |
{ | |
label: __( 'Base' ), | |
name: '__unstableBase', | |
kind: 'root', | |
baseURL: '/', | |
}, | |
{ | |
label: __( 'Site' ), | |
name: 'site', | |
kind: 'root', | |
baseURL: '/wp/v2/settings', | |
getTitle: ( record ) => { | |
return get( record, [ 'title' ], __( 'Site Title' ) ); | |
}, | |
}, | |
{ | |
label: __( 'Post Type' ), | |
name: 'postType', | |
kind: 'root', | |
key: 'slug', | |
baseURL: '/wp/v2/types', | |
baseURLParams: { context: 'edit' }, | |
}, | |
{ | |
name: 'media', | |
kind: 'root', | |
baseURL: '/wp/v2/media', | |
baseURLParams: { context: 'edit' }, | |
plural: 'mediaItems', | |
label: __( 'Media' ), | |
}, | |
{ | |
name: 'taxonomy', | |
kind: 'root', | |
key: 'slug', | |
baseURL: '/wp/v2/taxonomies', | |
baseURLParams: { context: 'edit' }, | |
plural: 'taxonomies', | |
label: __( 'Taxonomy' ), | |
}, | |
{ | |
name: 'sidebar', | |
kind: 'root', | |
baseURL: '/wp/v2/sidebars', | |
plural: 'sidebars', | |
transientEdits: { blocks: true }, | |
label: __( 'Widget areas' ), | |
}, | |
{ | |
name: 'widget', | |
kind: 'root', | |
baseURL: '/wp/v2/widgets', | |
baseURLParams: { context: 'edit' }, | |
plural: 'widgets', | |
transientEdits: { blocks: true }, | |
label: __( 'Widgets' ), | |
}, | |
{ | |
name: 'widgetType', | |
kind: 'root', | |
baseURL: '/wp/v2/widget-types', | |
baseURLParams: { context: 'edit' }, | |
plural: 'widgetTypes', | |
label: __( 'Widget types' ), | |
}, | |
{ | |
label: __( 'User' ), | |
name: 'user', | |
kind: 'root', | |
baseURL: '/wp/v2/users', | |
baseURLParams: { context: 'edit' }, | |
plural: 'users', | |
}, | |
{ | |
name: 'comment', | |
kind: 'root', | |
baseURL: '/wp/v2/comments', | |
baseURLParams: { context: 'edit' }, | |
plural: 'comments', | |
label: __( 'Comment' ), | |
}, | |
{ | |
name: 'menu', | |
kind: 'root', | |
baseURL: '/wp/v2/menus', | |
baseURLParams: { context: 'edit' }, | |
plural: 'menus', | |
label: __( 'Menu' ), | |
}, | |
{ | |
name: 'menuItem', | |
kind: 'root', | |
baseURL: '/wp/v2/menu-items', | |
baseURLParams: { context: 'edit' }, | |
plural: 'menuItems', | |
label: __( 'Menu Item' ), | |
rawAttributes: [ 'title', 'content' ], | |
}, | |
{ | |
name: 'menuLocation', | |
kind: 'root', | |
baseURL: '/wp/v2/menu-locations', | |
baseURLParams: { context: 'edit' }, | |
plural: 'menuLocations', | |
label: __( 'Menu Location' ), | |
key: 'name', | |
}, | |
{ | |
name: 'navigationArea', | |
kind: 'root', | |
baseURL: '/wp/v2/block-navigation-areas', | |
baseURLParams: { context: 'edit' }, | |
plural: 'navigationAreas', | |
label: __( 'Navigation Area' ), | |
key: 'name', | |
getTitle: ( record ) => record?.description, | |
}, | |
{ | |
label: __( 'Global Styles' ), | |
name: 'globalStyles', | |
kind: 'root', | |
baseURL: '/wp/v2/global-styles', | |
baseURLParams: { context: 'edit' }, | |
plural: 'globalStylesVariations', // should be different than name | |
getTitle: ( record ) => record?.title?.rendered || record?.title, | |
}, | |
{ | |
label: __( 'Themes' ), | |
name: 'theme', | |
kind: 'root', | |
baseURL: '/wp/v2/themes', | |
baseURLParams: { context: 'edit' }, | |
key: 'stylesheet', | |
}, | |
{ | |
label: __( 'Plugins' ), | |
name: 'plugin', | |
kind: 'root', | |
baseURL: '/wp/v2/plugins', | |
baseURLParams: { context: 'edit' }, | |
key: 'plugin', | |
}, | |
]; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { defaultEntities } from "./entities.mjs"; | |
import fetch from 'node-fetch'; | |
import { compile } from 'json-schema-to-typescript'; | |
const SITE_URL = 'http://localhost:8888'; | |
const results = []; | |
for ( const entity of defaultEntities ) { | |
if ( ['Base'].includes( entity?.label ) ) { | |
continue; | |
} | |
const url = `${ SITE_URL }/wp-json${ entity.baseURL }`; | |
const response = await fetch( url, { method: 'OPTIONS' } ); | |
const json = await response.json(); | |
let schema = json.schema; | |
if ( !schema ) { | |
continue; | |
} | |
schema = fixEnums( schema ); | |
let ts = await compile( schema, 'MySchema', { | |
bannerComment: false, | |
} ); | |
ts = ts.replace( /\n\s+\[k: string\]: unknown;/gm, '' ); | |
results.push( { title: schema.title, code: ts } ); | |
} | |
const allEntityNames = results.map( | |
( { code } ) => code.split( 'interface ' )[ 1 ].split( '{' )[ 0 ].trim() ); | |
console.log( | |
results | |
.sort( ( a, b ) => a.title?.localeCompare( b.title ) ) | |
.map( e => e.code ) | |
.join( "\n" ), | |
); | |
console.log( 'export type EntityRecord = ' + allEntityNames.join( ' | ' ) + ';' ); | |
console.log(''); | |
/* json-schema-to-typescript can't deal with object enums, it requires an array */ | |
function fixEnums( obj ) { | |
const isArray = Array.isArray( obj ); | |
const newObj = isArray ? [] : {}; | |
const push = ( key, value ) => { | |
if ( isArray ) { | |
newObj.push( value ); | |
} else { | |
newObj[ key ] = value; | |
} | |
}; | |
for ( const key in obj ) { | |
const entry = obj[ key ]; | |
if ( key === "enum" ) { | |
if ( typeof entry === 'object' ) { | |
push( key, Object.values( entry ) ); | |
} else { | |
push( key, entry ); | |
} | |
} else if ( Array.isArray( entry ) || typeof entry === 'object' ) { | |
push( key, fixEnums( entry ) ); | |
} else { | |
push( key, entry ); | |
} | |
} | |
return newObj; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "json-schema-generator", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "Adam Zielinski <adam@adamziel.com> (http://adamziel.com)", | |
"license": "ISC", | |
"type": "module", | |
"dependencies": { | |
"json-schema-to-typescript": "^10.1.5", | |
"node-fetch": "^3.2.0" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment