Skip to content

Darkle/openapi-to-rescript-generator

Repository files navigation

Openapi to Rescript generator

Note This is just a first pass at this. Some stuff isn't supported yet. Expect some bugs.

Introduction:

  • Generate rescript code from an openapi spec document to help you validate & parse responses from your api. It also generates types for parameters and validation for request bodies.

  • It supports openapi specs in json and yaml form.

  • Most of the heavy lifting is done by the Rescript Struct and Rescript Json Schema libs.

Usage:

  1. Install via npm install openapi-to-rescript-generator -g
  2. Run openapi-to-rescript --inputFile <inputFilePath> --outputFile <outputFilePath>.
    • Example: openapi-to-rescript --inputFile ./foo/openapi.json --outputFile ./bar/output.res
  3. You will then need to install rescript struct in your app for working with the file you created.

Limitations

  • Needs an operationId to be specified
  • The validation structs are only generated for responses and request bodies.
  • Parameters are just generated as types and have no validation.
  • We only support string enums for parameters at the moment
  • You may need to manually annotate unions in the output. See here for more details: DZakh/sury#56
    • Here is an example of annotating a union inline:
let saveLogRequestBodyStruct = S.object(o => { "level": o->S.field( "level", ( S.union([ S.literalVariant(String("fatal"), #fatal), S.literalVariant(String("error"), #error), S.literalVariant(String("warn"), #warn), S.literalVariant(String("info"), #info), S.literalVariant(String("debug"), #debug), S.literalVariant(String("trace"), #trace), ]): S.t<[#fatal | #error | #warn | #info | #debug | #trace]> ), ), "service": o->S.field("service", S.string()), } )->S.Object.strict
  • If an enum contains a Rescript reserved keyword, we can't convert it to a polymorphic variant, so instead we just set it as a string. (I don't know of a way to alias a poly variant's name).

    • e.g. type queryParams = {state: [#open | #merged | #declined]} becomes type queryParams = {state: string} as open is a Rescript reserved keyword.
  • We don't do nested parameter schemas at the moment. We only do the first level of the schema. e.g.

parameters: - name: tags in: query description: tags to filter by required: false style: form schema: type: array items: type: string - name: limit in: query description: maximum number of results to return required: false schema: type: integer format: int32

will be converted to:

type queryParams = { tags?: array, limit?: int, } 

Things to possibly add in the future

Dev:

  • Use npm link for trying out while developing
  • Note: we develop in esm, but bundle to cjs as I had issues of dynamically created import statements being created when i tried to bundle to esm (e.g. import("foo" + bar + "baz")). I think it was a library file.
  • Run node bundle/index.bundle.cjs --inputFile /wherever/openapi.json --outputFile ./output.res to run/test when developing
  • To publish a new version:
    1. First check it installs ok by running npm run build-and-publish-dry-run, then npm install . -g from the project folder and test the command works globally
      • If it works ok, run npm uninstall openapi-to-rescript-generator -g to uninstall.
    2. bump the version in package.json
    3. run npm build-and-publish-dry-run and check there are no wayward files listed.
    4. run npm build-and-publish

About

Generate rescript code from an openapi spec document

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published