Package Exports
- schema2typebox
- schema2typebox/dist/src/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (schema2typebox) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Schema2TypeBox
Cli tool used for converting JSON schema draft-06 files to TypeBox code.
Installation
npm i -g schema2typebox
Use Case
- You got JSON schemas that you want to validate your data against. But you
also want automatic type inference after validating the data. You have
chosen typebox for this, but figured
that you would need to manually create the typebox code. To avoid this pain, you
simply use
schema2typebox
to generate the required code for you🎉.
Usage
- The cli can be used with
schema2typebox --input <fileName> --output <fileName>
, or by simply runningschema2typebox
. The input defaults to "schema.json" and the output to "generated-types.ts" relative to the current working directory. For more see cli usage.
Examples
//
// Let's start with our JSON schema
//
{
"title": "Person",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 20
},
"age": {
"type": "number",
"minimum": 18,
"maximum": 90
},
"hobbies": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"favoriteAnimal": {
"enum": ["dog", "cat", "sloth"]
}
},
"required": ["name", "age"]
}
//
// Which becomes..
//
export enum FavoriteAnimalEnum {
DOG = "dog",
CAT = "cat",
SLOTH = "sloth",
}
export type Person = Static<typeof Person>;
export const Person = Type.Object({
name: Type.String({ minLength: 20 }),
age: Type.Number({ minimum: 18, maximum: 90 }),
hobbies: Type.Optional(Type.Array(Type.String(), { minItems: 1 })),
favoriteAnimal: Type.Optional(Type.Enum(FavoriteAnimalEnum)),
});
//
// Nice! But.. I have structured my JSON schemas into multiple files and I am
// using the $ref keyword ...
// No worries! Something like this
//
{
"title": "Contract",
"type": "object",
"properties": {
"person": {
"$ref": "./person.json"
},
"status": {
"$ref": "./status.json"
}
},
"required": ["person"]
}
//
// Can easily become this
//
export enum StatusEnum {
UNKNOWN = "unknown",
ACCEPTED = "accepted",
DENIED = "denied",
}
export type Contract = Static<typeof Contract>;
export const Contract = Type.Object({
person: Type.Object({
name: Type.String({ maxLength: 100 }),
age: Type.Number({ minimum: 18 }),
}),
status: Type.Optional(Type.Enum(StatusEnum)),
});
Please take a look at the feature list below to see the currently supported features. For examples, take a look into the ./examples folder. You can also check the test cases, every feature is tested.
Feature List
Tracking the progress/features of JSON schema -> TypeBox
transformation to see
whats already implemented and what is missing.
- Type.String() via "string" instance type
- Type.Boolean() via "boolean" instance type
- Type.Number() via "number" instance type
- Type.Null() via "null" instance type
- Type.Array() via "array" instance type
- Type.Object() via "object" instance type
- Type.Literal() via "const" property
- Type.Union() via "anyOf" property
- Type.Intersect() via "allOf" property
- SchemaOptions for everything that is implemented
- Type.Enum() via "enum" property
- NOTE: Interesting that Type.Enum() creates a json schema with a list of anyOf consts instead of enum.
- $ref to other schema files via relative path
- name of generated value and type based on "title" attribute
- are there other attributes one should check if "title" is undefined?
- (low prio?) $ref to definitions inside the current schema
- NOTE: perhaps wait and see if people mention the need
- Initial idea to implement this via collecting all $defs in a "preprocessing" step inside a map and whenever we get a $ref we query the map to insert the correct type.
- (low prio) $ref to remote schemas
- (low prio) Type.Tuple() via "array" instance type with minimalItems, maximalItems and additionalItems false
- (low prio) Type.Not() via "not" property
- TODO: Is this even possible? I am confused.
DEV/CONTRIBUTOR NOTES
- If you have an idea or want to help implement something, feel free to do so.
Please always start by creating a discussion post to avoid any unnecessary
work.
- Please always create tests for new features that are implemented. This will decrease mental overhead for reviewing and developing in the long run.
- See specification for JSON schema draft-06 here
- Link to meta schema. Meta schema means that a JSON schema is created in order to validate that a given schema adheres to a given JSON schema draft.
cli usage
The following text is the output that will be displayed when you issue
schema2typebox -h
or schema2typebox --help
.
schema2typebox is a cli tool for converting JSON schema draft-06 files to
typebox code. The generated output is formatted based on the prettier
config inside your repo (or the default one, if you don't have one).
Version: ${packageJson.version}
Usage:
schema2typebox [ARGUMENTS]
Arguments:
-h, --help
Displays this menu.
-i, --input
Specifies the relative path to the file containing the JSON schema that
will be used to generated typebox types. Defaults to "schema.json".
-o, --output
Specifies the relative path to generated file that will contain the
typebox code. Defaults to "generated-types.ts".
--output-stdout
Does not generate an output file and prints the generated code to stdout
instead. Has precedence over -o/--output.
The stuff below is left over from copying from using the template from
here and can be read through for understanding the basic setup.
Node.js Typescript Modern Starter
While developing with Typescript and Node.js is awesome, setting up a new project is painful. This minimal and modern starter repo is here to help you get started with Node.js and Typecript without the pain.
Overview
This starter uses a bare-bones and minimal approach to get anyone up and running with a new project in no time. It provides:
- Typescript 5 with a strict tsconfig.
- Yarn/Npm scripts ready to do everything you commonly need. Supporting
build
,clean
,test
,bundle
,dev
andstart
. These scripts are created to be compatible with the operating systems linux, macos and windows. - Github Actions in place runnung with current node version (18,20) on linux,
macos and windows to automatically (for each PR):
- build and test the code
- check for formatting issues
- lint the codebase
- Testing via the new Node.js test runner instead of something like mocha or jest.
- Formatting via prettier.
- Linting via eslint and typescript-eslint
- Bundling via esbuild, a fast bundler that "just works" and is nowadays even used in the typescript codebase.
- Using the current LTS, Node.js 18
Project Goals
- Help you to just get started with a Node.js Typescript setup and not worry about configuration.
- All scripts compatible with linux, macos and windows.
- No magic. Everything kept as simple as possible while configuring anything you might need.
- Advocate for testing your code. The common approaches of tests and code side by side as well as all tests in a seperate folder already working and set up for you.
- Advocate for using CI/CD (in this case Github Actions). Automatically check formatting, linting and build and test the code base. Everything running on each PR.
- Advocate establishing best practices via linting rules using eslint and typescript-eslint. However, still giving a documented way to quickly and easily disable them, if that is preferred.
- Use modern tools like esbuild, typescript 5 and the nodejs test runner.
- Be open for any framework or library that you prefer. This setup should be useful to everyone. You can easily add your preferred packages in to time.
Prerequisites
- nvm (or something like nvm-windows if you are on windows)
Quickstart
- Clone the repo
git clone git@github.com:xddq/nodejs-typescript-modern-starter
- Remove the .git folder
cd nodejs-typescript-modern-starter && rm -rf .git
- (optional) Update the package.json name, author, keywords, etc..
- Set up your own git folder and create your first commit. Run
git init && git add . && git commit -am "initial commit"
- (optional) Set up the git hook for formatting your code.
cp .git-hooks/pre-commit .git/hooks/pre-commit
. For windows you need to use WSL to use this. - Use the node version specified in .nvmrc
nvm install && nvm use
- Install dependencies
npm i -g yarn && yarn
- You're done🎉 What about you try running the tests? Run
yarn test
. See the section below for all available commands together with their explanation.
Scripts and their explanation
All scripts can be found inside the package.json file under the "scripts"
attribute. They simply invoke the tasks.mjs
file which handles the logic
behind these scripts. The tasks.mjs
file was created in order to be able to
easily implement operating system dependant code and leverage comments. You can
just take a look inside the tasks.mjs file in order to understand what is going
on behind the scenes. It contains comments for every script.
yarn build
-> Builds the project. It transpiles the typescript code to javascript and stores the output inside the dist folder. Deletes any files from previous builds beforehand to become repeatable/idempotent.yarn bundle
-> Bundles the whole code into a single javascript file which will be stored inside the bundle folder.yarn clean
-> Removes built files. Deletes the dist and bundle directory and the files inside of them. Normally there is no need to invoke this manually.yarn dev
-> This should be used for running the code while developing. It watches all changes you make to your typescript codebase and automatically rebuilds the project. It does also watch all changes made to the built project and restarts the code whenever changes are detected. This enables a quick feedback loop.yarn format
-> Formats the code using prettier.yarn format-check
-> Checks for formatting errors using prettier. This is typically only invoked by the CI/CD pipeline.yarn lint
-> Lints the code using eslint. Fixes problems that are auto-fixable and reports the rest of them to you.yarn lint-check
-> Checks for linting errors using eslint. This is typically only invoked by the CI/CD pipeline.yarn start
-> Runs the code. This only works if the code was built before ;).yarn test
-> Tests your codebase. Basic tests are created for both major approaches of putting tests beside the source code as well as putting tests in a seperate folder.
Linting
This repo has eslint and typescript-eslint as well as an automated Github Action to check for linting set up and ready to go.
The rules in this project are my personal preference and reflect a subset of the recommended options. They also include a lot of the more strict options (NOT included in the recommended ones). My goal is to simplify having a consistent code base/code style, to avoid catchable bugs early and advocate for usage of newer features of the language.
However, I made it dead simple to enable the default/recommended eslint rules, if you want to use them instead. Everything is documented, just browse to ./eslintrc.cjs and adapt the code.