@@ -4,23 +4,28 @@ import {formatJSON} from './util';
44
55/**
66 * This script generates markdown documentation from the JSON schema.
7- * It leverages exitsing md files in the docs folder and adds generated files from the v8.json file.
7+ * It leverages existing md files in the docs folder and adds generated files from the v8.json file.
88 */
99
1010const BASE_PATH = 'docs' ;
1111
1212type JsonExpressionSyntax = {
1313 overloads : {
1414 parameters : string [ ] ;
15- 'output-type' : string ;
16- } [ ] ;
17- parameters ?: {
18- name : string ;
19- type : string ;
20- doc ?: string ;
15+ 'output-type' : string | string [ ] ;
2116 } [ ] ;
17+ parameters ?: Parameter [ ] ;
18+ }
19+
20+ type Parameter = {
21+ name : string ;
22+ type : ParameterType ;
23+ doc ?: string ;
2224} ;
2325
26+ // either a basic type, a union of a few basic types or an object
27+ type ParameterType = string | string [ ] | { [ key : string ] : JsonObject } ;
28+
2429type JsonSdkSupport = {
2530 [ info : string ] : {
2631 js ?: string ;
@@ -36,10 +41,13 @@ type JsonObject = {
3641 type : string ;
3742 doc : string ;
3843 requires ?: any [ ] ;
39- example : string | object | number ;
40- expression ?: { interpolated ?: boolean ; parameters ?: string [ ] } ;
44+ example : string | object | number | boolean ;
45+ expression ?: { interpolated ?: boolean ; parameters ?: string [ ] } ;
4146 transition ?: boolean ;
42- values ?: { [ key : string ] : { doc : string ; 'sdk-support' ?: JsonSdkSupport } } | number [ ] ;
47+ // for enum type: what is the type of the emum elements
48+ values ?: { [ key : string ] : { doc : string ; 'sdk-support' ?: JsonSdkSupport } } | number [ ] ;
49+ // for array type: what is the type of the array elements?
50+ value ?: string ;
4351 minimum ?: number ;
4452 maximum ?: number ;
4553} ;
@@ -123,6 +131,52 @@ function sdkSupportToMarkdown(support: JsonSdkSupport): string {
123131 return markdown ;
124132}
125133
134+ /**
135+ * Joins the array of type strings into a single string with `" | "` between them.
136+ * @param input the array or string to be joined
137+ * @returns the joined string
138+ */
139+ function parameterTypeToType ( input : ParameterType ) :string {
140+ if ( typeof input === 'string' )
141+ return input
142+ if ( Array . isArray ( input ) ) {
143+ return input . join ( ' | ' )
144+ }
145+ const parameters = Object . entries ( input )
146+ . map ( ( [ key , val ] ) => {
147+ const requiredSuffix = val . required ? '' : '?' ;
148+ return `${ key } ${ requiredSuffix } : ${ jsonObjectToType ( val ) } `
149+ } )
150+ . join ( ', ' )
151+
152+ return `{${ parameters } }` ;
153+ }
154+
155+ /**
156+ * Converts the JSON object to a type string.
157+ * @param val - the JSON object
158+ * @returns the type string
159+ */
160+ function jsonObjectToType ( val : JsonObject ) :string {
161+ switch ( val . type ) {
162+ case 'boolean' :
163+ case 'string' :
164+ case 'number' :
165+ case 'color' :
166+ // basic types -> no conversion needed
167+ return val . type
168+ case 'array' :
169+ return `${ val . type } <${ parameterTypeToType ( val . value ) } >` ;
170+ case 'enum' :
171+ const values = val . values ;
172+ if ( ! values || Array . isArray ( values ) )
173+ throw new Error ( `Enum ${ JSON . stringify ( val ) } has no "values" describing the contained Options in the form of an Object` )
174+ return Object . keys ( values ) . map ( s => `"${ s } "` ) . join ( ' | ' ) ;
175+ default :
176+ throw new Error ( `Unknown "type" ${ val . type } for ${ JSON . stringify ( val ) } ` )
177+ }
178+ }
179+
126180/**
127181 * Converts the expression syntax object to markdown format.
128182 * @param key - the expression name
@@ -132,17 +186,32 @@ function sdkSupportToMarkdown(support: JsonSdkSupport): string {
132186function expressionSyntaxToMarkdown ( key : string , syntax : JsonExpressionSyntax ) {
133187 let markdown = '\nSyntax:\n' ;
134188 const codeBlockLines = syntax . overloads . map ( ( overload ) => {
135- return `[${ [ `"${ key } "` , ...overload . parameters ] . join ( ', ' ) } ]: ${ overload [ 'output-type' ] } ` ;
189+ const key_and_parameters = [ `"${ key } "` , ...overload . parameters ] . join ( ', ' ) ;
190+
191+ return `[${ key_and_parameters } ]: ${ parameterTypeToType ( overload [ 'output-type' ] ) } ` ;
136192 } ) ;
137193 markdown += `${ codeBlockMarkdown ( codeBlockLines . join ( '\n' ) , 'js' ) } \n` ;
138194 for ( const parameter of syntax . parameters ?? [ ] ) {
139- markdown += `- \`${ parameter . name } \`` ;
140- if ( parameter . type ) {
141- const type = parameter . type . replaceAll ( '<' , '<' ) . replaceAll ( '>' , '>' ) ;
142- markdown += `: *${ type } *` ;
143- }
195+ const type = parameterTypeToType ( parameter . type ) . replaceAll ( '<' , '<' ) . replaceAll ( '>' , '>' ) ;
196+ markdown += `- \`${ parameter . name } \`: \`${ type } \`` ;
144197 if ( parameter . doc ) {
145- markdown += ` — ${ parameter . doc } ` ;
198+ markdown += `- ${ parameter . doc } ` ;
199+ }
200+ if ( typeof parameter . type !== 'string' && ! Array . isArray ( parameter . type ) ) {
201+ // the type is an object type => we can attach more documentation about the contained variables
202+ markdown += ' \nParameters:'
203+ Object . entries ( parameter . type ) . forEach ( ( [ key , val ] ) => {
204+ const type = jsonObjectToType ( val ) . replaceAll ( '<' , '<' ) . replaceAll ( '>' , '>' ) ;
205+ markdown += `\n - \`${ key } \`: \`${ type } \` - ${ val . doc } `
206+ if ( val . type === 'enum' && val . values ) {
207+ markdown += ' \n Possible values are:'
208+ for ( const [ enumKey , enumValue ] of Object . entries ( val . values ) ) {
209+ const defaultIndicator = val . default === enumKey ? ' *default*' : '' ;
210+ markdown += `\n - \`"${ enumKey } "\`${ defaultIndicator } - ${ enumValue . doc } `
211+ }
212+ }
213+
214+ } )
146215 }
147216 markdown += '\n' ;
148217 }
0 commit comments