Skip to content

Feature request: Support for generating type defs from JSON Schemas #98

@safwanyp

Description

@safwanyp

Context / Background

Been trying to work on a solution that allows me to generate .d.ts files from a bunch of JSON Schemas. There are 2 tools I have already tried to use before, but they don't really fit my use case.

  • json-schema-to-ts
    • No output of static .d.ts files - this is quite important to me. Only compile time.
    • Naming of generated types is not always as I expect it to be.
  • json-schema-to-dts
    • while it does generate types that can be persisted in a file, naming and generation of referenced types is very finicky. I basically have had to spend 30-40 mins to make them more easy to understand.

Suggested Scope

JSON Schema has a bunch of spec versions, but to begin with I am thinking of draft-07. It's what I work with the most at work and for my own stuff. Since the schemas I tend to work with are also quite large, supporting multiple spec versions will be an undertaking I know I won't be able to manage for now.

Ownership of the Feature

I had a quick chat with @mcollina about this, and he suggested opening up a PR for this in massimo since the main problem of extracting definitions has already been solved in massimo. I already have a tool that does almost exactly what I want (repo). It's a lot og agent generated code which I am trying to refactor to make maintaining it easier for me. Truth be told, I probably gave the agent way too much leeway lol

My idea was that instead of spending more time refactoring that code, I could open up a PR here once I have a reliable solution that fits into massimo's existing tooling.

Final thoughts before the example

If this seems like something that could fit into massimo's api surface, I am willing to expand on this issue with more details on the specific criteria I plan to have for this feature.

Input/Output Example

Just one example of what I'm trying to achieve with this feature. The example is overly simplified to make reviewing this request a bit easier on the eyes. The tool i am working on somewhat achieves this, with a few too many extra types. It's still a WIP, but I'm getting there!

Input

{
  "$id": "syp://neobank-sim-schema/schemas/account/commands/activate-account.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "ActivateAccount",
  "type": "object",
  "required": [
    "specversion",
    "type",
    "source",
    "subject",
    "id",
    "datacontenttype",
    "idempotencykey",
    "data"
  ],
  "properties": {
    "specversion": {
      "type": "string",
      "const": "1.0"
    },
    "type": {
      "$ref": "#/definitions/CommandType"
    },
    "source": {
      "type": "string",
      "format": "uri-reference"
    },
    "subject": {
      "type": "string",
      "pattern": "^.+$"
    },
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "datacontenttype": {
      "const": "application/json"
    },
    "idempotencykey": {
      "type": "string"
    },
    "correlationid": {
      "type": "string",
      "format": "uuid"
    },
    "data": {
      "$ref": "#/definitions/CommandData"
    }
  },
  "definitions": {
    "CommandType": {
      "const": "neo.account.commands.activate-account"
    },
    "CommandData": {
      "type": "object",
      "required": ["account"],
      "properties": {
        "account": {
          "type": "object",
          "required": ["id", "countryCode", "partyIdentifiers"],
          "properties": {
            "id": {
              "type": "string",
              "description": "Unique identifier of the Account, used as a surrogate key."
            },
            "countryCode": {
              "type": "string",
              "description": "Used to identify which country the account is registered in.",
              "enum": ["SE", "DE", "NO", "DK", "FR", "IT"]
            },
            "partyIdentifiers": {
              "type": "array",
              "description": "Identifying details about the party to which the account belongs to.",
              "items": {
                "type": "object",
                "required": ["type", "value"],
                "properties": {
                  "type": {
                    "type": "string",
                    "description": "The type of the identifier.",
                    "enum": ["email", "phone_number", "national_id"]
                  },
                  "value": {
                    "type": "string",
                    "description": "The value of the identifier."
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Output

/**
 * ActivateAccount
 */
interface ActivateAccount {
  specversion: Specversion;
  type: CommandType;
  source: Source;
  subject: Subject;
  id: Id;
  datacontenttype: Datacontenttype;
  idempotencykey: Idempotencykey;
  correlationid?: Correlationid;
  data: CommandData;
}

interface CommandData {
  account: CommandDataAccount;
}

interface CommandDataAccount {
  id: CommandDataAccountId;
  countryCode: CommandDataAccountCountryCode;
  partyIdentifiers: CommandDataAccountPartyIdentifiers;
}

/**
 * Used to identify which country the account is registered in.
 */
type CommandDataAccountCountryCode = 'SE' | 'DE' | 'NO' | 'DK' | 'FR' | 'IT';

/**
 * Unique identifier of the Account, used as a surrogate key.
 */
type CommandDataAccountId = string;

/**
 * Identifying details about the party to which the account belongs to.
 */
type CommandDataAccountPartyIdentifiers = CommandDataAccountPartyIdentifiersItem[];

interface CommandDataAccountPartyIdentifiersItem {
  type: CommandDataAccountPartyIdentifiersItemType;
  value: CommandDataAccountPartyIdentifiersItemValue;
}

/**
 * The type of the identifier.
 */
type CommandDataAccountPartyIdentifiersItemType = 'email' | 'phone_number' | 'national_id';

/**
 * The value of the identifier.
 */
type CommandDataAccountPartyIdentifiersItemValue = string;

type CommandType = 'neo.account.commands.activate-account';

type Correlationid = string;

type Datacontenttype = 'application/json';

type Id = string;

type Idempotencykey = string;

type Source = string;

type Specversion = '1.0';

type Subject = string;

export { ActivateAccount };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions