diff --git a/src/quicktype-core/language/JavaScript.ts b/src/quicktype-core/language/JavaScript.ts index 02a1b3271b..a9a9fa155e 100644 --- a/src/quicktype-core/language/JavaScript.ts +++ b/src/quicktype-core/language/JavaScript.ts @@ -10,6 +10,8 @@ import { } from "../Type"; import { matchType, directlyReachableSingleNamedType } from "../TypeUtils"; import { acronymOption, acronymStyle, AcronymStyleOptions } from "../support/Acronyms"; +import { convertersOption, ConvertersOptions } from "../support/Converters"; + import { utf16LegalizeCharacters, utf16StringEscape, @@ -33,7 +35,8 @@ import { isES3IdentifierPart, isES3IdentifierStart } from "./JavaScriptUnicodeMa export const javaScriptOptions = { acronymStyle: acronymOption(AcronymStyleOptions.Pascal), - runtimeTypecheck: new BooleanOption("runtime-typecheck", "Verify JSON.parse results at runtime", true) + runtimeTypecheck: new BooleanOption("runtime-typecheck", "Verify JSON.parse results at runtime", true), + converters: convertersOption() }; export type JavaScriptTypeAnnotations = { @@ -56,7 +59,7 @@ export class JavaScriptTargetLanguage extends TargetLanguage { } protected getOptions(): Option[] { - return [javaScriptOptions.runtimeTypecheck, javaScriptOptions.acronymStyle]; + return [javaScriptOptions.runtimeTypecheck, javaScriptOptions.acronymStyle, javaScriptOptions.converters]; } get stringTypeMapping(): StringTypeMapping { @@ -255,7 +258,7 @@ export class JavaScriptRenderer extends ConvenienceRenderer { } protected emitConvertModuleBody(): void { - this.forEachTopLevel("interposing", (t, name) => { + const converter = (t: Type, name: Name) => { const typeMap = this.typeMapTypeFor(t); this.emitBlock([this.deserializerFunctionLine(t, name), " "], "", () => { if (!this._jsOptions.runtimeTypecheck) { @@ -273,7 +276,17 @@ export class JavaScriptRenderer extends ConvenienceRenderer { this.emitLine("return JSON.stringify(uncast(value, ", typeMap, "), null, 2);"); } }); - }); + }; + + switch (this._jsOptions.converters) { + case ConvertersOptions.AllObjects: + this.forEachObject("interposing", converter); + break; + + default: + this.forEachTopLevel("interposing", converter); + break; + } } protected emitConvertModuleHelpers(): void { diff --git a/src/quicktype-core/language/TypeScriptFlow.ts b/src/quicktype-core/language/TypeScriptFlow.ts index 4587ae3516..28c56d0b8d 100644 --- a/src/quicktype-core/language/TypeScriptFlow.ts +++ b/src/quicktype-core/language/TypeScriptFlow.ts @@ -39,7 +39,8 @@ export abstract class TypeScriptFlowBaseTargetLanguage extends JavaScriptTargetL tsFlowOptions.nicePropertyNames, tsFlowOptions.declareUnions, tsFlowOptions.runtimeTypecheck, - tsFlowOptions.acronymStyle + tsFlowOptions.acronymStyle, + tsFlowOptions.converters ]; } diff --git a/src/quicktype-core/support/Converters.ts b/src/quicktype-core/support/Converters.ts new file mode 100644 index 0000000000..4231237d30 --- /dev/null +++ b/src/quicktype-core/support/Converters.ts @@ -0,0 +1,19 @@ +import { EnumOption } from "../RendererOptions"; + +export enum ConvertersOptions { + TopLevel = "top-level", + AllObjects = "all-objects" +} + +export function convertersOption() { + return new EnumOption( + "converters", + "Which converters to generate (top-level by default)", + [ + [ConvertersOptions.TopLevel, ConvertersOptions.TopLevel], + [ConvertersOptions.AllObjects, ConvertersOptions.AllObjects] + ], + ConvertersOptions.TopLevel, + "secondary" + ); +} diff --git a/test/languages.ts b/test/languages.ts index bf0e2d0c9c..aed0e8d5c9 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -595,7 +595,8 @@ export const TypeScriptLanguage: Language = { { "runtime-typecheck": "false" }, { "nice-property-names": "true" }, { "declare-unions": "true" }, - { "acronym-style": "pascal" } + { "acronym-style": "pascal" }, + { converters: "all-objects" } ], sourceFiles: ["src/language/TypeScript.ts"] }; @@ -619,7 +620,7 @@ export const JavaScriptLanguage: Language = { skipMiscJSON: false, skipSchema: ["keyword-unions.schema"], // can't handle "constructor" property rendererOptions: {}, - quickTestRendererOptions: [{ "runtime-typecheck": "false" }], + quickTestRendererOptions: [{ "runtime-typecheck": "false" }, { converters: "top-level" }], sourceFiles: ["src/language/JavaScript.ts"] };