Categories:
aura-json-schema-generator utility
aura-json-schema-generator utility is a tool to generate Typescript classes
Introduction
aura-json-schema-generator utility is a tool to generate Typescript classes from JSON schema file(s). It provides a command that generates Typescript interface files from one or more schema files.
It is placed in the Github repository:
aura-bot-libraries/packages/aura-json-schema-generator/.
The input file(s) is mandatory. The output directory is optional (./types by default). In it, a directory is created for every schema including the schema version, and inside that directory, another one is created with the schema name that will contain the typescript interfaces.
Installation
Although it is possible to install the package locally, it is recommended to install it globally, in order to allow the execution of the generator binary anywhere.
$ npm install -g @telefonica/aura-json-schema-generator
Once installed globally, a new command aura-json-schema-generator will be available in the PATH, so we can generate Typescript interface files from one or more schema files.
Run aura-json-schema-generator utility
aura-json-schema-generator
Two other names for this command are available:
aura-jsgandaujsg
Arguments
There are two arguments that can be passed in the command line when running:
- The first argument (mandatory) is the path of a JSON Schema file or a directory that contains JSON Schema files.
- The second argument (optional) is the path where the Typescript files will be created.
typesis the default value. This information can be found when running the command without arguments:
$ aura-json-schema-generator
ERROR Argument missing. Use: aura-json-schema-generator <input file or dir> [<output dir>]
This command will create the Typescript interfaces from a JSON Schema file named simple.json in the default output directory types within current directory:
$ aura-json-schema-generator ./simple.schema.json
DEBUG Reading json schema ./simple.schema.json
INFO Output path will be './types'
INFO Writing ./types/1.0.0/simple/simple.d.ts
This command will create all the Typescript interfaces from channelData schemas in the directory resources/channel-data/3.0.0 in a specified output directory src/channel-data/:
$ aura-json-schema-generator resources/channel-data/3.0.0/ src/channel-data/
DEBUG Reading json schema ./resources/channel-data/3.0.0/request/channeldata-3.0.0-request.schema.json
DEBUG Reading json schema ./resources/channel-data/3.0.0/response/channeldata-3.0.0-response.schema.json
INFO Output path will be './src/channel-data'
INFO Writing ./src/channel-data/3.0.0/request/request-channel-data.d.ts
INFO Writing ./src/channel-data/3.0.0/response/response-channel-data.d.ts
The following example shows the execution of the aura-json-schema-generator in the happening of an error in any of the provided schemas. As can be seen, an error is shown indicating both the file that contains the error and thus cannot be processed and the specific error or errors in the schema.
In this case, the error is in the file request/channeldata-3.0.0-request-wrong.schema.json and the problems are that neither ApplicationWrong nor AuraCommandWrong cannot be found, so the schema for this file cannot be generated. The rest of the files in the folder resources/channel-data/3.0.0/ will be processed and their schemas will be generated correctly.
$ aura-json-schema-generator resources/channel-data/3.0.0/ src/channel-data/
DEBUG Reading json schema ./resources/channel-data/3.0.0/request/channeldata-3.0.0-request-wrong.schema.json
ERROR Object ApplicationWrong not found
ERROR Object AuraCommandWrong not found
ERROR Error reading file ./channel-data/3.0.0/request/channeldata-3.0.0-request-wrong.schema.json
DEBUG Reading json schema ./channel-data/3.0.0/response/channeldata-3.0.0-response.schema.json
INFO Output path will be './src/channel-data'
INFO Writing ./src/channel-data/3.0.0/response/response-channel-data.d.ts
aura-types-from-swagger-generator
Two other names for this command are available:
aura-tfsgandautfsg
Arguments
There are three arguments that can be passed in the command line when running:
- The first argument (mandatory) is the path of a JSON/YAML Schema file or a directory that contain JSON/YAML Schema files.
- The second argument (optional) is the path where the Typescript files will be created.
typesis the default value. - The third argument (optional) is an array of strings with options:
- –unique-file: Create all the models data in a single file by swagger.
- –unify-enumerated: Unify the generated enums.
- –particularize-enumerated: Particularize the generated enums.
This command will create the typescript interfaces, enums and types from a Swagger file named swagger.json in the default output directory types within current directory:
$ aura-types-from-swagger-generator ./swagger.json
Using swagger with this info:
{
"openapi": "3.0.0",
"info": {
"title": "Aura Bridge",
"description": "Set of endpoints that support the aura bridge",
"version": "1.1.0"
},
...
}
The result has the following structure:
types
└── 1.1.0
└── aura-bridge.ts
aura-markdown-from-json-schema-generator
The execution of the following command will create the markdown documentation from a JSON schema file:
$ aura-markdown-from-json-schema-generator aura-models/resources/channel-data/payload.schema.json payload-types.md
For example, using a JSON schema with this info:
{
...
"Payload": {
"description": "Channel data payload information",
"title": "Payload",
"type": "object",
"additionalProperties": false,
"properties": {
"bridge": {
"$ref": "#/definitions/channel-data/Bridge",
"description": "Information sent from the bridge",
"title": "bridge"
},
"handover": {
"$ref": "#/definitions/channel-data/Handover",
"description": "Information sent from Handover",
"title": "handover"
},
"event": {
"$ref": "#/definitions/channel-data/PayloadEvent",
"description": "Information sent as an event",
"title": "event"
}
},
"required": [
"bridge"
]
},
...
}
The outcome of the execution of the previous command will generate:
-
The input JSON schema (in the example,
aura-models/resources/channel-data/payload.schema.json) -
A markdown output file, in the example:
payload-types.md:
### Payload
Channel data payload information
| Property | Type | Description |
| --------------- | ------------ | -------------------------------------------------- |
| **bridge** | Bridge | Information sent from the bridge |
| *handover* | Handover | Information sent from Handover |
| *event* | PayloadEvent | Information sent as an event |
Components
Enums
Particularize Enumerated
For this flow, enums are generated as follows:
- Enums are generated from the properties of models that have the
isEnumeratedandenumsflags. - Enums are generated from types, checking if it is a type with an array, a type with different types, etc.
- The enums that are not being used are filtered out to avoid generating them.
oneOf
oneOf is a property used to indicate that a component can have one of the types it receives as options. For example:
Component1:
properties:
property1:
type: array
items:
oneOf:
- $ref: '#/components/schemas/Item1'
- $ref: '#/components/schemas/Item2'
- $ref: '#/components/schemas/Item3'
If the items within oneOf do not have the title field filled, by default it will be name + Type + incr_counter:
{
"paths": {},
"components": {
"schemas": {
"Component_Property_1": {
"type": "string",
"enum": [
"none",
"auto"
]
},
"Component_Property_2": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
]
},
"Component_1": {
"oneOf": [
{
"type": "string",
"enum": [
"none",
"auto"
]
},
{
"$ref": "#/components/schemas/Component_Property_1"
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
]
},
{
"type": "string",
"enum": [
"none",
"auto"
]
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
]
},
{
"$ref": "#/components/schemas/Component_Property_2"
}
]
}
}
}
}
The result would be as follows:
/**
* Enum for Component_Property_1
*
* @enum {string}
*/
export enum ComponentProperty1 {
None = 'none',
Auto = 'auto'
}
/**
* Enum for Component_1
*
* @enum {string}
*/
export enum Component_1Enum {
None = 'none',
Auto = 'auto'
}
/**
* Enum for Component_1
*
* @enum {string}
*/
export enum Component_1Enum1 {
None = 'none',
Auto = 'auto'
}
/**
* Type for Component1
*/
export type Component1 = Component_1Enum | ComponentProperty1 | Component1Type | Component_1Enum1 | Component1Type1 | ComponentProperty2;
/**
* @interface ComponentProperty2
*/
export interface ComponentProperty2 {
name: string;
}
/**
* @interface Component1Type
*/
export interface Component1Type {
name: string;
}
/**
* @interface Component1Type1
*/
export interface Component1Type1 {
name: string;
}