openapi-typescript-validator
Advanced tools
Comparing version 0.2.0 to 1.0.0
import { Options } from 'prettier'; | ||
import { SchemaType } from './parse-schema'; | ||
export interface GenerateOptions { | ||
schemaFile: string; | ||
schemaType: 'yaml' | 'json'; | ||
schemaType: SchemaType; | ||
name: string; | ||
directory: string; | ||
directory: string | string[]; | ||
prettierOptions?: Options; | ||
} | ||
export declare function generate(options: GenerateOptions): Promise<void>; |
@@ -57,5 +57,2 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -67,36 +64,17 @@ exports.generate = void 0; | ||
var fs_1 = require("fs"); | ||
var js_yaml_1 = __importDefault(require("js-yaml")); | ||
var prettier_1 = require("prettier"); | ||
var toJsonSchema = require('@openapi-contrib/openapi-schema-to-json-schema'); | ||
var parse_schema_1 = require("./parse-schema"); | ||
function generate(options) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var directory, name, schemaFile, schemaType, prettierOptions, schema, properties, definitions, schemaJsonOutput, compiledSchema, rawTypescriptModels, typescriptModels, decoders, rawDecoderOutput, decoderOutput; | ||
var name, schemaFile, schemaType, prettierOptions, directories, schema, compiledSchema, rawTypescriptModels, typescriptModels, decoders, rawDecoderOutput, decoderOutput; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
directory = options.directory, name = options.name, schemaFile = options.schemaFile, schemaType = options.schemaType; | ||
name = options.name, schemaFile = options.schemaFile, schemaType = options.schemaType; | ||
prettierOptions = (_a = options.prettierOptions) !== null && _a !== void 0 ? _a : { parser: 'typescript' }; | ||
if (schemaType === 'yaml') { | ||
schema = js_yaml_1.default.load(fs_1.readFileSync(schemaFile, 'utf8')); | ||
} | ||
else { | ||
schema = JSON.parse(fs_1.readFileSync(schemaFile, 'utf8')); | ||
} | ||
properties = {}; | ||
definitions = {}; | ||
Object.entries(schema.components.schemas).forEach(function (_a) { | ||
var key = _a[0], value = _a[1]; | ||
properties[key] = { $ref: "#/definitions/" + key }; | ||
definitions[key] = toJsonSchema(value); | ||
}); | ||
schemaJsonOutput = JSON | ||
.stringify({ | ||
type: 'object', | ||
title: 'Schema', | ||
definitions: definitions, | ||
properties: properties, | ||
}, undefined, 2) | ||
.replace(/\#\/components\/schemas/g, '#/definitions'); | ||
return [4 /*yield*/, json_schema_to_typescript_1.compile(JSON.parse(schemaJsonOutput), 'Schema')]; | ||
directories = typeof options.directory === 'string' ? [options.directory] : options.directory; | ||
console.info("Start generating files for " + schemaType + " schema: " + schemaFile); | ||
schema = parse_schema_1.parseSchema(schemaFile, schemaType); | ||
return [4 /*yield*/, json_schema_to_typescript_1.compile(JSON.parse(schema.json), 'Schema')]; | ||
case 1: | ||
@@ -109,3 +87,3 @@ compiledSchema = _b.sent(); | ||
typescriptModels = prettier_1.format(rawTypescriptModels, prettierOptions); | ||
decoders = Object.entries(definitions) | ||
decoders = Object.entries(schema.definitions) | ||
.filter(function (_a) { | ||
@@ -118,2 +96,3 @@ var name = _a[0], definition = _a[1]; | ||
return templates_1.decoderTemplate | ||
.replace(/\$DecoderName/g, definitionName + "Decoder") | ||
.replace(/\$Class/g, definitionName) | ||
@@ -127,6 +106,9 @@ .trim(); | ||
decoderOutput = prettier_1.format(rawDecoderOutput, prettierOptions); | ||
fs_1.mkdirSync(directory, { recursive: true }); | ||
fs_1.writeFileSync(path.join(directory, name + "-models.ts"), typescriptModels); | ||
fs_1.writeFileSync(path.join(directory, name + "-decoders.ts"), decoderOutput); | ||
fs_1.writeFileSync(path.join(directory, name + "-schema.json"), schemaJsonOutput); | ||
directories.forEach(function (directory) { | ||
fs_1.mkdirSync(directory, { recursive: true }); | ||
fs_1.writeFileSync(path.join(directory, name + "-models.ts"), typescriptModels); | ||
fs_1.writeFileSync(path.join(directory, name + "-decoders.ts"), decoderOutput); | ||
fs_1.writeFileSync(path.join(directory, name + "-schema.json"), schema.json); | ||
}); | ||
console.info("Successfully generated files for " + schemaFile); | ||
return [2 /*return*/]; | ||
@@ -133,0 +115,0 @@ } |
export { generate, GenerateOptions } from './generate'; | ||
export * from './builder'; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -6,2 +16,3 @@ exports.generate = void 0; | ||
Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return generate_1.generate; } }); | ||
__exportStar(require("./builder"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -1,4 +0,3 @@ | ||
export declare const decodersTemplate = "\n/* eslint-disable */\n/* tslint-disable */\nimport Ajv, { ErrorObject } from 'ajv';\nimport schema from './$SchemaName-schema.json';\nimport * as types from './$SchemaName-models'\n\n// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n// !!! AUTO GENERATED CODE, DON'T TOUCH !!!\n// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\nconst ajv = new Ajv();\najv.addSchema(schema);\n\nfunction validateJson(json: any, schemaRef: string, className: string): any {\n const schema = ajv.getSchema(schemaRef);\n if (!schema) {\n throw new Error(`Schema ${schemaRef} not found`);\n }\n\n const jsonObject = typeof json === 'string' ? JSON.parse(json) : json;\n\n if (schema(jsonObject)) {\n return jsonObject;\n }\n\n const jsonPreviewStr = (typeof json === 'string' ? json : JSON.stringify(jsonObject)).substring(0, 100);\n if (schema.errors) {\n throw Error(`${className} ${errorsText(schema.errors)}. JSON-preview: ${jsonPreviewStr}`);\n }\n\n throw Error(`${className} Unexpected data received. JSON: ${jsonPreviewStr}`);\n}\n\nfunction errorsText(errors: ErrorObject[]): string {\n return errors.map(error => `${error.dataPath}: ${error.message}`).join('\\n')\n}\n\n// Decoders\n$Decoders\n"; | ||
export declare const decoderTemplate = "\nexport class $ClassDecoder {\n public static schemaRef: string = '#/definitions/$Class'\n\n public static decode(json: any): types.$Class {\n return validateJson(json, $ClassDecoder.schemaRef, '$Class');\n }\n}\n"; | ||
export declare const decodersTemplate = "\n/* eslint-disable */\n/* tslint-disable */\nimport Ajv, { ErrorObject } from 'ajv';\nimport schema from './$SchemaName-schema.json';\nimport * as types from './$SchemaName-models'\n\n// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n// !!! AUTO GENERATED CODE, DON'T TOUCH !!!\n// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\nconst ajv = new Ajv();\najv.addSchema(schema);\n\nfunction validateJson(json: any, schemaRef: string): any {\n const schema = ajv.getSchema(schemaRef);\n if (!schema) {\n throw new Error(`Schema ${schemaRef} not found`);\n }\n\n const jsonObject = typeof json === 'string' ? JSON.parse(json) : json;\n\n if (schema(jsonObject)) {\n return jsonObject;\n }\n\n const jsonPreviewStr = (typeof json === 'string' ? json : JSON.stringify(jsonObject)).substring(0, 100);\n if (schema.errors) {\n throw Error(`${schemaRef} ${errorsText(schema.errors)}. JSON-preview: ${jsonPreviewStr}`);\n }\n\n throw Error(`${schemaRef} Unexpected data received. JSON: ${jsonPreviewStr}`);\n}\n\nfunction errorsText(errors: ErrorObject[]): string {\n return errors.map(error => `${error.dataPath}: ${error.message}`).join('\\n')\n}\n\n// Decoders\n$Decoders\n"; | ||
export declare const decoderTemplate = "\nexport class $DecoderName {\n public static definitionName: string = '$Class';\n public static schemaRef: string = '#/definitions/$Class';\n\n public static decode(json: any): types.$Class {\n return validateJson(json, $DecoderName.schemaRef);\n }\n}\n"; | ||
export declare const modelsTemplate = "\n/* eslint-disable */\n\n$Models\n"; | ||
export declare const schemaJsonTemplate = "$SchemaOutput"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.schemaJsonTemplate = exports.modelsTemplate = exports.decoderTemplate = exports.decodersTemplate = void 0; | ||
exports.decodersTemplate = "\n/* eslint-disable */\n/* tslint-disable */\nimport Ajv, { ErrorObject } from 'ajv';\nimport schema from './$SchemaName-schema.json';\nimport * as types from './$SchemaName-models'\n\n// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n// !!! AUTO GENERATED CODE, DON'T TOUCH !!!\n// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\nconst ajv = new Ajv();\najv.addSchema(schema);\n\nfunction validateJson(json: any, schemaRef: string, className: string): any {\n const schema = ajv.getSchema(schemaRef);\n if (!schema) {\n throw new Error(`Schema ${schemaRef} not found`);\n }\n\n const jsonObject = typeof json === 'string' ? JSON.parse(json) : json;\n\n if (schema(jsonObject)) {\n return jsonObject;\n }\n\n const jsonPreviewStr = (typeof json === 'string' ? json : JSON.stringify(jsonObject)).substring(0, 100);\n if (schema.errors) {\n throw Error(`${className} ${errorsText(schema.errors)}. JSON-preview: ${jsonPreviewStr}`);\n }\n\n throw Error(`${className} Unexpected data received. JSON: ${jsonPreviewStr}`);\n}\n\nfunction errorsText(errors: ErrorObject[]): string {\n return errors.map(error => `${error.dataPath}: ${error.message}`).join('\\n')\n}\n\n// Decoders\n$Decoders\n"; | ||
exports.decoderTemplate = "\nexport class $ClassDecoder {\n public static schemaRef: string = '#/definitions/$Class'\n\n public static decode(json: any): types.$Class {\n return validateJson(json, $ClassDecoder.schemaRef, '$Class');\n }\n}\n"; | ||
exports.modelsTemplate = exports.decoderTemplate = exports.decodersTemplate = void 0; | ||
exports.decodersTemplate = "\n/* eslint-disable */\n/* tslint-disable */\nimport Ajv, { ErrorObject } from 'ajv';\nimport schema from './$SchemaName-schema.json';\nimport * as types from './$SchemaName-models'\n\n// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n// !!! AUTO GENERATED CODE, DON'T TOUCH !!!\n// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\nconst ajv = new Ajv();\najv.addSchema(schema);\n\nfunction validateJson(json: any, schemaRef: string): any {\n const schema = ajv.getSchema(schemaRef);\n if (!schema) {\n throw new Error(`Schema ${schemaRef} not found`);\n }\n\n const jsonObject = typeof json === 'string' ? JSON.parse(json) : json;\n\n if (schema(jsonObject)) {\n return jsonObject;\n }\n\n const jsonPreviewStr = (typeof json === 'string' ? json : JSON.stringify(jsonObject)).substring(0, 100);\n if (schema.errors) {\n throw Error(`${schemaRef} ${errorsText(schema.errors)}. JSON-preview: ${jsonPreviewStr}`);\n }\n\n throw Error(`${schemaRef} Unexpected data received. JSON: ${jsonPreviewStr}`);\n}\n\nfunction errorsText(errors: ErrorObject[]): string {\n return errors.map(error => `${error.dataPath}: ${error.message}`).join('\\n')\n}\n\n// Decoders\n$Decoders\n"; | ||
exports.decoderTemplate = "\nexport class $DecoderName {\n public static definitionName: string = '$Class';\n public static schemaRef: string = '#/definitions/$Class';\n\n public static decode(json: any): types.$Class {\n return validateJson(json, $DecoderName.schemaRef);\n }\n}\n"; | ||
exports.modelsTemplate = "\n/* eslint-disable */\n\n$Models\n"; | ||
exports.schemaJsonTemplate = "$SchemaOutput"; | ||
//# sourceMappingURL=templates.js.map |
{ | ||
"name": "openapi-typescript-validator", | ||
"version": "0.2.0", | ||
"version": "1.0.0", | ||
"description": "Generate typescript with ajv validation based on openapi schemas", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -75,3 +75,3 @@ # openapi-typescript-validator | ||
"Component": { | ||
"oneOf": [ | ||
"anyOf": [ | ||
{ "$ref": "#/components/schemas/TitleComponent" }, | ||
@@ -91,2 +91,6 @@ { "$ref": "#/components/schemas/ImageComponent" } | ||
"type": "string" | ||
}, | ||
"subtitle": { | ||
"type": "string", | ||
"nullable": true | ||
} | ||
@@ -126,2 +130,3 @@ }, | ||
title: string; | ||
subtitle?: string | null; | ||
} | ||
@@ -134,3 +139,36 @@ export interface ImageComponent { | ||
### Custom builder | ||
We also created a way to define your JSON schema a bit easier. The example above can also be written as: | ||
Example: `custom-schema.js` | ||
```javascript | ||
const { anyOf, array, constant, nillable, object, string } = require('openapi-typescript-validator'); | ||
const types = {}; | ||
types.Screen = object({ | ||
components: array('Component'), | ||
}) | ||
types.Component = anyOf(['TitleComponent', 'ImageComponent']); | ||
types.TitleComponent = object({ | ||
type: constant('title'), | ||
title: string, | ||
subtitle: nillable(string), | ||
}); | ||
types.ImageComponent = object({ | ||
type: constant('image'), | ||
url: string, | ||
}); | ||
module.exports = { types } | ||
``` | ||
Just call `generate` with `schemaType: custom`. | ||
See [src/builder.ts](src/builder.ts) for all helpers which can be used. | ||
## Getting started | ||
@@ -178,6 +216,5 @@ | ||
schemaFile | true | file location of the schema. | ||
schemaType | true | `yaml` or `json` | ||
schemaType | true | `yaml`, `json` or `custom` | ||
name | true | prefix for the generated files | ||
directory | true | location where the output files will be stored to | ||
directory | true | `string` or `string[]` location(s) where the output files will be stored. | ||
prettierOptions | false | See [Prettier Options](https://prettier.io/docs/en/options.html) | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
37336
17
515
0
216
3
1