├── README.md ├── bin └── index.js ├── fixtures ├── fixture-v1.2.json └── petstore-v2.0.json ├── package.json └── parsers ├── 1.2.js └── 2.0.js /README.md: -------------------------------------------------------------------------------- 1 | # swagger-models-to-react-proptypes 2 | CLI that consumes a swagger endpoint and spits out React propType definitions. 3 | 4 | ### Installation: 5 | __`npm install -g swagger-models-to-react-proptypes`__ 6 | 7 | ### Usage: 8 | 9 | __`swagger-models-to-react-proptypes http://petstore.swagger.io/v2/swagger.json`__ 10 | 11 | ```js 12 | /** 13 | 14 | Generated PropTypes for http://petstore.swagger.io/v2/swagger.json 15 | ------------------------------------------------------------------ 16 | 17 | **/ 18 | 19 | 20 | var PropTypes = { 21 | 22 | Order: React.PropTypes.shape({ 23 | id: React.PropTypes.number, 24 | petId: React.PropTypes.number, 25 | quantity: React.PropTypes.number, 26 | shipDate: React.PropTypes.string, 27 | status: React.PropTypes.oneOf([ 28 | "placed", 29 | "approved", 30 | "delivered" 31 | ]), 32 | complete: React.PropTypes.bool 33 | }), 34 | 35 | Category: React.PropTypes.shape({ 36 | id: React.PropTypes.number, 37 | name: React.PropTypes.string 38 | }), 39 | 40 | User: React.PropTypes.shape({ 41 | id: React.PropTypes.number, 42 | username: React.PropTypes.string, 43 | firstName: React.PropTypes.string, 44 | lastName: React.PropTypes.string, 45 | email: React.PropTypes.string, 46 | password: React.PropTypes.string, 47 | phone: React.PropTypes.string, 48 | userStatus: React.PropTypes.number 49 | }), 50 | 51 | Tag: React.PropTypes.shape({ 52 | id: React.PropTypes.number, 53 | name: React.PropTypes.string 54 | }), 55 | 56 | Pet: React.PropTypes.shape({ 57 | id: React.PropTypes.number, 58 | category: PropTypes.Category, 59 | name: React.PropTypes.string.isRequired, 60 | photoUrls: React.PropTypes.arrayOf(React.PropTypes.string).isRequired, 61 | tags: React.PropTypes.arrayOf(PropTypes.Tag), 62 | status: React.PropTypes.oneOf([ 63 | "available", 64 | "pending", 65 | "sold" 66 | ]) 67 | }), 68 | 69 | ApiResponse: React.PropTypes.shape({ 70 | code: React.PropTypes.number, 71 | type: React.PropTypes.string, 72 | message: React.PropTypes.string 73 | }) 74 | 75 | }; 76 | ``` 77 | -------------------------------------------------------------------------------- /bin/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var SwaggerClient = require('swagger-client'); 4 | var _ = require('lodash'); 5 | 6 | var swaggerParsers = { 7 | '1.2': require('../parsers/1.2'), 8 | '2.0': require('../parsers/2.0') 9 | }; 10 | 11 | var url = process.argv[2]; 12 | 13 | var client = new SwaggerClient({ 14 | url: url, 15 | success: function() { 16 | if (!_.has(swaggerParsers, client.swaggerVersion)) { 17 | throw new Error('Unsupported swagger version - ' + client.swaggerVersion); 18 | } 19 | swaggerParsers[client.swaggerVersion](client); 20 | } 21 | }); -------------------------------------------------------------------------------- /fixtures/fixture-v1.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion":"1.0", 3 | "swaggerVersion":"1.2", 4 | "basePath":"http://[hostname/ip address]:[port]/SpringWithSwagger/rest", 5 | "resourcePath":"/users", 6 | "apis":[ 7 | { 8 | "path":"/users/{userName}", 9 | "operations":[ 10 | { 11 | "method":"GET", 12 | "summary":"Returns user details", 13 | "notes":"Returns a complete list of users details with a date of last modification.", 14 | "type":"User", 15 | "nickname":"getUser", 16 | "produces":[ 17 | "application/json" 18 | ], 19 | "authorizations":{ 20 | 21 | }, 22 | "parameters":[ 23 | { 24 | "name":"userName", 25 | "description":"Alphanumeric login to application", 26 | "required":true, 27 | "type":"string", 28 | "paramType":"path", 29 | "allowMultiple":false 30 | } 31 | ], 32 | "responseMessages":[ 33 | { 34 | "code":200, 35 | "message":"Successful retrieval of user detail", 36 | "responseModel":"User" 37 | }, 38 | { 39 | "code":404, 40 | "message":"User with given username does not exist" 41 | }, 42 | { 43 | "code":500, 44 | "message":"Internal server error" 45 | } 46 | ] 47 | } 48 | ] 49 | } 50 | ], 51 | "models":{ 52 | "User":{ 53 | "id":"User", 54 | "properties": { 55 | "surname":{"type":"string"}, 56 | "userName":{"type":"string"}, 57 | "lastUpdated": 58 | { 59 | "type":"string", 60 | "format":"date-time" 61 | }, 62 | "avatar":{ 63 | "type":"array", 64 | "items":{"type":"byte"} 65 | }, 66 | "firstName":{"type":"string"}, 67 | "email":{"type":"string"} 68 | } 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /fixtures/petstore-v2.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", 5 | "version": "1.0.0", 6 | "title": "Swagger Petstore", 7 | "termsOfService": "http://swagger.io/terms/", 8 | "contact": { 9 | "email": "apiteam@swagger.io" 10 | }, 11 | "license": { 12 | "name": "Apache 2.0", 13 | "url": "http://www.apache.org/licenses/LICENSE-2.0.html" 14 | } 15 | }, 16 | "host": "petstore.swagger.io", 17 | "basePath": "/v2", 18 | "tags": [ 19 | { 20 | "name": "pet", 21 | "description": "Everything about your Pets", 22 | "externalDocs": { 23 | "description": "Find out more", 24 | "url": "http://swagger.io" 25 | } 26 | }, 27 | { 28 | "name": "store", 29 | "description": "Access to Petstore orders" 30 | }, 31 | { 32 | "name": "user", 33 | "description": "Operations about user", 34 | "externalDocs": { 35 | "description": "Find out more about our store", 36 | "url": "http://swagger.io" 37 | } 38 | } 39 | ], 40 | "schemes": [ 41 | "http" 42 | ], 43 | "paths": { 44 | "/pet": { 45 | "post": { 46 | "tags": [ 47 | "pet" 48 | ], 49 | "summary": "Add a new pet to the store", 50 | "description": "", 51 | "operationId": "addPet", 52 | "consumes": [ 53 | "application/json", 54 | "application/xml" 55 | ], 56 | "produces": [ 57 | "application/xml", 58 | "application/json" 59 | ], 60 | "parameters": [ 61 | { 62 | "in": "body", 63 | "name": "body", 64 | "description": "Pet object that needs to be added to the store", 65 | "required": true, 66 | "schema": { 67 | "$ref": "#/definitions/Pet" 68 | } 69 | } 70 | ], 71 | "responses": { 72 | "405": { 73 | "description": "Invalid input" 74 | } 75 | }, 76 | "security": [ 77 | { 78 | "petstore_auth": [ 79 | "write:pets", 80 | "read:pets" 81 | ] 82 | } 83 | ] 84 | }, 85 | "put": { 86 | "tags": [ 87 | "pet" 88 | ], 89 | "summary": "Update an existing pet", 90 | "description": "", 91 | "operationId": "updatePet", 92 | "consumes": [ 93 | "application/json", 94 | "application/xml" 95 | ], 96 | "produces": [ 97 | "application/xml", 98 | "application/json" 99 | ], 100 | "parameters": [ 101 | { 102 | "in": "body", 103 | "name": "body", 104 | "description": "Pet object that needs to be added to the store", 105 | "required": true, 106 | "schema": { 107 | "$ref": "#/definitions/Pet" 108 | } 109 | } 110 | ], 111 | "responses": { 112 | "400": { 113 | "description": "Invalid ID supplied" 114 | }, 115 | "404": { 116 | "description": "Pet not found" 117 | }, 118 | "405": { 119 | "description": "Validation exception" 120 | } 121 | }, 122 | "security": [ 123 | { 124 | "petstore_auth": [ 125 | "write:pets", 126 | "read:pets" 127 | ] 128 | } 129 | ] 130 | } 131 | }, 132 | "/pet/findByStatus": { 133 | "get": { 134 | "tags": [ 135 | "pet" 136 | ], 137 | "summary": "Finds Pets by status", 138 | "description": "Multiple status values can be provided with comma seperated strings", 139 | "operationId": "findPetsByStatus", 140 | "produces": [ 141 | "application/xml", 142 | "application/json" 143 | ], 144 | "parameters": [ 145 | { 146 | "name": "status", 147 | "in": "query", 148 | "description": "Status values that need to be considered for filter", 149 | "required": true, 150 | "type": "array", 151 | "items": { 152 | "type": "string", 153 | "enum": [ 154 | "available", 155 | "pending", 156 | "sold" 157 | ], 158 | "default": "available" 159 | }, 160 | "collectionFormat": "csv" 161 | } 162 | ], 163 | "responses": { 164 | "200": { 165 | "description": "successful operation", 166 | "schema": { 167 | "type": "array", 168 | "items": { 169 | "$ref": "#/definitions/Pet" 170 | } 171 | } 172 | }, 173 | "400": { 174 | "description": "Invalid status value" 175 | } 176 | }, 177 | "security": [ 178 | { 179 | "petstore_auth": [ 180 | "write:pets", 181 | "read:pets" 182 | ] 183 | } 184 | ] 185 | } 186 | }, 187 | "/pet/findByTags": { 188 | "get": { 189 | "tags": [ 190 | "pet" 191 | ], 192 | "summary": "Finds Pets by tags", 193 | "description": "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.", 194 | "operationId": "findPetsByTags", 195 | "produces": [ 196 | "application/xml", 197 | "application/json" 198 | ], 199 | "parameters": [ 200 | { 201 | "name": "tags", 202 | "in": "query", 203 | "description": "Tags to filter by", 204 | "required": true, 205 | "type": "array", 206 | "items": { 207 | "type": "string" 208 | }, 209 | "collectionFormat": "csv" 210 | } 211 | ], 212 | "responses": { 213 | "200": { 214 | "description": "successful operation", 215 | "schema": { 216 | "type": "array", 217 | "items": { 218 | "$ref": "#/definitions/Pet" 219 | } 220 | } 221 | }, 222 | "400": { 223 | "description": "Invalid tag value" 224 | } 225 | }, 226 | "security": [ 227 | { 228 | "petstore_auth": [ 229 | "write:pets", 230 | "read:pets" 231 | ] 232 | } 233 | ] 234 | } 235 | }, 236 | "/pet/{petId}": { 237 | "get": { 238 | "tags": [ 239 | "pet" 240 | ], 241 | "summary": "Find pet by ID", 242 | "description": "Returns a single pet", 243 | "operationId": "getPetById", 244 | "produces": [ 245 | "application/xml", 246 | "application/json" 247 | ], 248 | "parameters": [ 249 | { 250 | "name": "petId", 251 | "in": "path", 252 | "description": "ID of pet to return", 253 | "required": true, 254 | "type": "integer", 255 | "format": "int64" 256 | } 257 | ], 258 | "responses": { 259 | "200": { 260 | "description": "successful operation", 261 | "schema": { 262 | "$ref": "#/definitions/Pet" 263 | } 264 | }, 265 | "400": { 266 | "description": "Invalid ID supplied" 267 | }, 268 | "404": { 269 | "description": "Pet not found" 270 | } 271 | }, 272 | "security": [ 273 | { 274 | "api_key": [] 275 | } 276 | ] 277 | }, 278 | "post": { 279 | "tags": [ 280 | "pet" 281 | ], 282 | "summary": "Updates a pet in the store with form data", 283 | "description": "", 284 | "operationId": "updatePetWithForm", 285 | "consumes": [ 286 | "application/x-www-form-urlencoded" 287 | ], 288 | "produces": [ 289 | "application/xml", 290 | "application/json" 291 | ], 292 | "parameters": [ 293 | { 294 | "name": "petId", 295 | "in": "path", 296 | "description": "ID of pet that needs to be updated", 297 | "required": true, 298 | "type": "integer", 299 | "format": "int64" 300 | }, 301 | { 302 | "name": "name", 303 | "in": "formData", 304 | "description": "Updated name of the pet", 305 | "required": false, 306 | "type": "string" 307 | }, 308 | { 309 | "name": "status", 310 | "in": "formData", 311 | "description": "Updated status of the pet", 312 | "required": false, 313 | "type": "string" 314 | } 315 | ], 316 | "responses": { 317 | "405": { 318 | "description": "Invalid input" 319 | } 320 | }, 321 | "security": [ 322 | { 323 | "petstore_auth": [ 324 | "write:pets", 325 | "read:pets" 326 | ] 327 | } 328 | ] 329 | }, 330 | "delete": { 331 | "tags": [ 332 | "pet" 333 | ], 334 | "summary": "Deletes a pet", 335 | "description": "", 336 | "operationId": "deletePet", 337 | "produces": [ 338 | "application/xml", 339 | "application/json" 340 | ], 341 | "parameters": [ 342 | { 343 | "name": "api_key", 344 | "in": "header", 345 | "required": false, 346 | "type": "string" 347 | }, 348 | { 349 | "name": "petId", 350 | "in": "path", 351 | "description": "Pet id to delete", 352 | "required": true, 353 | "type": "integer", 354 | "format": "int64" 355 | } 356 | ], 357 | "responses": { 358 | "400": { 359 | "description": "Invalid pet value" 360 | } 361 | }, 362 | "security": [ 363 | { 364 | "petstore_auth": [ 365 | "write:pets", 366 | "read:pets" 367 | ] 368 | } 369 | ] 370 | } 371 | }, 372 | "/pet/{petId}/uploadImage": { 373 | "post": { 374 | "tags": [ 375 | "pet" 376 | ], 377 | "summary": "uploads an image", 378 | "description": "", 379 | "operationId": "uploadFile", 380 | "consumes": [ 381 | "multipart/form-data" 382 | ], 383 | "produces": [ 384 | "application/json" 385 | ], 386 | "parameters": [ 387 | { 388 | "name": "petId", 389 | "in": "path", 390 | "description": "ID of pet to update", 391 | "required": true, 392 | "type": "integer", 393 | "format": "int64" 394 | }, 395 | { 396 | "name": "additionalMetadata", 397 | "in": "formData", 398 | "description": "Additional data to pass to server", 399 | "required": false, 400 | "type": "string" 401 | }, 402 | { 403 | "name": "file", 404 | "in": "formData", 405 | "description": "file to upload", 406 | "required": false, 407 | "type": "file" 408 | } 409 | ], 410 | "responses": { 411 | "200": { 412 | "description": "successful operation", 413 | "schema": { 414 | "$ref": "#/definitions/ApiResponse" 415 | } 416 | } 417 | }, 418 | "security": [ 419 | { 420 | "petstore_auth": [ 421 | "write:pets", 422 | "read:pets" 423 | ] 424 | } 425 | ] 426 | } 427 | }, 428 | "/store/inventory": { 429 | "get": { 430 | "tags": [ 431 | "store" 432 | ], 433 | "summary": "Returns pet inventories by status", 434 | "description": "Returns a map of status codes to quantities", 435 | "operationId": "getInventory", 436 | "produces": [ 437 | "application/json" 438 | ], 439 | "parameters": [], 440 | "responses": { 441 | "200": { 442 | "description": "successful operation", 443 | "schema": { 444 | "type": "object", 445 | "additionalProperties": { 446 | "type": "integer", 447 | "format": "int32" 448 | } 449 | } 450 | } 451 | }, 452 | "security": [ 453 | { 454 | "api_key": [] 455 | } 456 | ] 457 | } 458 | }, 459 | "/store/order": { 460 | "post": { 461 | "tags": [ 462 | "store" 463 | ], 464 | "summary": "Place an order for a pet", 465 | "description": "", 466 | "operationId": "placeOrder", 467 | "produces": [ 468 | "application/xml", 469 | "application/json" 470 | ], 471 | "parameters": [ 472 | { 473 | "in": "body", 474 | "name": "body", 475 | "description": "order placed for purchasing the pet", 476 | "required": true, 477 | "schema": { 478 | "$ref": "#/definitions/Order" 479 | } 480 | } 481 | ], 482 | "responses": { 483 | "200": { 484 | "description": "successful operation", 485 | "schema": { 486 | "$ref": "#/definitions/Order" 487 | } 488 | }, 489 | "400": { 490 | "description": "Invalid Order" 491 | } 492 | } 493 | } 494 | }, 495 | "/store/order/{orderId}": { 496 | "get": { 497 | "tags": [ 498 | "store" 499 | ], 500 | "summary": "Find purchase order by ID", 501 | "description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", 502 | "operationId": "getOrderById", 503 | "produces": [ 504 | "application/xml", 505 | "application/json" 506 | ], 507 | "parameters": [ 508 | { 509 | "name": "orderId", 510 | "in": "path", 511 | "description": "ID of pet that needs to be fetched", 512 | "required": true, 513 | "type": "integer", 514 | "maximum": 5, 515 | "minimum": 1, 516 | "format": "int64" 517 | } 518 | ], 519 | "responses": { 520 | "200": { 521 | "description": "successful operation", 522 | "schema": { 523 | "$ref": "#/definitions/Order" 524 | } 525 | }, 526 | "400": { 527 | "description": "Invalid ID supplied" 528 | }, 529 | "404": { 530 | "description": "Order not found" 531 | } 532 | } 533 | }, 534 | "delete": { 535 | "tags": [ 536 | "store" 537 | ], 538 | "summary": "Delete purchase order by ID", 539 | "description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", 540 | "operationId": "deleteOrder", 541 | "produces": [ 542 | "application/xml", 543 | "application/json" 544 | ], 545 | "parameters": [ 546 | { 547 | "name": "orderId", 548 | "in": "path", 549 | "description": "ID of the order that needs to be deleted", 550 | "required": true, 551 | "type": "string", 552 | "minimum": 1 553 | } 554 | ], 555 | "responses": { 556 | "400": { 557 | "description": "Invalid ID supplied" 558 | }, 559 | "404": { 560 | "description": "Order not found" 561 | } 562 | } 563 | } 564 | }, 565 | "/user": { 566 | "post": { 567 | "tags": [ 568 | "user" 569 | ], 570 | "summary": "Create user", 571 | "description": "This can only be done by the logged in user.", 572 | "operationId": "createUser", 573 | "produces": [ 574 | "application/xml", 575 | "application/json" 576 | ], 577 | "parameters": [ 578 | { 579 | "in": "body", 580 | "name": "body", 581 | "description": "Created user object", 582 | "required": true, 583 | "schema": { 584 | "$ref": "#/definitions/User" 585 | } 586 | } 587 | ], 588 | "responses": { 589 | "default": { 590 | "description": "successful operation" 591 | } 592 | } 593 | } 594 | }, 595 | "/user/createWithArray": { 596 | "post": { 597 | "tags": [ 598 | "user" 599 | ], 600 | "summary": "Creates list of users with given input array", 601 | "description": "", 602 | "operationId": "createUsersWithArrayInput", 603 | "produces": [ 604 | "application/xml", 605 | "application/json" 606 | ], 607 | "parameters": [ 608 | { 609 | "in": "body", 610 | "name": "body", 611 | "description": "List of user object", 612 | "required": true, 613 | "schema": { 614 | "type": "array", 615 | "items": { 616 | "$ref": "#/definitions/User" 617 | } 618 | } 619 | } 620 | ], 621 | "responses": { 622 | "default": { 623 | "description": "successful operation" 624 | } 625 | } 626 | } 627 | }, 628 | "/user/createWithList": { 629 | "post": { 630 | "tags": [ 631 | "user" 632 | ], 633 | "summary": "Creates list of users with given input array", 634 | "description": "", 635 | "operationId": "createUsersWithListInput", 636 | "produces": [ 637 | "application/xml", 638 | "application/json" 639 | ], 640 | "parameters": [ 641 | { 642 | "in": "body", 643 | "name": "body", 644 | "description": "List of user object", 645 | "required": true, 646 | "schema": { 647 | "type": "array", 648 | "items": { 649 | "$ref": "#/definitions/User" 650 | } 651 | } 652 | } 653 | ], 654 | "responses": { 655 | "default": { 656 | "description": "successful operation" 657 | } 658 | } 659 | } 660 | }, 661 | "/user/login": { 662 | "get": { 663 | "tags": [ 664 | "user" 665 | ], 666 | "summary": "Logs user into the system", 667 | "description": "", 668 | "operationId": "loginUser", 669 | "produces": [ 670 | "application/xml", 671 | "application/json" 672 | ], 673 | "parameters": [ 674 | { 675 | "name": "username", 676 | "in": "query", 677 | "description": "The user name for login", 678 | "required": true, 679 | "type": "string" 680 | }, 681 | { 682 | "name": "password", 683 | "in": "query", 684 | "description": "The password for login in clear text", 685 | "required": true, 686 | "type": "string" 687 | } 688 | ], 689 | "responses": { 690 | "200": { 691 | "description": "successful operation", 692 | "schema": { 693 | "type": "string" 694 | }, 695 | "headers": { 696 | "X-Rate-Limit": { 697 | "type": "integer", 698 | "format": "int32", 699 | "description": "calls per hour allowed by the user" 700 | }, 701 | "X-Expires-After": { 702 | "type": "string", 703 | "format": "date-time", 704 | "description": "date in UTC when toekn expires" 705 | } 706 | } 707 | }, 708 | "400": { 709 | "description": "Invalid username/password supplied" 710 | } 711 | } 712 | } 713 | }, 714 | "/user/logout": { 715 | "get": { 716 | "tags": [ 717 | "user" 718 | ], 719 | "summary": "Logs out current logged in user session", 720 | "description": "", 721 | "operationId": "logoutUser", 722 | "produces": [ 723 | "application/xml", 724 | "application/json" 725 | ], 726 | "parameters": [], 727 | "responses": { 728 | "default": { 729 | "description": "successful operation" 730 | } 731 | } 732 | } 733 | }, 734 | "/user/{username}": { 735 | "get": { 736 | "tags": [ 737 | "user" 738 | ], 739 | "summary": "Get user by user name", 740 | "description": "", 741 | "operationId": "getUserByName", 742 | "produces": [ 743 | "application/xml", 744 | "application/json" 745 | ], 746 | "parameters": [ 747 | { 748 | "name": "username", 749 | "in": "path", 750 | "description": "The name that needs to be fetched. Use user1 for testing. ", 751 | "required": true, 752 | "type": "string" 753 | } 754 | ], 755 | "responses": { 756 | "200": { 757 | "description": "successful operation", 758 | "schema": { 759 | "$ref": "#/definitions/User" 760 | } 761 | }, 762 | "400": { 763 | "description": "Invalid username supplied" 764 | }, 765 | "404": { 766 | "description": "User not found" 767 | } 768 | } 769 | }, 770 | "put": { 771 | "tags": [ 772 | "user" 773 | ], 774 | "summary": "Updated user", 775 | "description": "This can only be done by the logged in user.", 776 | "operationId": "updateUser", 777 | "produces": [ 778 | "application/xml", 779 | "application/json" 780 | ], 781 | "parameters": [ 782 | { 783 | "name": "username", 784 | "in": "path", 785 | "description": "name that need to be deleted", 786 | "required": true, 787 | "type": "string" 788 | }, 789 | { 790 | "in": "body", 791 | "name": "body", 792 | "description": "Updated user object", 793 | "required": true, 794 | "schema": { 795 | "$ref": "#/definitions/User" 796 | } 797 | } 798 | ], 799 | "responses": { 800 | "400": { 801 | "description": "Invalid user supplied" 802 | }, 803 | "404": { 804 | "description": "User not found" 805 | } 806 | } 807 | }, 808 | "delete": { 809 | "tags": [ 810 | "user" 811 | ], 812 | "summary": "Delete user", 813 | "description": "This can only be done by the logged in user.", 814 | "operationId": "deleteUser", 815 | "produces": [ 816 | "application/xml", 817 | "application/json" 818 | ], 819 | "parameters": [ 820 | { 821 | "name": "username", 822 | "in": "path", 823 | "description": "The name that needs to be deleted", 824 | "required": true, 825 | "type": "string" 826 | } 827 | ], 828 | "responses": { 829 | "400": { 830 | "description": "Invalid username supplied" 831 | }, 832 | "404": { 833 | "description": "User not found" 834 | } 835 | } 836 | } 837 | } 838 | }, 839 | "securityDefinitions": { 840 | "petstore_auth": { 841 | "type": "oauth2", 842 | "authorizationUrl": "http://petstore.swagger.io/api/oauth/dialog", 843 | "flow": "implicit", 844 | "scopes": { 845 | "write:pets": "modify pets in your account", 846 | "read:pets": "read your pets" 847 | } 848 | }, 849 | "api_key": { 850 | "type": "apiKey", 851 | "name": "api_key", 852 | "in": "header" 853 | } 854 | }, 855 | "definitions": { 856 | "Order": { 857 | "type": "object", 858 | "properties": { 859 | "id": { 860 | "type": "integer", 861 | "format": "int64" 862 | }, 863 | "petId": { 864 | "type": "integer", 865 | "format": "int64" 866 | }, 867 | "quantity": { 868 | "type": "integer", 869 | "format": "int32" 870 | }, 871 | "shipDate": { 872 | "type": "string", 873 | "format": "date-time" 874 | }, 875 | "status": { 876 | "type": "string", 877 | "description": "Order Status", 878 | "enum": [ 879 | "placed", 880 | "approved", 881 | "delivered" 882 | ] 883 | }, 884 | "complete": { 885 | "type": "boolean", 886 | "default": false 887 | } 888 | }, 889 | "xml": { 890 | "name": "Order" 891 | } 892 | }, 893 | "Category": { 894 | "type": "object", 895 | "properties": { 896 | "id": { 897 | "type": "integer", 898 | "format": "int64" 899 | }, 900 | "name": { 901 | "type": "string" 902 | } 903 | }, 904 | "xml": { 905 | "name": "Category" 906 | } 907 | }, 908 | "User": { 909 | "type": "object", 910 | "properties": { 911 | "id": { 912 | "type": "integer", 913 | "format": "int64" 914 | }, 915 | "username": { 916 | "type": "string" 917 | }, 918 | "firstName": { 919 | "type": "string" 920 | }, 921 | "lastName": { 922 | "type": "string" 923 | }, 924 | "email": { 925 | "type": "string" 926 | }, 927 | "password": { 928 | "type": "string" 929 | }, 930 | "phone": { 931 | "type": "string" 932 | }, 933 | "userStatus": { 934 | "type": "integer", 935 | "format": "int32", 936 | "description": "User Status" 937 | } 938 | }, 939 | "xml": { 940 | "name": "User" 941 | } 942 | }, 943 | "Tag": { 944 | "type": "object", 945 | "properties": { 946 | "id": { 947 | "type": "integer", 948 | "format": "int64" 949 | }, 950 | "name": { 951 | "type": "string" 952 | } 953 | }, 954 | "xml": { 955 | "name": "Tag" 956 | } 957 | }, 958 | "ApiResponse": { 959 | "type": "object", 960 | "properties": { 961 | "code": { 962 | "type": "integer", 963 | "format": "int32" 964 | }, 965 | "type": { 966 | "type": "string" 967 | }, 968 | "message": { 969 | "type": "string" 970 | } 971 | } 972 | }, 973 | "Pet": { 974 | "type": "object", 975 | "required": [ 976 | "name", 977 | "photoUrls" 978 | ], 979 | "properties": { 980 | "id": { 981 | "type": "integer", 982 | "format": "int64" 983 | }, 984 | "category": { 985 | "$ref": "#/definitions/Category" 986 | }, 987 | "name": { 988 | "type": "string", 989 | "example": "doggie" 990 | }, 991 | "photoUrls": { 992 | "type": "array", 993 | "xml": { 994 | "name": "photoUrl", 995 | "wrapped": true 996 | }, 997 | "items": { 998 | "type": "string" 999 | } 1000 | }, 1001 | "tags": { 1002 | "type": "array", 1003 | "xml": { 1004 | "name": "tag", 1005 | "wrapped": true 1006 | }, 1007 | "items": { 1008 | "$ref": "#/definitions/Tag" 1009 | } 1010 | }, 1011 | "status": { 1012 | "type": "string", 1013 | "description": "pet status in the store", 1014 | "enum": [ 1015 | "available", 1016 | "pending", 1017 | "sold" 1018 | ] 1019 | } 1020 | }, 1021 | "xml": { 1022 | "name": "Pet" 1023 | } 1024 | } 1025 | }, 1026 | "externalDocs": { 1027 | "description": "Find out more about Swagger", 1028 | "url": "http://swagger.io" 1029 | } 1030 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "swagger-models-to-react-proptypes", 3 | "version": "1.1.0", 4 | "description": "CLI that generates React propType definitions from a swagger endpoint", 5 | "main": "bin/index.js", 6 | "bin": "bin/index.js", 7 | "scripts": { 8 | "fixtures": "./node_modules/node-static/bin/cli.js fixtures -p 1337 &", 9 | "test": "npm run fixtures && npm run test-1.2 && npm run test-2.0", 10 | "test-1.2": "./bin/index.js http://127.0.0.1:1337/fixture-v1.2.json", 11 | "test-2.0": "./bin/index.js http://127.0.0.1:1337/petstore-v2.0.json" 12 | }, 13 | "author": "Patrick Williams ", 14 | "license": "ISC", 15 | "dependencies": { 16 | "lodash": "^3.10.0", 17 | "swagger-client": "^2.1.1" 18 | }, 19 | "devDependencies": { 20 | "node-static": "^0.7.7" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /parsers/1.2.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | 3 | var indent = function (str) { 4 | return _.map(str.split('\n'), function (line) { 5 | return ' ' + line; 6 | }).join('\n'); 7 | } 8 | 9 | var missingRefPropType = function(props, propName, componentName) { 10 | return new Error('The propType for \'' + propName + '\' could not be determined due to a missing Swagger model definition reference. Perhaps try \'React.PropTypes.any\'?'); 11 | }; 12 | 13 | var unknownPropType = function(props, propName, componentName) { 14 | return new Error('The propType for \'' + propName + '\' could not be determined from Swagger model definition. Perhaps try \'React.PropTypes.any\'?'); 15 | }; 16 | 17 | var getPropType = function (definition) { 18 | if (definition.enum) { 19 | return 'React.PropTypes.oneOf(' + JSON.stringify(definition.enum, null, 4) + ')'; 20 | } 21 | if (definition.$ref) { 22 | var name = definition.$ref.match('#/definitions/(.*)')[1]; 23 | return name === 'undefined' ? missingRefPropType : 'PropTypes.' + name; 24 | } 25 | 26 | // treat it like an object definition if there's no type specificed 27 | if (!definition.type) { 28 | return 'React.PropTypes.shape({\n' 29 | + indent(_.map(definition.properties, function (property, name) { 30 | var keyPropType = convertDefinitionObjectToPropTypes(property, name); 31 | if (_.contains(definition.required || [], name)) { 32 | keyPropType += '.isRequired'; 33 | } 34 | return keyPropType; 35 | }).join(',\n')) + 36 | '\n})'; 37 | } 38 | 39 | switch (definition.type) { 40 | case 'array': 41 | return 'React.PropTypes.arrayOf(' + getPropType(definition.items) + ')'; 42 | case 'string': 43 | return 'React.PropTypes.string'; 44 | case 'integer': 45 | return 'React.PropTypes.number'; 46 | case 'boolean': 47 | return 'React.PropTypes.bool'; 48 | default: 49 | return unknownPropType; 50 | } 51 | }; 52 | 53 | var convertDefinitionObjectToPropTypes = function (definition, name) { 54 | return name + ': ' + getPropType(definition); 55 | }; 56 | 57 | module.exports = function (swagger) { 58 | var header = 'Generated PropTypes for ' + swagger.url; 59 | console.log('\n/**\n\n' + header + '\n' + new Array(header.length + 1).join('-') + '\n\n**/\n\n'); 60 | 61 | console.log('var PropTypes = {\n'); 62 | 63 | var propTypes = _.map(swagger.models, function (model, name) { 64 | return convertDefinitionObjectToPropTypes(model.definition, name); 65 | }); 66 | 67 | console.log(indent(propTypes.join(',\n\n'))); 68 | console.log('\n};\n\n'); 69 | }; -------------------------------------------------------------------------------- /parsers/2.0.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | 3 | var indent = function (str) { 4 | return _.map(str.split('\n'), function (line) { 5 | return ' ' + line; 6 | }).join('\n'); 7 | }; 8 | 9 | var missingRefPropType = function(props, propName, componentName) { 10 | return new Error('PropType could not be determined due to a missing Swagger model definition reference'); 11 | }; 12 | 13 | var unknownPropType = function(props, propName, componentName) { 14 | return new Error('PropType could not be determined from Swagger model definition'); 15 | }; 16 | 17 | var getPropType = function (definition) { 18 | if (definition.enum) { 19 | return 'React.PropTypes.oneOf(' + JSON.stringify(definition.enum, null, 4) + ')'; 20 | } 21 | if (definition.$ref) { 22 | var name = definition.$ref.match('#/definitions/(.*)')[1]; 23 | return name === 'undefined' ? missingRefPropType.toString() : 'PropTypes.' + name; 24 | } 25 | switch (definition.type) { 26 | case 'object': 27 | if(_.isEmpty(definition.properties)) { 28 | return 'React.PropTypes.object'; 29 | } 30 | return 'React.PropTypes.shape({\n' 31 | + indent(_.map(definition.properties, function (property, name) { 32 | var keyPropType = convertDefinitionObjectToPropTypes(property, name); 33 | if (_.contains(definition.required || [], name)) { 34 | keyPropType += '.isRequired'; 35 | } 36 | return keyPropType; 37 | }).join(',\n')) + 38 | '\n})'; 39 | case 'array': 40 | return 'React.PropTypes.arrayOf(' + getPropType(definition.items) + ')'; 41 | case 'string': 42 | return 'React.PropTypes.string'; 43 | case 'integer': 44 | case 'number': 45 | return 'React.PropTypes.number'; 46 | case 'boolean': 47 | return 'React.PropTypes.bool'; 48 | default: 49 | return unknownPropType.toString(); 50 | } 51 | }; 52 | 53 | var convertDefinitionObjectToPropTypes = function (definition, name) { 54 | return name + ': ' + getPropType(definition); 55 | }; 56 | 57 | module.exports = function (swagger) { 58 | var header = 'Generated PropTypes for ' + swagger.url; 59 | console.log('\n/**\n\n' + header + '\n' + new Array(header.length + 1).join('-') + '\n\n**/\n\n'); 60 | 61 | console.log('var PropTypes = {\n'); 62 | 63 | var propTypes = _.map(swagger.models, function (model, name) { 64 | return convertDefinitionObjectToPropTypes(model.definition, name); 65 | }); 66 | 67 | console.log(indent(propTypes.join(',\n\n'))); 68 | console.log('\n};\n\n'); 69 | }; --------------------------------------------------------------------------------