@trayio/tray-schema
TypeScript icon, indicating that this package has built-in type declarations

4.10.0 • Public • Published

Tray-schema

This module contains a collection of utilities for transforming and manipulating various representations of Tray's connector schema.

TJSTraySchemaTypeTransformer

Overview

This part of the module takes a CDK connectors input or output typescript type definitions, along with any JSdoc annotations, and generates JSON schema representing these types. Specifically this format is Tray schema, otherwise known as CAPI schema, but importantly it is not the old way of writing connector JSON schema, which is reffered to as the legacy connector schema.

To generate the full schema for a connector this utility will be invoked for each operation's input and output. Operation metadata is pulled from the handler (using a different util) and then all of this schema is stiched together (using yet another different util) to produce the final connectors.json in Tray schema format. Which will then be transformed into legcay connector schema (by yet another different util) to ensure the connector works with the legacy deployment process.

Have a look at the example types used for unit tests within src/TJSTraySchemaTypeTransformer/tests/ for examples of how to do different things with typescript and JSdoc.

Why use NPM lib typescript-json-schema

We found only 2 suitable libraries for converting typescript types to JSON schema:

  • typescript-json-schema:
    • It's functionality cannot be extended
    • It won't throw an exception if you ask it to generate "invalid" schema
  • ts-json-schema-generator
    • Is an extension of typescript-json-schema
    • It's functionality can be extended
    • It will throw an exception if you ask it to generate "invalid" schema. And this is the main reason we did not chose this library, because this library sees some of the extra properties Tray schema has as invalid.

Post processing

To get around the non extendable nature of the typescript-json-schema lib we perform a number of different post processing steps on the generated JSON schema.

Enums

Tray schema supports enum labels so users can have a enum value which is sent and an enum label which is just displayed in the UI. Adding support for enum lables is trivial, until you realise that typescript-json-schema sorts the enums alphabetically. There are a few different ways to handle this, all of them are not ideal.

You can force the user to specify their enum, enum labels and enum order, which is incredibley cumbersome, they would have to write the enum list 4 times (its 4 not 3 because a TS enum needs a key and value).

For now we will not allow custom enum labels, instead we try to generate they best enum label possible automatically, in addition the order of enums can't be specified. We are planning on opening a PR to the typescript-json-schema lib to add a config option to disable this sorting. This way when we have this PR merged we can enable enum labels through the @enumLabel JSdoc annotation and it will be backwards compatible for end users.

Lookup / DDLs

Ideally DDLs would be defined in JSdoc like this, using the dot to target the property in the resulting JSON schema (e.g. @lookup.operation). Unfortunately this doesn't work with the typescript-json-schema library. So instead we use camelCased annotation names (e.g. @lookupOperation) and then use post processing to rearrange the schema. Potentially we could also raise a PR to the lib to add this dot notation support.

// ideal input
export type Input = {
	/**
	 * @lookup.operation list_users_actual_ddl
	 * @lookup.input {"include_private_channels": false,"workspace_id": "{{{workspace_id}}}"}
	 */
	emails: string;
};

// actual input
export type Input = {
	/**
	 * @lookupOperation list_users_actual_ddl
	 * @lookupInput {"include_private_channels": false,"workspace_id": "{{{workspace_id}}}"}
	 */
	emails: string;
};

// Output
emails: {
    type: 'string',
    lookup: {
        operation: 'list_users_actual_ddl',
        input: {
            include_private_channels: false,
            workspace_id: '{{{workspace_id}}}',
        },
    },
},

Advance fields not supported yet

Some more work is required to support advanced fields, which is when a field is hidden within the Tray UI in an expandable advanced section.

Would need to add a new JSdoc annotation @advanced, this will be added to each item of the schema though when it needs to be in an array, similar to how the required fields works. So post processing would be required to strip out the individual required: true on each item and combine them into an array at the parent item level.

Readme

Keywords

none

Package Sidebar

Install

npm i @trayio/tray-schema

Weekly Downloads

266

Version

4.10.0

License

MIT

Unpacked Size

76.6 kB

Total Files

66

Last publish

Collaborators

  • trayprod
  • johnbastian_trayio
  • thomaschaplin
  • simone_trayio