quicktype 17.0.1 → 17.0.3

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.
Files changed (139) hide show
  1. package/dist/cli/CompressedJSONFromStream.js +26 -38
  2. package/dist/cli/GraphQLIntrospection.js +33 -41
  3. package/dist/cli/TypeSource.d.ts +1 -1
  4. package/dist/cli/URLGrammar.js +4 -3
  5. package/dist/cli/index.js +363 -364
  6. package/dist/quicktype-core/Annotation.js +2 -0
  7. package/dist/quicktype-core/ConvenienceRenderer.d.ts +17 -17
  8. package/dist/quicktype-core/ConvenienceRenderer.js +104 -81
  9. package/dist/quicktype-core/DateTime.js +1 -0
  10. package/dist/quicktype-core/DeclarationIR.d.ts +1 -1
  11. package/dist/quicktype-core/DeclarationIR.js +13 -10
  12. package/dist/quicktype-core/EncodedMarkovChain.js +1 -0
  13. package/dist/quicktype-core/GatherNames.js +47 -25
  14. package/dist/quicktype-core/Graph.d.ts +2 -2
  15. package/dist/quicktype-core/Graph.js +23 -19
  16. package/dist/quicktype-core/GraphRewriting.d.ts +2 -2
  17. package/dist/quicktype-core/GraphRewriting.js +65 -54
  18. package/dist/quicktype-core/MakeTransformations.js +23 -22
  19. package/dist/quicktype-core/MarkovChain.d.ts +3 -3
  20. package/dist/quicktype-core/MarkovChain.js +9 -8
  21. package/dist/quicktype-core/Messages.d.ts +3 -3
  22. package/dist/quicktype-core/Messages.js +8 -3
  23. package/dist/quicktype-core/Naming.d.ts +11 -11
  24. package/dist/quicktype-core/Naming.js +76 -61
  25. package/dist/quicktype-core/Renderer.d.ts +6 -6
  26. package/dist/quicktype-core/Renderer.js +34 -17
  27. package/dist/quicktype-core/RendererOptions.d.ts +5 -5
  28. package/dist/quicktype-core/RendererOptions.js +6 -3
  29. package/dist/quicktype-core/Run.d.ts +9 -9
  30. package/dist/quicktype-core/Run.js +72 -67
  31. package/dist/quicktype-core/Source.d.ts +3 -3
  32. package/dist/quicktype-core/Source.js +19 -18
  33. package/dist/quicktype-core/TargetLanguage.d.ts +10 -10
  34. package/dist/quicktype-core/TargetLanguage.js +6 -2
  35. package/dist/quicktype-core/Transformers.d.ts +25 -25
  36. package/dist/quicktype-core/Transformers.js +94 -66
  37. package/dist/quicktype-core/Type.d.ts +41 -43
  38. package/dist/quicktype-core/Type.js +96 -71
  39. package/dist/quicktype-core/TypeBuilder.d.ts +2 -2
  40. package/dist/quicktype-core/TypeBuilder.js +53 -47
  41. package/dist/quicktype-core/TypeGraph.d.ts +4 -4
  42. package/dist/quicktype-core/TypeGraph.js +49 -40
  43. package/dist/quicktype-core/TypeUtils.d.ts +2 -2
  44. package/dist/quicktype-core/TypeUtils.js +23 -22
  45. package/dist/quicktype-core/UnifyClasses.js +16 -12
  46. package/dist/quicktype-core/UnionBuilder.d.ts +3 -3
  47. package/dist/quicktype-core/UnionBuilder.js +33 -30
  48. package/dist/quicktype-core/attributes/AccessorNames.d.ts +2 -2
  49. package/dist/quicktype-core/attributes/AccessorNames.js +18 -17
  50. package/dist/quicktype-core/attributes/Constraints.d.ts +3 -3
  51. package/dist/quicktype-core/attributes/Constraints.js +8 -4
  52. package/dist/quicktype-core/attributes/Description.js +6 -5
  53. package/dist/quicktype-core/attributes/EnumValues.js +4 -3
  54. package/dist/quicktype-core/attributes/StringTypes.d.ts +1 -1
  55. package/dist/quicktype-core/attributes/StringTypes.js +24 -21
  56. package/dist/quicktype-core/attributes/TypeAttributes.d.ts +3 -3
  57. package/dist/quicktype-core/attributes/TypeAttributes.js +12 -10
  58. package/dist/quicktype-core/attributes/TypeNames.d.ts +9 -9
  59. package/dist/quicktype-core/attributes/TypeNames.js +49 -21
  60. package/dist/quicktype-core/attributes/URIAttributes.d.ts +1 -1
  61. package/dist/quicktype-core/attributes/URIAttributes.js +10 -6
  62. package/dist/quicktype-core/index.js +128 -125
  63. package/dist/quicktype-core/input/CompressedJSON.d.ts +7 -7
  64. package/dist/quicktype-core/input/CompressedJSON.js +49 -54
  65. package/dist/quicktype-core/input/FetchingJSONSchemaStore.js +5 -13
  66. package/dist/quicktype-core/input/Inference.d.ts +2 -2
  67. package/dist/quicktype-core/input/Inference.js +25 -17
  68. package/dist/quicktype-core/input/Inputs.d.ts +2 -2
  69. package/dist/quicktype-core/input/Inputs.js +38 -54
  70. package/dist/quicktype-core/input/JSONSchemaInput.d.ts +11 -11
  71. package/dist/quicktype-core/input/JSONSchemaInput.js +503 -523
  72. package/dist/quicktype-core/input/JSONSchemaStore.d.ts +1 -1
  73. package/dist/quicktype-core/input/JSONSchemaStore.js +24 -35
  74. package/dist/quicktype-core/input/PostmanCollection.js +2 -1
  75. package/dist/quicktype-core/input/io/NodeIO.js +55 -44
  76. package/dist/quicktype-core/input/io/get-stream/index.js +6 -2
  77. package/dist/quicktype-core/language/All.js +3 -2
  78. package/dist/quicktype-core/language/CPlusPlus.d.ts +8 -8
  79. package/dist/quicktype-core/language/CPlusPlus.js +185 -151
  80. package/dist/quicktype-core/language/CSharp.d.ts +7 -7
  81. package/dist/quicktype-core/language/CSharp.js +82 -72
  82. package/dist/quicktype-core/language/Crystal.d.ts +2 -2
  83. package/dist/quicktype-core/language/Crystal.js +18 -17
  84. package/dist/quicktype-core/language/Dart.d.ts +4 -4
  85. package/dist/quicktype-core/language/Dart.js +36 -34
  86. package/dist/quicktype-core/language/Elm.d.ts +6 -6
  87. package/dist/quicktype-core/language/Elm.js +47 -45
  88. package/dist/quicktype-core/language/Golang.d.ts +4 -4
  89. package/dist/quicktype-core/language/Golang.js +23 -20
  90. package/dist/quicktype-core/language/Haskell.d.ts +5 -5
  91. package/dist/quicktype-core/language/Haskell.js +25 -23
  92. package/dist/quicktype-core/language/JSONSchema.d.ts +3 -3
  93. package/dist/quicktype-core/language/JSONSchema.js +17 -16
  94. package/dist/quicktype-core/language/Java.d.ts +2 -2
  95. package/dist/quicktype-core/language/Java.js +97 -97
  96. package/dist/quicktype-core/language/JavaScript.d.ts +7 -7
  97. package/dist/quicktype-core/language/JavaScript.js +19 -17
  98. package/dist/quicktype-core/language/JavaScriptPropTypes.js +15 -13
  99. package/dist/quicktype-core/language/JavaScriptUnicodeMaps.js +12 -11
  100. package/dist/quicktype-core/language/Kotlin.d.ts +2 -2
  101. package/dist/quicktype-core/language/Kotlin.js +39 -37
  102. package/dist/quicktype-core/language/Objective-C.d.ts +3 -3
  103. package/dist/quicktype-core/language/Objective-C.js +45 -41
  104. package/dist/quicktype-core/language/Php.d.ts +2 -2
  105. package/dist/quicktype-core/language/Php.js +66 -41
  106. package/dist/quicktype-core/language/Pike.d.ts +1 -1
  107. package/dist/quicktype-core/language/Pike.js +18 -17
  108. package/dist/quicktype-core/language/Python.d.ts +8 -8
  109. package/dist/quicktype-core/language/Python.js +63 -64
  110. package/dist/quicktype-core/language/Rust.d.ts +2 -2
  111. package/dist/quicktype-core/language/Rust.js +21 -19
  112. package/dist/quicktype-core/language/Swift.d.ts +7 -7
  113. package/dist/quicktype-core/language/Swift.js +568 -565
  114. package/dist/quicktype-core/language/TypeScriptFlow.d.ts +7 -7
  115. package/dist/quicktype-core/language/TypeScriptFlow.js +28 -26
  116. package/dist/quicktype-core/language/ruby/index.d.ts +4 -4
  117. package/dist/quicktype-core/language/ruby/index.js +49 -24
  118. package/dist/quicktype-core/language/ruby/keywords.js +1 -0
  119. package/dist/quicktype-core/rewrites/CombineClasses.js +9 -8
  120. package/dist/quicktype-core/rewrites/ExpandStrings.d.ts +1 -1
  121. package/dist/quicktype-core/rewrites/ExpandStrings.js +18 -17
  122. package/dist/quicktype-core/rewrites/FlattenStrings.js +7 -6
  123. package/dist/quicktype-core/rewrites/FlattenUnions.js +9 -8
  124. package/dist/quicktype-core/rewrites/InferMaps.js +11 -10
  125. package/dist/quicktype-core/rewrites/ReplaceObjectType.js +8 -7
  126. package/dist/quicktype-core/rewrites/ResolveIntersections.js +68 -67
  127. package/dist/quicktype-core/support/Acronyms.js +3 -1
  128. package/dist/quicktype-core/support/Chance.js +10 -0
  129. package/dist/quicktype-core/support/Converters.js +1 -0
  130. package/dist/quicktype-core/support/Strings.d.ts +4 -4
  131. package/dist/quicktype-core/support/Strings.js +17 -16
  132. package/dist/quicktype-core/support/Support.d.ts +1 -1
  133. package/dist/quicktype-core/support/Support.js +30 -6
  134. package/dist/quicktype-graphql-input/GraphQLSchema.d.ts +4 -4
  135. package/dist/quicktype-graphql-input/GraphQLSchema.js +1 -0
  136. package/dist/quicktype-graphql-input/index.d.ts +1 -1
  137. package/dist/quicktype-graphql-input/index.js +229 -212
  138. package/dist/quicktype-typescript-input/index.js +30 -5
  139. package/package.json +25 -19
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SwiftRenderer = exports.SwiftTargetLanguage = exports.swiftOptions = void 0;
3
4
  const collection_utils_1 = require("collection-utils");
4
5
  const Support_1 = require("../support/Support");
5
6
  const TargetLanguage_1 = require("../TargetLanguage");
@@ -26,7 +27,7 @@ exports.swiftOptions = {
26
27
  ["class", true]
27
28
  ]),
28
29
  mutableProperties: new RendererOptions_1.BooleanOption("mutable-properties", "Use var instead of let for object properties", false),
29
- acronymStyle: Acronyms_1.acronymOption(Acronyms_1.AcronymStyleOptions.Pascal),
30
+ acronymStyle: (0, Acronyms_1.acronymOption)(Acronyms_1.AcronymStyleOptions.Pascal),
30
31
  dense: new RendererOptions_1.EnumOption("density", "Code density", [
31
32
  ["dense", true],
32
33
  ["normal", false]
@@ -98,7 +99,7 @@ class SwiftTargetLanguage extends TargetLanguage_1.TargetLanguage {
98
99
  return true;
99
100
  }
100
101
  makeRenderer(renderContext, untypedOptionValues) {
101
- return new SwiftRenderer(this, renderContext, RendererOptions_1.getOptionValues(exports.swiftOptions, untypedOptionValues));
102
+ return new SwiftRenderer(this, renderContext, (0, RendererOptions_1.getOptionValues)(exports.swiftOptions, untypedOptionValues));
102
103
  }
103
104
  get dateTimeRecognizer() {
104
105
  return new SwiftDateTimeRecognizer();
@@ -207,485 +208,193 @@ const keywords = [
207
208
  "jsonData"
208
209
  ];
209
210
  function isPartCharacter(codePoint) {
210
- return Strings_1.isLetterOrUnderscore(codePoint) || Strings_1.isNumeric(codePoint);
211
+ return (0, Strings_1.isLetterOrUnderscore)(codePoint) || (0, Strings_1.isNumeric)(codePoint);
211
212
  }
212
213
  function isStartCharacter(codePoint) {
213
- return isPartCharacter(codePoint) && !Strings_1.isDigit(codePoint);
214
+ return isPartCharacter(codePoint) && !(0, Strings_1.isDigit)(codePoint);
214
215
  }
215
- const legalizeName = Strings_1.legalizeCharacters(isPartCharacter);
216
+ const legalizeName = (0, Strings_1.legalizeCharacters)(isPartCharacter);
216
217
  function swiftNameStyle(prefix, isUpper, original, acronymsStyle = Strings_1.allUpperWordStyle) {
217
- const words = Strings_1.splitIntoWords(original);
218
- const combined = Strings_1.combineWords(words, legalizeName, isUpper ? Strings_1.firstUpperWordStyle : Strings_1.allLowerWordStyle, Strings_1.firstUpperWordStyle, isUpper ? Strings_1.allUpperWordStyle : Strings_1.allLowerWordStyle, acronymsStyle, "", isStartCharacter);
219
- return Strings_1.addPrefixIfNecessary(prefix, combined);
218
+ const words = (0, Strings_1.splitIntoWords)(original);
219
+ const combined = (0, Strings_1.combineWords)(words, legalizeName, isUpper ? Strings_1.firstUpperWordStyle : Strings_1.allLowerWordStyle, Strings_1.firstUpperWordStyle, isUpper ? Strings_1.allUpperWordStyle : Strings_1.allLowerWordStyle, acronymsStyle, "", isStartCharacter);
220
+ return (0, Strings_1.addPrefixIfNecessary)(prefix, combined);
220
221
  }
221
222
  function unicodeEscape(codePoint) {
222
- return "\\u{" + Strings_1.intToHex(codePoint, 0) + "}";
223
+ return "\\u{" + (0, Strings_1.intToHex)(codePoint, 0) + "}";
223
224
  }
224
- const stringEscape = Strings_1.utf32ConcatMap(Strings_1.escapeNonPrintableMapper(Strings_1.isPrintable, unicodeEscape));
225
+ const stringEscape = (0, Strings_1.utf32ConcatMap)((0, Strings_1.escapeNonPrintableMapper)(Strings_1.isPrintable, unicodeEscape));
225
226
  class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
227
+ _options;
228
+ _currentFilename;
229
+ _needAny = false;
230
+ _needNull = false;
226
231
  constructor(targetLanguage, renderContext, _options) {
227
232
  super(targetLanguage, renderContext);
228
233
  this._options = _options;
229
- this._needAny = false;
230
- this._needNull = false;
231
- this.emitSupportFunctions4 = () => {
232
- this.startFile("JSONSchemaSupport");
233
- this.emitLineOnce("import Foundation");
234
- this.forEachTopLevel("leading", (t, name) => this.renderTopLevelAlias(t, name), t => this.namedTypeToNameForTopLevel(t) === undefined);
235
- if (this._options.convenienceInitializers) {
236
- this.ensureBlankLine();
237
- this.forEachTopLevel("leading-and-interposing", (t, name) => this.emitTopLevelMapAndArrayConvenienceInitializerExtensions(t, name));
238
- }
239
- if ((!this._options.justTypes && this._options.convenienceInitializers) || this._options.alamofire) {
240
- this.ensureBlankLine();
241
- this.emitMark("Helper functions for creating encoders and decoders", true);
242
- this.ensureBlankLine();
243
- this.emitNewEncoderDecoder();
244
- }
245
- if (this._options.alamofire) {
246
- this.ensureBlankLine();
247
- this.emitMark("Alamofire response handlers", true);
248
- this.ensureBlankLine();
249
- this.emitAlamofireExtension();
250
- }
251
- // This assumes that this method is called after declarations
252
- // are emitted.
253
- if (this._needAny || this._needNull) {
254
- this.ensureBlankLine();
255
- this.emitMark("Encode/decode helpers", true);
256
- this.ensureBlankLine();
257
- if (this._options.objcSupport) {
258
- this.emitLine(this.objcMembersDeclaration, this.accessLevel, "class JSONNull: NSObject, Codable {");
259
- }
260
- else {
261
- this.emitLine(this.accessLevel, "class JSONNull: Codable, Hashable {");
262
- }
263
- this.ensureBlankLine();
264
- this.emitMultiline(` public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
265
- return true
266
- }`);
267
- if (this._options.objcSupport === false) {
268
- this.ensureBlankLine();
269
- this.emitMultiline(` public var hashValue: Int {
270
- return 0
271
- }`);
272
- if (this._options.swift5Support) {
273
- this.ensureBlankLine();
274
- this.emitMultiline(` public func hash(into hasher: inout Hasher) {
275
- // No-op
276
- }`);
277
- }
278
- }
279
- this.ensureBlankLine();
280
- if (this._options.objcSupport) {
281
- this.emitItem(" override ");
282
- }
283
- else {
284
- this.emitItem(" ");
285
- }
286
- this.emitMultiline(`public init() {}
287
-
288
- public required init(from decoder: Decoder) throws {
289
- let container = try decoder.singleValueContainer()
290
- if !container.decodeNil() {
291
- throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
234
+ }
235
+ forbiddenNamesForGlobalNamespace() {
236
+ if (this._options.alamofire) {
237
+ return ["DataRequest", ...keywords];
292
238
  }
239
+ return keywords;
293
240
  }
294
-
295
- public func encode(to encoder: Encoder) throws {
296
- var container = encoder.singleValueContainer()
297
- try container.encodeNil()
241
+ forbiddenForObjectProperties(_c, _classNamed) {
242
+ return { names: ["fromURL", "json"], includeGlobalForbidden: true };
298
243
  }
299
- }`);
300
- }
301
- if (this._needAny) {
302
- this.ensureBlankLine();
303
- this.emitMultiline(`class JSONCodingKey: CodingKey {
304
- let key: String
305
-
306
- required init?(intValue: Int) {
307
- return nil
244
+ forbiddenForEnumCases(_e, _enumName) {
245
+ return { names: [], includeGlobalForbidden: true };
308
246
  }
309
-
310
- required init?(stringValue: String) {
311
- key = stringValue
247
+ forbiddenForUnionMembers(_u, _unionName) {
248
+ return { names: [], includeGlobalForbidden: true };
312
249
  }
313
-
314
- var intValue: Int? {
315
- return nil
250
+ makeNamedTypeNamer() {
251
+ return (0, Naming_1.funPrefixNamer)("upper", s => swiftNameStyle(this._options.namedTypePrefix, true, s, (0, Acronyms_1.acronymStyle)(this._options.acronymStyle)));
316
252
  }
317
-
318
- var stringValue: String {
319
- return key
253
+ namerForObjectProperty() {
254
+ return this.lowerNamingFunction;
320
255
  }
321
- }`);
322
- this.ensureBlankLine();
323
- if (this._options.objcSupport) {
324
- this.emitLine(this.objcMembersDeclaration, this.accessLevel, "class JSONAny: NSObject, Codable {");
325
- }
326
- else {
327
- this.emitLine(this.accessLevel, "class JSONAny: Codable {");
328
- }
329
- this.ensureBlankLine();
330
- this.emitMultiline(` ${this.accessLevel}let value: Any
331
-
332
- static func decodingError(forCodingPath codingPath: [CodingKey]) -> DecodingError {
333
- let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode JSONAny")
334
- return DecodingError.typeMismatch(JSONAny.self, context)
256
+ makeUnionMemberNamer() {
257
+ return this.lowerNamingFunction;
335
258
  }
336
-
337
- static func encodingError(forValue value: Any, codingPath: [CodingKey]) -> EncodingError {
338
- let context = EncodingError.Context(codingPath: codingPath, debugDescription: "Cannot encode JSONAny")
339
- return EncodingError.invalidValue(value, context)
259
+ makeEnumCaseNamer() {
260
+ return this.lowerNamingFunction;
340
261
  }
341
-
342
- static func decode(from container: SingleValueDecodingContainer) throws -> Any {
343
- if let value = try? container.decode(Bool.self) {
344
- return value
345
- }
346
- if let value = try? container.decode(Int64.self) {
347
- return value
348
- }
349
- if let value = try? container.decode(Double.self) {
350
- return value
351
- }
352
- if let value = try? container.decode(String.self) {
353
- return value
354
- }
355
- if container.decodeNil() {
356
- return JSONNull()
357
- }
358
- throw decodingError(forCodingPath: container.codingPath)
262
+ isImplicitCycleBreaker(t) {
263
+ const kind = t.kind;
264
+ return kind === "array" || kind === "map";
359
265
  }
360
-
361
- static func decode(from container: inout UnkeyedDecodingContainer) throws -> Any {
362
- if let value = try? container.decode(Bool.self) {
363
- return value
364
- }
365
- if let value = try? container.decode(Int64.self) {
366
- return value
367
- }
368
- if let value = try? container.decode(Double.self) {
369
- return value
266
+ emitDescriptionBlock(lines) {
267
+ this.emitCommentLines(lines, "/// ");
268
+ }
269
+ emitBlock(line, f) {
270
+ this.emitLine(line, " {");
271
+ this.indent(f);
272
+ this.emitLine("}");
273
+ }
274
+ emitBlockWithAccess(line, f) {
275
+ this.emitBlock([this.accessLevel, line], f);
276
+ }
277
+ justTypesCase(justTypes, notJustTypes) {
278
+ if (this._options.justTypes)
279
+ return justTypes;
280
+ else
281
+ return notJustTypes;
282
+ }
283
+ get lowerNamingFunction() {
284
+ return (0, Naming_1.funPrefixNamer)("lower", s => swiftNameStyle("", false, s, (0, Acronyms_1.acronymStyle)(this._options.acronymStyle)));
285
+ }
286
+ swiftPropertyType(p) {
287
+ if (p.isOptional || (this._options.optionalEnums && p.type.kind === "enum")) {
288
+ return [this.swiftType(p.type, true, true), "?"];
370
289
  }
371
- if let value = try? container.decode(String.self) {
372
- return value
290
+ else {
291
+ return this.swiftType(p.type, true);
373
292
  }
374
- if let value = try? container.decodeNil() {
375
- if value {
376
- return JSONNull()
293
+ }
294
+ swiftType(t, withIssues = false, noOptional = false) {
295
+ const optional = noOptional ? "" : "?";
296
+ return (0, TypeUtils_1.matchType)(t, _anyType => {
297
+ this._needAny = true;
298
+ return (0, Source_1.maybeAnnotated)(withIssues, Annotation_1.anyTypeIssueAnnotation, this.justTypesCase(["Any", optional], "JSONAny"));
299
+ }, _nullType => {
300
+ this._needNull = true;
301
+ return (0, Source_1.maybeAnnotated)(withIssues, Annotation_1.nullTypeIssueAnnotation, this.justTypesCase("NSNull", ["JSONNull", optional]));
302
+ }, _boolType => "Bool", _integerType => "Int", _doubleType => "Double", _stringType => "String", arrayType => ["[", this.swiftType(arrayType.items, withIssues), "]"], classType => this.nameForNamedType(classType), mapType => ["[String: ", this.swiftType(mapType.values, withIssues), "]"], enumType => this.nameForNamedType(enumType), unionType => {
303
+ const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
304
+ if (nullable !== null)
305
+ return [this.swiftType(nullable, withIssues), optional];
306
+ return this.nameForNamedType(unionType);
307
+ }, transformedStringType => {
308
+ if (transformedStringType.kind === "date-time") {
309
+ return "Date";
377
310
  }
311
+ else {
312
+ return (0, Support_2.panic)(`Transformed string type ${transformedStringType.kind} not supported`);
313
+ }
314
+ });
315
+ }
316
+ proposedUnionMemberNameForTypeKind(kind) {
317
+ if (kind === "enum") {
318
+ return "enumeration";
378
319
  }
379
- if var container = try? container.nestedUnkeyedContainer() {
380
- return try decodeArray(from: &container)
381
- }
382
- if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self) {
383
- return try decodeDictionary(from: &container)
320
+ if (kind === "union") {
321
+ return "one_of";
384
322
  }
385
- throw decodingError(forCodingPath: container.codingPath)
323
+ return null;
386
324
  }
387
-
388
- static func decode(from container: inout KeyedDecodingContainer<JSONCodingKey>, forKey key: JSONCodingKey) throws -> Any {
389
- if let value = try? container.decode(Bool.self, forKey: key) {
390
- return value
325
+ renderSingleFileHeaderComments() {
326
+ this.emitLineOnce("// This file was generated from JSON Schema using quicktype, do not modify it directly.");
327
+ this.emitLineOnce("// To parse the JSON, add this file to your project and do:");
328
+ this.emitLineOnce("//");
329
+ this.forEachTopLevel("none", (t, topLevelName) => {
330
+ if (this._options.convenienceInitializers && !(t instanceof Type_1.EnumType)) {
331
+ this.emitLineOnce("// let ", (0, Source_1.modifySource)(Strings_1.camelCase, topLevelName), " = try ", topLevelName, "(json)");
332
+ }
333
+ else {
334
+ this.emitLineOnce("// let ", (0, Source_1.modifySource)(Strings_1.camelCase, topLevelName), " = ", "try? JSONDecoder().decode(", topLevelName, ".self, from: jsonData)");
335
+ }
336
+ });
337
+ }
338
+ renderHeader(type, name) {
339
+ if (this.leadingComments !== undefined) {
340
+ this.emitCommentLines(this.leadingComments);
391
341
  }
392
- if let value = try? container.decode(Int64.self, forKey: key) {
393
- return value
342
+ else if (!this._options.justTypes) {
343
+ if (this._options.multiFileOutput) {
344
+ this.emitLineOnce("// This file was generated from JSON Schema using quicktype, do not modify it directly.");
345
+ this.emitLineOnce("// To parse the JSON, add this file to your project and do:");
346
+ this.emitLineOnce("//");
347
+ if (this._options.convenienceInitializers && !(type instanceof Type_1.EnumType)) {
348
+ this.emitLine("// let ", (0, Source_1.modifySource)(Strings_1.camelCase, name), " = try ", name, "(json)");
349
+ }
350
+ else {
351
+ this.emitLine("// let ", (0, Source_1.modifySource)(Strings_1.camelCase, name), " = ", "try? newJSONDecoder().decode(", name, ".self, from: jsonData)");
352
+ }
353
+ }
354
+ if (this._options.alamofire) {
355
+ this.emitLine("//");
356
+ this.emitLine("// To parse values from Alamofire responses:");
357
+ this.emitLine("//");
358
+ this.emitLine("// Alamofire.request(url).response", name, " { response in");
359
+ this.emitLine("// if let ", (0, Source_1.modifySource)(Strings_1.camelCase, name), " = response.result.value {");
360
+ this.emitLine("// ...");
361
+ this.emitLine("// }");
362
+ this.emitLine("// }");
363
+ }
364
+ if (this._options.protocol.hashable || this._options.protocol.equatable) {
365
+ this.emitLine("//");
366
+ this.emitLine("// Hashable or Equatable:");
367
+ this.emitLine("// The compiler will not be able to synthesize the implementation of Hashable or Equatable");
368
+ this.emitLine("// for types that require the use of JSONAny, nor will the implementation of Hashable be");
369
+ this.emitLine("// synthesized for types that have collections (such as arrays or dictionaries).");
370
+ }
394
371
  }
395
- if let value = try? container.decode(Double.self, forKey: key) {
396
- return value
372
+ this.ensureBlankLine();
373
+ this.emitLineOnce("import Foundation");
374
+ if (!this._options.justTypes && this._options.alamofire) {
375
+ this.emitLineOnce("import Alamofire");
397
376
  }
398
- if let value = try? container.decode(String.self, forKey: key) {
399
- return value
377
+ this.ensureBlankLine();
378
+ }
379
+ renderTopLevelAlias(t, name) {
380
+ this.emitLine(this.accessLevel, "typealias ", name, " = ", this.swiftType(t, true));
381
+ }
382
+ getProtocolsArray(_t, isClass) {
383
+ const protocols = [];
384
+ // [Michael Fey (@MrRooni), 2019-4-24] Technically NSObject isn't a "protocol" in this instance, but this felt like the best place to slot in this superclass declaration.
385
+ if (isClass && this._options.objcSupport) {
386
+ protocols.push("NSObject");
400
387
  }
401
- if let value = try? container.decodeNil(forKey: key) {
402
- if value {
403
- return JSONNull()
404
- }
388
+ if (!this._options.justTypes) {
389
+ protocols.push("Codable");
405
390
  }
406
- if var container = try? container.nestedUnkeyedContainer(forKey: key) {
407
- return try decodeArray(from: &container)
391
+ if (this._options.protocol.hashable) {
392
+ protocols.push("Hashable");
408
393
  }
409
- if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key) {
410
- return try decodeDictionary(from: &container)
394
+ if (this._options.protocol.equatable) {
395
+ protocols.push("Equatable");
411
396
  }
412
- throw decodingError(forCodingPath: container.codingPath)
413
- }
414
-
415
- static func decodeArray(from container: inout UnkeyedDecodingContainer) throws -> [Any] {
416
- var arr: [Any] = []
417
- while !container.isAtEnd {
418
- let value = try decode(from: &container)
419
- arr.append(value)
420
- }
421
- return arr
422
- }
423
-
424
- static func decodeDictionary(from container: inout KeyedDecodingContainer<JSONCodingKey>) throws -> [String: Any] {
425
- var dict = [String: Any]()
426
- for key in container.allKeys {
427
- let value = try decode(from: &container, forKey: key)
428
- dict[key.stringValue] = value
429
- }
430
- return dict
431
- }
432
-
433
- static func encode(to container: inout UnkeyedEncodingContainer, array: [Any]) throws {
434
- for value in array {
435
- if let value = value as? Bool {
436
- try container.encode(value)
437
- } else if let value = value as? Int64 {
438
- try container.encode(value)
439
- } else if let value = value as? Double {
440
- try container.encode(value)
441
- } else if let value = value as? String {
442
- try container.encode(value)
443
- } else if value is JSONNull {
444
- try container.encodeNil()
445
- } else if let value = value as? [Any] {
446
- var container = container.nestedUnkeyedContainer()
447
- try encode(to: &container, array: value)
448
- } else if let value = value as? [String: Any] {
449
- var container = container.nestedContainer(keyedBy: JSONCodingKey.self)
450
- try encode(to: &container, dictionary: value)
451
- } else {
452
- throw encodingError(forValue: value, codingPath: container.codingPath)
453
- }
454
- }
455
- }
456
-
457
- static func encode(to container: inout KeyedEncodingContainer<JSONCodingKey>, dictionary: [String: Any]) throws {
458
- for (key, value) in dictionary {
459
- let key = JSONCodingKey(stringValue: key)!
460
- if let value = value as? Bool {
461
- try container.encode(value, forKey: key)
462
- } else if let value = value as? Int64 {
463
- try container.encode(value, forKey: key)
464
- } else if let value = value as? Double {
465
- try container.encode(value, forKey: key)
466
- } else if let value = value as? String {
467
- try container.encode(value, forKey: key)
468
- } else if value is JSONNull {
469
- try container.encodeNil(forKey: key)
470
- } else if let value = value as? [Any] {
471
- var container = container.nestedUnkeyedContainer(forKey: key)
472
- try encode(to: &container, array: value)
473
- } else if let value = value as? [String: Any] {
474
- var container = container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key)
475
- try encode(to: &container, dictionary: value)
476
- } else {
477
- throw encodingError(forValue: value, codingPath: container.codingPath)
478
- }
479
- }
480
- }
481
-
482
- static func encode(to container: inout SingleValueEncodingContainer, value: Any) throws {
483
- if let value = value as? Bool {
484
- try container.encode(value)
485
- } else if let value = value as? Int64 {
486
- try container.encode(value)
487
- } else if let value = value as? Double {
488
- try container.encode(value)
489
- } else if let value = value as? String {
490
- try container.encode(value)
491
- } else if value is JSONNull {
492
- try container.encodeNil()
493
- } else {
494
- throw encodingError(forValue: value, codingPath: container.codingPath)
495
- }
496
- }
497
-
498
- public required init(from decoder: Decoder) throws {
499
- if var arrayContainer = try? decoder.unkeyedContainer() {
500
- self.value = try JSONAny.decodeArray(from: &arrayContainer)
501
- } else if var container = try? decoder.container(keyedBy: JSONCodingKey.self) {
502
- self.value = try JSONAny.decodeDictionary(from: &container)
503
- } else {
504
- let container = try decoder.singleValueContainer()
505
- self.value = try JSONAny.decode(from: container)
506
- }
507
- }
508
-
509
- public func encode(to encoder: Encoder) throws {
510
- if let arr = self.value as? [Any] {
511
- var container = encoder.unkeyedContainer()
512
- try JSONAny.encode(to: &container, array: arr)
513
- } else if let dict = self.value as? [String: Any] {
514
- var container = encoder.container(keyedBy: JSONCodingKey.self)
515
- try JSONAny.encode(to: &container, dictionary: dict)
516
- } else {
517
- var container = encoder.singleValueContainer()
518
- try JSONAny.encode(to: &container, value: self.value)
519
- }
520
- }
521
- }`);
522
- }
523
- this.endFile();
524
- };
525
- }
526
- forbiddenNamesForGlobalNamespace() {
527
- if (this._options.alamofire) {
528
- return ["DataRequest", ...keywords];
529
- }
530
- return keywords;
531
- }
532
- forbiddenForObjectProperties(_c, _classNamed) {
533
- return { names: ["fromURL", "json"], includeGlobalForbidden: true };
534
- }
535
- forbiddenForEnumCases(_e, _enumName) {
536
- return { names: [], includeGlobalForbidden: true };
537
- }
538
- forbiddenForUnionMembers(_u, _unionName) {
539
- return { names: [], includeGlobalForbidden: true };
540
- }
541
- makeNamedTypeNamer() {
542
- return Naming_1.funPrefixNamer("upper", s => swiftNameStyle(this._options.namedTypePrefix, true, s, Acronyms_1.acronymStyle(this._options.acronymStyle)));
543
- }
544
- namerForObjectProperty() {
545
- return this.lowerNamingFunction;
546
- }
547
- makeUnionMemberNamer() {
548
- return this.lowerNamingFunction;
549
- }
550
- makeEnumCaseNamer() {
551
- return this.lowerNamingFunction;
552
- }
553
- isImplicitCycleBreaker(t) {
554
- const kind = t.kind;
555
- return kind === "array" || kind === "map";
556
- }
557
- emitDescriptionBlock(lines) {
558
- this.emitCommentLines(lines, "/// ");
559
- }
560
- emitBlock(line, f) {
561
- this.emitLine(line, " {");
562
- this.indent(f);
563
- this.emitLine("}");
564
- }
565
- emitBlockWithAccess(line, f) {
566
- this.emitBlock([this.accessLevel, line], f);
567
- }
568
- justTypesCase(justTypes, notJustTypes) {
569
- if (this._options.justTypes)
570
- return justTypes;
571
- else
572
- return notJustTypes;
573
- }
574
- get lowerNamingFunction() {
575
- return Naming_1.funPrefixNamer("lower", s => swiftNameStyle("", false, s, Acronyms_1.acronymStyle(this._options.acronymStyle)));
576
- }
577
- swiftPropertyType(p) {
578
- if (p.isOptional || (this._options.optionalEnums && p.type.kind === "enum")) {
579
- return [this.swiftType(p.type, true, true), "?"];
580
- }
581
- else {
582
- return this.swiftType(p.type, true);
583
- }
584
- }
585
- swiftType(t, withIssues = false, noOptional = false) {
586
- const optional = noOptional ? "" : "?";
587
- return TypeUtils_1.matchType(t, _anyType => {
588
- this._needAny = true;
589
- return Source_1.maybeAnnotated(withIssues, Annotation_1.anyTypeIssueAnnotation, this.justTypesCase(["Any", optional], "JSONAny"));
590
- }, _nullType => {
591
- this._needNull = true;
592
- return Source_1.maybeAnnotated(withIssues, Annotation_1.nullTypeIssueAnnotation, this.justTypesCase("NSNull", ["JSONNull", optional]));
593
- }, _boolType => "Bool", _integerType => "Int", _doubleType => "Double", _stringType => "String", arrayType => ["[", this.swiftType(arrayType.items, withIssues), "]"], classType => this.nameForNamedType(classType), mapType => ["[String: ", this.swiftType(mapType.values, withIssues), "]"], enumType => this.nameForNamedType(enumType), unionType => {
594
- const nullable = TypeUtils_1.nullableFromUnion(unionType);
595
- if (nullable !== null)
596
- return [this.swiftType(nullable, withIssues), optional];
597
- return this.nameForNamedType(unionType);
598
- }, transformedStringType => {
599
- if (transformedStringType.kind === "date-time") {
600
- return "Date";
601
- }
602
- else {
603
- return Support_2.panic(`Transformed string type ${transformedStringType.kind} not supported`);
604
- }
605
- });
606
- }
607
- proposedUnionMemberNameForTypeKind(kind) {
608
- if (kind === "enum") {
609
- return "enumeration";
610
- }
611
- if (kind === "union") {
612
- return "one_of";
613
- }
614
- return null;
615
- }
616
- renderSingleFileHeaderComments() {
617
- this.emitLineOnce("// This file was generated from JSON Schema using quicktype, do not modify it directly.");
618
- this.emitLineOnce("// To parse the JSON, add this file to your project and do:");
619
- this.emitLineOnce("//");
620
- this.forEachTopLevel("none", (t, topLevelName) => {
621
- if (this._options.convenienceInitializers && !(t instanceof Type_1.EnumType)) {
622
- this.emitLineOnce("// let ", Source_1.modifySource(Strings_1.camelCase, topLevelName), " = try ", topLevelName, "(json)");
623
- }
624
- else {
625
- this.emitLineOnce("// let ", Source_1.modifySource(Strings_1.camelCase, topLevelName), " = ", "try? JSONDecoder().decode(", topLevelName, ".self, from: jsonData)");
626
- }
627
- });
628
- }
629
- renderHeader(type, name) {
630
- if (this.leadingComments !== undefined) {
631
- this.emitCommentLines(this.leadingComments);
632
- }
633
- else if (!this._options.justTypes) {
634
- if (this._options.multiFileOutput) {
635
- this.emitLineOnce("// This file was generated from JSON Schema using quicktype, do not modify it directly.");
636
- this.emitLineOnce("// To parse the JSON, add this file to your project and do:");
637
- this.emitLineOnce("//");
638
- if (this._options.convenienceInitializers && !(type instanceof Type_1.EnumType)) {
639
- this.emitLine("// let ", Source_1.modifySource(Strings_1.camelCase, name), " = try ", name, "(json)");
640
- }
641
- else {
642
- this.emitLine("// let ", Source_1.modifySource(Strings_1.camelCase, name), " = ", "try? newJSONDecoder().decode(", name, ".self, from: jsonData)");
643
- }
644
- }
645
- if (this._options.alamofire) {
646
- this.emitLine("//");
647
- this.emitLine("// To parse values from Alamofire responses:");
648
- this.emitLine("//");
649
- this.emitLine("// Alamofire.request(url).response", name, " { response in");
650
- this.emitLine("// if let ", Source_1.modifySource(Strings_1.camelCase, name), " = response.result.value {");
651
- this.emitLine("// ...");
652
- this.emitLine("// }");
653
- this.emitLine("// }");
654
- }
655
- if (this._options.protocol.hashable || this._options.protocol.equatable) {
656
- this.emitLine("//");
657
- this.emitLine("// Hashable or Equatable:");
658
- this.emitLine("// The compiler will not be able to synthesize the implementation of Hashable or Equatable");
659
- this.emitLine("// for types that require the use of JSONAny, nor will the implementation of Hashable be");
660
- this.emitLine("// synthesized for types that have collections (such as arrays or dictionaries).");
661
- }
662
- }
663
- this.ensureBlankLine();
664
- this.emitLineOnce("import Foundation");
665
- if (!this._options.justTypes && this._options.alamofire) {
666
- this.emitLineOnce("import Alamofire");
667
- }
668
- this.ensureBlankLine();
669
- }
670
- renderTopLevelAlias(t, name) {
671
- this.emitLine(this.accessLevel, "typealias ", name, " = ", this.swiftType(t, true));
672
- }
673
- getProtocolsArray(_t, isClass) {
674
- const protocols = [];
675
- // [Michael Fey (@MrRooni), 2019-4-24] Technically NSObject isn't a "protocol" in this instance, but this felt like the best place to slot in this superclass declaration.
676
- if (isClass && this._options.objcSupport) {
677
- protocols.push("NSObject");
678
- }
679
- if (!this._options.justTypes) {
680
- protocols.push("Codable");
681
- }
682
- if (this._options.protocol.hashable) {
683
- protocols.push("Hashable");
684
- }
685
- if (this._options.protocol.equatable) {
686
- protocols.push("Equatable");
687
- }
688
- return protocols;
397
+ return protocols;
689
398
  }
690
399
  getProtocolString(_t, isClass) {
691
400
  const protocols = this.getProtocolsArray(_t, isClass);
@@ -730,7 +439,7 @@ class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
730
439
  if (this._options.multiFileOutput === false) {
731
440
  return;
732
441
  }
733
- Support_1.assert(this._currentFilename === undefined, "Previous file wasn't finished: " + this._currentFilename);
442
+ (0, Support_1.assert)(this._currentFilename === undefined, "Previous file wasn't finished: " + this._currentFilename);
734
443
  // FIXME: The filenames should actually be Sourcelikes, too
735
444
  this._currentFilename = `${this.sourcelikeToString(basename)}.swift`;
736
445
  this.initializeEmitContextForFilename(this._currentFilename);
@@ -740,7 +449,7 @@ class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
740
449
  if (this._options.multiFileOutput === false) {
741
450
  return;
742
451
  }
743
- this.finishFile(Support_1.defined(this._currentFilename));
452
+ this.finishFile((0, Support_1.defined)(this._currentFilename));
744
453
  this._currentFilename = undefined;
745
454
  }
746
455
  propertyLinesDefinition(name, parameter) {
@@ -834,7 +543,7 @@ class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
834
543
  this.emitLine("case ", name, ' = "', label, '"');
835
544
  }
836
545
  else {
837
- const names = collection_utils_1.arrayIntercalate(", ", group.map(p => p.name));
546
+ const names = (0, collection_utils_1.arrayIntercalate)(", ", group.map(p => p.name));
838
547
  this.emitLine("case ", names);
839
548
  }
840
549
  }
@@ -999,135 +708,429 @@ encoder.dateEncodingStrategy = .formatted(formatter)`);
999
708
  protocols.push("String"); // Not a protocol
1000
709
  protocols.push("Codable");
1001
710
  }
1002
- if (this._options.protocol.hashable) {
1003
- protocols.push("Hashable");
711
+ if (this._options.protocol.hashable) {
712
+ protocols.push("Hashable");
713
+ }
714
+ if (this._options.protocol.equatable) {
715
+ protocols.push("Equatable");
716
+ }
717
+ const protocolString = protocols.length > 0 ? ": " + protocols.join(", ") : "";
718
+ if (this._options.justTypes) {
719
+ this.emitBlockWithAccess(["enum ", enumName, protocolString], () => {
720
+ this.forEachEnumCase(e, "none", name => {
721
+ this.emitLine("case ", name);
722
+ });
723
+ });
724
+ }
725
+ else {
726
+ this.emitBlockWithAccess(["enum ", enumName, protocolString], () => {
727
+ this.forEachEnumCase(e, "none", (name, jsonName) => {
728
+ this.emitLine("case ", name, ' = "', stringEscape(jsonName), '"');
729
+ });
730
+ });
731
+ }
732
+ this.endFile();
733
+ }
734
+ renderUnionDefinition(u, unionName) {
735
+ this.startFile(unionName);
736
+ this.emitLineOnce("import Foundation");
737
+ this.ensureBlankLine();
738
+ function sortBy(t) {
739
+ const kind = t.kind;
740
+ if (kind === "class")
741
+ return kind;
742
+ return "_" + kind;
743
+ }
744
+ const renderUnionCase = (t) => {
745
+ this.emitBlock(["if let x = try? container.decode(", this.swiftType(t), ".self)"], () => {
746
+ this.emitLine("self = .", this.nameForUnionMember(u, t), "(x)");
747
+ this.emitLine("return");
748
+ });
749
+ };
750
+ this.emitDescription(this.descriptionForType(u));
751
+ const indirect = this.isCycleBreakerType(u) ? "indirect " : "";
752
+ const [maybeNull, nonNulls] = (0, TypeUtils_1.removeNullFromUnion)(u, sortBy);
753
+ this.emitBlockWithAccess([indirect, "enum ", unionName, this.getProtocolString(u, false)], () => {
754
+ this.forEachUnionMember(u, nonNulls, "none", null, (name, t) => {
755
+ this.emitLine("case ", name, "(", this.swiftType(t), ")");
756
+ });
757
+ if (maybeNull !== null) {
758
+ this.emitLine("case ", this.nameForUnionMember(u, maybeNull));
759
+ }
760
+ if (!this._options.justTypes) {
761
+ this.ensureBlankLine();
762
+ this.emitBlockWithAccess("init(from decoder: Decoder) throws", () => {
763
+ this.emitLine("let container = try decoder.singleValueContainer()");
764
+ const boolMember = u.findMember("bool");
765
+ if (boolMember !== undefined)
766
+ renderUnionCase(boolMember);
767
+ const integerMember = u.findMember("integer");
768
+ if (integerMember !== undefined)
769
+ renderUnionCase(integerMember);
770
+ for (const t of nonNulls) {
771
+ if (t.kind === "bool" || t.kind === "integer")
772
+ continue;
773
+ renderUnionCase(t);
774
+ }
775
+ if (maybeNull !== null) {
776
+ this.emitBlock("if container.decodeNil()", () => {
777
+ this.emitLine("self = .", this.nameForUnionMember(u, maybeNull));
778
+ this.emitLine("return");
779
+ });
780
+ }
781
+ this.emitDecodingError(unionName);
782
+ });
783
+ this.ensureBlankLine();
784
+ this.emitBlockWithAccess("func encode(to encoder: Encoder) throws", () => {
785
+ this.emitLine("var container = encoder.singleValueContainer()");
786
+ this.emitLine("switch self {");
787
+ this.forEachUnionMember(u, nonNulls, "none", null, (name, _) => {
788
+ this.emitLine("case .", name, "(let x):");
789
+ this.indent(() => this.emitLine("try container.encode(x)"));
790
+ });
791
+ if (maybeNull !== null) {
792
+ this.emitLine("case .", this.nameForUnionMember(u, maybeNull), ":");
793
+ this.indent(() => this.emitLine("try container.encodeNil()"));
794
+ }
795
+ this.emitLine("}");
796
+ });
797
+ }
798
+ });
799
+ this.endFile();
800
+ }
801
+ emitTopLevelMapAndArrayConvenienceInitializerExtensions(t, name) {
802
+ let extensionSource;
803
+ if (t instanceof Type_1.ArrayType) {
804
+ extensionSource = ["Array where Element == ", name, ".Element"];
805
+ }
806
+ else if (t instanceof Type_1.MapType) {
807
+ extensionSource = ["Dictionary where Key == String, Value == ", this.swiftType(t.values)];
808
+ }
809
+ else {
810
+ return;
811
+ }
812
+ this.emitBlockWithAccess(["extension ", extensionSource], () => {
813
+ this.emitBlock(["init(data: Data) throws"], () => {
814
+ this.emitLine("self = try newJSONDecoder().decode(", name, ".self, from: data)");
815
+ });
816
+ this.ensureBlankLine();
817
+ this.emitBlock("init(_ json: String, using encoding: String.Encoding = .utf8) throws", () => {
818
+ this.emitBlock("guard let data = json.data(using: encoding) else", () => {
819
+ this.emitLine(`throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)`);
820
+ });
821
+ this.emitLine("try self.init(data: data)");
822
+ });
823
+ this.ensureBlankLine();
824
+ this.emitBlock(`init(fromURL url: URL) throws`, () => {
825
+ this.emitLine("try self.init(data: try Data(contentsOf: url))");
826
+ });
827
+ this.ensureBlankLine();
828
+ this.emitBlock("func jsonData() throws -> Data", () => {
829
+ this.emitLine("return try newJSONEncoder().encode(self)");
830
+ });
831
+ this.ensureBlankLine();
832
+ this.emitBlock("func jsonString(encoding: String.Encoding = .utf8) throws -> String?", () => {
833
+ this.emitLine("return String(data: try self.jsonData(), encoding: encoding)");
834
+ });
835
+ });
836
+ }
837
+ emitDecodingError(name) {
838
+ this.emitLine("throw DecodingError.typeMismatch(", name, '.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ', name, '"))');
839
+ }
840
+ emitSupportFunctions4 = () => {
841
+ this.startFile("JSONSchemaSupport");
842
+ this.emitLineOnce("import Foundation");
843
+ this.forEachTopLevel("leading", (t, name) => this.renderTopLevelAlias(t, name), t => this.namedTypeToNameForTopLevel(t) === undefined);
844
+ if (this._options.convenienceInitializers) {
845
+ this.ensureBlankLine();
846
+ this.forEachTopLevel("leading-and-interposing", (t, name) => this.emitTopLevelMapAndArrayConvenienceInitializerExtensions(t, name));
847
+ }
848
+ if ((!this._options.justTypes && this._options.convenienceInitializers) || this._options.alamofire) {
849
+ this.ensureBlankLine();
850
+ this.emitMark("Helper functions for creating encoders and decoders", true);
851
+ this.ensureBlankLine();
852
+ this.emitNewEncoderDecoder();
853
+ }
854
+ if (this._options.alamofire) {
855
+ this.ensureBlankLine();
856
+ this.emitMark("Alamofire response handlers", true);
857
+ this.ensureBlankLine();
858
+ this.emitAlamofireExtension();
859
+ }
860
+ // This assumes that this method is called after declarations
861
+ // are emitted.
862
+ if (this._needAny || this._needNull) {
863
+ this.ensureBlankLine();
864
+ this.emitMark("Encode/decode helpers", true);
865
+ this.ensureBlankLine();
866
+ if (this._options.objcSupport) {
867
+ this.emitLine(this.objcMembersDeclaration, this.accessLevel, "class JSONNull: NSObject, Codable {");
868
+ }
869
+ else {
870
+ this.emitLine(this.accessLevel, "class JSONNull: Codable, Hashable {");
871
+ }
872
+ this.ensureBlankLine();
873
+ this.emitMultiline(` public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
874
+ return true
875
+ }`);
876
+ if (this._options.objcSupport === false) {
877
+ this.ensureBlankLine();
878
+ this.emitMultiline(` public var hashValue: Int {
879
+ return 0
880
+ }`);
881
+ if (this._options.swift5Support) {
882
+ this.ensureBlankLine();
883
+ this.emitMultiline(` public func hash(into hasher: inout Hasher) {
884
+ // No-op
885
+ }`);
886
+ }
887
+ }
888
+ this.ensureBlankLine();
889
+ if (this._options.objcSupport) {
890
+ this.emitItem(" override ");
891
+ }
892
+ else {
893
+ this.emitItem(" ");
894
+ }
895
+ this.emitMultiline(`public init() {}
896
+
897
+ public required init(from decoder: Decoder) throws {
898
+ let container = try decoder.singleValueContainer()
899
+ if !container.decodeNil() {
900
+ throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
901
+ }
902
+ }
903
+
904
+ public func encode(to encoder: Encoder) throws {
905
+ var container = encoder.singleValueContainer()
906
+ try container.encodeNil()
907
+ }
908
+ }`);
909
+ }
910
+ if (this._needAny) {
911
+ this.ensureBlankLine();
912
+ this.emitMultiline(`class JSONCodingKey: CodingKey {
913
+ let key: String
914
+
915
+ required init?(intValue: Int) {
916
+ return nil
917
+ }
918
+
919
+ required init?(stringValue: String) {
920
+ key = stringValue
921
+ }
922
+
923
+ var intValue: Int? {
924
+ return nil
925
+ }
926
+
927
+ var stringValue: String {
928
+ return key
929
+ }
930
+ }`);
931
+ this.ensureBlankLine();
932
+ if (this._options.objcSupport) {
933
+ this.emitLine(this.objcMembersDeclaration, this.accessLevel, "class JSONAny: NSObject, Codable {");
934
+ }
935
+ else {
936
+ this.emitLine(this.accessLevel, "class JSONAny: Codable {");
937
+ }
938
+ this.ensureBlankLine();
939
+ this.emitMultiline(` ${this.accessLevel}let value: Any
940
+
941
+ static func decodingError(forCodingPath codingPath: [CodingKey]) -> DecodingError {
942
+ let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode JSONAny")
943
+ return DecodingError.typeMismatch(JSONAny.self, context)
944
+ }
945
+
946
+ static func encodingError(forValue value: Any, codingPath: [CodingKey]) -> EncodingError {
947
+ let context = EncodingError.Context(codingPath: codingPath, debugDescription: "Cannot encode JSONAny")
948
+ return EncodingError.invalidValue(value, context)
949
+ }
950
+
951
+ static func decode(from container: SingleValueDecodingContainer) throws -> Any {
952
+ if let value = try? container.decode(Bool.self) {
953
+ return value
954
+ }
955
+ if let value = try? container.decode(Int64.self) {
956
+ return value
957
+ }
958
+ if let value = try? container.decode(Double.self) {
959
+ return value
960
+ }
961
+ if let value = try? container.decode(String.self) {
962
+ return value
963
+ }
964
+ if container.decodeNil() {
965
+ return JSONNull()
966
+ }
967
+ throw decodingError(forCodingPath: container.codingPath)
968
+ }
969
+
970
+ static func decode(from container: inout UnkeyedDecodingContainer) throws -> Any {
971
+ if let value = try? container.decode(Bool.self) {
972
+ return value
973
+ }
974
+ if let value = try? container.decode(Int64.self) {
975
+ return value
976
+ }
977
+ if let value = try? container.decode(Double.self) {
978
+ return value
1004
979
  }
1005
- if (this._options.protocol.equatable) {
1006
- protocols.push("Equatable");
980
+ if let value = try? container.decode(String.self) {
981
+ return value
1007
982
  }
1008
- const protocolString = protocols.length > 0 ? ": " + protocols.join(", ") : "";
1009
- if (this._options.justTypes) {
1010
- this.emitBlockWithAccess(["enum ", enumName, protocolString], () => {
1011
- this.forEachEnumCase(e, "none", name => {
1012
- this.emitLine("case ", name);
1013
- });
1014
- });
983
+ if let value = try? container.decodeNil() {
984
+ if value {
985
+ return JSONNull()
986
+ }
1015
987
  }
1016
- else {
1017
- this.emitBlockWithAccess(["enum ", enumName, protocolString], () => {
1018
- this.forEachEnumCase(e, "none", (name, jsonName) => {
1019
- this.emitLine("case ", name, ' = "', stringEscape(jsonName), '"');
1020
- });
1021
- });
988
+ if var container = try? container.nestedUnkeyedContainer() {
989
+ return try decodeArray(from: &container)
1022
990
  }
1023
- this.endFile();
991
+ if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self) {
992
+ return try decodeDictionary(from: &container)
993
+ }
994
+ throw decodingError(forCodingPath: container.codingPath)
1024
995
  }
1025
- renderUnionDefinition(u, unionName) {
1026
- this.startFile(unionName);
1027
- this.emitLineOnce("import Foundation");
1028
- this.ensureBlankLine();
1029
- function sortBy(t) {
1030
- const kind = t.kind;
1031
- if (kind === "class")
1032
- return kind;
1033
- return "_" + kind;
996
+
997
+ static func decode(from container: inout KeyedDecodingContainer<JSONCodingKey>, forKey key: JSONCodingKey) throws -> Any {
998
+ if let value = try? container.decode(Bool.self, forKey: key) {
999
+ return value
1034
1000
  }
1035
- const renderUnionCase = (t) => {
1036
- this.emitBlock(["if let x = try? container.decode(", this.swiftType(t), ".self)"], () => {
1037
- this.emitLine("self = .", this.nameForUnionMember(u, t), "(x)");
1038
- this.emitLine("return");
1039
- });
1040
- };
1041
- this.emitDescription(this.descriptionForType(u));
1042
- const indirect = this.isCycleBreakerType(u) ? "indirect " : "";
1043
- const [maybeNull, nonNulls] = TypeUtils_1.removeNullFromUnion(u, sortBy);
1044
- this.emitBlockWithAccess([indirect, "enum ", unionName, this.getProtocolString(u, false)], () => {
1045
- this.forEachUnionMember(u, nonNulls, "none", null, (name, t) => {
1046
- this.emitLine("case ", name, "(", this.swiftType(t), ")");
1047
- });
1048
- if (maybeNull !== null) {
1049
- this.emitLine("case ", this.nameForUnionMember(u, maybeNull));
1001
+ if let value = try? container.decode(Int64.self, forKey: key) {
1002
+ return value
1003
+ }
1004
+ if let value = try? container.decode(Double.self, forKey: key) {
1005
+ return value
1006
+ }
1007
+ if let value = try? container.decode(String.self, forKey: key) {
1008
+ return value
1009
+ }
1010
+ if let value = try? container.decodeNil(forKey: key) {
1011
+ if value {
1012
+ return JSONNull()
1050
1013
  }
1051
- if (!this._options.justTypes) {
1052
- this.ensureBlankLine();
1053
- this.emitBlockWithAccess("init(from decoder: Decoder) throws", () => {
1054
- this.emitLine("let container = try decoder.singleValueContainer()");
1055
- const boolMember = u.findMember("bool");
1056
- if (boolMember !== undefined)
1057
- renderUnionCase(boolMember);
1058
- const integerMember = u.findMember("integer");
1059
- if (integerMember !== undefined)
1060
- renderUnionCase(integerMember);
1061
- for (const t of nonNulls) {
1062
- if (t.kind === "bool" || t.kind === "integer")
1063
- continue;
1064
- renderUnionCase(t);
1065
- }
1066
- if (maybeNull !== null) {
1067
- this.emitBlock("if container.decodeNil()", () => {
1068
- this.emitLine("self = .", this.nameForUnionMember(u, maybeNull));
1069
- this.emitLine("return");
1070
- });
1071
- }
1072
- this.emitDecodingError(unionName);
1073
- });
1074
- this.ensureBlankLine();
1075
- this.emitBlockWithAccess("func encode(to encoder: Encoder) throws", () => {
1076
- this.emitLine("var container = encoder.singleValueContainer()");
1077
- this.emitLine("switch self {");
1078
- this.forEachUnionMember(u, nonNulls, "none", null, (name, _) => {
1079
- this.emitLine("case .", name, "(let x):");
1080
- this.indent(() => this.emitLine("try container.encode(x)"));
1081
- });
1082
- if (maybeNull !== null) {
1083
- this.emitLine("case .", this.nameForUnionMember(u, maybeNull), ":");
1084
- this.indent(() => this.emitLine("try container.encodeNil()"));
1085
- }
1086
- this.emitLine("}");
1087
- });
1014
+ }
1015
+ if var container = try? container.nestedUnkeyedContainer(forKey: key) {
1016
+ return try decodeArray(from: &container)
1017
+ }
1018
+ if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key) {
1019
+ return try decodeDictionary(from: &container)
1020
+ }
1021
+ throw decodingError(forCodingPath: container.codingPath)
1022
+ }
1023
+
1024
+ static func decodeArray(from container: inout UnkeyedDecodingContainer) throws -> [Any] {
1025
+ var arr: [Any] = []
1026
+ while !container.isAtEnd {
1027
+ let value = try decode(from: &container)
1028
+ arr.append(value)
1029
+ }
1030
+ return arr
1031
+ }
1032
+
1033
+ static func decodeDictionary(from container: inout KeyedDecodingContainer<JSONCodingKey>) throws -> [String: Any] {
1034
+ var dict = [String: Any]()
1035
+ for key in container.allKeys {
1036
+ let value = try decode(from: &container, forKey: key)
1037
+ dict[key.stringValue] = value
1038
+ }
1039
+ return dict
1040
+ }
1041
+
1042
+ static func encode(to container: inout UnkeyedEncodingContainer, array: [Any]) throws {
1043
+ for value in array {
1044
+ if let value = value as? Bool {
1045
+ try container.encode(value)
1046
+ } else if let value = value as? Int64 {
1047
+ try container.encode(value)
1048
+ } else if let value = value as? Double {
1049
+ try container.encode(value)
1050
+ } else if let value = value as? String {
1051
+ try container.encode(value)
1052
+ } else if value is JSONNull {
1053
+ try container.encodeNil()
1054
+ } else if let value = value as? [Any] {
1055
+ var container = container.nestedUnkeyedContainer()
1056
+ try encode(to: &container, array: value)
1057
+ } else if let value = value as? [String: Any] {
1058
+ var container = container.nestedContainer(keyedBy: JSONCodingKey.self)
1059
+ try encode(to: &container, dictionary: value)
1060
+ } else {
1061
+ throw encodingError(forValue: value, codingPath: container.codingPath)
1088
1062
  }
1089
- });
1090
- this.endFile();
1063
+ }
1091
1064
  }
1092
- emitTopLevelMapAndArrayConvenienceInitializerExtensions(t, name) {
1093
- let extensionSource;
1094
- if (t instanceof Type_1.ArrayType) {
1095
- extensionSource = ["Array where Element == ", name, ".Element"];
1065
+
1066
+ static func encode(to container: inout KeyedEncodingContainer<JSONCodingKey>, dictionary: [String: Any]) throws {
1067
+ for (key, value) in dictionary {
1068
+ let key = JSONCodingKey(stringValue: key)!
1069
+ if let value = value as? Bool {
1070
+ try container.encode(value, forKey: key)
1071
+ } else if let value = value as? Int64 {
1072
+ try container.encode(value, forKey: key)
1073
+ } else if let value = value as? Double {
1074
+ try container.encode(value, forKey: key)
1075
+ } else if let value = value as? String {
1076
+ try container.encode(value, forKey: key)
1077
+ } else if value is JSONNull {
1078
+ try container.encodeNil(forKey: key)
1079
+ } else if let value = value as? [Any] {
1080
+ var container = container.nestedUnkeyedContainer(forKey: key)
1081
+ try encode(to: &container, array: value)
1082
+ } else if let value = value as? [String: Any] {
1083
+ var container = container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key)
1084
+ try encode(to: &container, dictionary: value)
1085
+ } else {
1086
+ throw encodingError(forValue: value, codingPath: container.codingPath)
1087
+ }
1096
1088
  }
1097
- else if (t instanceof Type_1.MapType) {
1098
- extensionSource = ["Dictionary where Key == String, Value == ", this.swiftType(t.values)];
1089
+ }
1090
+
1091
+ static func encode(to container: inout SingleValueEncodingContainer, value: Any) throws {
1092
+ if let value = value as? Bool {
1093
+ try container.encode(value)
1094
+ } else if let value = value as? Int64 {
1095
+ try container.encode(value)
1096
+ } else if let value = value as? Double {
1097
+ try container.encode(value)
1098
+ } else if let value = value as? String {
1099
+ try container.encode(value)
1100
+ } else if value is JSONNull {
1101
+ try container.encodeNil()
1102
+ } else {
1103
+ throw encodingError(forValue: value, codingPath: container.codingPath)
1099
1104
  }
1100
- else {
1101
- return;
1105
+ }
1106
+
1107
+ public required init(from decoder: Decoder) throws {
1108
+ if var arrayContainer = try? decoder.unkeyedContainer() {
1109
+ self.value = try JSONAny.decodeArray(from: &arrayContainer)
1110
+ } else if var container = try? decoder.container(keyedBy: JSONCodingKey.self) {
1111
+ self.value = try JSONAny.decodeDictionary(from: &container)
1112
+ } else {
1113
+ let container = try decoder.singleValueContainer()
1114
+ self.value = try JSONAny.decode(from: container)
1102
1115
  }
1103
- this.emitBlockWithAccess(["extension ", extensionSource], () => {
1104
- this.emitBlock(["init(data: Data) throws"], () => {
1105
- this.emitLine("self = try newJSONDecoder().decode(", name, ".self, from: data)");
1106
- });
1107
- this.ensureBlankLine();
1108
- this.emitBlock("init(_ json: String, using encoding: String.Encoding = .utf8) throws", () => {
1109
- this.emitBlock("guard let data = json.data(using: encoding) else", () => {
1110
- this.emitLine(`throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)`);
1111
- });
1112
- this.emitLine("try self.init(data: data)");
1113
- });
1114
- this.ensureBlankLine();
1115
- this.emitBlock(`init(fromURL url: URL) throws`, () => {
1116
- this.emitLine("try self.init(data: try Data(contentsOf: url))");
1117
- });
1118
- this.ensureBlankLine();
1119
- this.emitBlock("func jsonData() throws -> Data", () => {
1120
- this.emitLine("return try newJSONEncoder().encode(self)");
1121
- });
1122
- this.ensureBlankLine();
1123
- this.emitBlock("func jsonString(encoding: String.Encoding = .utf8) throws -> String?", () => {
1124
- this.emitLine("return String(data: try self.jsonData(), encoding: encoding)");
1125
- });
1126
- });
1127
1116
  }
1128
- emitDecodingError(name) {
1129
- this.emitLine("throw DecodingError.typeMismatch(", name, '.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ', name, '"))');
1117
+
1118
+ public func encode(to encoder: Encoder) throws {
1119
+ if let arr = self.value as? [Any] {
1120
+ var container = encoder.unkeyedContainer()
1121
+ try JSONAny.encode(to: &container, array: arr)
1122
+ } else if let dict = self.value as? [String: Any] {
1123
+ var container = encoder.container(keyedBy: JSONCodingKey.self)
1124
+ try JSONAny.encode(to: &container, dictionary: dict)
1125
+ } else {
1126
+ var container = encoder.singleValueContainer()
1127
+ try JSONAny.encode(to: &container, value: self.value)
1128
+ }
1130
1129
  }
1130
+ }`);
1131
+ }
1132
+ this.endFile();
1133
+ };
1131
1134
  emitConvenienceMutator(c, className) {
1132
1135
  this.emitLine("func with(");
1133
1136
  this.indent(() => {