Create Joi schemas from your Open Api Specification file
Bonus: Typescript Types files from the OAS schemas definitions too.
npm install --save-dev oas-to-joi
oas-to-joi --oas-file openapi-example.yaml --output path_to_output_directory
// ...
scripts: {
"oas-to-joi": "oas-to-joi --oas-file openapi-example.yaml --output path_to_output_directory"
}
npm run oas-to-joi
import OasToJoi from "oas-to-joi";
import path from "path";
// pass the open api file
const oasFilePath = path.resolve(`${__dirname}/openapi-example.yaml`);
const outputDirPath = path.resolve(`${__dirname}/my-output-folder`);
// create OasToJoi object
const oasToJoi = new OasToJoi({
fileName: oasFilePath,
outputDir: outputDirPath,
});
// get Joi schemas and validations
await oasToJoi.dumpJoiSchemas();
// get Typescript types
await oasToJoi.dumpTypes();
import schema from "./output/joi/add-pet.schema";
const validate = (data) => {
const result = schema.validate(data, { abortEarly: false });
console.log(result);
};
validate({ name: "Flanki" });
==============================
Dumping Joi Files ✨
==============================
Getting definitions...
------------------------------
# -> Pet: 1.34 ms
# -> Category: 0.06 ms
# -> Tag: 0.18 ms
# -> Order: 0.34 ms
# -> User: 0.27 ms
Writing files...
------------------------------
# -> update-pet.schema.ts: 3.85 ms
# -> add-pet.schema.ts: 0.40 ms
# -> place-order.schema.ts: 0.36 ms
# -> create-user.schema.ts: 0.35 ms
# -> create-users-with-list-input.schema.ts: 0.34 ms
# -> update-user.schema.ts: 0.32 ms
# -> category.schema.ts: 0.41 ms
# -> tag.schema.ts: 0.39 ms
# -> pet.schema.ts: 0.40 ms
# -> order.schema.ts: 0.41 ms
# -> user.schema.ts: 0.48 ms
Done (11) Files
==============================
Dumping TypeScript Files ✨
==============================
Getting definitions...
------------------------------
# -> Order: 0.56 ms
# -> Customer: 0.15 ms
# -> Address: 0.04 ms
# -> Category: 0.03 ms
# -> User: 0.18 ms
# -> Tag: 0.03 ms
# -> Pet: 0.30 ms
# -> ApiResponse: 0.03 ms
Writing files...
------------------------------
# -> order.type.ts: 0.58 ms
# -> address.type.ts: 1.34 ms
# -> customer.type.ts: 0.91 ms
# -> category.type.ts: 1.01 ms
# -> user.type.ts: 2.71 ms
# -> tag.type.ts: 0.86 ms
# -> pet.type.ts: 0.63 ms
# -> api-response.type.ts: 0.51 ms
Done (8) Files
After dump the object you will get two folders with a set of files which represents the OAS file operations and schemas. For example:
└──── output
├── joi
│ ├── add-pet.schema.ts
│ ├── category.schema.ts
│ ├── create-user.schema.ts
│ ├── order.schema.ts
│ ├── pet.schema.ts
│ ├── place-order.schema.ts
│ ├── tag.schema.ts
│ ├── update-pet.schema.ts
│ ├── update-user.schema.ts
│ └── user.schema.ts
└── types
├── address.type.ts
├── api-response.type.ts
├── category.type.ts
├── customer.type.ts
├── order.type.ts
├── pet.type.ts
├── tag.type.ts
└── user.type.ts
//#user.schema.ts
// This file is autogenerated by "oas-to-joi"
import Joi from "joi";
const schema = Joi.object({
id: Joi.number(),
username: Joi.string().max(20),
firstName: Joi.string().min(3).max(20),
lastName: Joi.string().max(20),
email: Joi.string().email(),
password: Joi.string(),
phone: Joi.string().pattern(/^\d{3}-\d{3}-\d{4}$/),
userStatus: Joi.number()
});
export default schema;
//#order.schema.ts
// This file is autogenerated by "oas-to-joi"
import Joi from "joi";
const schema = Joi.object({
id: Joi.number(),
petId: Joi.number(),
quantity: Joi.number(),
shipDate: Joi.date(),
status: Joi.string().valid("placed","approved","delivered"),
complete: Joi.boolean()
});
export default schema;
-
string
- format: date & date-time -> joi date type (only default settings)
- format: email -> joi email type (only default settings)
- format: uuid -> joi uuid type (only default settings)
- format: hostname -> joi hostname (only default settings)
- format: uri -> joi uri (only default settings)
- format: byte -> joi base64 (only default setings)
- format: ipv4 -> ip({ version: ["ipv4"], cidr: "optional" }) (cidr optional by default)
- format: ipv6 -> ip({ version: ["ipv6"], cidr: "optional" }) (cidr optional by default)
- pattern -> joi string patter
- minLength -> joi string min
- maxLength -> joi string max
- nullable -> joi allow null
-
number & integer
- minimum -> joi number min
- maximum -> joi number max
- nullable -> joi allow null
-
boolean
-
array
- Only support YAML files.
- Only tested with OAS 3.x version
- The YAML file have to be in utf8 encode.
- Doesn't support circular references, for example:
// Pet schema file
const schema = Joi.object({
id: Joi.number(),
name: Joi.string().required(),
tags: Joi.array().items(Tag),
});
// Tag schema file
const schema = Joi.object({
id: Joi.number(),
name: Joi.string().required(),
others: Pet,
});
In this case, Tags schema has a reference to Pet and Pet also has a reference to Tag. The workaround is put both together in the same file and modify the export default value.