1.0.1 • Published 6 years ago

babel-plugin-flow-to-json v1.0.1

Weekly downloads
2
License
MIT
Repository
github
Last release
6 years ago

babel-plugin-flow-to-json

Build Status

This plugin transforms flow types to JSON schema. You can manually validate data at runtime.

Example and why

// animals.js
type DogProps = {
  age: number,
  color: string
};
export class Dog {
  // $flow-to-json
  static properties: DogProps;
  constructor(props: DogProps) {
    this.props = props;
    // lots of logic
  }
}
type CatProps = {
  color: string,
  hasFur: boolean
};
export class Cat {
  // $flow-to-json
  static properties: CatProps;
  constructor(props: CatProps) {
    this.props = props;
    // lots of logic
  }
}
// api.js
import Ajv from 'ajv';
import * as animanls from 'animals';

const ajv = new Ajv();

router.post('/create-animal', ctx => {
  const { type, properties: requestProps } = ctx.request.body;
  const Animal = animals[type];
  if (!Animal) {
    ctx.throw(404);
  }
  if (!ajv.validate(Animal.properties, requestProps)) {
    ctx.status = 400;
    ctx.body = ajv.errors;
    return;
  }
  // your logic
});

It is nice to be able to do some validation at runtime with no writing JSON schema with already implemented Flow types. The animal types above would be transformed to:

export class Dog {
  // $flow-to-json
  static properties = {
    type: 'object',
    properties: {
      age: {
        type: 'number'
      },
      color: {
        type: 'string'
      }
    },
    required: ['age', 'color']
  };
  constructor(props) {
    this.props = props;
    // lots of logic
  }
}

export class Cat {
  // $flow-to-json
  static properties = {
    type: 'object',
    properties: {
      color: {
        type: 'string'
      },
      hasFur: {
        type: 'boolean'
      }
    },
    required: ['color', 'hasFur']
  };
  constructor(props) {
    this.props = props;
    // lots of logic
  }
}

Usage

yarn add babel-plugin-flow-to-json

Be sure to remove preset flow and place transform-flow-strip-types after flow-to-json to keep the flow types for json schema plugin.

.babelrc

{
    "presets": [
-       "flow"
    ],
    "plugins": [
+        "flow-to-json",
+        "transform-flow-strip-types"
    ]
}

Plugin transforms static properties of classes with flow types and leading comment $flow-to-json

More complex example

In:

type Element = {
  id: number,
  name: ?string
};

type Foo = {
  baz?: number,
  qux: Array<Element | number>
};

class Bar {
  // $flow-to-json
  static prop: Foo;
}

Out:

class Bar {
  static prop = {
    type: 'object',
    properties: {
      baz: {
        type: 'number'
      },
      qux: {
        type: 'array',
        items: {
          anyOf: [
            {
              type: 'object',
              properties: {
                id: {
                  type: 'number'
                },
                name: {
                  anyOf: [
                    {
                      type: 'null'
                    },
                    {
                      type: 'string'
                    }
                  ]
                }
              },
              required: ['id', 'name']
            },
            {
              type: 'number'
            }
          ]
        }
      }
    },
    required: ['qux']
  };
}

Supported

  • Object
  • Array
  • Union
  • number, string, boolean, null
  • optional key
  • optional value
  • literal types (fixed value)
  • type aliases
  • opaque types
  • mixed, any

Broken

  • typeof types: typeof prop is ok, typeof { a: 2, ... } is not correct

Not implemented

  • imports
  • generics
  • intersection
  • tuples