diff --git a/README.md b/README.md index d9e50cdb..816dee18 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ See [server demo](example) and [browser demo](https://github.com/bcherny/json-sc | unknownAny | boolean | `true` | Use `unknown` instead of `any` where possible | | unreachableDefinitions | boolean | `false` | Generates code for `$defs` that aren't referenced by the schema. | | $refOptions | object | `{}` | [$RefParser](https://github.com/APIDevTools/json-schema-ref-parser) Options, used when resolving `$ref`s | - +| readonly | boolean | `false` | Emit all types as `readonly` | ## Tests ```sh diff --git a/src/cli.ts b/src/cli.ts index 3976b75f..7378ad8e 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -24,6 +24,7 @@ main( 'strictIndexSignatures', 'unknownAny', 'unreachableDefinitions', + 'readonly', ], default: DEFAULT_OPTIONS, string: ['bannerComment', 'cwd'], @@ -197,6 +198,8 @@ Boolean values can be set to false using the 'no-' prefix. Output unknown type instead of any type --unreachableDefinitions Generates code for definitions that aren't referenced by the schema + --readonly + Emits all types as readonly `, ) } diff --git a/src/generator.ts b/src/generator.ts index fb8d23b0..863542f1 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -305,6 +305,7 @@ function generateInterface(ast: TInterface, options: Options): string { .map( ([isRequired, keyName, ast, type]) => (hasComment(ast) && !ast.standaloneName ? generateComment(ast.comment, ast.deprecated) + '\n' : '') + + (options.readonly ? 'readonly ' : '') + escapeKeyName(keyName) + (isRequired ? '' : '?') + ': ' + diff --git a/src/index.ts b/src/index.ts index 1aa67be0..2d0d42d9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -85,6 +85,10 @@ export interface Options { * Generate unknown type instead of any */ unknownAny: boolean + /** + * Emit all types as readonly + */ + readonly: boolean } export const DEFAULT_OPTIONS: Options = { @@ -115,6 +119,7 @@ export const DEFAULT_OPTIONS: Options = { }, unreachableDefinitions: false, unknownAny: true, + readonly: false, } export function compileFromFile(filename: string, options: Partial = DEFAULT_OPTIONS): Promise { diff --git a/test/__snapshots__/test/test.ts.md b/test/__snapshots__/test/test.ts.md index 28670fb1..42b8e84b 100644 --- a/test/__snapshots__/test/test.ts.md +++ b/test/__snapshots__/test/test.ts.md @@ -2610,6 +2610,28 @@ Generated by [AVA](https://avajs.dev). }␊ ` +## readonly.1.js + +> Expected output to match snapshot for e2e test: readonly.1.js + + `/* eslint-disable */␊ + /**␊ + * This file was automatically generated by json-schema-to-typescript.␊ + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊ + * and run json-schema-to-typescript to regenerate this file.␊ + */␊ + ␊ + export interface ReadonlyConfiguredToTrue {␊ + readonly a?: {␊ + readonly [k: string]: unknown;␊ + };␊ + readonly b?: {␊ + readonly [k: string]: unknown;␊ + };␊ + readonly [k: string]: unknown;␊ + }␊ + ` + ## realWorld.awsQuicksight.js > Expected output to match snapshot for e2e test: realWorld.awsQuicksight.js diff --git a/test/__snapshots__/test/test.ts.snap b/test/__snapshots__/test/test.ts.snap index 05f2ed95..71ac9761 100644 Binary files a/test/__snapshots__/test/test.ts.snap and b/test/__snapshots__/test/test.ts.snap differ diff --git a/test/e2e/readonly.1.ts b/test/e2e/readonly.1.ts new file mode 100644 index 00000000..fe8d1679 --- /dev/null +++ b/test/e2e/readonly.1.ts @@ -0,0 +1,21 @@ +export const input = { + title: 'Readonly (configured to true)', + type: 'object', + definitions: { + e: { + type: 'object', + }, + }, + properties: { + a: { + type: 'object', + }, + b: { + type: 'object', + }, + }, +} + +export const options = { + readonly: true, +}