openapi-ts-json-schema
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -1,12 +0,11 @@ | ||
import { JSONSchema } from './utils'; | ||
export declare function openapiToTsJsonSchema({ openApiSchema: openApiSchemaRelative, definitionPathsToGenerateFrom, schemaPatcher, outputPath: providedOutputPath, silent, }: { | ||
import { SchemaPatcher } from './utils'; | ||
export declare function openapiToTsJsonSchema({ openApiSchema: openApiSchemaRelative, definitionPathsToGenerateFrom, schemaPatcher, outputPath: providedOutputPath, silent, experimentalImportRefs, }: { | ||
openApiSchema: string; | ||
definitionPathsToGenerateFrom: string[]; | ||
schemaPatcher?: (params: { | ||
schema: JSONSchema; | ||
}) => void; | ||
schemaPatcher?: SchemaPatcher; | ||
outputPath?: string; | ||
silent?: boolean; | ||
experimentalImportRefs?: boolean; | ||
}): Promise<{ | ||
outputPath: string; | ||
}>; |
@@ -14,9 +14,14 @@ "use strict"; | ||
const utils_1 = require("./utils"); | ||
async function openapiToTsJsonSchema({ openApiSchema: openApiSchemaRelative, definitionPathsToGenerateFrom, schemaPatcher, outputPath: providedOutputPath, silent, }) { | ||
async function openapiToTsJsonSchema({ openApiSchema: openApiSchemaRelative, definitionPathsToGenerateFrom, schemaPatcher, outputPath: providedOutputPath, silent, experimentalImportRefs = false, }) { | ||
if (definitionPathsToGenerateFrom.length === 0 && !silent) { | ||
console.log(`[openapi-ts-json-schema] ⚠️ No schemas will be generated since definitionPathsToGenerateFrom option is empty`); | ||
} | ||
definitionPathsToGenerateFrom.forEach((defPath) => { | ||
if (path_1.default.isAbsolute(defPath)) { | ||
throw new Error(`[openapi-ts-json-schema] "definitionPathsToGenerateFrom" must be an array of relative paths. "${defPath}" found.`); | ||
} | ||
}); | ||
const openApiSchemaPath = path_1.default.resolve(openApiSchemaRelative); | ||
if (!(0, fs_1.existsSync)(openApiSchemaPath)) { | ||
throw new Error(`Provided OpenAPI definition path doesn't exist: ${openApiSchemaPath}`); | ||
throw new Error(`[openapi-ts-json-schema] Provided OpenAPI definition path doesn't exist: ${openApiSchemaPath}`); | ||
} | ||
@@ -31,17 +36,24 @@ const outputPath = providedOutputPath ?? | ||
const initialJsonSchema = (0, utils_1.convertOpenApiToJsonSchema)(bundledOpenApiSchema); | ||
// Replace $refs | ||
const inlinedRefs = new Map(); | ||
const dereferencedJsonSchema = await json_schema_ref_parser_1.default.dereference(initialJsonSchema, { | ||
dereference: { | ||
// @ts-expect-error onDereference seems not to be properly typed | ||
onDereference: (path, value) => { | ||
onDereference: (ref, inlinedSchema) => { | ||
/** | ||
* Add commented out $ref prop with: | ||
* Mark inlined refs with a "REF_SYMBOL" prop to replace them | ||
* in case experimentalImportRefs option is true | ||
*/ | ||
inlinedSchema[utils_1.REF_SYMBOL] = ref; | ||
/** | ||
* Add a $ref comment to each inlined schema with the original ref value. Using: | ||
* https://github.com/kaelzhang/node-comment-json | ||
*/ | ||
value[Symbol.for('before')] = [ | ||
inlinedSchema[Symbol.for('before')] = [ | ||
{ | ||
type: 'LineComment', | ||
value: ` $ref: "${path}"`, | ||
value: ` $ref: "${ref}"`, | ||
}, | ||
]; | ||
// Keep track of inline refs | ||
inlinedRefs.set(ref, inlinedSchema); | ||
}, | ||
@@ -51,13 +63,36 @@ }, | ||
const jsonSchema = (0, utils_1.convertOpenApiParameters)(dereferencedJsonSchema); | ||
const schemasToGenerate = new Map(); | ||
// Generate schema meta info for inlined refs, first | ||
if (experimentalImportRefs) { | ||
for (const [ref, schema] of inlinedRefs) { | ||
const { schemaRelativeDirName, schemaName } = (0, utils_1.refToPath)(ref); | ||
(0, utils_1.addSchemaToGenerationMap)({ | ||
schemasToGenerate, | ||
schemaRelativeDirName, | ||
schemaName, | ||
schema, | ||
outputPath, | ||
schemaPatcher, | ||
experimentalImportRefs, | ||
}); | ||
} | ||
} | ||
// Generate schema meta info for user requested schemas | ||
for (const definitionPath of definitionPathsToGenerateFrom) { | ||
const schemas = (0, lodash_get_1.default)(jsonSchema, definitionPath); | ||
const schemasOutputPath = path_1.default.resolve(outputPath, definitionPath); | ||
if (schemas) { | ||
await (0, utils_1.generateJsonSchemaFiles)({ | ||
schemas, | ||
outputPath: schemasOutputPath, | ||
for (const schemaName in schemas) { | ||
(0, utils_1.addSchemaToGenerationMap)({ | ||
schemasToGenerate, | ||
schemaRelativeDirName: definitionPath.replaceAll('.', '/'), | ||
schemaName, | ||
schema: schemas[schemaName], | ||
outputPath, | ||
schemaPatcher, | ||
experimentalImportRefs, | ||
}); | ||
} | ||
} | ||
await (0, utils_1.makeJsonSchemaFiles)({ | ||
schemasToGenerate, | ||
}); | ||
if (!silent) { | ||
@@ -64,0 +99,0 @@ console.log(`[openapi-ts-json-schema] ✅ JSON schema models generated at ${outputPath}`); |
export { patchJsonSchema } from './patchJsonSchema'; | ||
export { clearFolder } from './clearFolder'; | ||
export { jsonSchemaToTsConst } from './jsonSchemaToTsConst'; | ||
export { generateJsonSchemaFiles } from './generateJsonSchemaFiles'; | ||
export { convertOpenApiParameters } from './convertOpenApiParameters'; | ||
export { convertOpenApiToJsonSchema } from './convertOpenApiToJsonSchema'; | ||
export type { JSONSchema, OpenApiSchema } from './types'; | ||
export { makeJsonSchemaFiles } from './makeJsonSchemaFiles'; | ||
export { refToPath } from './refToPath'; | ||
export { REF_SYMBOL, replacePlaceholdersWith, refToPlaceholder, } from './refReplacementUtils'; | ||
export { replaceInlinedRefsWithStringPlaceholder } from './replaceInlinedRefsWithStringPlaceholder'; | ||
export { replacePlaceholdersWithImportedSchemas } from './jsonSchemaToTsConst/replacePlaceholdersWithImportedSchemas'; | ||
export type { JSONSchema, OpenApiSchema, SchemaPatcher, SchemaMetaInfo, SchemaMetaInfoMap, } from './types'; | ||
export { addSchemaToGenerationMap } from './addSchemaToGenerationMap'; | ||
export { makeRelativePath } from './makeRelativePath'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.convertOpenApiToJsonSchema = exports.convertOpenApiParameters = exports.generateJsonSchemaFiles = exports.jsonSchemaToTsConst = exports.clearFolder = exports.patchJsonSchema = void 0; | ||
exports.makeRelativePath = exports.addSchemaToGenerationMap = exports.replacePlaceholdersWithImportedSchemas = exports.replaceInlinedRefsWithStringPlaceholder = exports.refToPlaceholder = exports.replacePlaceholdersWith = exports.REF_SYMBOL = exports.refToPath = exports.makeJsonSchemaFiles = exports.convertOpenApiToJsonSchema = exports.convertOpenApiParameters = exports.jsonSchemaToTsConst = exports.clearFolder = exports.patchJsonSchema = void 0; | ||
var patchJsonSchema_1 = require("./patchJsonSchema"); | ||
@@ -10,4 +10,2 @@ Object.defineProperty(exports, "patchJsonSchema", { enumerable: true, get: function () { return patchJsonSchema_1.patchJsonSchema; } }); | ||
Object.defineProperty(exports, "jsonSchemaToTsConst", { enumerable: true, get: function () { return jsonSchemaToTsConst_1.jsonSchemaToTsConst; } }); | ||
var generateJsonSchemaFiles_1 = require("./generateJsonSchemaFiles"); | ||
Object.defineProperty(exports, "generateJsonSchemaFiles", { enumerable: true, get: function () { return generateJsonSchemaFiles_1.generateJsonSchemaFiles; } }); | ||
var convertOpenApiParameters_1 = require("./convertOpenApiParameters"); | ||
@@ -17,1 +15,17 @@ Object.defineProperty(exports, "convertOpenApiParameters", { enumerable: true, get: function () { return convertOpenApiParameters_1.convertOpenApiParameters; } }); | ||
Object.defineProperty(exports, "convertOpenApiToJsonSchema", { enumerable: true, get: function () { return convertOpenApiToJsonSchema_1.convertOpenApiToJsonSchema; } }); | ||
var makeJsonSchemaFiles_1 = require("./makeJsonSchemaFiles"); | ||
Object.defineProperty(exports, "makeJsonSchemaFiles", { enumerable: true, get: function () { return makeJsonSchemaFiles_1.makeJsonSchemaFiles; } }); | ||
var refToPath_1 = require("./refToPath"); | ||
Object.defineProperty(exports, "refToPath", { enumerable: true, get: function () { return refToPath_1.refToPath; } }); | ||
var refReplacementUtils_1 = require("./refReplacementUtils"); | ||
Object.defineProperty(exports, "REF_SYMBOL", { enumerable: true, get: function () { return refReplacementUtils_1.REF_SYMBOL; } }); | ||
Object.defineProperty(exports, "replacePlaceholdersWith", { enumerable: true, get: function () { return refReplacementUtils_1.replacePlaceholdersWith; } }); | ||
Object.defineProperty(exports, "refToPlaceholder", { enumerable: true, get: function () { return refReplacementUtils_1.refToPlaceholder; } }); | ||
var replaceInlinedRefsWithStringPlaceholder_1 = require("./replaceInlinedRefsWithStringPlaceholder"); | ||
Object.defineProperty(exports, "replaceInlinedRefsWithStringPlaceholder", { enumerable: true, get: function () { return replaceInlinedRefsWithStringPlaceholder_1.replaceInlinedRefsWithStringPlaceholder; } }); | ||
var replacePlaceholdersWithImportedSchemas_1 = require("./jsonSchemaToTsConst/replacePlaceholdersWithImportedSchemas"); | ||
Object.defineProperty(exports, "replacePlaceholdersWithImportedSchemas", { enumerable: true, get: function () { return replacePlaceholdersWithImportedSchemas_1.replacePlaceholdersWithImportedSchemas; } }); | ||
var addSchemaToGenerationMap_1 = require("./addSchemaToGenerationMap"); | ||
Object.defineProperty(exports, "addSchemaToGenerationMap", { enumerable: true, get: function () { return addSchemaToGenerationMap_1.addSchemaToGenerationMap; } }); | ||
var makeRelativePath_1 = require("./makeRelativePath"); | ||
Object.defineProperty(exports, "makeRelativePath", { enumerable: true, get: function () { return makeRelativePath_1.makeRelativePath; } }); |
@@ -1,4 +0,2 @@ | ||
import type { JSONSchema } from './'; | ||
export declare function patchJsonSchema(schema: JSONSchema, schemaPatcher?: (params: { | ||
schema: JSONSchema; | ||
}) => void): JSONSchema; | ||
import type { JSONSchema, SchemaPatcher } from './'; | ||
export declare function patchJsonSchema(schema: JSONSchema, schemaPatcher?: SchemaPatcher): JSONSchema; |
import type { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema'; | ||
export type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7; | ||
export type OpenApiSchema = Record<string, any>; | ||
export type SchemaPatcher = (params: { | ||
schema: JSONSchema; | ||
}) => void; | ||
export type SchemaMetaInfo = { | ||
schemaName: string; | ||
schemaFileName: string; | ||
schemaUniqueName: string; | ||
schemaAbsoluteDirName: string; | ||
schema: JSONSchema; | ||
}; | ||
export type SchemaMetaInfoMap = Map<string, // Schema file relative path | ||
SchemaMetaInfo>; |
{ | ||
"name": "openapi-ts-json-schema", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "OpenAPI to JSON schema generator with TypeScript in mind", | ||
@@ -60,2 +60,4 @@ "main": "./dist/index.js", | ||
"lodash.get": "^4.4.2", | ||
"map-obj": "^4.3.0", | ||
"namify": "^0.1.3", | ||
"openapi-jsonschema-parameters": "^12.1.3", | ||
@@ -62,0 +64,0 @@ "prettier": "^3.0.1", |
@@ -38,3 +38,3 @@ # openapi-ts-json-schema | ||
import { FromSchema } from 'json-schema-to-ts'; | ||
import myModelSchema from 'path/to/schemas-autogenerated/MyModel.ts'; | ||
import myModelSchema from 'path/to/schemas-autogenerated/components/schemas/MyModel.ts'; | ||
@@ -49,6 +49,2 @@ // Use generated JSON schemas as usual | ||
### Notes | ||
Generated JSON schema path names get escaped in order to be valid file system names. | ||
## Options | ||
@@ -60,2 +56,3 @@ | ||
| **definitionPathsToGenerateFrom** _(required)_ | `string[]` | OpenApi definition object paths to generate the JSON schemas from. Only matching paths will be generated. (Supports dot notation: `["components.schemas"]`). | - | | ||
| **experimentalImportRefs** | `boolean` | Experimental option. Generate `$ref` schema files and import them instead of inlining. | `false` | | ||
| **schemaPatcher** | `(params: { schema: JSONSchema }) => void` | Dynamically patch generated JSON schemas. The provided function will be invoked against every single JSON schema node. | - | | ||
@@ -65,7 +62,15 @@ | **outputPath** | `string` | Path where the generated schemas will be saved. Defaults to `/schemas-autogenerated` in same directory as provided `openApiSchema`. | - | | ||
### Notes | ||
Generated JSON schema path names get escaped in order to be valid file system names. | ||
Circular `$ref`s can be technically resolved with `experimentalImportRefs` option. But TS will stop the type recursion and type the schema as `any`. See [relevant tests](https://github.com/toomuchdesign/openapi-ts-json-schema/blob/master/test/circularReference.test.ts). | ||
Take a look at the [Developer's notes](./docs/developer-notes.md) for a few more in-depth explanations. | ||
## Todo | ||
- Explore ability to import dereferenced schemas instead of inlining | ||
- Consider merging "operation" and "path" parameters definition | ||
- Consider removing required `definitionPathsToGenerateFrom` option in favour of exporting the whole OpenAPI definitions based on the structure defined in specs | ||
- Consider adding a way to keep specific `$ref` values in case of recursion | ||
@@ -72,0 +77,0 @@ [ci-badge]: https://github.com/toomuchdesign/openapi-ts-json-schema/actions/workflows/ci.yml/badge.svg |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
36673
35
592
79
12
1
+ Addedmap-obj@^4.3.0
+ Addednamify@^0.1.3
+ Added@types/node@20.17.6(transitive)
+ Addedmap-obj@4.3.0(transitive)
+ Addednamify@0.1.3(transitive)
+ Addedreserved@0.1.2(transitive)
- Removed@types/node@20.17.8(transitive)