1 /** 2 * Authors: Szabo Bogdan <szabobogdan@yahoo.com> 3 * Date: 13 3, 2018 4 * License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. 5 * Copyright: Public Domain 6 */ 7 module openapi.definitions; 8 9 import std.traits; 10 import std.array; 11 import std.algorithm; 12 import std.conv; 13 import std.typecons; 14 import std.stdio; 15 import std.math; 16 17 import vibe.data.json; 18 import vibe.data.serialization : SerializedName = name; 19 20 private string memberToKey(alias member)() pure { 21 static if(member[$-1..$] == "_") { 22 return member[0..$-1]; 23 } else { 24 return member; 25 } 26 } 27 28 /// 29 Type toEnumValue(Type)(string value) { 30 foreach(member; EnumMembers!Type) {{ 31 if((cast(OriginalType!Type) member).to!string == value) { 32 return member; 33 } 34 }} 35 36 throw new Exception("`" ~ value ~ "` is not a member in `" ~ Type.stringof ~ "`"); 37 } 38 39 OriginalType!Type toOriginalEnumValue(Type)(Type value) { 40 return cast(OriginalType!Type) value; 41 } 42 43 mixin template Serialization(T) { 44 45 @trusted: 46 Json[string] extensions; 47 48 /// 49 Json toJson() const { 50 auto dest = Json.emptyObject; 51 52 static if(__traits(hasMember, T, "_ref")) { 53 if(_ref != "") { 54 dest["$ref"] = _ref; 55 return dest; 56 } 57 } 58 59 static foreach (member; __traits(allMembers, T)) 60 static if(member != "extensions" && !isCallable!(__traits(getMember, T, member))) {{ 61 alias Type = typeof(__traits(getMember, this, member)); 62 63 64 auto tmp = __traits(getMember, this, member); 65 66 static if(is(Type == class)) { 67 Json value; 68 69 if(tmp is null) { 70 value = Json.undefined; 71 } else { 72 value = tmp.serializeToJson; 73 } 74 } else static if(!isSomeString!Type && (isArray!Type || isAssociativeArray!Type)) { 75 auto value = tmp.serializeToJson; 76 } else static if(is(Unqual!Type == bool)) { 77 auto value = tmp ? Json(true) : Json.undefined; 78 } else static if(isSomeString!Type || isBuiltinType!Type) { 79 auto value = Json(tmp); 80 } else { 81 auto value = tmp.serializeToJson; 82 } 83 84 alias key = memberToKey!member; 85 86 if(value.type == Json.Type.array && value.length == 0) { 87 value = Json.undefined; 88 } 89 90 if(value.type == Json.Type.object && value.length == 0) { 91 value = Json.undefined; 92 } 93 94 if(value.type == Json.Type..string && value == "") { 95 value = Json.undefined; 96 } 97 98 if(value.type != Json.Type.undefined) { 99 dest[key] = value; 100 } 101 }} 102 103 foreach(string key, Json value; extensions) { 104 dest[key] = value; 105 } 106 107 return dest; 108 } 109 110 /// 111 static T fromJson(Json src) { 112 T value; 113 114 static if(__traits(hasMember, T, "_ref")) { 115 if("$ref" in src) { 116 value._ref = src["$ref"].to!string; 117 return value; 118 } 119 } 120 121 static foreach (member; __traits(allMembers, T)) 122 static if(member != "extensions" && !isCallable!(__traits(getMember, T, member))) {{ 123 alias Type = typeof(__traits(getMember, value, member)); 124 alias key = memberToKey!member; 125 Type tmp; 126 127 if(key in src) { 128 static if(is(Type == enum)) { 129 tmp = src[key].to!string.toEnumValue!Type; 130 } else static if(isSomeString!Type) { 131 tmp = src[key].to!Type; 132 } else static if (isArray!Type) { 133 tmp = src[key].deserializeJson!Type; 134 } else static if(isAssociativeArray!Type) { 135 tmp = src[key].deserializeJson!Type; 136 } else static if(!isSomeString!Type && (isAggregateType!Type || isArray!Type || isAssociativeArray!Type)) { 137 tmp = src[key].deserializeJson!Type; 138 } else { 139 tmp = src[key].to!Type; 140 } 141 142 __traits(getMember, value, member) = tmp; 143 } 144 }} 145 146 value.extensions = src.byKeyValue.filter!(a => a.key.startsWith("x-")).assocArray; 147 148 return value; 149 } 150 } 151 152 /// 153 enum Schemes: string { 154 http = "http", 155 https = "https", 156 ws = "ws", 157 wss = "wss" 158 } 159 160 /// 161 struct OpenApi { 162 /// This string MUST be the semantic version number of the OpenApi Specification 163 /// version that the OpenApi document uses. The openapi field SHOULD be used by 164 /// tooling specifications and clients to interpret the OpenApi document. This 165 /// is not related to the API info.version string 166 string openapi = "3.0.1"; 167 168 /// Provides metadata about the API. The metadata MAY be used by tooling as required 169 Info info; 170 171 /// The available paths and operations for the API 172 Path[string] paths; 173 174 @optional { 175 /// An array of Server Objects, which provide connectivity information to a 176 /// target server. If the servers property is not provided, or is an empty 177 /// array, the default value would be a Server Object with a url value of / 178 Server[] servers; 179 180 /// An element to hold various schemas for the specification 181 Components components; 182 183 /// A declaration of which security mechanisms can be used across the API. 184 /// The list of values includes alternative security requirement objects 185 /// that can be used. Only one of the security requirement objects need 186 /// to be satisfied to authorize a request. Individual operations can 187 /// override this definition 188 SecurityRequirement security; 189 190 /// A list of tags used by the specification with additional metadata. 191 /// The order of the tags can be used to reflect on their order by 192 /// the parsing tools. Not all tags that are used by the Operation 193 /// Object must be declared. The tags that are not declared MAY be organized 194 /// randomly or based on the tools' logic. Each tag name in the list MUST be unique. 195 Tag[] tags; 196 197 /// Additional external documentation. 198 ExternalDocumentation externalDocs; 199 } 200 201 mixin Serialization!OpenApi; 202 } 203 204 /// The object provides metadata about the API. The metadata MAY 205 /// be used by the clients if needed, and MAY be presented in editing 206 /// or documentation generation tools for convenience. 207 struct Info { 208 /// The title of the application. 209 string title; 210 211 /// The version of the OpenApi document (which is distinct from the 212 /// OpenApi Specification version or the API implementation version). 213 @SerializedName("version") string version_; 214 215 @optional { 216 /// A short description of the application. CommonMark syntax MAY be used 217 /// for rich text representation. 218 string description; 219 220 /// A URL to the Terms of Service for the API. MUST be in the format of a URL. 221 string termsOfService; 222 223 /// The contact information for the exposed API. 224 Contact contact; 225 226 /// The license information for the exposed API. 227 License license; 228 } 229 230 mixin Serialization!Info; 231 } 232 233 /// Contact information for the exposed API. 234 struct Contact { 235 @optional { 236 /// The identifying name of the contact person/organization. 237 string name; 238 239 /// The URL pointing to the contact information. MUST be in the format of a URL. 240 string url; 241 242 /// The email address of the contact person/organization. MUST be in the format of an email address. 243 string email; 244 } 245 246 mixin Serialization!Contact; 247 } 248 249 /// License information for the exposed API. 250 struct License { 251 /// The license name used for the API. 252 string name; 253 254 /// A URL to the license used for the API. MUST be in the format of a URL. 255 @optional string url; 256 257 mixin Serialization!License; 258 } 259 260 // An object representing a Server. 261 struct Server { 262 263 /// A URL to the target host. This URL supports Server Variables and MAY 264 /// be relative, to indicate that the host location is relative to the location 265 /// where the OpenApi document is being served. Variable substitutions will be 266 /// made when a variable is named in {brackets}. 267 string url; 268 269 @optional { 270 /// An optional string describing the host designated by the URL. CommonMark syntax 271 /// MAY be used for rich text representation. 272 string description; 273 274 /// A map between a variable name and its value. The value is used for substitution 275 /// in the server's URL template. 276 ServerVariable[string] variables; 277 } 278 279 @safe: 280 /// 281 Json toJson() const { 282 auto dest = Json.emptyObject; 283 284 if(url != "") { 285 dest["url"] = url; 286 } 287 288 if(description != "") { 289 dest["description"] = description; 290 } 291 292 if(variables.length > 0) { 293 dest["variables"] = variables.serializeToJson; 294 } 295 296 return dest; 297 } 298 299 /// 300 static Server fromJson(Json src) { 301 Server server; 302 303 server.url = src["url"].to!string; 304 305 if("description" in src) { 306 server.description = src["description"].to!string; 307 } 308 309 if("variables" in src && src["variables"].length > 0) { 310 server.variables = src["variables"].deserializeJson!(ServerVariable[string]); 311 } 312 313 return server; 314 } 315 } 316 317 /// An object representing a Server Variable for server URL template substitution. 318 struct ServerVariable { 319 320 /// The default value to use for substitution, and to send, if an alternate value is not 321 /// supplied. Unlike the Schema Object's default, this value MUST be provided by the consumer. 322 @SerializedName("default") string default_; 323 324 @optional { 325 /// An enumeration of string values to be used if the substitution options are from a limited set. 326 @SerializedName("enum") string[] enum_; 327 328 /// An optional description for the server variable. CommonMark syntax MAY be used for 329 /// rich text representation. 330 string description; 331 } 332 } 333 334 /// Holds a set of reusable objects for different aspects of the OAS. All objects defined within 335 /// the components object will have no effect on the API unless they are explicitly referenced from 336 /// properties outside the components object. 337 struct Components { 338 339 @optional { 340 ///An object to hold reusable Schema Objects. 341 Schema[string] schemas; 342 343 ///An object to hold reusable Response Objects. 344 Response[string] responses; 345 346 ///An object to hold reusable Parameter Objects. 347 Parameter[string] parameters; 348 349 ///An object to hold reusable Example Objects. 350 Example[string] examples; 351 352 ///An object to hold reusable Request Body Objects. 353 RequestBody[string] requestBodies; 354 355 ///An object to hold reusable Header Objects. 356 Header[string] headers; 357 358 ///An object to hold reusable Security Scheme Objects. 359 SecurityScheme[string] securitySchemes; 360 361 ///An object to hold reusable Link Objects. 362 Link[string] links; 363 364 ///An object to hold reusable Callback Objects. 365 Callback[string] callbacks; 366 } 367 368 mixin Serialization!Components; 369 } 370 371 alias Callback = Path[string]; 372 373 enum OperationsType : string { 374 get = "get", 375 put = "put", 376 post = "post", 377 delete_ = "delete", 378 options = "options", 379 head = "head", 380 patch = "patch", 381 trace = "trace" 382 } 383 384 /// Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path 385 /// itself is still exposed to the documentation viewer but they will not know which operations and parameters are available. 386 struct Path { 387 alias operations this; 388 389 @optional { 390 /// Allows for an external definition of this path item. The referenced structure MUST be in the format of 391 /// a Path Item Object. If there are conflicts between the referenced definition and this Path Item's 392 /// definition, the behavior is undefined. 393 @SerializedName("$ref") string _ref; 394 395 /// An optional, string summary, intended to apply to all operations in this path. 396 string summary; 397 398 /// An optional, string description, intended to apply to all operations in this path. 399 /// CommonMark syntax MAY be used for rich text representation. 400 string description; 401 402 /// Defined operations 403 Operation[OperationsType] operations; 404 405 /// An alternative server array to service all operations in this path. 406 Server[] servers; 407 408 /// A list of parameters that are applicable for all the operations described under this path. 409 /// These parameters can be overridden at the operation level, but cannot be removed there. 410 /// The list MUST NOT include duplicated parameters. A unique parameter is defined by 411 /// a combination of a name and location. The list can use the Reference Object to link 412 /// to parameters that are defined at the OpenApi Object's components/parameters. 413 Parameter[] parameters; 414 } 415 416 @trusted: 417 /// 418 Json toJson() const { 419 auto dest = Json.emptyObject; 420 421 if(_ref != "") { 422 dest["$ref"] = _ref; 423 return dest; 424 } 425 426 if(summary != "") { 427 dest["summary"] = summary; 428 } 429 430 if(description != "") { 431 dest["description"] = description; 432 } 433 434 if(servers.length > 0) { 435 dest["servers"] = servers.serializeToJson; 436 } 437 438 if(parameters.length > 0) { 439 dest["parameters"] = parameters.serializeToJson; 440 } 441 442 foreach(string key, operation; operations) { 443 dest[key] = operation.serializeToJson; 444 } 445 446 return dest; 447 } 448 449 /// 450 static Path fromJson(Json src) { 451 Path path; 452 453 if("$ref" in src) { 454 path._ref = ""; 455 return path; 456 } 457 458 if("summary" in src) { 459 path.summary = src["summary"].to!string; 460 } 461 462 if("description" in src) { 463 path.description = src["description"].to!string; 464 } 465 466 if("servers" in src) { 467 path.servers = src["servers"].deserializeJson!(Server[]); 468 } 469 470 if("parameters" in src) { 471 path.parameters = src["parameters"].deserializeJson!(Parameter[]); 472 } 473 474 static foreach(value; EnumMembers!OperationsType) { 475 if(value in src) { 476 path.operations[value] = src[value].deserializeJson!Operation; 477 } 478 } 479 480 return path; 481 } 482 } 483 484 /// Describes a single API operation on a path. 485 struct Operation { 486 487 /// The list of possible responses as they are returned from executing this operation. 488 Response[string] responses; 489 490 @optional { 491 /// A list of tags for API documentation control. Tags can be used for logical 492 /// grouping of operations by resources or any other qualifier. 493 string[] tags; 494 495 /// A short summary of what the operation does. 496 string summary; 497 498 /// A verbose explanation of the operation behavior. CommonMark syntax MAY be used for rich text representation. 499 string description; 500 501 /// Additional external documentation for this operation. 502 ExternalDocumentation externalDocs; 503 504 /// Unique string used to identify the operation. The id MUST be unique among all operations described 505 /// in the API. Tools and libraries MAY use the operationId to uniquely identify an operation, therefore, 506 /// it is RECOMMENDED to follow common programming naming conventions. 507 string operationId; 508 509 /// A list of parameters that are applicable for this operation. If a parameter is already defined at the 510 /// Path Item, the new definition will override it but can never remove it. The list MUST NOT include 511 /// duplicated parameters. A unique parameter is defined by a combination of a name and location. 512 /// The list can use the Reference Object to link to parameters that are defined at the OpenApi 513 /// Object's components/parameters. 514 Parameter[] parameters; 515 516 /// The request body applicable for this operation. The requestBody is only supported in HTTP methods 517 /// where the HTTP 1.1 specification RFC7231 has explicitly defined semantics for request bodies. In 518 /// other cases where the HTTP spec is vague, requestBody SHALL be ignored by consumers. 519 RequestBody requestBody; 520 521 /// A map of possible out-of band callbacks related to the parent operation. The key is a unique identifier 522 /// for the Callback Object. Each value in the map is a Callback Object that describes a request that may 523 /// be initiated by the API provider and the expected responses. The key value used to identify the callback 524 /// object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation. 525 Callback[string] callbacks; 526 527 /// Declares this operation to be deprecated. Consumers SHOULD refrain from usage of the declared operation. 528 /// Default value is false. 529 @SerializedName("deprecated") bool deprecated_; 530 531 /// A declaration of which security mechanisms can be used for this operation. The list of values 532 /// includes alternative security requirement objects that can be used. Only one of the security 533 /// requirement objects need to be satisfied to authorize a request. This definition overrides any 534 /// declared top-level security. To remove a top-level security declaration, an empty array can be used. 535 SecurityRequirement[] security; 536 537 /// An alternative server array to service this operation. If an alternative server object is specified 538 /// at the Path Item Object or Root level, it will be overridden by this value. 539 Server[] servers; 540 } 541 542 @trusted: 543 /// 544 Json toJson() const { 545 Json data = Json.emptyObject; 546 data["responses"] = responses.serializeToJson; 547 548 if(tags.length > 0) { 549 data["tags"] = tags.serializeToJson; 550 } 551 552 if(summary != "") { 553 data["summary"] = summary; 554 } 555 556 if(description != "") { 557 data["description"] = description; 558 } 559 560 if(operationId != "") { 561 data["operationId"] = operationId; 562 } 563 564 if(parameters.length > 0) { 565 data["parameters"] = parameters.serializeToJson; 566 } 567 568 if(deprecated_) { 569 data["deprecated"] = deprecated_; 570 } 571 572 if(security.length > 0) { 573 data["security"] = security.serializeToJson; 574 } 575 576 if(servers.length > 0) { 577 data["servers"] = servers.serializeToJson; 578 } 579 580 auto externalDocsJson = externalDocs.serializeToJson; 581 if(externalDocsJson.length > 0) { 582 data["externalDocs"] = externalDocs.serializeToJson; 583 } 584 585 auto requestBodyJson = requestBody.serializeToJson; 586 if(requestBodyJson.length > 0) { 587 data["requestBody"] = requestBodyJson; 588 } 589 590 auto callbacksJson = callbacks.serializeToJson; 591 if(callbacksJson.length > 0) { 592 data["callbacks"] = callbacks.serializeToJson; 593 } 594 595 return data; 596 } 597 598 /// 599 static Operation fromJson(Json src) { 600 auto operation = Operation(); 601 602 if("responses" in src) { 603 operation.responses = src["responses"].deserializeJson!(Response[string]); 604 } 605 606 if("tags" in src) { 607 operation.tags = src["tags"].deserializeJson!(string[]); 608 } 609 610 if("summary" in src) { 611 operation.summary = src["summary"].to!string; 612 } 613 614 if("description" in src) { 615 operation.description = src["description"].to!string; 616 } 617 618 if("operationId" in src) { 619 operation.operationId = src["operationId"].to!string; 620 } 621 622 if("externalDocs" in src) { 623 operation.externalDocs = src["externalDocs"].deserializeJson!ExternalDocumentation; 624 } 625 626 if("parameters" in src) { 627 operation.parameters = src["parameters"].deserializeJson!(Parameter[]); 628 } 629 630 if("requestBody" in src) { 631 operation.requestBody = src["requestBody"].deserializeJson!RequestBody; 632 } 633 634 if("deprecated" in src) { 635 operation.deprecated_ = src["deprecated"].to!bool; 636 } 637 638 if("security" in src) { 639 operation.security = src["security"].deserializeJson!(SecurityRequirement[]); 640 } 641 642 if("servers" in src) { 643 operation.servers = src["servers"].deserializeJson!(Server[]); 644 } 645 646 if("callbacks" in src) { 647 operation.callbacks = src["callbacks"].deserializeJson !(Callback[string]); 648 } 649 650 return operation; 651 } 652 } 653 654 /// Allows referencing an external resource for extended documentation. 655 struct ExternalDocumentation { 656 657 /// The URL for the target documentation. Value MUST be in the format of a URL. 658 string url; 659 660 /// A short description of the target documentation. CommonMark syntax MAY be used for rich text representation. 661 @optional string description; 662 663 mixin Serialization!ExternalDocumentation; 664 } 665 666 /// 667 enum ParameterIn : string { 668 /// 669 query = "query", 670 671 /// 672 header = "header", 673 674 /// 675 path = "path", 676 677 /// 678 cookie = "cookie", 679 680 /// 681 body_ = "body" 682 } 683 684 mixin template ParameterOptions() { 685 686 @optional: 687 /// Determines whether this parameter is mandatory. If the parameter location is "path", this property is REQUIRED 688 /// and its value MUST be true. Otherwise, the property MAY be included and its default value is false. 689 bool required; 690 691 /// A brief description of the parameter. This could contain examples of use. CommonMark syntax MAY be used 692 /// for rich text representation. 693 string description; 694 695 /// Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. 696 @SerializedName("deprecated") bool deprecated_; 697 698 /// Sets the ability to pass empty-valued parameters. This is valid only for query parameters and allows 699 /// sending a parameter with an empty value. Default value is false. If style is used, and if behavior 700 /// is n/a (cannot be serialized), the value of allowEmptyValue SHALL be ignored. 701 bool allowEmptyValue; 702 703 /// Describes how the parameter value will be serialized depending on the type of the parameter value. 704 /// Default values (based on value of in): for query - form; for path - simple; 705 /// for header - simple; for cookie - form. 706 Style style; 707 708 /// When this is true, parameter values of type array or object generate separate parameters for each 709 /// value of the array or key-value pair of the map. For other types of parameters this property has no effect. 710 /// When style is form, the default value is true. For all other styles, the default value is false. 711 bool explode; 712 713 /// Determines whether the parameter value SHOULD allow reserved characters, as defined by 714 /// RFC3986 :/?#[]@!$&'()*+,;= to be included without percent-encoding. This property only applies to 715 /// parameters with an in value of query. The default value is false. 716 bool allowReserved; 717 718 /// The schema defining the type used for the parameter. 719 Schema schema; 720 721 /// Example of the media type. The example SHOULD match the specified schema andencoding properties 722 /// if present. The example field is mutually exclusive of the examples field. Furthermore, if 723 /// referencing a schema which contains an example, the example value SHALL override the example provided 724 /// by the schema. To represent examples of media types that cannot naturally be represented in JSON or 725 /// YAML, a string value can contain the example with escaping where necessary. 726 string example; 727 728 /// Examples of the media type. Each example SHOULD contain a value in the correct format as specified in 729 /// the parameter encoding. The examples field is mutually exclusive of the example field. Furthermore, 730 /// if referencing a schema which contains an example, the examples value SHALL override the example 731 /// provided by the schema. 732 Example[string] examples; 733 734 /// A map containing the representations for the parameter. The key is the media type and the value 735 /// describes it. The map MUST only contain one entry. 736 MediaType[string] content; 737 } 738 739 /// Describes a single operation parameter. A unique parameter is defined by a 740 /// combination of a name and location. 741 struct Parameter { 742 /*** 743 The name of the parameter. Parameter names are case sensitive. 744 745 - If in is "path", the name field MUST correspond to the associated path segment from the path field 746 in the Paths Object. See Path Templating for further information. 747 748 - If in is "header" and the name field is "Accept", "Content-Type" or "Authorization", 749 the parameter definition SHALL be ignored. 750 751 - For all other cases, the name corresponds to the parameter name used by the in property. 752 */ 753 string name; 754 755 /// The location of the parameter. 756 @SerializedName("in") ParameterIn in_; 757 758 mixin ParameterOptions; 759 760 mixin Serialization!Parameter; 761 } 762 763 /// The Header Object follows the structure of the Parameter Object 764 struct Header { 765 mixin ParameterOptions; 766 767 mixin Serialization!Header; 768 } 769 770 /// In order to support common ways of serializing simple parameters, a set of style values are defined. 771 enum Style : string { 772 /// 773 undefined = "", 774 775 /// Path-style parameters defined by RFC6570 776 matrix = "matrix", 777 778 /// Label style parameters defined by RFC6570 779 label = "label", 780 781 /// Form style parameters defined by RFC6570. This option replaces collectionFormat with a csv (when explode is false) or multi 782 /// (when explode is true) value from OpenApi 2.0. 783 form = "form", 784 785 /// Simple style parameters defined by RFC6570. This option replaces collectionFormat with a csv value from OpenApi 2.0. 786 simple = "simple", 787 788 /// Space separated array values. This option replaces collectionFormat equal to ssv from OpenApi 2.0. 789 spaceDelimited = "spaceDelimited", 790 791 /// Pipe separated array values. This option replaces collectionFormat equal to pipes from OpenApi 2.0. 792 pipeDelimited = "pipeDelimited", 793 794 /// Provides a simple way of rendering nested objects using form parameters. 795 deepObject = "deepObject", 796 } 797 798 /// Describes a single request body. 799 struct RequestBody { 800 /// The content of the request body. The key is a media type or media type range and the value 801 /// describes it. For requests that match multiple keys, only the most specific key is applicable. 802 /// e.g. text/plain overrides text/* 803 MediaType[string] content; 804 805 @optional { 806 /// A brief description of the request body. This could contain examples of use. 807 /// CommonMark syntax MAY be used for rich text representation. 808 string description; 809 810 /// Determines if the request body is required in the request. Defaults to false. 811 bool required; 812 } 813 814 mixin Serialization!RequestBody; 815 } 816 817 /// Each Media Type Object provides schema and examples for the media type identified by its key. 818 struct MediaType { 819 @optional { 820 /// The schema defining the type used for the request body. 821 Schema schema; 822 823 /// The example object SHOULD be in the correct format as specified by the media type. The example 824 /// field is mutually exclusive of the examples field. Furthermore, if referencing a schema which contains an 825 /// example, the example value SHALL override the example provided by the schema. 826 string example; 827 828 /// True if the example is a Json object or array. This flag is used for serialization. 829 bool parseJsonExample; 830 831 /// Examples of the media type. Each example object SHOULD match the media type and specified schema if present. 832 /// The examples field is mutually exclusive of the example field. Furthermore, if referencing a schema which 833 /// contains an example, the examples value SHALL override the example provided by the schema. 834 Example[string] examples; 835 836 /// A map between a property name and its encoding information. The key, being the property name, MUST exist in 837 /// the schema as a property. The encoding object SHALL only apply to requestBody objects when the media type is 838 /// multipart or application/x-www-form-urlencoded. 839 Encoding[string] encoding; 840 } 841 842 @trusted: 843 Json toJson() const { 844 Json value = Json.emptyObject; 845 846 if(schema !is null) { 847 value["schema"] = schema.toJson; 848 } 849 850 if(example != "") { 851 if(parseJsonExample) { 852 value["example"] = example.parseJsonString; 853 } else { 854 value["example"] = example; 855 } 856 } 857 858 if(examples.length > 0) { 859 value["examples"] = examples.serializeToJson; 860 } 861 862 if(encoding.length > 0) { 863 value["encoding"] = encoding.serializeToJson; 864 } 865 866 return value; 867 } 868 869 static MediaType fromJson(Json src) { 870 MediaType value; 871 872 if("schema" in src) { 873 value.schema = Schema.fromJson(src["schema"]); 874 } 875 876 if("example" in src) { 877 value.parseJsonExample = src["example"].type == Json.Type.array || src["example"].type == Json.Type.object; 878 value.example = src["example"].to!string; 879 } 880 881 if("examples" in src) { 882 value.examples = src["examples"].deserializeJson!(Example[string]); 883 } 884 885 if("encoding" in src) { 886 value.encoding = src["encoding"].deserializeJson!(Encoding[string]); 887 } 888 889 return value; 890 } 891 } 892 893 /// A single encoding definition applied to a single schema property. 894 struct Encoding { 895 @optional: 896 /// The Content-Type for encoding a specific property. Default value depends on the property type: for string with 897 /// format being binary – application/octet-stream; for other primitive types – text/plain; for object - application/json; 898 /// for array – the default is defined based on the inner type. The value can be a specific media type (e.g. application/json), 899 /// a wildcard media type (e.g. image/*), or a comma-separated list of the two types. 900 string contentType; 901 902 /// A map allowing additional information to be provided as headers, for example Content-Disposition. Content-Type is 903 /// described separately and SHALL be ignored in this section. This property SHALL be ignored if the request body media 904 /// type is not a multipart. 905 Header[string] headers; 906 907 /// Describes how a specific property value will be serialized depending on its type. See Parameter Object for details on the style 908 /// property. The behavior follows the same values as query parameters, including default values. This property SHALL be ignored 909 /// if the request body media type is not application/x-www-form-urlencoded. 910 Style style; 911 912 /// When this is true, property values of type array or object generate separate parameters for each value of the array, or 913 /// key-value-pair of the map. For other types of properties this property has no effect. When style is form, the default value is 914 /// true. For all other styles, the default value is false. This property SHALL be ignored if the request body media type is not 915 /// application/x-www-form-urlencoded. 916 bool explode; 917 918 /// Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 :/?#[]@!$&'()*+,;= to be included 919 /// without percent-encoding. The default value is false. This property SHALL be ignored if the request body media type is not 920 /// application/x-www-form-urlencoded. 921 bool allowReserved; 922 } 923 924 /// Describes a single response from an API Operation, including design-time, static links to operations based on the response. 925 struct Response { 926 /// A short description of the response. CommonMark syntax MAY be used for rich text representation. 927 string description; 928 929 @optional { 930 /// Maps a header name to its definition. RFC7230 states header names are case insensitive. If a response header is 931 /// defined with the name "Content-Type", it SHALL be ignored. 932 Header[string] headers; 933 934 /// A map containing descriptions of potential response payloads. The key is a media type or media type range and the value 935 /// describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/* 936 MediaType[string] content; 937 938 /// A map of operations links that can be followed from the response. The key of the map is a short name for the link, 939 /// following the naming constraints of the names for Component Objects. 940 Link[string] links; 941 } 942 943 mixin Serialization!Response; 944 } 945 946 /*** 947 The Link object represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability 948 to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations. 949 950 Unlike dynamic links (i.e. links provided in the response payload), the OAS linking mechanism does not require link information in 951 the runtime response. 952 953 For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation 954 and using them as parameters while invoking the linked operation. 955 */ 956 struct Link { 957 @optional: 958 /// A relative or absolute reference to an OAS operation. This field is mutually exclusive of the operationId field, and MUST point to an 959 /// Operation Object. Relative operationRef values MAY be used to locate an existing Operation Object in the OpenApi definition. 960 string operationRef; 961 962 /// The name of an existing, resolvable OAS operation, as defined with a unique operationId. This field is mutually exclusive of the operationRef field. 963 string operationId; 964 965 /// A map representing parameters to pass to an operation as specified with operationId or identified via operationRef. The key is the parameter 966 /// name to be used, whereas the value can be a constant or an expression to be evaluated and passed to the linked operation. The parameter 967 /// name can be qualified using the parameter location [{in}.]{name} for operations that use the same parameter name in different locations (e.g. path.id). 968 string[string] parameters; 969 970 /// A literal value or {expression} to use as a request body when calling the target operation. 971 string requestBody; 972 973 /// A description of the link. CommonMark syntax MAY be used for rich text representation. 974 string description; 975 976 /// A server object to be used by the target operation. 977 Server server; 978 979 /// The reference string. 980 @SerializedName("$ref") string _ref; 981 982 mixin Serialization!Link; 983 } 984 985 enum SchemaType : string { 986 null_ = "null", 987 boolean = "boolean", 988 object = "object", 989 array = "array", 990 number = "number", 991 integer = "integer", 992 string = "string" 993 } 994 995 enum SchemaFormat : string { 996 /// 997 undefined = "undefined", 998 999 /// 1000 string = "string", 1001 1002 /// signed 32 bits 1003 int32 = "int32", 1004 1005 /// signed 64 bits 1006 int64 = "int64", 1007 1008 /// 1009 float_ = "float", 1010 1011 /// base64 encoded characters 1012 byte_ = "byte", 1013 1014 /// any sequence of octets 1015 binary = "binary", 1016 1017 /// As defined by full-date - RFC3339 1018 date = "date", 1019 1020 /// As defined by date-time - RFC3339 1021 dateTime = "date-time", 1022 1023 /// A hint to UIs to obscure input. 1024 password = "password", 1025 1026 /// 1027 uri = "uri", 1028 1029 /// 1030 uriref = "uriref" 1031 } 1032 1033 /*** 1034 The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. 1035 This object is an extended subset of the JSON Schema Specification Wright Draft 00. 1036 1037 For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions 1038 follow the JSON Schema. 1039 */ 1040 class Schema { 1041 @optional { 1042 /++ The following properties are taken directly from the JSON Schema definition and follow the same specifications: +/ 1043 1044 /// A title will preferrably be short 1045 string title; 1046 1047 /// A numeric instance is only valid if division by this keyword's value results in an integer. 1048 ulong multipleOf; 1049 1050 /// An upper limit for a numeric instance. 1051 /// If the instance is a number, then this keyword validates if "exclusiveMaximum" is true and instance is less than the provided 1052 /// value, or else if the instance is less than or exactly equal to the 1053 /// provided value. 1054 double maximum; 1055 1056 /// ditto 1057 bool exclusiveMaximum; 1058 1059 /// A lower limit for a numeric instance. 1060 /// If the instance is a number, then this keyword validates if "exclusiveMinimum" is true and instance is greater than the provided 1061 /// value, or else if the instance is greater than or exactly equal to the provided value. 1062 double minimum; 1063 1064 /// ditto 1065 bool exclusiveMinimum; 1066 1067 /// A string instance is valid against this keyword if its length is less than, or equal to, the value of this keyword. 1068 ulong maxLength; 1069 1070 /// A string instance is valid against this keyword if its length is greater than, or equal to, the value of this keyword. 1071 ulong minLength; 1072 1073 /// This string SHOULD be a valid regular expression, according to the ECMA 262 regular expression dialect. 1074 string pattern; 1075 1076 /// An array instance is valid against "maxItems" if its size is less than, or equal to. 1077 ulong maxItems; 1078 1079 /// An array instance is valid against "minItems" if its size is greater than, or equal to. 1080 ulong minItems; 1081 1082 /// If this keyword has boolean value false, the instance validates successfully. If it has boolean value true, the instance validates 1083 /// successfully if all of its elements are unique. 1084 bool uniqueItems; 1085 1086 /// An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value of this keyword. 1087 ulong maxProperties; 1088 1089 /// An object instance is valid against "minProperties" if its number of properties is greater than, or equal to, the value of this keyword. 1090 ulong minProperties; 1091 1092 /// An object instance is valid against this keyword if its property set contains all elements in this keyword's array value. 1093 string[] required; 1094 1095 /// 1096 @SerializedName("enum") string[] enum_; 1097 } 1098 1099 /++ 1100 The following properties are taken from the JSON Schema definition but their definitions were adjusted to the OpenApi Specification. 1101 +/ 1102 @optional { 1103 /// An instance validates successfully against this keyword if its value is equal to one of the elements in this keyword's array value. 1104 SchemaType type; 1105 1106 /// An instance validates successfully against this keyword if it validates successfully against all schemas defined by this keyword's 1107 /// value. 1108 Schema[] allOf; 1109 1110 /// An instance validates successfully against this keyword if it validates successfully against exactly one schema defined by this 1111 /// keyword's value. 1112 Schema[] oneOf; 1113 1114 /// An instance validates successfully against this keyword if it validates successfully against at least one schema defined by this 1115 /// keyword's value. 1116 Schema[] anyOf; 1117 1118 /// An instance is valid against this keyword if it fails to validate successfully against the schema defined by this keyword. 1119 Schema[] not; 1120 1121 /*** 1122 MUST be present if the type is array. 1123 1124 Successful validation of an array instance with regards to these two keywords is determined as follows: 1125 1126 If either keyword is absent, it may be considered present with an empty schema. 1127 */ 1128 Schema items; 1129 1130 /// Using properties, we can define a known set of properties, however if we 1131 /// wish to use any other hash/map where we can't specify how many keys 1132 /// there are nor what they are in advance, we should use additionalProperties. 1133 Schema[string] properties; 1134 1135 1136 /// It will match any property name (that will act as the dict's key, and the $ref or 1137 /// type will be the schema of the dict's value, and since there should not be more than 1138 /// one properties with the same name for every given object, we will get the enforcement 1139 /// of unique keys. 1140 Schema additionalProperties; 1141 1142 /// CommonMark syntax MAY be used for rich text representation. 1143 string description; 1144 1145 /// 1146 SchemaFormat format; 1147 1148 /// The default value 1149 @SerializedName("default") string default_; 1150 1151 /+ Other than the JSON Schema subset fields, the following fields MAY be used for further schema documentation: +/ 1152 1153 /// Allows sending a null value for the defined schema. 1154 bool nullable; 1155 1156 /// Adds support for polymorphism. The discriminator is an object name that is used to differentiate between 1157 /// other schemas which may satisfy the payload description. See Composition and Inheritance for more details. 1158 Discriminator discriminator; 1159 1160 /// Relevant only for Schema "properties" definitions. Declares the property as "read only". This means that it MAY be sent as part of a response but 1161 /// SHOULD NOT be sent as part of the request. If the property is marked as readOnly being true and is in the required list, the required will take 1162 /// effect on the response only. A property MUST NOT be marked as both readOnly and writeOnly being true. Default value is false. 1163 bool readOnly; 1164 1165 /// Relevant only for Schema "properties" definitions. Declares the property as "write only". Therefore, it MAY be sent as part of a 1166 /// request but SHOULD NOT be sent as part of the response. If the property is marked as writeOnly being true and is in the required 1167 /// list, the required will take effect on the request only. A property MUST NOT be marked as both readOnly and writeOnly being 1168 /// true. Default value is false. 1169 bool writeOnly; 1170 1171 /// This MAY be used only on properties schemas. It has no effect on root schemas. Adds additional metadata to describe 1172 /// the XML representation of this property. 1173 XML xml; 1174 1175 /// Additional external documentation for this schema. 1176 ExternalDocumentation externalDocs; 1177 1178 /// A free-form property to include an example of an instance for this schema. To represent examples that cannot 1179 /// be naturally represented in JSON or YAML, a string value can be used to contain the example with escaping where necessary. 1180 string example; 1181 1182 /// Specifies that a schema is deprecated and SHOULD be transitioned out of usage. Default value is false. 1183 @SerializedName("deprecated") bool deprecated_; 1184 1185 /// The reference string. 1186 @SerializedName("$ref") string _ref; 1187 } 1188 1189 @trusted: 1190 1191 enum toFields = [ 1192 "title", "multipleOf", "maximum", "exclusiveMaximum", 1193 "minimum", "exclusiveMinimum", "maxLength", "minLength", 1194 "pattern", "maxItems", "minItems", "uniqueItems", 1195 "maxProperties", "minProperties", "description", 1196 "nullable", "readOnly", "writeOnly"]; 1197 1198 enum enumField = [ 1199 "type", "format" 1200 ]; 1201 1202 enum aFields = [ 1203 "allOf", "oneOf", "anyOf", "not" 1204 ]; 1205 1206 enum aaFields = [ 1207 "properties" 1208 ]; 1209 1210 enum deserializableFields = [ 1211 "discriminator", "xml", "externalDocs", "required" 1212 ]; 1213 1214 Json toJson() const { 1215 Json value = Json.emptyObject; 1216 Schema defaultSchema = new Schema; 1217 1218 if(_ref != "") { 1219 value["$ref"] = _ref; 1220 1221 return value; 1222 } 1223 1224 if(default_ != "") { 1225 try { 1226 value["default"] = default_.parseJsonString; 1227 } catch(JSONException) { 1228 value["default"] = default_; 1229 } 1230 } 1231 1232 if(deprecated_) { 1233 value["deprecated"] = true; 1234 } 1235 1236 if(enum_.length > 0) { 1237 value["enum"] = enum_.serializeToJson; 1238 } 1239 1240 if(example != "") { 1241 value["example"] = example.parseJsonString; 1242 } 1243 1244 /// to fields 1245 static foreach(field; toFields) {{ 1246 alias Type = typeof(__traits(getMember, Schema, field)); 1247 1248 auto tmp = __traits(getMember, this, field); 1249 auto defaultValue = __traits(getMember, defaultSchema, field); 1250 1251 static if(is(Type == double)) { 1252 if(!isNaN(tmp)) { 1253 value[field] = tmp; 1254 } 1255 } else if(tmp != defaultValue) { 1256 value[field] = tmp; 1257 } 1258 }} 1259 1260 /// enum fields 1261 static foreach(field; enumField) {{ 1262 auto tmp = __traits(getMember, this, field); 1263 auto defaultValue = __traits(getMember, defaultSchema, field); 1264 1265 if(tmp != defaultValue) { 1266 value[field] = tmp.toOriginalEnumValue; 1267 } 1268 }} 1269 1270 /// array fields 1271 static foreach(field; aFields) {{ 1272 auto tmp = __traits(getMember, this, field); 1273 1274 if(tmp.length > 0) { 1275 value[field] = tmp.serializeToJson; 1276 } 1277 }} 1278 1279 /// assoc array fields 1280 static foreach(field; aaFields) {{ 1281 auto tmp = __traits(getMember, this, field); 1282 1283 if(tmp.length > 0) { 1284 value[field] = tmp.serializeToJson; 1285 } 1286 }} 1287 1288 if(items !is null) { 1289 value["items"] = items.toJson; 1290 } 1291 1292 /// deserializable fields 1293 static foreach(field; deserializableFields) {{ 1294 alias Type = typeof(__traits(getMember, Schema, field)); 1295 1296 Json tmp = __traits(getMember, this, field).serializeToJson; 1297 1298 if(tmp.length > 0) { 1299 value[field] = tmp; 1300 } 1301 }} 1302 1303 if(additionalProperties !is null) { 1304 value["additionalProperties"] = additionalProperties.toJson; 1305 } 1306 1307 return value; 1308 } 1309 1310 /// 1311 static Schema fromJson(Json src) { 1312 Schema schema = new Schema; 1313 1314 if("$ref" in src) { 1315 schema._ref = src["$ref"].to!string; 1316 return schema; 1317 } 1318 1319 if("default" in src) { 1320 schema.default_ = src["default"].to!string; 1321 } 1322 1323 if("deprecated" in src) { 1324 schema.deprecated_ = src["deprecated"].to!bool; 1325 } 1326 1327 if("enum" in src) { 1328 schema.enum_ = src["enum"].deserializeJson!(string[]); 1329 } 1330 1331 if("items" in src) { 1332 schema.items = src["items"].deserializeJson!Schema; 1333 } 1334 1335 if("example" in src) { 1336 schema.example = src["example"].toString; 1337 } 1338 1339 /// to fields 1340 static foreach(field; toFields) {{ 1341 alias Type = typeof(__traits(getMember, Schema, field)); 1342 1343 if(field in src) { 1344 auto value = src[field].to!Type; 1345 if(__traits(getMember, schema, field) != value) { 1346 __traits(getMember, schema, field) = value; 1347 } 1348 } 1349 }} 1350 1351 /// enum fields 1352 static foreach(field; enumField) {{ 1353 alias Type = typeof(__traits(getMember, Schema, field)); 1354 1355 if(field in src) { 1356 Type value; 1357 1358 try { 1359 value = src[field].to!string.toEnumValue!Type; 1360 1361 if(__traits(getMember, schema, field) != value) { 1362 __traits(getMember, schema, field) = value; 1363 } 1364 } catch(Exception e) { 1365 writeln(e.msg); 1366 } 1367 } 1368 }} 1369 1370 /// array fields 1371 static foreach(field; aFields) {{ 1372 if(field in src && src[field].length > 0) { 1373 auto value = src[field].byValue.map!(a => Schema.fromJson(a)).array; 1374 __traits(getMember, schema, field) = value; 1375 } 1376 }} 1377 1378 /// assoc array fields 1379 static foreach(field; aaFields) {{ 1380 if(field in src && src[field].length > 0) { 1381 try { 1382 auto value = src[field].byKeyValue.map!(a => tuple(a.key, Schema.fromJson(a.value))).assocArray; 1383 __traits(getMember, schema, field) = value; 1384 } catch(Exception e) { 1385 writeln("Error: ", e.msg); 1386 } 1387 } 1388 }} 1389 1390 /// deserializable fields 1391 static foreach(field; deserializableFields) {{ 1392 alias Type = typeof(__traits(getMember, Schema, field)); 1393 1394 if(field in src && src[field].length > 0) { 1395 try { 1396 auto value = src[field].deserializeJson!Type; 1397 __traits(getMember, schema, field) = value; 1398 } catch(Exception e) { 1399 writeln("`", field, "` error: ", e.msg); 1400 } 1401 } 1402 }} 1403 1404 if("additionalProperties" in src && src["additionalProperties"].type == Json.Type.object) { 1405 schema.additionalProperties = Schema.fromJson(src["additionalProperties"]); 1406 } 1407 1408 return schema; 1409 } 1410 } 1411 1412 /*** 1413 When request bodies or response payloads may be one of a number of different schemas, a discriminator object can be used 1414 to aid in serialization, deserialization, and validation. The discriminator is a specific object in a schema which is used 1415 to inform the consumer of the specification of an alternative schema based on the value associated with it. 1416 1417 When using the discriminator, inline schemas will not be considered. 1418 */ 1419 struct Discriminator { 1420 /// The name of the property in the payload that will hold the discriminator value. 1421 string propertyName; 1422 1423 /// An object to hold mappings between payload values and schema names or references. 1424 @optional string[string][string] mapping; 1425 1426 mixin Serialization!Discriminator; 1427 } 1428 1429 /*** 1430 A metadata object that allows for more fine-tuned XML model definitions. 1431 1432 When using arrays, XML element names are not inferred (for singular/plural forms) and the name property SHOULD 1433 be used to add that information. See examples for expected behavior. 1434 */ 1435 struct XML { 1436 @optional { 1437 /// Replaces the name of the element/attribute used for the described schema property. When defined within items, it 1438 /// will affect the name of the individual XML elements within the list. When defined alongside type being array 1439 /// (outside the items), it will affect the wrapping element and only if wrapped is true. If wrapped is false, it will be ignored. 1440 string name; 1441 1442 /// The URI of the namespace definition. Value MUST be in the form of an absolute URI. 1443 string namespace; 1444 1445 /// The prefix to be used for the name. 1446 string prefix; 1447 1448 /// Declares whether the property definition translates to an attribute instead of an element. Default value is false. 1449 bool attribute; 1450 1451 /// MAY be used only for an array definition. Signifies whether the array is wrapped 1452 /// (for example, <books><book/><book/></books>) or unwrapped (<book/><book/>). 1453 /// Default value is false. The definition takes effect only when defined alongside type being array (outside the items). 1454 bool wrapped; 1455 } 1456 1457 mixin Serialization!XML; 1458 } 1459 1460 /// 1461 struct Example { 1462 @optional { 1463 /// Short description for the example. 1464 string summary; 1465 1466 /// Long description for the example. CommonMark syntax MAY be used for rich text representation. 1467 string description; 1468 1469 /// Embedded literal example. The value field and externalValue field are mutually exclusive. To represent examples 1470 /// of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. 1471 string value; 1472 1473 /// A URL that points to the literal example. This provides the capability to reference examples that 1474 /// cannot easily be included in JSON or YAML documents. The value field and externalValue field are mutually exclusive. 1475 string externalValue; 1476 1477 /// True if the value should be treated as a json object or array 1478 bool parseJsonValue; 1479 } 1480 1481 Json toJson() const @safe { 1482 Json jsonValue = Json.emptyObject; 1483 1484 if(summary != "") { 1485 jsonValue["summary"] = summary; 1486 } 1487 1488 if(description != "") { 1489 jsonValue["description"] = description; 1490 } 1491 1492 if(externalValue != "") { 1493 jsonValue["externalValue"] = externalValue; 1494 } 1495 1496 if(value != "") { 1497 if(parseJsonValue) { 1498 jsonValue["value"] = value.parseJsonString; 1499 } else { 1500 jsonValue["value"] = value; 1501 } 1502 } 1503 1504 return jsonValue; 1505 } 1506 1507 /// 1508 static Example fromJson(Json src) @safe { 1509 Example example; 1510 1511 if("summary" in src) { 1512 example.summary = src["summary"].to!string; 1513 } 1514 1515 if("description" in src) { 1516 example.description = src["description"].to!string; 1517 } 1518 1519 if("externalValue" in src) { 1520 example.externalValue = src["externalValue"].to!string; 1521 } 1522 1523 if("value" in src) { 1524 example.parseJsonValue = src["value"].type == Json.Type.array || src["value"].type == Json.Type.object; 1525 example.value = src["value"].to!string; 1526 } 1527 1528 return example; 1529 } 1530 } 1531 1532 /// Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a 1533 /// Tag Object per tag defined in the Operation Object instances. 1534 struct Tag { 1535 /// The name of the tag 1536 string name; 1537 1538 @optional { 1539 /// A short description for the tag. CommonMark syntax MAY be used for rich text representation. 1540 string description; 1541 1542 /// Additional external documentation for this tag. 1543 ExternalDocumentation externalDocs; 1544 } 1545 1546 mixin Serialization!Tag; 1547 } 1548 1549 /// 1550 enum SecurityType : string { 1551 apiKey = "apiKey", 1552 http = "http", 1553 oauth2 = "oauth2", 1554 openIdConnect = "openIdConnect" 1555 } 1556 1557 /** 1558 Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either 1559 as a header or as a query parameter), OAuth2's common flows (implicit, password, application and access code) as defined 1560 in RFC6749, and OpenID Connect Discovery. 1561 */ 1562 struct SecurityScheme { 1563 /// 1564 SecurityType type; 1565 1566 @optional { 1567 /// A hint to the client to identify how the bearer token is formatted. Bearer tokens are usually generated by an 1568 /// authorization server, so this information is primarily for documentation purposes. 1569 string bearerFormat; 1570 1571 /// A short description for security scheme. CommonMark syntax MAY be used for rich text representation. 1572 string description; 1573 1574 /// The name of the header, query or cookie parameter to be used. 1575 string name; 1576 1577 /// The location of the API key 1578 @SerializedName("in") ParameterIn in_; 1579 1580 /// The name of the HTTP Authorization scheme to be used in the Authorization header as defined in RFC7235. 1581 string scheme; 1582 1583 /// An object containing configuration information for the flow types supported. 1584 OAuthFlows flows; 1585 1586 /// OpenId Connect URL to discover OAuth2 configuration values. This MUST be in the form of a URL. 1587 string openIdConnectUrl; 1588 } 1589 1590 mixin Serialization!SecurityScheme; 1591 } 1592 1593 /// Allows configuration of the supported OAuth Flows. 1594 struct OAuthFlows { 1595 @optional { 1596 /// Configuration for the OAuth Implicit flow 1597 OAuthFlow implicit; 1598 1599 /// Configuration for the OAuth Resource Owner Password flow 1600 OAuthFlow password; 1601 1602 /// Configuration for the OAuth Client Credentials flow. Previously called application in OpenApi 2.0. 1603 OAuthFlow clientCredentials; 1604 1605 /// Configuration for the OAuth Authorization Code flow. Previously called accessCode in OpenApi 2.0. 1606 OAuthFlow authorizationCode; 1607 } 1608 1609 mixin Serialization!OAuthFlows; 1610 } 1611 1612 /// Configuration details for a supported OAuth Flow 1613 struct OAuthFlow { 1614 1615 /// The authorization URL to be used for this flow. This MUST be in the form of a URL. 1616 string authorizationUrl; 1617 1618 /// The token URL to be used for this flow. This MUST be in the form of a URL. 1619 string tokenUrl; 1620 1621 /// The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. 1622 string[string] scopes; 1623 1624 /// The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. 1625 @optional string oauth2; 1626 1627 1628 mixin Serialization!OAuthFlow; 1629 } 1630 1631 /// 1632 alias SecurityRequirement = string[][string];