diff --git a/README.md b/README.md index d9e50cdb..0790a9cd 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ json2ts -i foo.json -o foo.d.ts --style.singleQuote --no-style.semi To invoke json-schema-to-typescript from your TypeScript or JavaScript program, import it and call `compile` or `compileFromFile`. ```js -import { compile, compileFromFile } from 'json-schema-to-typescript' +import { compile, compileFromFile, compileSync } from 'json-schema-to-typescript' // compile from file compileFromFile('foo.json') @@ -122,6 +122,9 @@ let mySchema = { } compile(mySchema, 'MySchema') .then(ts => ...) + +// or, compile a JS object synchronously, if there are not remote refs +const ts = compileSync(mySchema, 'MySchema') ``` See [server demo](example) and [browser demo](https://github.com/bcherny/json-schema-to-typescript-browser) for full examples. diff --git a/src/index.ts b/src/index.ts index 1aa67be0..4bf14f6d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -132,7 +132,13 @@ function parseAsJSONSchema(filename: string): JSONSchema4 { return parseFileAsJSONSchema(filename, contents.toString()) } -export async function compile(schema: JSONSchema4, name: string, options: Partial = {}): Promise { +export async function compile( + schema: JSONSchema4, + name: string, + options: Partial & { + dereferenced?: Awaited> + } = {}, +): Promise { validateOptions(options) const _options = merge({}, DEFAULT_OPTIONS, options) @@ -149,8 +155,41 @@ export async function compile(schema: JSONSchema4, name: string, options: Partia // Initial clone to avoid mutating the input const _schema = cloneDeep(schema) + const dereferenced = await dereference(_schema, _options) + const generated = compileSync(schema, name, {...options, dereferenced}) - const {dereferencedPaths, dereferencedSchema} = await dereference(_schema, _options) + const formatted = await format(generated, _options) + log('white', 'formatter', time(), '✅ Result:', formatted) + + return formatted +} + +export function compileSync( + schema: JSONSchema4, + name: string, + options: Partial & {dereferenced?: Awaited>} = {}, +): string { + validateOptions(options) + + const _options = merge({}, DEFAULT_OPTIONS, options) + + const start = Date.now() + function time() { + return `(${Date.now() - start}ms)` + } + + // normalize options + if (!endsWith(_options.cwd, '/')) { + _options.cwd += '/' + } + + // Initial clone to avoid mutating the input + const _schema = cloneDeep(schema) + + const {dereferencedPaths, dereferencedSchema} = options.dereferenced || { + dereferencedPaths: new WeakMap(), + dereferencedSchema: _schema, + } if (process.env.VERBOSE) { if (isDeepStrictEqual(_schema, dereferencedSchema)) { log('green', 'dereferencer', time(), '✅ No change') @@ -185,10 +224,7 @@ export async function compile(schema: JSONSchema4, name: string, options: Partia const generated = generate(optimized, _options) log('magenta', 'generator', time(), '✅ Result:', generated) - const formatted = await format(generated, _options) - log('white', 'formatter', time(), '✅ Result:', formatted) - - return formatted + return generated } export class ValidationError extends Error {}