1.0.11 • Published 2 years ago

create-schema v1.0.11

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

create-schema

TypeScript-first schema validation with static type inference

Installation

To install:

npm install create-schema

⚠️ IMPORTANT: You must enable strict mode in your tsconfig.json. This is a best practice for all TypeScript projects.

// tsconfig.json
{
  // ...
  "compilerOptions": {
    // ...
    "strict": true
  }
}

Usage

Schema

  const addressSchema = createSchema({
    street: 'string',
    number: 'int?',
  });

  const schemaDefinition = {
    name: 'string', // any string
    email: 'email?', // email type - will validate against email regex
    age: 'int?', // optional integer
    notes: '[int]?',

    // represents an enum
    letter: ['a', 'b', 'c'],

    letterOptionalList: {
      type: 'enum',
      def: ['x', 'y', 'z'],
      optional: true,
      list: true,
    },

    address: {
      // more detailed field declaration
      type: addressSchema,
      optional: true,
    },
  } as const; // needed to TS infer on array os strings

  const userSchema = createSchema(schemaDefinition);

  expect(() => userSchema.parse({ name: 'Antonio', letter: 'x' })).toThrow(
    `field "letter": accepted: 'a' or 'b' or 'c', found x.`
  );

  const parsed = userSchema.parse({ name: 'antonio', letter: 'a' });

  type InferType = typeof parsed;

  assert<
    IsExact<
      InferType,
      {
        name: string;
        email: string | undefined;
        age: number | undefined;
        notes: number[] | undefined;
        letter: 'a' | 'b' | 'c';
        letterOptionalList: ('x' | 'y' | 'z')[] | undefined;
        address:
          | {
              street: string;
              number: number | undefined;
            }
          | undefined;
      }
    >
  >(true);

schemaToTypescript

Returns a string of an interface representing a DarchSchema;

import { schemaToTypescript } from 'create-schema';

const interfaceTxt = await schemaToTypescript('User', userSchema);
  
expect(interfaceTxt).toBe(
`/* tslint:disable */
/**
 * This file was automatically generated.
 * DO NOT MODIFY IT BY HAND.
 */

export type EnumLetterUser = "a" | "b" | "c";
export type Enum_SubLetterOptionalList = "x" | "y" | "z";

export interface User {
  name: string;
  email?: Email;
  age?: number;
  notes?: number[];
  letter: EnumLetterUser;
  letterOptionalList?: Enum_SubLetterOptionalList[];
  address?: {
    street: string;
    number?: number;
    [k: string]: unknown;
  };
  [k: string]: unknown;
}
`
  );

schemaToJSON

Receives a DarchSchema and returns a json-schema

  import { schemaToJSON } from 'create-schema';

  const jsonSchema = schemaToJSON('User', userSchema);

  expect(jsonSchema).toEqual({
    properties: {
      address: {
        properties: {
          number: {
            type: 'integer',
          },
          street: {
            type: 'string',
          },
        },
        required: ['street'],
        title: '',
        type: 'object',
      },
      age: {
        type: 'integer',
      },
      email: {
        tsType: 'Email',
        type: 'string',
      },
      letter: {
        enum: ['a', 'b', 'c'],
        title: 'EnumLetterUser',
        type: 'string',
      },
      letterOptionalList: {
        items: {
          enum: ['x', 'y', 'z'],
          title: 'Enum__subLetterOptionalList',
          type: 'string',
        },
        type: 'array',
      },
      name: {
        type: 'string',
      },
      notes: {
        items: {
          type: 'integer',
        },
        type: 'array',
      },
    },
    required: ['name', 'letter'],
    title: 'User',
    type: 'object',
  });

TODO

  • improve documentation