quicktype-core 6.0.65 → 6.0.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -174,6 +174,7 @@ export declare class CPlusPlusRenderer extends ConvenienceRenderer {
174
174
  protected emitUnionHeaders(u: UnionType): void;
175
175
  protected emitUnionFunctions(u: UnionType): void;
176
176
  protected emitEnumHeaders(enumName: Name): void;
177
+ private isLargeEnum;
177
178
  protected emitEnumFunctions(e: EnumType, enumName: Name): void;
178
179
  protected emitTopLevelTypedef(t: Type, name: Name): void;
179
180
  protected emitAllUnionFunctions(): void;
@@ -1103,16 +1103,34 @@ class CPlusPlusRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
1103
1103
  this.emitLine("void from_json(", this.withConst("json"), " & j, ", ourQualifier, enumName, " & x);");
1104
1104
  this.emitLine("void to_json(json & j, ", this.withConst([ourQualifier, enumName]), " & x);");
1105
1105
  }
1106
+ isLargeEnum(e) {
1107
+ // This is just an estimation. Someone might want to do some
1108
+ // benchmarks to find the optimum value here
1109
+ return e.cases.size > 15;
1110
+ }
1106
1111
  emitEnumFunctions(e, enumName) {
1107
1112
  const ourQualifier = this.ourQualifier(true);
1108
1113
  this.emitBlock(["inline void from_json(", this.withConst("json"), " & j, ", ourQualifier, enumName, " & x)"], false, () => {
1109
- let onFirst = true;
1110
- this.forEachEnumCase(e, "none", (name, jsonName) => {
1111
- const maybeElse = onFirst ? "" : "else ";
1112
- this.emitLine(maybeElse, "if (j == ", this._stringType.wrapEncodingChange([ourQualifier], this._stringType.getType(), this.NarrowString.getType(), [this._stringType.createStringLiteral([Strings_1.stringEscape(jsonName)])]), ") x = ", ourQualifier, enumName, "::", name, ";");
1113
- onFirst = false;
1114
- });
1115
- this.emitLine('else throw "Input JSON does not conform to schema";');
1114
+ if (this.isLargeEnum(e)) {
1115
+ this.emitBlock(["static std::unordered_map<", this._stringType.getType(), ", ", ourQualifier, enumName, "> enumValues"], true, () => {
1116
+ this.forEachEnumCase(e, "none", (name, jsonName) => {
1117
+ this.emitLine("{", this._stringType.wrapEncodingChange([ourQualifier], this._stringType.getType(), this.NarrowString.getType(), [this._stringType.createStringLiteral([Strings_1.stringEscape(jsonName)])]), ", ", ourQualifier, enumName, "::", name, "},");
1118
+ });
1119
+ });
1120
+ this.emitLine(`auto iter = enumValues.find(j.get<${this._stringType.getType()}>());`);
1121
+ this.emitBlock("if (iter != enumValues.end())", false, () => {
1122
+ this.emitLine("x = iter->second;");
1123
+ });
1124
+ }
1125
+ else {
1126
+ let onFirst = true;
1127
+ this.forEachEnumCase(e, "none", (name, jsonName) => {
1128
+ const maybeElse = onFirst ? "" : "else ";
1129
+ this.emitLine(maybeElse, "if (j == ", this._stringType.wrapEncodingChange([ourQualifier], this._stringType.getType(), this.NarrowString.getType(), [this._stringType.createStringLiteral([Strings_1.stringEscape(jsonName)])]), ") x = ", ourQualifier, enumName, "::", name, ";");
1130
+ onFirst = false;
1131
+ });
1132
+ this.emitLine('else throw "Input JSON does not conform to schema";');
1133
+ }
1116
1134
  });
1117
1135
  this.ensureBlankLine();
1118
1136
  this.emitBlock(["inline void to_json(json & j, ", this.withConst([ourQualifier, enumName]), " & x)"], false, () => {
@@ -1325,6 +1343,10 @@ class CPlusPlusRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
1325
1343
  this.emitInclude(true, `codecvt`);
1326
1344
  this.emitInclude(true, `locale`);
1327
1345
  }
1346
+ // Include unordered_map if contains large enums
1347
+ if (Array.from(this.enums).some(enumType => this.isLargeEnum(enumType))) {
1348
+ this.emitInclude(true, `unordered_map`);
1349
+ }
1328
1350
  this.ensureBlankLine();
1329
1351
  }
1330
1352
  emitHelper() {
@@ -58,7 +58,7 @@ function canOmitEmpty(cp) {
58
58
  if (!cp.isOptional)
59
59
  return false;
60
60
  const t = cp.type;
61
- return ["union", "null", "any", "array"].indexOf(t.kind) < 0;
61
+ return ["union", "null", "any"].indexOf(t.kind) < 0;
62
62
  }
63
63
  class GoRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
64
64
  constructor(targetLanguage, renderContext, _options) {
@@ -6,13 +6,14 @@ import { Namer, Name } from "../Naming";
6
6
  import { ConvenienceRenderer } from "../ConvenienceRenderer";
7
7
  import { TargetLanguage } from "../TargetLanguage";
8
8
  import { StringTypeMapping } from "../TypeBuilder";
9
- import { BooleanOption, Option, OptionValues } from "../RendererOptions";
9
+ import { BooleanOption, Option, OptionValues, EnumOption } from "../RendererOptions";
10
10
  import { RenderContext } from "../Renderer";
11
11
  export declare const javaScriptOptions: {
12
- acronymStyle: import("../RendererOptions").EnumOption<AcronymStyleOptions>;
12
+ acronymStyle: EnumOption<AcronymStyleOptions>;
13
13
  runtimeTypecheck: BooleanOption;
14
14
  runtimeTypecheckIgnoreUnknownProperties: BooleanOption;
15
- converters: import("../RendererOptions").EnumOption<ConvertersOptions>;
15
+ converters: EnumOption<ConvertersOptions>;
16
+ rawType: EnumOption<"any" | "json">;
16
17
  };
17
18
  export declare type JavaScriptTypeAnnotations = {
18
19
  any: string;
@@ -17,6 +17,10 @@ exports.javaScriptOptions = {
17
17
  runtimeTypecheck: new RendererOptions_1.BooleanOption("runtime-typecheck", "Verify JSON.parse results at runtime", true),
18
18
  runtimeTypecheckIgnoreUnknownProperties: new RendererOptions_1.BooleanOption("runtime-typecheck-ignore-unknown-properties", "Ignore unknown properties when verifying at runtime", false, "secondary"),
19
19
  converters: Converters_1.convertersOption(),
20
+ rawType: new RendererOptions_1.EnumOption("raw-type", "Type to raw input (json by default)", [
21
+ ["json", "json"],
22
+ ["any", "any"]
23
+ ], "json", "secondary")
20
24
  };
21
25
  class JavaScriptTargetLanguage extends TargetLanguage_1.TargetLanguage {
22
26
  constructor(displayName = "JavaScript", names = ["javascript", "js", "jsx"], extension = "js") {
@@ -28,6 +32,7 @@ class JavaScriptTargetLanguage extends TargetLanguage_1.TargetLanguage {
28
32
  exports.javaScriptOptions.runtimeTypecheckIgnoreUnknownProperties,
29
33
  exports.javaScriptOptions.acronymStyle,
30
34
  exports.javaScriptOptions.converters,
35
+ exports.javaScriptOptions.rawType
31
36
  ];
32
37
  }
33
38
  get stringTypeMapping() {
@@ -153,26 +158,45 @@ class JavaScriptRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
153
158
  return ["function cast(val, typ)", "function uncast(val, typ)"];
154
159
  }
155
160
  get typeAnnotations() {
156
- return { any: "", anyArray: "", anyMap: "", string: "", stringArray: "", boolean: "", never: "" };
161
+ return {
162
+ any: "",
163
+ anyArray: "",
164
+ anyMap: "",
165
+ string: "",
166
+ stringArray: "",
167
+ boolean: "",
168
+ never: ""
169
+ };
157
170
  }
158
171
  emitConvertModuleBody() {
159
172
  const converter = (t, name) => {
160
173
  const typeMap = this.typeMapTypeFor(t);
161
174
  this.emitBlock([this.deserializerFunctionLine(t, name), " "], "", () => {
175
+ const parsedJson = this._jsOptions.rawType === "json" ? "JSON.parse(json)" : "json";
162
176
  if (!this._jsOptions.runtimeTypecheck) {
163
- this.emitLine("return JSON.parse(json);");
177
+ this.emitLine("return ", parsedJson, ";");
164
178
  }
165
179
  else {
166
- this.emitLine("return cast(JSON.parse(json), ", typeMap, ");");
180
+ this.emitLine("return cast(", parsedJson, ", ", typeMap, ");");
167
181
  }
168
182
  });
169
183
  this.ensureBlankLine();
170
184
  this.emitBlock([this.serializerFunctionLine(t, name), " "], "", () => {
171
- if (!this._jsOptions.runtimeTypecheck) {
172
- this.emitLine("return JSON.stringify(value);");
185
+ if (this._jsOptions.rawType === "json") {
186
+ if (!this._jsOptions.runtimeTypecheck) {
187
+ this.emitLine("return JSON.stringify(value);");
188
+ }
189
+ else {
190
+ this.emitLine("return JSON.stringify(uncast(value, ", typeMap, "), null, 2);");
191
+ }
173
192
  }
174
193
  else {
175
- this.emitLine("return JSON.stringify(uncast(value, ", typeMap, "), null, 2);");
194
+ if (!this._jsOptions.runtimeTypecheck) {
195
+ this.emitLine("return value;");
196
+ }
197
+ else {
198
+ this.emitLine("return uncast(value, ", typeMap, ");");
199
+ }
176
200
  }
177
201
  });
178
202
  };
@@ -189,8 +213,12 @@ class JavaScriptRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
189
213
  if (this._jsOptions.runtimeTypecheck) {
190
214
  const { any: anyAnnotation, anyArray: anyArrayAnnotation, anyMap: anyMapAnnotation, string: stringAnnotation, stringArray: stringArrayAnnotation, never: neverAnnotation } = this.typeAnnotations;
191
215
  this.ensureBlankLine();
192
- this.emitMultiline(`function invalidValue(typ${anyAnnotation}, val${anyAnnotation})${neverAnnotation} {
193
- throw Error(\`Invalid value \${JSON.stringify(val)} for type \${JSON.stringify(typ)}\`);
216
+ this
217
+ .emitMultiline(`function invalidValue(typ${anyAnnotation}, val${anyAnnotation}, key${anyAnnotation} = '')${neverAnnotation} {
218
+ if (key) {
219
+ throw Error(\`Invalid value for key \"\${key}\". Expected type \${JSON.stringify(typ)} but got \${JSON.stringify(val)}\`);
220
+ }
221
+ throw Error(\`Invalid value \${JSON.stringify(val)} for type \${JSON.stringify(typ)}\`, );
194
222
  }
195
223
 
196
224
  function jsonToJSProps(typ${anyAnnotation})${anyAnnotation} {
@@ -211,10 +239,10 @@ function jsToJSONProps(typ${anyAnnotation})${anyAnnotation} {
211
239
  return typ.jsToJSON;
212
240
  }
213
241
 
214
- function transform(val${anyAnnotation}, typ${anyAnnotation}, getProps${anyAnnotation})${anyAnnotation} {
242
+ function transform(val${anyAnnotation}, typ${anyAnnotation}, getProps${anyAnnotation}, key${anyAnnotation} = '')${anyAnnotation} {
215
243
  function transformPrimitive(typ${stringAnnotation}, val${anyAnnotation})${anyAnnotation} {
216
244
  if (typeof typ === typeof val) return val;
217
- return invalidValue(typ, val);
245
+ return invalidValue(typ, val, key);
218
246
  }
219
247
 
220
248
  function transformUnion(typs${anyArrayAnnotation}, val${anyAnnotation})${anyAnnotation} {
@@ -259,13 +287,13 @@ function transform(val${anyAnnotation}, typ${anyAnnotation}, getProps${anyAnnota
259
287
  Object.getOwnPropertyNames(props).forEach(key => {
260
288
  const prop = props[key];
261
289
  const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
262
- result[prop.key] = transform(v, prop.typ, getProps);
290
+ result[prop.key] = transform(v, prop.typ, getProps, prop.key);
263
291
  });
264
292
  Object.getOwnPropertyNames(val).forEach(key => {
265
293
  if (!Object.prototype.hasOwnProperty.call(props, key)) {
266
294
  result[key] = ${this._jsOptions.runtimeTypecheckIgnoreUnknownProperties
267
295
  ? `val[key]`
268
- : `transform(val[key], additional, getProps)`};
296
+ : `transform(val[key], additional, getProps, key)`};
269
297
  }
270
298
  });
271
299
  return result;
@@ -325,9 +353,9 @@ function r(name${stringAnnotation}) {
325
353
  }
326
354
  emitConvertModule() {
327
355
  this.ensureBlankLine();
328
- this.emitMultiline(`// Converts JSON strings to/from your types`);
356
+ this.emitMultiline(`// Converts JSON ${this._jsOptions.rawType === "json" ? "strings" : "types"} to/from your types`);
329
357
  if (this._jsOptions.runtimeTypecheck) {
330
- this.emitMultiline(`// and asserts the results of JSON.parse at runtime`);
358
+ this.emitMultiline(`// and asserts the results${this._jsOptions.rawType === "json" ? " of JSON.parse" : ""} at runtime`);
331
359
  }
332
360
  const moduleLine = this.moduleLine;
333
361
  if (moduleLine === undefined) {
@@ -540,6 +540,14 @@ class ObjectiveCRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
540
540
  this.emitLine("id resolved = ", className, ".properties[key];");
541
541
  this.emitLine("if (resolved) [super setValue:value forKey:resolved];");
542
542
  });
543
+ // setNilValueForKey: is automatically invoked by the NSObject setValue:forKey: when it is passed nil for a scalar (a.k.a. non-nullable) object
544
+ // The approach below sets the scalar to 0 in this case, and therefore assumes an initializer with incomplete data shouldn't be grounds for raising an exception.
545
+ // Put another way, if the initializer didn't have a key at all, there wouldn't be an exception raised, so sending nil for something probably shouldn't cause one.
546
+ this.ensureBlankLine();
547
+ this.emitMethod("- (void)setNilValueForKey:(NSString *)key", () => {
548
+ this.emitLine("id resolved = ", className, ".properties[key];");
549
+ this.emitLine("if (resolved) [super setValue:@(0) forKey:resolved];");
550
+ });
543
551
  this.ensureBlankLine();
544
552
  this.emitMethod("- (NSDictionary *)JSONDictionary", () => {
545
553
  if (!hasIrregularProperties && !hasUnsafeProperties) {
@@ -18,6 +18,8 @@ export declare const rustOptions: {
18
18
  density: EnumOption<Density>;
19
19
  visibility: EnumOption<Visibility>;
20
20
  deriveDebug: BooleanOption;
21
+ edition2018: BooleanOption;
22
+ leadingComments: BooleanOption;
21
23
  };
22
24
  export declare class RustTargetLanguage extends TargetLanguage {
23
25
  protected makeRenderer(renderContext: RenderContext, untypedOptionValues: {
@@ -22,13 +22,18 @@ var Visibility;
22
22
  Visibility[Visibility["Public"] = 2] = "Public";
23
23
  })(Visibility = exports.Visibility || (exports.Visibility = {}));
24
24
  exports.rustOptions = {
25
- density: new RendererOptions_1.EnumOption("density", "Density", [["normal", Density.Normal], ["dense", Density.Dense]]),
25
+ density: new RendererOptions_1.EnumOption("density", "Density", [
26
+ ["normal", Density.Normal],
27
+ ["dense", Density.Dense]
28
+ ]),
26
29
  visibility: new RendererOptions_1.EnumOption("visibility", "Field visibility", [
27
30
  ["private", Visibility.Private],
28
31
  ["crate", Visibility.Crate],
29
32
  ["public", Visibility.Public]
30
33
  ]),
31
- deriveDebug: new RendererOptions_1.BooleanOption("derive-debug", "Derive Debug impl", false)
34
+ deriveDebug: new RendererOptions_1.BooleanOption("derive-debug", "Derive Debug impl", false),
35
+ edition2018: new RendererOptions_1.BooleanOption("edition-2018", "Edition 2018", false),
36
+ leadingComments: new RendererOptions_1.BooleanOption("leading-comments", "Leading Comments", true)
32
37
  };
33
38
  class RustTargetLanguage extends TargetLanguage_1.TargetLanguage {
34
39
  makeRenderer(renderContext, untypedOptionValues) {
@@ -274,9 +279,16 @@ class RustRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
274
279
  // }`);
275
280
  }
276
281
  emitSourceStructure() {
277
- this.emitLeadingComments();
282
+ if (this._options.leadingComments) {
283
+ this.emitLeadingComments();
284
+ }
278
285
  this.ensureBlankLine();
279
- this.emitLine("extern crate serde_json;");
286
+ if (this._options.edition2018) {
287
+ this.emitLine("use serde::{Serialize, Deserialize};");
288
+ }
289
+ else {
290
+ this.emitLine("extern crate serde_derive;");
291
+ }
280
292
  if (this.haveMaps) {
281
293
  this.emitLine("use std::collections::HashMap;");
282
294
  }
@@ -10,6 +10,7 @@ export declare const tsFlowOptions: {
10
10
  runtimeTypecheck: BooleanOption;
11
11
  runtimeTypecheckIgnoreUnknownProperties: BooleanOption;
12
12
  converters: import("../RendererOptions").EnumOption<import("../support/Converters").ConvertersOptions>;
13
+ rawType: import("../RendererOptions").EnumOption<"any" | "json">;
13
14
  } & {
14
15
  justTypes: BooleanOption;
15
16
  nicePropertyNames: BooleanOption;
@@ -29,7 +30,7 @@ export declare class TypeScriptTargetLanguage extends TypeScriptFlowBaseTargetLa
29
30
  }): TypeScriptRenderer;
30
31
  }
31
32
  export declare abstract class TypeScriptFlowBaseRenderer extends JavaScriptRenderer {
32
- private readonly _tsFlowOptions;
33
+ protected readonly _tsFlowOptions: OptionValues<typeof tsFlowOptions>;
33
34
  constructor(targetLanguage: TargetLanguage, renderContext: RenderContext, _tsFlowOptions: OptionValues<typeof tsFlowOptions>);
34
35
  protected namerForObjectProperty(): Namer;
35
36
  protected sourceFor(t: Type): MultiWord;
@@ -31,7 +31,8 @@ class TypeScriptFlowBaseTargetLanguage extends JavaScript_1.JavaScriptTargetLang
31
31
  exports.tsFlowOptions.runtimeTypecheck,
32
32
  exports.tsFlowOptions.runtimeTypecheckIgnoreUnknownProperties,
33
33
  exports.tsFlowOptions.acronymStyle,
34
- exports.tsFlowOptions.converters
34
+ exports.tsFlowOptions.converters,
35
+ exports.tsFlowOptions.rawType
35
36
  ];
36
37
  }
37
38
  get supportsOptionalClassProperties() {
@@ -138,11 +139,13 @@ class TypeScriptFlowBaseRenderer extends JavaScript_1.JavaScriptRenderer {
138
139
  super.emitUsageComments();
139
140
  }
140
141
  deserializerFunctionLine(t, name) {
141
- return ["function to", name, "(json: string): ", this.sourceFor(t).source];
142
+ const jsonType = this._tsFlowOptions.rawType === "json" ? "string" : "any";
143
+ return ["function to", name, "(json: ", jsonType, "): ", this.sourceFor(t).source];
142
144
  }
143
145
  serializerFunctionLine(t, name) {
144
146
  const camelCaseName = Source_1.modifySource(Strings_1.camelCase, name);
145
- return ["function ", camelCaseName, "ToJson(value: ", this.sourceFor(t).source, "): string"];
147
+ const returnType = this._tsFlowOptions.rawType === "json" ? "string" : "any";
148
+ return ["function ", camelCaseName, "ToJson(value: ", this.sourceFor(t).source, "): ", returnType];
146
149
  }
147
150
  get moduleLine() {
148
151
  return undefined;
@@ -178,11 +181,13 @@ class TypeScriptRenderer extends TypeScriptFlowBaseRenderer {
178
181
  return ["Array", "Date"];
179
182
  }
180
183
  deserializerFunctionLine(t, name) {
181
- return ["public static to", name, "(json: string): ", this.sourceFor(t).source];
184
+ const jsonType = this._tsFlowOptions.rawType === "json" ? "string" : "any";
185
+ return ["public static to", name, "(json: ", jsonType, "): ", this.sourceFor(t).source];
182
186
  }
183
187
  serializerFunctionLine(t, name) {
184
188
  const camelCaseName = Source_1.modifySource(Strings_1.camelCase, name);
185
- return ["public static ", camelCaseName, "ToJson(value: ", this.sourceFor(t).source, "): string"];
189
+ const returnType = this._tsFlowOptions.rawType === "json" ? "string" : "any";
190
+ return ["public static ", camelCaseName, "ToJson(value: ", this.sourceFor(t).source, "): ", returnType];
186
191
  }
187
192
  get moduleLine() {
188
193
  return "export class Convert";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quicktype-core",
3
- "version": "6.0.65",
3
+ "version": "6.0.69",
4
4
  "description": "The quicktype engine as a library",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",
@@ -14,6 +14,7 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "collection-utils": "^1.0.1",
17
+ "is-url": "^1.2.4",
17
18
  "js-base64": "^2.4.3",
18
19
  "pako": "^1.0.6",
19
20
  "pluralize": "^7.0.0",
@@ -28,13 +29,13 @@
28
29
  "devDependencies": {
29
30
  "@types/urijs": "^1.19.8",
30
31
  "@types/js-base64": "^2.3.1",
31
- "@types/node": "^8.10.10",
32
+ "@types/node": "8.10.10",
32
33
  "@types/pako": "^1.0.0",
33
34
  "@types/pluralize": "0.0.28",
34
35
  "@types/yaml": "^1.0.2",
35
36
  "typescript": "~3.2.1",
36
37
  "tslint": "^5.11.0",
37
- "@types/readable-stream": "2.3.0",
38
+ "@types/readable-stream": "2.3.9",
38
39
  "@types/browser-or-node": "^1.2.0"
39
40
  },
40
41
  "files": [
@@ -44,6 +45,6 @@
44
45
  "fs": false
45
46
  },
46
47
  "config": {
47
- "commit": "7a6a0fbdaa817ac36d0acf8701fe92e36ae261d6"
48
+ "commit": "e6cc44fdfcb75c3f3ed3e12f69f15a0c863a1a05"
48
49
  }
49
50
  }