diesel-api-dsl 0.1.3 → 0.1.5
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.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/diesel.gemspec +1 -1
- data/lib/diesel/api_builder.rb +82 -32
- data/lib/diesel/api_group.rb +3 -2
- data/lib/diesel/middleware/auth/api_key.rb +13 -1
- data/lib/diesel/middleware/auth/basic.rb +27 -0
- data/lib/diesel/middleware/auth/oauth2.rb +2 -2
- data/lib/diesel/middleware/convert_json_body.rb +15 -0
- data/lib/diesel/middleware/set_body_parameter.rb +5 -1
- data/lib/diesel/middleware/set_path_parameter.rb +2 -1
- data/lib/diesel/request_context.rb +7 -1
- data/lib/diesel/swagger/definition.rb +1 -1
- data/lib/diesel/swagger/operation.rb +3 -1
- data/lib/diesel/swagger/parser.rb +25 -9
- data/lib/diesel/uri.rb +36 -0
- data/lib/diesel/version.rb +1 -1
- data/spec/diesel/api_builder_spec.rb +9 -3
- data/spec/diesel/swagger/parser_spec.rb +14 -0
- data/spec/diesel_spec.rb +173 -56
- data/spec/files/github.json +186 -0
- data/spec/files/harvest.json +75 -0
- data/spec/files/mandrill.json +502 -0
- data/spec/files/uber.json +43 -0
- data/spec/fixtures/vcr_cassettes/github_checkAuthorization.yml +71 -0
- data/spec/fixtures/vcr_cassettes/github_getUser.yml +82 -0
- data/spec/fixtures/vcr_cassettes/harvest_invoiceList.yml +85 -0
- data/spec/fixtures/vcr_cassettes/mandrill_userPing.yml +44 -0
- data/spec/fixtures/vcr_cassettes/uber_getProducts.yml +60 -0
- data/spec/spec_helper.rb +1 -0
- metadata +28 -6
    
        data/lib/diesel/version.rb
    CHANGED
    
    
| @@ -3,12 +3,18 @@ require 'diesel' | |
| 3 3 |  | 
| 4 4 | 
             
            describe Diesel::APIBuilder do
         | 
| 5 5 |  | 
| 6 | 
            -
               | 
| 7 | 
            -
                Diesel.parse_specification(File.join(File.dirname(__FILE__), '..', 'files',  | 
| 6 | 
            +
              def build_spec(name)
         | 
| 7 | 
            +
                Diesel.parse_specification(File.join(File.dirname(__FILE__), '..', 'files', "#{name}.json"))
         | 
| 8 8 | 
             
              end
         | 
| 9 9 |  | 
| 10 10 | 
             
              it "should build a API class from specification" do
         | 
| 11 | 
            -
                api = Diesel::APIBuilder.new( | 
| 11 | 
            +
                api = Diesel::APIBuilder.new(build_spec("pivotal_tracker")).build
         | 
| 12 | 
            +
                expect(api).to_not be_nil
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              it "should build a API class from specification" do
         | 
| 16 | 
            +
                api = Diesel::APIBuilder.new(build_spec("mandrill")).build
         | 
| 17 | 
            +
                expect(api).to_not be_nil
         | 
| 12 18 | 
             
              end
         | 
| 13 19 |  | 
| 14 20 | 
             
            end
         | 
| @@ -90,4 +90,18 @@ describe Diesel::Swagger::Parser do | |
| 90 90 | 
             
                expect(attachments_prop.items.count).to eq 1
         | 
| 91 91 | 
             
                expect(attachments_prop.items["$ref"]).to eq '#/definitions/Attachment'
         | 
| 92 92 | 
             
              end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
              it "should parse a swagger specification with operation specific security" do
         | 
| 95 | 
            +
                specification = Diesel::Swagger::Parser.new.parse(load_spec('github'))
         | 
| 96 | 
            +
                op = specification.paths["/applications/{clientId}/tokens/{accessToken}"].get
         | 
| 97 | 
            +
                expect(op.security["basic"]).to_not be_nil
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              it "should parse nested schema objects" do
         | 
| 101 | 
            +
                specification = Diesel::Swagger::Parser.new.parse(load_spec('mandrill'))
         | 
| 102 | 
            +
                op = specification.paths["/messages/send.json"].post
         | 
| 103 | 
            +
                request_param = op.parameters.first
         | 
| 104 | 
            +
                expect(specification.consumes).to include "application/json"
         | 
| 105 | 
            +
                expect(request_param.schema.class).to eq Diesel::Swagger::Definition
         | 
| 106 | 
            +
              end
         | 
| 93 107 | 
             
            end
         | 
    
        data/spec/diesel_spec.rb
    CHANGED
    
    | @@ -4,74 +4,191 @@ require 'logger' | |
| 4 4 |  | 
| 5 5 | 
             
            describe Diesel do
         | 
| 6 6 |  | 
| 7 | 
            +
              def configure_client(client)
         | 
| 8 | 
            +
                #client.logger = Logger.new(STDOUT)
         | 
| 9 | 
            +
                #client.logger.level = Logger::DEBUG
         | 
| 10 | 
            +
                client
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 7 13 | 
             
              def load_api(name)
         | 
| 8 14 | 
             
                fn = File.join(File.dirname(__FILE__), 'files', "#{name}.json")
         | 
| 9 15 | 
             
                Diesel.load_api(fn)
         | 
| 10 16 | 
             
              end
         | 
| 11 17 |  | 
| 12 | 
            -
               | 
| 13 | 
            -
                 | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
                 | 
| 17 | 
            -
             | 
| 18 | 
            -
                 | 
| 19 | 
            -
                   | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
                     | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 18 | 
            +
              describe "Pivotal Tracker API" do
         | 
| 19 | 
            +
                before do
         | 
| 20 | 
            +
                  PivotalTracker = load_api('pivotal_tracker')
         | 
| 21 | 
            +
                  @client = configure_client(PivotalTracker.new(api_token: 'afaketoken'))
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                after do
         | 
| 25 | 
            +
                  Object.send(:remove_const, :PivotalTracker)
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                it "should be able to build a client" do
         | 
| 29 | 
            +
                  VCR.use_cassette('pivotal_tracker_create_story') do
         | 
| 30 | 
            +
                    result = @client.create_story(
         | 
| 31 | 
            +
                      project_id: '1053124',
         | 
| 32 | 
            +
                      story: {
         | 
| 33 | 
            +
                        name: 'Testing Pivotal API',
         | 
| 34 | 
            +
                        story_type: :chore
         | 
| 35 | 
            +
                      })
         | 
| 36 | 
            +
                    expect(result['kind']).to eq 'story'
         | 
| 37 | 
            +
                    expect(result).to have_key('id')
         | 
| 38 | 
            +
                    expect(result.response.code).to eq "200"
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              describe "Honeybadger API" do
         | 
| 44 | 
            +
                before do
         | 
| 45 | 
            +
                  Honeybadger = load_api('honeybadger')
         | 
| 46 | 
            +
                  @client = configure_client(Honeybadger.new(auth_token: 'afaketoken'))
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                after do
         | 
| 50 | 
            +
                  Object.send(:remove_const, :Honeybadger)
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                it "should be able to build a Honeybadger API client" do
         | 
| 54 | 
            +
                  VCR.use_cassette('honeybadger') do
         | 
| 55 | 
            +
                    results = @client.get_faults(project_id: 3167)
         | 
| 56 | 
            +
                    expect(results['results'].first).to have_key('project_id')
         | 
| 57 | 
            +
                    expect(results.response.code).to eq "200"
         | 
| 58 | 
            +
                  end
         | 
| 28 59 | 
             
                end
         | 
| 29 60 | 
             
              end
         | 
| 30 61 |  | 
| 31 | 
            -
               | 
| 32 | 
            -
                 | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
                 | 
| 62 | 
            +
              describe "Slack API" do
         | 
| 63 | 
            +
                before do
         | 
| 64 | 
            +
                  Slack = load_api('slack')
         | 
| 65 | 
            +
                  @client = configure_client(Slack.new)
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                after do
         | 
| 69 | 
            +
                  Object.send(:remove_const, :Slack)
         | 
| 70 | 
            +
                end
         | 
| 36 71 |  | 
| 37 | 
            -
                 | 
| 38 | 
            -
                   | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 72 | 
            +
                it "should be able to build a Slack API client" do
         | 
| 73 | 
            +
                  VCR.use_cassette('slack') do
         | 
| 74 | 
            +
                    results = @client.post_message(path: 'abcd/efgh/ijkl',
         | 
| 75 | 
            +
                                                   payload: {
         | 
| 76 | 
            +
                                                     text: 'Testing',
         | 
| 77 | 
            +
                                                     username: 'TestBot',
         | 
| 78 | 
            +
                                                     attachments: [{
         | 
| 79 | 
            +
                                                       fallback: "test fallback text",
         | 
| 80 | 
            +
                                                       text: "test text",
         | 
| 81 | 
            +
                                                       pretext: "test pretext",
         | 
| 82 | 
            +
                                                       fields: [{
         | 
| 83 | 
            +
                                                         title: "test field 1",
         | 
| 84 | 
            +
                                                         value: "test value 1"
         | 
| 85 | 
            +
                                                       },{
         | 
| 86 | 
            +
                                                         title: "test field 2",
         | 
| 87 | 
            +
                                                         value: "test value 2"
         | 
| 88 | 
            +
                                                       }]
         | 
| 89 | 
            +
                                                     }]
         | 
| 90 | 
            +
                                                   })
         | 
| 91 | 
            +
                    expect(results.response.code).to eq "200"
         | 
| 92 | 
            +
                    expect(results.parsed_response).to eq "ok"
         | 
| 93 | 
            +
                  end
         | 
| 41 94 | 
             
                end
         | 
| 42 95 | 
             
              end
         | 
| 43 96 |  | 
| 44 | 
            -
               | 
| 45 | 
            -
                 | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 97 | 
            +
              describe "Github API" do
         | 
| 98 | 
            +
                before do
         | 
| 99 | 
            +
                  Github = load_api("github")
         | 
| 100 | 
            +
                  @client = configure_client(Github.new(
         | 
| 101 | 
            +
                    oauth2: { token: "afaketoken" },
         | 
| 102 | 
            +
                    basic: {
         | 
| 103 | 
            +
                      username: "afakeclientid",
         | 
| 104 | 
            +
                      password: "afakeclientsecret"
         | 
| 105 | 
            +
                    }
         | 
| 106 | 
            +
                  ))
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                after do
         | 
| 110 | 
            +
                  Object.send(:remove_const, :Github)
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                it "should be able to call a zero parameter operation" do
         | 
| 114 | 
            +
                  VCR.use_cassette('github_getUser') do
         | 
| 115 | 
            +
                    results = @client.get_user
         | 
| 116 | 
            +
                    expect(results.response.code).to eq "200"
         | 
| 117 | 
            +
                    expect(results.parsed_response['login']).to eq "cyu"
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                it "should be able to use the appropriate security scheme" do
         | 
| 122 | 
            +
                  VCR.use_cassette('github_checkAuthorization') do
         | 
| 123 | 
            +
                    results = @client.check_authorization(
         | 
| 124 | 
            +
                      client_id: "afakeclientid",
         | 
| 125 | 
            +
                      access_token: "afakeaccesstoken"
         | 
| 126 | 
            +
                    )
         | 
| 127 | 
            +
                    expect(results.response.code).to eq "200"
         | 
| 128 | 
            +
                  end
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              describe "Uber API" do
         | 
| 133 | 
            +
                before do
         | 
| 134 | 
            +
                  Uber = load_api("uber")
         | 
| 135 | 
            +
                  @client = configure_client(Uber.new(
         | 
| 136 | 
            +
                    server_token: "TEST_SERVER_TOKEN"
         | 
| 137 | 
            +
                  ))
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                after do
         | 
| 141 | 
            +
                  Object.send(:remove_const, :Uber)
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                it "should be able to support x-format extension for apiKey" do
         | 
| 145 | 
            +
                  VCR.use_cassette('uber_getProducts') do
         | 
| 146 | 
            +
                    results = @client.get_products(latitude: 33.776776, longitude: -84.389683)
         | 
| 147 | 
            +
                    expect(results.response.code).to eq "200"
         | 
| 148 | 
            +
                    expect(results.parsed_response["products"].length).to eq 5
         | 
| 149 | 
            +
                  end
         | 
| 150 | 
            +
                end
         | 
| 151 | 
            +
              end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
              describe "Mandrill API" do
         | 
| 154 | 
            +
                before do
         | 
| 155 | 
            +
                  Mandrill = load_api("mandrill")
         | 
| 156 | 
            +
                  @client = configure_client(Mandrill.new(
         | 
| 157 | 
            +
                    key: "fakekey"
         | 
| 158 | 
            +
                  ))
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                after do
         | 
| 162 | 
            +
                  Object.send(:remove_const, :Mandrill)
         | 
| 163 | 
            +
                end
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                it "should be able to support apiKey in JSON body" do
         | 
| 166 | 
            +
                  VCR.use_cassette('mandrill_userPing') do
         | 
| 167 | 
            +
                    result = @client.user_ping
         | 
| 168 | 
            +
                    expect(result.parsed_response).to eq "PONG!"
         | 
| 169 | 
            +
                  end
         | 
| 170 | 
            +
                end
         | 
| 171 | 
            +
              end
         | 
| 172 | 
            +
             | 
| 173 | 
            +
              describe "Harvest API" do
         | 
| 174 | 
            +
                before do
         | 
| 175 | 
            +
                  Harvest = load_api("harvest")
         | 
| 176 | 
            +
                  @client = configure_client(Harvest.new(
         | 
| 177 | 
            +
                    subdomain: "fakedomain",
         | 
| 178 | 
            +
                    oauth2: {
         | 
| 179 | 
            +
                      token: "faketoken"
         | 
| 180 | 
            +
                    }))
         | 
| 181 | 
            +
                end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                after do
         | 
| 184 | 
            +
                  Object.send(:remove_const, :Harvest)
         | 
| 185 | 
            +
                end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                it "should be able to x-base-host extension" do
         | 
| 188 | 
            +
                  VCR.use_cassette('harvest_invoiceList') do
         | 
| 189 | 
            +
                    result = @client.invoice_list
         | 
| 190 | 
            +
                    expect(result.length).to eq 2
         | 
| 191 | 
            +
                  end
         | 
| 75 192 | 
             
                end
         | 
| 76 193 | 
             
              end
         | 
| 77 194 | 
             
            end
         | 
| @@ -0,0 +1,186 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "swagger": "2.0",
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              "info": {
         | 
| 5 | 
            +
                "title": "Github",
         | 
| 6 | 
            +
                "version": "3"
         | 
| 7 | 
            +
              },
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              "host": "api.github.com",
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              "basePath": "/",
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              "schemes": ["https"],
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              "produces": ["application/json"],
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              "securityDefinitions": {
         | 
| 18 | 
            +
                "oauth2": {
         | 
| 19 | 
            +
                  "type": "oauth2",
         | 
| 20 | 
            +
                  "flow": "accessCode",
         | 
| 21 | 
            +
                  "authorizationUrl": "https://github.com/login/oauth/authorize",
         | 
| 22 | 
            +
                  "tokenUrl": "https://github.com/login/oauth/access_token",
         | 
| 23 | 
            +
                  "scopes": {
         | 
| 24 | 
            +
                    "user": "Grants read/write access to profile info only.",
         | 
| 25 | 
            +
                    "user:email": "Grants read access to a user’s email addresses.",
         | 
| 26 | 
            +
                    "user:follow": "Grants access to follow or unfollow other users.",
         | 
| 27 | 
            +
                    "public_repo": "Grants read/write access to code, commit statuses, collaborators, and deployment statuses for public repositories and organizations.",
         | 
| 28 | 
            +
                    "repo": "Grants read/write access to code, commit statuses, collaborators, and deployment statuses for public and private repositories and organizations.",
         | 
| 29 | 
            +
                    "repo_deployment": "Grants access to deployment statuses for public and private repositories.",
         | 
| 30 | 
            +
                    "repo:status": "Grants read/write access to public and private repository commit statuses.",
         | 
| 31 | 
            +
                    "delete_repo": "Grants access to delete adminable repositories.",
         | 
| 32 | 
            +
                    "notifications": "Grants read access to a user’s notifications.",
         | 
| 33 | 
            +
                    "gist": "Grants write access to gists.",
         | 
| 34 | 
            +
                    "read:repo_hook": "Grants read and ping access to hooks in public or private repositories.",
         | 
| 35 | 
            +
                    "write:repo_hook": "Grants read, write, and ping access to hooks in public or private repositories.",
         | 
| 36 | 
            +
                    "admin:repo_hook": "Grants read, write, ping, and delete access to hooks in public or private repositories.",
         | 
| 37 | 
            +
                    "admin:org_hook": "Grants read, write, ping, and delete access to organization hooks.",
         | 
| 38 | 
            +
                    "read:org": "Read-only access to organization, teams, and membership.",
         | 
| 39 | 
            +
                    "write:org": "Publicize and unpublicize organization membership.",
         | 
| 40 | 
            +
                    "admin:org": "Fully manage organization, teams, and memberships.",
         | 
| 41 | 
            +
                    "read:public_key": "List and view details for public keys.",
         | 
| 42 | 
            +
                    "write:public_key": "Create, list, and view details for public keys.",
         | 
| 43 | 
            +
                    "admin:public_key": "Fully manage public keys."
         | 
| 44 | 
            +
                  }
         | 
| 45 | 
            +
                },
         | 
| 46 | 
            +
                "basic": {
         | 
| 47 | 
            +
                  "type": "basic"
         | 
| 48 | 
            +
                }
         | 
| 49 | 
            +
              },
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              "security": {
         | 
| 52 | 
            +
                "oauth2": []
         | 
| 53 | 
            +
              },
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              "paths": {
         | 
| 56 | 
            +
                "/user": {
         | 
| 57 | 
            +
                  "get": {
         | 
| 58 | 
            +
                    "summary": "Get the authenticated user",
         | 
| 59 | 
            +
                    "operationId": "getUser"
         | 
| 60 | 
            +
                  }
         | 
| 61 | 
            +
                },
         | 
| 62 | 
            +
                "/user/emails": {
         | 
| 63 | 
            +
                  "get": {
         | 
| 64 | 
            +
                    "summary": "List email addresses for a user",
         | 
| 65 | 
            +
                    "operationId": "getUserEmails",
         | 
| 66 | 
            +
                    "security": {
         | 
| 67 | 
            +
                      "basic": ["user:email"]
         | 
| 68 | 
            +
                    }
         | 
| 69 | 
            +
                  }
         | 
| 70 | 
            +
                },
         | 
| 71 | 
            +
                "/user/repos": {
         | 
| 72 | 
            +
                  "get": {
         | 
| 73 | 
            +
                    "summary": "List repositories that are accessible to the authenticated user.",
         | 
| 74 | 
            +
                    "operationId": "getUserRepos",
         | 
| 75 | 
            +
                    "parameters": [{
         | 
| 76 | 
            +
                      "name": "visibility",
         | 
| 77 | 
            +
                      "in": "query",
         | 
| 78 | 
            +
                      "enum": [
         | 
| 79 | 
            +
                        "all",
         | 
| 80 | 
            +
                        "public",
         | 
| 81 | 
            +
                        "private"
         | 
| 82 | 
            +
                      ]
         | 
| 83 | 
            +
                    }, {
         | 
| 84 | 
            +
                      "name": "affiliation",
         | 
| 85 | 
            +
                      "in": "query"
         | 
| 86 | 
            +
                    }, {
         | 
| 87 | 
            +
                      "name": "type",
         | 
| 88 | 
            +
                      "in": "query",
         | 
| 89 | 
            +
                      "enum": [
         | 
| 90 | 
            +
                        "all",
         | 
| 91 | 
            +
                        "owner",
         | 
| 92 | 
            +
                        "public",
         | 
| 93 | 
            +
                        "private",
         | 
| 94 | 
            +
                        "member"
         | 
| 95 | 
            +
                      ]
         | 
| 96 | 
            +
                    }, {
         | 
| 97 | 
            +
                      "name": "sort",
         | 
| 98 | 
            +
                      "in": "query",
         | 
| 99 | 
            +
                      "enum": [
         | 
| 100 | 
            +
                        "created",
         | 
| 101 | 
            +
                        "updated",
         | 
| 102 | 
            +
                        "pushed",
         | 
| 103 | 
            +
                        "full_name"
         | 
| 104 | 
            +
                      ]
         | 
| 105 | 
            +
                    }, {
         | 
| 106 | 
            +
                      "name": "direction",
         | 
| 107 | 
            +
                      "in": "query",
         | 
| 108 | 
            +
                      "enum": [
         | 
| 109 | 
            +
                        "asc",
         | 
| 110 | 
            +
                        "desc"
         | 
| 111 | 
            +
                      ]
         | 
| 112 | 
            +
                    }]
         | 
| 113 | 
            +
                  }
         | 
| 114 | 
            +
                },
         | 
| 115 | 
            +
                "/user/orgs": {
         | 
| 116 | 
            +
                  "get": {
         | 
| 117 | 
            +
                    "summary": "List organizations for the authenticated user",
         | 
| 118 | 
            +
                    "operationId": "getUserOrgs",
         | 
| 119 | 
            +
                    "security": {
         | 
| 120 | 
            +
                      "oauth2": [
         | 
| 121 | 
            +
                        "user",
         | 
| 122 | 
            +
                        "read:org"
         | 
| 123 | 
            +
                      ]
         | 
| 124 | 
            +
                    }
         | 
| 125 | 
            +
                  }
         | 
| 126 | 
            +
                },
         | 
| 127 | 
            +
                "/orgs/{org}/repos": {
         | 
| 128 | 
            +
                  "get": {
         | 
| 129 | 
            +
                    "summary": "List repositories for the specified org",
         | 
| 130 | 
            +
                    "operationId": "getOrgRepos",
         | 
| 131 | 
            +
                    "parameters": [{
         | 
| 132 | 
            +
                      "name": "org",
         | 
| 133 | 
            +
                      "in": "path",
         | 
| 134 | 
            +
                      "required": true
         | 
| 135 | 
            +
                    }, {
         | 
| 136 | 
            +
                      "name": "type",
         | 
| 137 | 
            +
                      "in": "query",
         | 
| 138 | 
            +
                      "enum": [
         | 
| 139 | 
            +
                        "all",
         | 
| 140 | 
            +
                        "public",
         | 
| 141 | 
            +
                        "private",
         | 
| 142 | 
            +
                        "forks",
         | 
| 143 | 
            +
                        "sources",
         | 
| 144 | 
            +
                        "member"
         | 
| 145 | 
            +
                      ]
         | 
| 146 | 
            +
                    }]
         | 
| 147 | 
            +
                  }
         | 
| 148 | 
            +
                },
         | 
| 149 | 
            +
                "/repos/{owner}/{repo}/issues/{number}": {
         | 
| 150 | 
            +
                  "get": {
         | 
| 151 | 
            +
                    "summary": "Get a single issue",
         | 
| 152 | 
            +
                    "operationId": "getIssue",
         | 
| 153 | 
            +
                    "parameters": [{
         | 
| 154 | 
            +
                      "name": "owner",
         | 
| 155 | 
            +
                      "in": "path",
         | 
| 156 | 
            +
                      "required": true
         | 
| 157 | 
            +
                    },{
         | 
| 158 | 
            +
                      "name": "repo",
         | 
| 159 | 
            +
                      "in": "path",
         | 
| 160 | 
            +
                      "required": true
         | 
| 161 | 
            +
                    },{
         | 
| 162 | 
            +
                      "name": "number",
         | 
| 163 | 
            +
                      "in": "path",
         | 
| 164 | 
            +
                      "required": true
         | 
| 165 | 
            +
                    }]
         | 
| 166 | 
            +
                  }
         | 
| 167 | 
            +
                },
         | 
| 168 | 
            +
                "/applications/{clientId}/tokens/{accessToken}": {
         | 
| 169 | 
            +
                  "get": {
         | 
| 170 | 
            +
                    "operationId": "checkAuthorization",
         | 
| 171 | 
            +
                    "parameters": [{
         | 
| 172 | 
            +
                      "name": "clientId",
         | 
| 173 | 
            +
                      "in": "path",
         | 
| 174 | 
            +
                      "required": true
         | 
| 175 | 
            +
                    },{
         | 
| 176 | 
            +
                      "name": "accessToken",
         | 
| 177 | 
            +
                      "in": "path",
         | 
| 178 | 
            +
                      "required": true
         | 
| 179 | 
            +
                    }],
         | 
| 180 | 
            +
                    "security": {
         | 
| 181 | 
            +
                      "basic": []
         | 
| 182 | 
            +
                    }
         | 
| 183 | 
            +
                  }
         | 
| 184 | 
            +
                }
         | 
| 185 | 
            +
              }
         | 
| 186 | 
            +
            }
         |