xporter_on_demand 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ceaf91f7c0ce11f34fde81948b9995d0d6ca9897
4
+ data.tar.gz: a815f2fa6e86d7fafcb1757e9082c8b6ca5b30cb
5
+ SHA512:
6
+ metadata.gz: 929d0d0e4609629fca2d12742b789e0f5983187a0b7c6fcd6065c2b996fa4313a98d7240606d2c6dc6012c59df409174840ceb007f6418fbb03d3cdc36ed3e9a
7
+ data.tar.gz: de14cee9e7c8b1fc5b606b9e48cb0b57de480e8ec2bcc82398eb6ea914dad412f36d6289df2aa1ec2673887a4fab5b0ae41da46d734241c2303895f8e2465fd9
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.15.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in xporter_on_demand.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Jordan Green
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # A Ruby client for the [XporterOnDemand API](https://xporter.groupcall.com/)
2
+
3
+ ## Installation
4
+ ```
5
+ gem install xod_client
6
+ ```
7
+
8
+ ## Getting started
9
+ ```ruby
10
+ require 'xporter_on_demand'
11
+
12
+ relying_party = "app.example.com" # Your relying party
13
+ school_estab = "1234567" # School establishment number
14
+ estab_secret = "YOUR SECRET HERE" # Supplied school secret
15
+
16
+ # Retrieve an IDAAS Authentication token
17
+ token = XporterOnDemand::Token.new(school_estab, relying_party, estab_secret).retrieve
18
+ # Initialize a client with the token
19
+ client = XporterOnDemand::Client.new(token.token)
20
+
21
+ # Craft a query with your desired options & parameters
22
+ students_endpoint = XporterOnDemand::Endpoint.create(:students, options: [:include_group_ids, :include_att_stats], parameters: { student_status: 'OnRoll' })
23
+
24
+ # Fetch the first page of results
25
+ student_results = client.query(students_endpoint)
26
+ # Retrieve all pages
27
+ student_results.fetch_all
28
+ ```
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "xporter_on_demand"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ module XporterOnDemand
2
+ module API
3
+ def fetch(endpoint)
4
+ raise ArgumentError, "endpoint must contain 'id' parameter" unless endpoint.id
5
+ create_result_set(get_endpoint(endpoint), endpoint)
6
+ end
7
+
8
+ def query(endpoint)
9
+ create_result_set(get_endpoint(endpoint), endpoint)
10
+ end
11
+
12
+ def changed_rows(endpoint)
13
+ raise ArgumentError, "endpoint must contain 'changed_rows' parameter" unless endpoint.parameters[:changed_rows]
14
+ create_result_set(get_endpoint(endpoint), endpoint)
15
+ end
16
+
17
+ def db_status(resource)
18
+ create_result_set(get(@uri + resource.to_s.camelize + "/?onlyGetDbStatus=true"))
19
+ end
20
+
21
+ def get_endpoint(endpoint)
22
+ get(@uri + endpoint.build_query)
23
+ end
24
+
25
+ private
26
+ def create_result_set(results, endpoint = nil)
27
+ XporterOnDemand::ResultSet.new(results).tap do |rs|
28
+ rs.attach_stuff(self, endpoint) if endpoint
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,43 @@
1
+ require 'httpi'
2
+ require 'json'
3
+ require 'active_support/core_ext/string'
4
+ require 'xporter_on_demand/utils'
5
+
6
+ module XporterOnDemand
7
+ class Client
8
+ include XporterOnDemand::API
9
+ include XporterOnDemand::Utils
10
+
11
+ attr_reader :token, :available_scopes, :estab, :uri
12
+
13
+ def initialize(token = nil, args = {})
14
+ @token = token
15
+ @args = args
16
+
17
+ details = token_details
18
+ @available_scopes = details["Scopes"]
19
+ @estab = @args.delete(:estab)
20
+ @estab ||= details["Estab"]
21
+
22
+ args[:edubase] ? edubase_client : school_client
23
+ end
24
+
25
+ %i(token_details scopes queries logs usage).each do |endpoint|
26
+ define_method(endpoint){ get_info(endpoint.to_s.camelcase) }
27
+ end
28
+
29
+ def school_client
30
+ @uri = API_PATH + "School/" + estab + "/"
31
+ end
32
+
33
+ # This is not finished and probably won't even work.
34
+ def edubase_client
35
+ @uri = API_PATH + "RunQuery/?"
36
+ end
37
+
38
+ private
39
+ def get_info(endpoint)
40
+ get(url: API_PATH + endpoint)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ require 'xporter_on_demand/factory'
2
+
3
+ module XporterOnDemand
4
+ class Endpoint
5
+ include XporterOnDemand::Utils
6
+
7
+ attr_accessor :endpoint, :options, :parameters, :pagination, :uri, :id
8
+
9
+ def self.create(endpoint, args = {})
10
+ endpoint_name = endpoint.to_s.classify
11
+
12
+ unless const_defined?(endpoint_name, false)
13
+ class_name = Class.new(self)
14
+ endpoint_class = const_set(endpoint_name, class_name)
15
+ end
16
+
17
+ const_get(endpoint_name).new(args).tap do |s|
18
+ s.instance_variable_set(:@endpoint, endpoint)
19
+ end
20
+ end
21
+
22
+ def initialize(args = {})
23
+ @options = args.fetch(:options, [])
24
+ @parameters = args.fetch(:parameters, {})
25
+
26
+ @parameters[:page] ||= 1
27
+ @parameters[:page_size] ||= 25
28
+
29
+ @id = args[:id]
30
+
31
+ # Check that all the options are valid?
32
+ # Check that the parameters are valid?
33
+ # Check the pagination params are valid?
34
+ end
35
+
36
+ def build_query
37
+ URI.escape(resource + "?" + build_parameters)
38
+ end
39
+
40
+ private
41
+ def resource
42
+ endpoint.to_s.camelize + "/" + (@id || "")
43
+ end
44
+
45
+ def build_options
46
+ @options.any? ? ["options=" + @options.map{ |o| parameterize(o) }.join(',')] : []
47
+ end
48
+
49
+ def build_parameters
50
+ (@parameters.map{ |k, v| parameterize(k) + "=" + v.to_s } + build_options).join('&')
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,19 @@
1
+ module XporterOnDemand
2
+ module Factory
3
+ def self.create(name, superclass, args = {})
4
+ i_vars = args.delete(:i_vars) || {}
5
+ namespace = args.delete(:namespace) || superclass
6
+
7
+ unless namespace.const_defined?(name, false)
8
+ s_class = Class.new(superclass)
9
+ namespace.const_set(name, s_class)
10
+ end
11
+
12
+ namespace.const_get(name).new(args).tap do |klass|
13
+ i_vars.each do |i_var, value|
14
+ klass.instance_variable_set(i_var, value)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module XporterOnDemand
2
+ module Result
3
+ class Base
4
+ include XporterOnDemand::Utils
5
+
6
+ def initialize(args = {})
7
+ result = args.delete(:result)
8
+ assign_attributes(result)
9
+ end
10
+
11
+ def type
12
+ self.class.name.demodulize
13
+ end
14
+
15
+ def update(other_result)
16
+ return if other_result.type != type ||\
17
+ other_result.id != id ||\
18
+ other_result.last_updated <= last_updated
19
+
20
+ attributes.each do |attribute|
21
+ send("#{attribute}=", other_result.send(attribute))
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,82 @@
1
+ module XporterOnDemand
2
+ class ResultSet
3
+ include Enumerable
4
+ include XporterOnDemand::Utils
5
+
6
+ attr_accessor :results, :school, :endpoint
7
+
8
+ def initialize(result_hash)
9
+ results = create_results(result_hash)
10
+ assign_attributes results
11
+ end
12
+
13
+ def each
14
+ all.each{ |result| yield result }
15
+ end
16
+
17
+ def all
18
+ attributes.reject{ |a| META_KEYS.include? a.camelcase }.flat_map{ |a| send(a) }
19
+ end
20
+
21
+ def length
22
+ all.length
23
+ end
24
+
25
+ def fetch_all
26
+ return self unless try :pagination
27
+ og_page = pagination.page_number
28
+
29
+ pagination.page_count.times do |i|
30
+ # Skip if we've already got this page
31
+ next if og_page == i + 1
32
+
33
+ endpoint.parameters[:page] = i + 1
34
+
35
+ results_hash = create_results(school.get_endpoint(endpoint))
36
+
37
+ results_hash.each do |type, results|
38
+ if META_KEYS.include? type.camelcase
39
+ assign_attributes(type => results)
40
+ elsif self.respond_to?(type)
41
+ results.each do |result|
42
+ if result.respond_to?(:id) && existing_result = send(type).find{ |r| r.id == result.id }
43
+ existing_result.update(result)
44
+ else
45
+ send(type).append(result)
46
+ end
47
+ end
48
+ else
49
+ assign_attributes(type => results)
50
+ end
51
+ end
52
+ end
53
+ self
54
+ end
55
+
56
+ def attach_stuff(sch, ep)
57
+ self.school = sch
58
+ self.endpoint = ep.dup
59
+ end
60
+
61
+ private
62
+ def create_results(result_hash)
63
+ result_hash.map do |namespace, objects|
64
+ type = namespace.underscore.camelize
65
+ result_objects = objects.flat_map{ |object| create_result(type, object) }
66
+
67
+ [namespace.underscore, result_objects]
68
+ end.to_h
69
+ end
70
+
71
+ # def create_result(type, object)
72
+ # Factory.create(
73
+ # META_KEYS.include?(type) ? type : type.singularize,
74
+ # XporterOnDemand::Result::Base,
75
+ # {
76
+ # namespace: XporterOnDemand::Result,
77
+ # result: object
78
+ # }
79
+ # )
80
+ # end
81
+ end
82
+ end
@@ -0,0 +1,57 @@
1
+ module XporterOnDemand
2
+ module Result
3
+ class Serialiser
4
+ FORMAT_REGISTRY = Hash.new{ |h, k| h[k] = { type: :default } }.update(
5
+ active: { type: :boolean },
6
+ date: { type: :date },
7
+ dateof_birth: { type: :date },
8
+ date_of_birth: { type: :date },
9
+ date_time: { type: :date_time },
10
+ eal: { type: :boolean },
11
+ expires: { type: :date_time },
12
+ fsm_eligible: { type: :boolean },
13
+ fsm_ever6: { type: :boolean },
14
+ gifted: { type: :boolean },
15
+ in_lea_care: { type: :boolean },
16
+ last_updated: { type: :date_time },
17
+ par_resp: { type: :boolean },
18
+ pupil_premium: { type: :boolean },
19
+ service_child: { type: :boolean },
20
+ uniform_allowance: { type: :boolean }
21
+ )
22
+
23
+ FORMATTERS = {
24
+ boolean: ->(v){ !!v.nonzero? },
25
+ csv: ->(v){ v.split(',') rescue [] },
26
+ date: ->(v){ Date.parse(v) rescue nil },
27
+ date_time: ->(v){ DateTime.parse(v) rescue nil },
28
+ default: ->(v){ v },
29
+ }
30
+
31
+ def self.serialise(attributes)
32
+ object_array = attributes.map do |attribute, value|
33
+ key = attribute.underscore
34
+ format = get_format(key)
35
+
36
+ [key, FORMATTERS[format].call(value)]
37
+ end
38
+ object_array.to_h
39
+ end
40
+
41
+ private
42
+ def self.get_format(key)
43
+ if key =~ /_ids\z/
44
+ :csv
45
+ elsif key =~ /(_?date\z|(start|end)\z)/
46
+ :date
47
+ elsif key =~ /_date_time\z/
48
+ :date_time
49
+ elsif key =~ /\Ais_/
50
+ :boolean
51
+ else
52
+ FORMAT_REGISTRY[key.to_sym][:type]
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,20 @@
1
+ module XporterOnDemand
2
+ class Token < Client
3
+ def initialize(*args)
4
+ @options = args.last.is_a?(Hash) ? args.pop : {}
5
+ @options[:url] ||= STS_PATH
6
+
7
+ @request_body = {}
8
+ %w(estab relyingParty password thirdpartyid).each_with_index{ |k, i| @request_body[k] = args[i] }
9
+
10
+ @request_body["thirdpartyid"] ||= "XporterOnDemand"
11
+ raise ArgumentError, "must supply all the sniz" unless @request_body.none?{ |k, v| v.nil? }
12
+ end
13
+
14
+ def retrieve
15
+ result = post(@options.merge(body: @request_body.to_json))
16
+ assign_attributes(result)
17
+ self
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,68 @@
1
+ module XporterOnDemand
2
+ module Utils
3
+ [:get, :post].each do |verb|
4
+ define_method(verb) do |*args|
5
+ request = configure_request(*args)
6
+ response = HTTPI.request(verb, request)
7
+ handle_exceptions(response)
8
+ JSON.parse(response.body.presence || {})
9
+ end
10
+ end
11
+
12
+ def configure_request(*args)
13
+ request = HTTPI::Request.new(*args)
14
+ request.headers["Content-Type"] = "application/json"
15
+ request.headers["Authorization"] = "Idaas " + @token if @token
16
+ request
17
+ end
18
+
19
+ def handle_exceptions(response)
20
+ response_body = JSON.parse(response.body || {})
21
+ raise response_body["ExceptionMessage"] if response_body["ExceptionMessage"]
22
+ end
23
+
24
+ def parameterize(sym)
25
+ sym.to_s.camelize(:lower)
26
+ end
27
+
28
+ def assign_attributes(attributes)
29
+ unless instance_variable_defined?("@attributes")
30
+ instance_variable_set("@attributes", [])
31
+ self.class.send(:attr_reader, :attributes)
32
+ end
33
+
34
+ XporterOnDemand::Result::Serialiser.serialise(attributes).each do |name, value|
35
+ method_name = name.camelize.underscore
36
+ unless META_KEYS.include?(name.camelize)
37
+ method_name = method_name.singularize if value.is_a?(Array) && value.length == 1
38
+ end
39
+
40
+ instance_variable_set("@#{method_name}", unwrap(value))
41
+ self.class.send(:attr_reader, method_name)
42
+
43
+ @attributes |= [method_name]
44
+ end
45
+ end
46
+
47
+ def create_result(type, object)
48
+ Factory.create(
49
+ META_KEYS.include?(type) ? type : type.singularize,
50
+ XporterOnDemand::Result::Base,
51
+ {
52
+ namespace: XporterOnDemand::Result,
53
+ result: object,
54
+ }
55
+ )
56
+ end
57
+
58
+ def unwrap(enum)
59
+ if enum.is_a?(Array)
60
+ enum.length <= 1 ? enum.first || [] : enum
61
+ elsif enum.is_a?(Hash)
62
+ enum.length == 1 ? unwrap(enum[enum.keys.first]) : enum
63
+ else
64
+ enum
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,3 @@
1
+ module XporterOnDemand
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,22 @@
1
+ # require "xporter_on_demand/version"
2
+ # require 'xporter_on_demand/client'
3
+ # require 'xporter_on_demand/token'
4
+ # # require 'xporter_on_demand/utils'
5
+ # require 'xporter_on_demand/result/serialiser'
6
+
7
+ require 'xporter_on_demand/api'
8
+ require 'xporter_on_demand/client'
9
+ require 'xporter_on_demand/endpoint'
10
+ require 'xporter_on_demand/factory'
11
+ require 'xporter_on_demand/token'
12
+ require 'xporter_on_demand/utils'
13
+ require 'xporter_on_demand/version'
14
+ require 'xporter_on_demand/result/base'
15
+ require 'xporter_on_demand/result/result_set'
16
+ require 'xporter_on_demand/result/serialiser'
17
+
18
+ module XporterOnDemand
19
+ API_PATH = "https://xporter.groupcall.com/api/v1/"
20
+ STS_PATH = "https://login.groupcall.com/idaas/sts/STS/GetToken"
21
+ META_KEYS = %w(ChangedRows DbStatus Meta Pagination)
22
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "xporter_on_demand/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "xporter_on_demand"
8
+ spec.version = XporterOnDemand::VERSION
9
+ spec.authors = ["Jordan Green"]
10
+ spec.email = ["jordan.green@meritec.co.uk"]
11
+
12
+ spec.summary = %q{Ruby client for the Xporter on Demand API.}
13
+ spec.homepage = "https://github.com/meritec/xporter_on_demand"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_runtime_dependency 'httpi', '~> 2.4.2', '>= 2.4.2'
24
+ # Gotta use httpclient cos net_http don't like the __foo__ JSON keys
25
+ spec.add_runtime_dependency 'httpclient', '~> 2.8.3', '>= 2.8.3'
26
+ spec.add_runtime_dependency 'activesupport', '~> 5.0.0.1', '>= 5.0.0.1'
27
+ spec.add_development_dependency "bundler", "~> 1.15"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "minitest", "~> 5.0"
30
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xporter_on_demand
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jordan Green
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-12-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httpi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.4.2
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.4.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 2.4.2
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.4.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: httpclient
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 2.8.3
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.8.3
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 2.8.3
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.8.3
53
+ - !ruby/object:Gem::Dependency
54
+ name: activesupport
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: 5.0.0.1
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 5.0.0.1
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 5.0.0.1
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 5.0.0.1
73
+ - !ruby/object:Gem::Dependency
74
+ name: bundler
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '1.15'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '1.15'
87
+ - !ruby/object:Gem::Dependency
88
+ name: rake
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '10.0'
94
+ type: :development
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: '10.0'
101
+ - !ruby/object:Gem::Dependency
102
+ name: minitest
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '5.0'
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '5.0'
115
+ description:
116
+ email:
117
+ - jordan.green@meritec.co.uk
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - ".gitignore"
123
+ - ".travis.yml"
124
+ - Gemfile
125
+ - LICENSE.txt
126
+ - README.md
127
+ - Rakefile
128
+ - bin/console
129
+ - bin/setup
130
+ - lib/xporter_on_demand.rb
131
+ - lib/xporter_on_demand/api.rb
132
+ - lib/xporter_on_demand/client.rb
133
+ - lib/xporter_on_demand/endpoint.rb
134
+ - lib/xporter_on_demand/factory.rb
135
+ - lib/xporter_on_demand/result/base.rb
136
+ - lib/xporter_on_demand/result/result_set.rb
137
+ - lib/xporter_on_demand/result/serialiser.rb
138
+ - lib/xporter_on_demand/token.rb
139
+ - lib/xporter_on_demand/utils.rb
140
+ - lib/xporter_on_demand/version.rb
141
+ - xporter_on_demand.gemspec
142
+ homepage: https://github.com/meritec/xporter_on_demand
143
+ licenses:
144
+ - MIT
145
+ metadata: {}
146
+ post_install_message:
147
+ rdoc_options: []
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ requirements: []
161
+ rubyforge_project:
162
+ rubygems_version: 2.6.12
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: Ruby client for the Xporter on Demand API.
166
+ test_files: []