orderspace-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ab5e3c865f82ea7b2797a52f607b6460da31a21564e87dd737500345640c179d
4
+ data.tar.gz: 72c899077ef985f60547a3d3f51bac54667c80ac15f9dabb67c95468f70c2c6c
5
+ SHA512:
6
+ metadata.gz: b4e33f5a8bb0e08247db43c0fab02f319eb7319801d23431d3c7291974fb5de664d61e7ab954dad568cbf3f8e57978e5cfb08e28d60306241ef63130309de944
7
+ data.tar.gz: 0f32c14f8b8d0fcc24a5187e45011d5a89500fff6c2383d2306bd26cac2124465b70b9c558efa50b9a96eacd801fca7c9b33da25f6f400abd4275a9810da5018
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.standard.yml ADDED
@@ -0,0 +1,3 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/testdouble/standard
3
+ ruby_version: 3.1.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2022-12-01
4
+
5
+ - Initial release connecting to the oauth, customers and orders endpoints as well as parsing webhook events.
@@ -0,0 +1,84 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment for our community include:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17
+ * Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behavior include:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or
22
+ advances of any kind
23
+ * Trolling, insulting or derogatory comments, and personal or political attacks
24
+ * Public or private harassment
25
+ * Publishing others' private information, such as a physical or email
26
+ address, without their explicit permission
27
+ * Other conduct which could reasonably be considered inappropriate in a
28
+ professional setting
29
+
30
+ ## Enforcement Responsibilities
31
+
32
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
33
+
34
+ Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
35
+
36
+ ## Scope
37
+
38
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
39
+
40
+ ## Enforcement
41
+
42
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at enrique@ecomba.pro. All complaints will be reviewed and investigated promptly and fairly.
43
+
44
+ All community leaders are obligated to respect the privacy and security of the reporter of any incident.
45
+
46
+ ## Enforcement Guidelines
47
+
48
+ Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
49
+
50
+ ### 1. Correction
51
+
52
+ **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
53
+
54
+ **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
55
+
56
+ ### 2. Warning
57
+
58
+ **Community Impact**: A violation through a single incident or series of actions.
59
+
60
+ **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
61
+
62
+ ### 3. Temporary Ban
63
+
64
+ **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
65
+
66
+ **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
67
+
68
+ ### 4. Permanent Ban
69
+
70
+ **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
71
+
72
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
73
+
74
+ ## Attribution
75
+
76
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
77
+ available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
78
+
79
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
80
+
81
+ [homepage]: https://www.contributor-covenant.org
82
+
83
+ For answers to common questions about this code of conduct, see the FAQ at
84
+ https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in orderspace-ruby.gemspec
6
+ gemspec
7
+
8
+ gem 'rake', '~> 13.0'
9
+ gem 'rspec', '~> 3.0'
10
+ gem 'standard', '~> 1.3'
11
+ gem 'webmock'
12
+ gem 'simplecov'
data/Gemfile.lock ADDED
@@ -0,0 +1,90 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ orderspace-ruby (0.1.0)
5
+ httparty (= 0.20.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ addressable (2.8.1)
11
+ public_suffix (>= 2.0.2, < 6.0)
12
+ ast (2.4.2)
13
+ crack (0.4.5)
14
+ rexml
15
+ diff-lcs (1.5.0)
16
+ docile (1.4.0)
17
+ hashdiff (1.0.1)
18
+ httparty (0.20.0)
19
+ mime-types (~> 3.0)
20
+ multi_xml (>= 0.5.2)
21
+ json (2.6.2)
22
+ mime-types (3.4.1)
23
+ mime-types-data (~> 3.2015)
24
+ mime-types-data (3.2022.0105)
25
+ multi_xml (0.6.0)
26
+ parallel (1.22.1)
27
+ parser (3.1.3.0)
28
+ ast (~> 2.4.1)
29
+ public_suffix (5.0.0)
30
+ rainbow (3.1.1)
31
+ rake (13.0.6)
32
+ regexp_parser (2.6.1)
33
+ rexml (3.2.5)
34
+ rspec (3.12.0)
35
+ rspec-core (~> 3.12.0)
36
+ rspec-expectations (~> 3.12.0)
37
+ rspec-mocks (~> 3.12.0)
38
+ rspec-core (3.12.0)
39
+ rspec-support (~> 3.12.0)
40
+ rspec-expectations (3.12.0)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.12.0)
43
+ rspec-mocks (3.12.0)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.12.0)
46
+ rspec-support (3.12.0)
47
+ rubocop (1.39.0)
48
+ json (~> 2.3)
49
+ parallel (~> 1.10)
50
+ parser (>= 3.1.2.1)
51
+ rainbow (>= 2.2.2, < 4.0)
52
+ regexp_parser (>= 1.8, < 3.0)
53
+ rexml (>= 3.2.5, < 4.0)
54
+ rubocop-ast (>= 1.23.0, < 2.0)
55
+ ruby-progressbar (~> 1.7)
56
+ unicode-display_width (>= 1.4.0, < 3.0)
57
+ rubocop-ast (1.24.0)
58
+ parser (>= 3.1.1.0)
59
+ rubocop-performance (1.15.1)
60
+ rubocop (>= 1.7.0, < 2.0)
61
+ rubocop-ast (>= 0.4.0)
62
+ ruby-progressbar (1.11.0)
63
+ simplecov (0.21.2)
64
+ docile (~> 1.1)
65
+ simplecov-html (~> 0.11)
66
+ simplecov_json_formatter (~> 0.1)
67
+ simplecov-html (0.12.3)
68
+ simplecov_json_formatter (0.1.4)
69
+ standard (1.18.1)
70
+ rubocop (= 1.39.0)
71
+ rubocop-performance (= 1.15.1)
72
+ unicode-display_width (2.3.0)
73
+ webmock (3.18.1)
74
+ addressable (>= 2.8.0)
75
+ crack (>= 0.3.2)
76
+ hashdiff (>= 0.4.0, < 2.0.0)
77
+
78
+ PLATFORMS
79
+ arm64-darwin-21
80
+
81
+ DEPENDENCIES
82
+ orderspace-ruby!
83
+ rake (~> 13.0)
84
+ rspec (~> 3.0)
85
+ simplecov
86
+ standard (~> 1.3)
87
+ webmock
88
+
89
+ BUNDLED WITH
90
+ 2.3.21
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Enrique Comba Riepenhausen
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,197 @@
1
+ # Bean Mind Orderspace Ruby Client
2
+
3
+ :bomb: **This gem is under development, USE AT YOUR OWN RISK**
4
+
5
+ A Ruby client to connect and use the Orderspace API (https://apidocs.orderspace.com/).
6
+
7
+ ![Orderspace Logo](orderspace-logo.png)
8
+
9
+ ## Installation
10
+
11
+ Install the gem and add to the application's Gemfile by executing:
12
+
13
+ $ bundle add orderspace-ruby
14
+
15
+ If bundler is not being used to manage dependencies, install the gem by executing:
16
+
17
+ $ gem install orderspace-ruby
18
+
19
+ ## Usage
20
+
21
+ Before you start you will have to setup a _"private app"_ in Orderspace.
22
+
23
+ ```https://[your_company_name].orderspace.com/admin/apps/new```
24
+
25
+ In the form you will have to name the app and add a contact email address. Once you've done so, you will be given
26
+ a `client_id` and a `client_secret`. These two values are the ones you'll need when using this client.
27
+
28
+ ### Initialising the client
29
+
30
+ The client is initialised with the `client_id` and the `client_secret` you acquired when setting up a new private app
31
+ in Orderspace as described above.
32
+
33
+ ```ruby
34
+ client = Orderspace::Client.with(client_id, client_secret)
35
+ ```
36
+
37
+ This will use the OAuth endpoint to grab the `auth token` and insert it in the headers for each subsequent call to the API.
38
+
39
+ Please note that Orderspace's Auth tokens work for a limited time.
40
+
41
+ :warning: DO NOT STORE YOUR AUTH TOKEN AS IT MIGHT NOT WORK IN LATER REQUESTS! :warning:
42
+
43
+ ### Customers Endpoint
44
+
45
+ Things you can do with the customers endpoint.
46
+
47
+ #### Creating a customer
48
+
49
+ ```ruby
50
+ customer = Orderspace::Structs::Customer.new.tap do |c|
51
+ c.company_name = "Your Customers Company"
52
+ # other attributes you might want to set.
53
+ end
54
+
55
+ # This customer will have an id as assigned by Orderspace during creation
56
+ created_customer = client.customers.create_customer(customer)
57
+ ```
58
+
59
+ #### Listing customers
60
+
61
+ Listing customers will return a `Orderspace::Structs::CustomerList` struct.
62
+
63
+ ```ruby
64
+ customers = client.customers.list_customers
65
+ ```
66
+
67
+ You can also pass options to narrow your list down like so:
68
+
69
+ ```ruby
70
+ options = { query: { limit: 42, status: 'active' } }
71
+ customers = client.customers.list_customers(options)
72
+ ```
73
+
74
+ Refer to the [list customers](https://apidocs.orderspace.com/#list-customers) endpoint documentation for further options you can use.
75
+
76
+ #### Getting a customer
77
+
78
+ ```ruby
79
+ customer_id = 'cu_dnwz8gnx'
80
+ customer = client.customers.get_customer(customer_id)
81
+ ```
82
+
83
+ #### Updating a customer
84
+
85
+ To update a customer you will have to first get the customer (so that the id and other fields are properly populated).
86
+
87
+ ```ruby
88
+ customer = client.customers.get_customer(customer_id)
89
+ customer.company_name = "New Company Name"
90
+
91
+ updated_customer = client.customers.edit_customer(customer)
92
+ ```
93
+
94
+ ### Orders Endpoint
95
+
96
+ Things you can do with orders.
97
+
98
+ #### List orders
99
+
100
+ Listing orders will return a `Orderspace::Structs::OrderList` struct.
101
+
102
+ ```ruby
103
+ orders = client.orders.list_orders
104
+ ```
105
+
106
+ You can also pass options to narrow your list down like so:
107
+
108
+ ```ruby
109
+ options = { query: { limit: 20, status: 'preorder' } }
110
+ orders = client.orders.list_orders(options)
111
+ ```
112
+
113
+ Refer to the [list orders](https://apidocs.orderspace.com/#list-orders) endpoint documentation for further options you can use.
114
+
115
+ #### Getting an order
116
+
117
+ ```ruby
118
+ order_id = 'or_l5DYqeDn'
119
+ order = client.orders.get_order(order_id)
120
+ ```
121
+
122
+ ### Webhooks Endpoint
123
+
124
+ Things you can do with webhooks.
125
+
126
+ #### Creating a webhook
127
+
128
+ ```ruby
129
+ webhook = Orderspace::Structs::Webhook.new.tap do |w|
130
+ w.endpoint = 'https://your/uri/to/receive/the/event'
131
+ w.events = %w[order.created dispatch.created]
132
+ end
133
+
134
+ new_webhook = client.webhooks.create(webhook)
135
+ ```
136
+
137
+ #### Listing webhooks
138
+
139
+ Listing webhooks will return a `Orderspace::Structs::WebhookList` struct.
140
+
141
+ ```ruby
142
+ webhooks = client.webhooks.list_webhooks
143
+ ```
144
+
145
+ #### Getting a webhook
146
+
147
+ ```ruby
148
+ webhook_id = 'wh_o9ernm4p'
149
+ webhook = client.webhooks.get_webhook(webhook_id)
150
+ ```
151
+
152
+ #### Updating a webhook
153
+
154
+ To update a webhook you will have to first get the webhook (so that the id field is properly populated).
155
+
156
+ ```ruby
157
+ webhook = client.webhooks.get_webhook(webhook_id)
158
+ webhook.events = %w[order.created order.deleted]
159
+
160
+ updated_webhook = client.webhooks.update_webhook(webhook)
161
+ ```
162
+
163
+ #### Deleting a webhook
164
+
165
+ To delete a webhook you will have to first get the webhook (so that the id field is properly populated).
166
+
167
+ It will return a `Orderspace::Structs::Webhook` struct with only it's `id` and `deleted` attributes as a confirmation.
168
+
169
+ ```ruby
170
+ webhook = client.webhooks.get_webhook(webhook_id)
171
+ deleted = client.webhooks.delete_webhook(webhook)
172
+ ```
173
+
174
+ ## Development
175
+
176
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
177
+
178
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
179
+
180
+ ## Contributing
181
+
182
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bean-mind/orderspace-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/orderspace-ruby/blob/main/CODE_OF_CONDUCT.md).
183
+
184
+ ## License
185
+
186
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
187
+
188
+ ## Code of Conduct
189
+
190
+ Everyone interacting in the Orderspace::Ruby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/bean-mind/orderspace-ruby/blob/main/CODE_OF_CONDUCT.md).
191
+
192
+ ## Bean Mind
193
+
194
+ This gem was created by [Bean Mind](https://beanmind.com) as part of the [Orderspace](https://www.orderspace.com) integration work
195
+ in our product.
196
+
197
+ ![Bean Mind](beanmind.svg)
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[spec standard]
data/beanmind.svg ADDED
@@ -0,0 +1,50 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 284 283" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:square;stroke-miterlimit:1.5;">
4
+ <g transform="matrix(1,0,0,1,-374.926,-351.162)">
5
+ <g id="Brain-mesh" serif:id="Brain mesh">
6
+ <g id="Layer1">
7
+ <path d="M450.335,633.979L514.98,576.351L563.917,575.572L586,534.937L636.823,533.51L658.665,477.801L628.127,429.901L552.961,397.447L499.215,401.398L397.477,437.725L374.926,476.631L381.042,514.036L407.483,541.91L415.115,565.172L454.579,571.421L450.335,633.979ZM456.153,622.094L459.877,567.198L418.913,560.712C418.913,560.712 411.884,539.284 411.884,539.284L385.728,511.711C385.728,511.711 380.149,477.59 380.149,477.59C380.149,477.59 400.884,441.818 400.884,441.818C400.884,441.818 500.257,406.335 500.257,406.335C500.257,406.335 552.104,402.523 552.104,402.523C552.104,402.523 624.736,433.883 624.736,433.883C624.736,433.883 653.082,478.344 653.082,478.344C653.082,478.344 633.376,528.605 633.376,528.605C633.376,528.605 582.982,530.019 582.982,530.019L560.918,570.619C560.918,570.619 513.041,571.381 513.041,571.381L456.153,622.094Z" style="fill:rgb(95,95,95);"/>
8
+ </g>
9
+ <g id="Layer2">
10
+ <path d="M478.422,570.959L516.796,552.829L584.264,533.059L655.034,475.462L599.569,449.102L555.293,402.349L534.806,460.234L599.569,449.102L584.264,533.059L534.806,460.234L488.559,513.955L584.264,533.059L488.559,513.955L430.706,513.955L378.63,478.007L430.706,513.955L458.785,448.169L398.684,441.01L458.785,448.169L500.022,402.893L458.785,448.169L534.806,460.234L458.785,448.169L488.559,513.955L430.706,513.955L408.262,538.765L458.087,568.187L488.559,513.955L478.422,570.959Z" style="fill:none;stroke:rgb(95,95,95);stroke-width:4px;"/>
11
+ <path d="M454.579,626.514L478.422,570.959L489.303,515.713L514.98,552.834L514.98,570.959" style="fill:none;stroke:rgb(95,95,95);stroke-width:4px;"/>
12
+ </g>
13
+ </g>
14
+ <g id="Circles">
15
+ <g transform="matrix(-0.000954338,0.781568,-0.781568,-0.000954338,429.901,516.847)">
16
+ <circle cx="0" cy="0" r="9.492" style="fill:rgb(102,153,153);stroke:rgb(95,95,95);stroke-width:7.68px;stroke-linecap:round;stroke-linejoin:round;"/>
17
+ </g>
18
+ <g transform="matrix(-0.175695,0.98794,-0.98794,-0.175695,488.453,511.672)">
19
+ <circle cx="0" cy="0" r="9.492" style="fill:rgb(255,102,51);stroke:rgb(95,95,95);stroke-width:5.98px;stroke-linecap:round;stroke-linejoin:round;"/>
20
+ </g>
21
+ <g transform="matrix(-0.0115577,0.776699,-0.776699,-0.0115577,458.546,449.12)">
22
+ <circle cx="0" cy="0" r="9.492" style="fill:white;stroke:rgb(95,95,95);stroke-width:7.72px;stroke-linecap:round;stroke-linejoin:round;"/>
23
+ </g>
24
+ <g transform="matrix(-0.0115577,0.776699,-0.776699,-0.0115577,540,386.276)">
25
+ <circle cx="0" cy="0" r="9.492" style="fill:rgb(0,255,51);stroke:rgb(95,95,95);stroke-width:7.72px;stroke-linecap:round;stroke-linejoin:round;"/>
26
+ </g>
27
+ <g transform="matrix(-0.0115577,0.776699,-0.776699,-0.0115577,565.31,361.535)">
28
+ <circle cx="0" cy="0" r="9.492" style="fill:white;stroke:rgb(95,95,95);stroke-width:7.72px;stroke-linecap:round;stroke-linejoin:round;"/>
29
+ </g>
30
+ <g transform="matrix(-0.088091,1.23528,-1.23528,-0.088091,534.681,459.842)">
31
+ <circle cx="0" cy="0" r="9.492" style="fill:rgb(255,0,153);stroke:rgb(95,95,95);stroke-width:4.84px;stroke-linecap:round;stroke-linejoin:round;"/>
32
+ </g>
33
+ <g transform="matrix(0.0737842,1.12488,-1.12488,0.0737842,499.078,404.349)">
34
+ <circle cx="0" cy="0" r="9.492" style="fill:rgb(255,102,51);stroke:rgb(95,95,95);stroke-width:5.32px;stroke-linecap:round;stroke-linejoin:round;"/>
35
+ </g>
36
+ <g transform="matrix(0.0737842,1.12488,-1.12488,0.0737842,589.89,386.747)">
37
+ <circle cx="0" cy="0" r="9.492" style="fill:rgb(255,0,153);stroke:rgb(95,95,95);stroke-width:5.32px;stroke-linecap:round;stroke-linejoin:round;"/>
38
+ </g>
39
+ <g transform="matrix(-0.105076,0.878331,-0.878331,-0.105076,599.664,450.617)">
40
+ <circle cx="0" cy="0" r="9.492" style="fill:rgb(102,153,153);stroke:rgb(95,95,95);stroke-width:6.78px;stroke-linecap:round;stroke-linejoin:round;"/>
41
+ </g>
42
+ <g transform="matrix(-0.0781548,1.05963,-1.05963,-0.0781548,582.768,531.351)">
43
+ <circle cx="0" cy="0" r="9.492" style="fill:rgb(0,255,51);stroke:rgb(95,95,95);stroke-width:5.65px;stroke-linecap:round;stroke-linejoin:round;"/>
44
+ </g>
45
+ <g transform="matrix(-0.0115577,0.776699,-0.776699,-0.0115577,452.99,571.176)">
46
+ <circle cx="0" cy="0" r="9.492" style="fill:white;stroke:rgb(95,95,95);stroke-width:7.72px;stroke-linecap:round;stroke-linejoin:round;"/>
47
+ </g>
48
+ </g>
49
+ </g>
50
+ </svg>
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httparty'
4
+
5
+ module Orderspace
6
+ ##
7
+ # This class is the entrypoint to the Orderspace API
8
+ #
9
+ # To obtain an access token you will have to have registered a private application
10
+ # with Orderspace (https://<your_space>.orderspace.com/admin/apps/new).
11
+ # This will give you the client_id and client_secret you need in order to get your access token.
12
+ #
13
+ # client = Client.with(client_key, client_secret)
14
+ class Client
15
+
16
+ include Default
17
+
18
+ HEADER_AUTHORIZATION = 'Authorization'
19
+ API_VERSION = 'v1'
20
+
21
+ attr_reader :access_token
22
+
23
+ def initialize(access_token = nil)
24
+ @access_token = access_token
25
+ end
26
+
27
+ def self.with(client_id, client_secret)
28
+ credentials = new.oauth.obtain_access_token(client_id, client_secret)
29
+ new(credentials.access_token)
30
+ end
31
+
32
+ ##
33
+ # Represents the base url to Orderspace's API (i.e. https://api.orderspace.com/)
34
+ # @return [String] the base url to Orderspace's API
35
+ def self.base_url
36
+ BASE_URL
37
+ end
38
+
39
+ ##
40
+ # Represents the URL to the Orderspace API with it's version (i.e. https://api.orderspace.com/v1/)
41
+ # @return [String] the versioned Orderspace API url
42
+ def self.versioned_url
43
+ "#{base_url}#{API_VERSION}/"
44
+ end
45
+
46
+ ##
47
+ # Returns the oauth endpoint
48
+ def oauth
49
+ OauthEndpoint.new(self)
50
+ end
51
+
52
+ ##
53
+ # Returns the customers endpoint
54
+ def customers
55
+ CustomersEndpoint.new(self)
56
+ end
57
+
58
+ ##
59
+ # Returns the orders endpoint
60
+ def orders
61
+ OrdersEndpoint.new(self)
62
+ end
63
+
64
+ ##
65
+ # Returns the webhooks endpoint
66
+ def webhooks
67
+ WebhooksEndpoint.new(self)
68
+ end
69
+
70
+ class OauthEndpoint < Orderspace::Endpoint
71
+ include Orderspace::Endpoint::Oauth
72
+ end
73
+
74
+ class CustomersEndpoint < Orderspace::Endpoint
75
+ include Orderspace::Endpoint::Customers
76
+ end
77
+
78
+ class OrdersEndpoint < Orderspace::Endpoint
79
+ include Orderspace::Endpoint::Orders
80
+ end
81
+
82
+ class WebhooksEndpoint < Orderspace::Endpoint
83
+ include Orderspace::Endpoint::Webhooks
84
+ end
85
+
86
+ def get(path, options = {})
87
+ execute(:get, path, nil, options.to_h)
88
+ end
89
+
90
+ def post(path, data = nil, options = {})
91
+ execute(:post, path, data, options)
92
+ end
93
+
94
+ def put(path, data = nil, options = {})
95
+ execute(:put, path, data, options)
96
+ end
97
+
98
+ def delete(path, data = nil, options = {})
99
+ execute(:delete, path, data, options)
100
+ end
101
+
102
+ def execute(method, path, data = nil, options = {})
103
+ uri = Client.versioned_url + path
104
+ response = request(method, uri, data, options)
105
+
106
+ case response.code
107
+ when 200..299
108
+ response
109
+ when 400
110
+ raise BadRequestError, response
111
+ when 401
112
+ raise AuthorizationFailedError, response
113
+ when 404
114
+ raise NotFoundError, response
115
+ when 422
116
+ raise UnprocessableEntityError, response
117
+ when 429
118
+ raise TooManyRequestsError, response
119
+ when 500
120
+ raise InternalServerError, response
121
+ else
122
+ raise RequestError, response
123
+ end
124
+ end
125
+
126
+ def request(method, uri, data = nil, options = {})
127
+ request_options = add_custom_request_options(options)
128
+
129
+ request_options[:headers]['Authorization'] = "Bearer #{@access_token}" if @access_token
130
+
131
+ if data
132
+ request_options[:headers]['Content-Type'] = 'application/json'
133
+ request_options[:body] = JSON.dump(data)
134
+ end
135
+
136
+ HTTParty.send(method, uri, request_options)
137
+ end
138
+
139
+ def add_custom_request_options(custom_options)
140
+ base_request_options.tap do |options|
141
+ custom_options.each do |key, value|
142
+ options[key] = value
143
+ end
144
+ end
145
+ end
146
+
147
+ def base_request_options
148
+ {
149
+ format: :json,
150
+ headers: {
151
+ 'Accept' => 'application/json',
152
+ 'User-Agent' => USER_AGENT
153
+ }
154
+ }
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ ##
5
+ # Module to compile the default settings
6
+ module Default
7
+
8
+ # Default Orderspace API endpoint
9
+ BASE_URL = 'https://api.orderspace.com/'
10
+
11
+ # Default User-Agent header
12
+ USER_AGENT = "beanmind-orderspace-ruby/#{VERSION}".freeze
13
+ end
14
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ class Endpoint
5
+ ##
6
+ # Contains the methods to interact with the customers endpoint.
7
+ # @see https://apidocs.orderspace.com/#customers
8
+ module Customers
9
+ include Orderspace::Structs
10
+
11
+ ##
12
+ # Used to add a customer to your orderspace account
13
+ #
14
+ # @see https://apidocs.orderspace.com/#create-a-customer
15
+ #
16
+ # @param customer [Orderspace::Structs::Customer] The customer to be added
17
+ # @return [Orderspace::Structs::Customer] The customer added (including the generated id)
18
+ def create_customer(customer)
19
+ response = client.post('customers', { customer: Orderspace::Structs.hashify(customer) })
20
+ Orderspace::Structs.from(JSON.parse(response.body)['customer'], Customer)
21
+ end
22
+
23
+ ##
24
+ # Lists all the customers in your account.
25
+ #
26
+ # You can pass in options like so:
27
+ # { query: { starting_after: 'cu_53zjgvnm', limit: 1 } }
28
+ #
29
+ # Check tho orderspace API documentation to know all the options available.
30
+ #
31
+ # @see https://apidocs.orderspace.com/#list-customers
32
+ #
33
+ # @return customer_list [Orderspace::Structs::CustomerList] a list of customers
34
+ def list_customers(options = {})
35
+ response = client.get('customers', options)
36
+
37
+ Orderspace::Structs.from(JSON.parse(response.body), CustomerList)
38
+ end
39
+
40
+ ##
41
+ # Returns a customer searching by it's id
42
+ # @param customer_id [String] the id of the customer we are looking for.
43
+ # @return [Orderspace::Structs::Customer] The customer found
44
+ def get_customer(customer_id)
45
+ response = client.get("customers/#{customer_id}")
46
+
47
+ Orderspace::Structs.from(JSON.parse(response.body)['customer'], Customer)
48
+ end
49
+
50
+ ##
51
+ # Allows to edit the customer and change it's attributes
52
+ # @param customer [Orderspace::Structs::Customer] the customer to be edited (note it must have it's id)
53
+ def edit_customer(customer)
54
+ response = client.put("customers/#{customer.id}", { customer: Orderspace::Structs.hashify(customer) })
55
+
56
+ Orderspace::Structs.from(JSON.parse(response.body)['customer'], Customer)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ ##
5
+ # Defines the parent class for the endpoints
6
+ class Endpoint
7
+ attr_reader :client
8
+
9
+ ##
10
+ # Endpoints are initialized by passing the client
11
+ # @param client [Orderspace::Client] the Orderspace client that interacts with the Orderspace API
12
+ def initialize(client)
13
+ @client = client
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ class Endpoint
5
+
6
+ ##
7
+ # Contains the methods to interact with the oauth endpoint.
8
+ # @see https://apidocs.orderspace.com/#authentication
9
+ module Oauth
10
+
11
+ include Orderspace::Structs
12
+
13
+ ##
14
+ # Fetches the orderspace access token to interact with the Orderspace API
15
+ # @param client_id [String] the client id as defined when the app was registered
16
+ # @param client_secret [String] the client secret as defined when the app was registered
17
+ # @return [Orderspace::Structs::OauthCredentials] the Oauth credentials containing the access token.
18
+ def obtain_access_token(client_id, client_secret)
19
+ response = client.request(:post, 'https://identity.orderspace.com/oauth/token',
20
+ { client_id:, client_secret:, grant_type: 'client_credentials' })
21
+
22
+ Orderspace::Structs.from(JSON.parse(response.body), OauthCredentials)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ class Endpoint
5
+
6
+ ##
7
+ # Contains the methods to interact with the orders endpoint.
8
+ # @see https://apidocs.orderspace.com/#orders
9
+ module Orders
10
+ include Orderspace::Structs
11
+
12
+ ##
13
+ # Lists all the orders.
14
+ #
15
+ # You can pass in options like so:
16
+ #
17
+ # { query: { limit: 20 } }
18
+ #
19
+ # Check tho orderspace API documentation to know all the options available.
20
+ #
21
+ # @see https://apidocs.orderspace.com/#list-orders
22
+ #
23
+ # @return order_list [Orderspace::Structs::OrderList] a list of orders
24
+ def list_orders(options = {})
25
+ response = client.get('orders', options)
26
+ Orderspace::Structs.from(JSON.parse(response.body), OrderList)
27
+ end
28
+
29
+ ##
30
+ # Returns an order recognised by its id
31
+ # @param order_id [String] the id of the order we want to get
32
+ # @return order [Orderspace::Structs::Order] the order found
33
+ def get_order(order_id)
34
+ response = client.get("orders/#{order_id}")
35
+
36
+ Orderspace::Structs.from(JSON.parse(response.body)['order'], Order)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ class Endpoint
5
+ ##
6
+ # Contains the methods to interact with the webhooks endpoint.
7
+ # @see https://apidocs.orderspace.com/#webhooks
8
+ module Webhooks
9
+ include Orderspace::Structs
10
+
11
+ ##
12
+ # Creates a new webhook
13
+ # @see https://apidocs.orderspace.com/#create-a-webhook
14
+ # @param webhook [Orderspace::Structs::Webhook]
15
+ # @return webhook [Orderspace::Structs::Webhook] the webhook with it's id
16
+ def create(webhook)
17
+ response = client.post('webhooks', { webhook: Orderspace::Structs.hashify(webhook) })
18
+ parse_webhook response
19
+ end
20
+
21
+ ##
22
+ # Lists all the webhooks you've registered
23
+ # @see https://apidocs.orderspace.com/#list-webhooks
24
+ # @return webhook_list [Orderspace::Struct::WebhookList]
25
+ def list_webhooks
26
+ response = client.get('webhooks')
27
+ Orderspace::Structs.from(JSON.parse(response.body), WebhookList)
28
+ end
29
+
30
+ ##
31
+ # Gets a webhook by it's id
32
+ # @param id [String] the id of the webhook
33
+ # @return webhook [Orderspace::Structs::Webhook] the webhook we were looking for
34
+ def get_webhook(id)
35
+ parse_webhook client.get("webhooks/#{id}")
36
+ end
37
+
38
+ ##
39
+ # Updates the current webhook
40
+ # @param webhook [Orderspace::Structs::Webhook] the webhook we want to update
41
+ # @return webhook [Orderspace::Structs::Webhook] the updated webhook
42
+ def update_webhook(webhook)
43
+ parse_webhook client.put("webhooks/#{webhook.id}")
44
+ end
45
+
46
+ ##
47
+ # Deletes the webhook
48
+ # @param webhook [Orderspace::Structs::Webhook] the webhook we want to delete
49
+ # @return webhook [Orderspace::Structs::Webhook] the deleted webhook (containing only the id and deleted (boolean))
50
+ def delete_webhook(webhook)
51
+ parse_webhook client.delete("webhooks/#{webhook.id}")
52
+ end
53
+
54
+ private
55
+ def parse_webhook(response)
56
+ Orderspace::Structs.from(JSON.parse(response.body)['webhook'], Webhook)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'endpoint/endpoint'
4
+ require_relative 'endpoint/customers'
5
+ require_relative 'endpoint/orders'
6
+ require_relative 'endpoint/oauth'
7
+ require_relative 'endpoint/webhooks'
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ ##
5
+ # Basic Error
6
+ class Error < StandardError
7
+ end
8
+
9
+ ##
10
+ # For when a validation fails
11
+ class ValidationFailedError < Error
12
+ end
13
+
14
+ ##
15
+ # Basic Error representing the possible errors that can happen during our communication with the API.
16
+ class RequestError < Error
17
+ attr_reader :response, :message
18
+
19
+ def initialize(response)
20
+ @response = response
21
+ super(message_from(response))
22
+ end
23
+
24
+ private
25
+
26
+ def message_from(response)
27
+ if contains_json?(response)
28
+ @message = response['message']
29
+ else
30
+ "#{response.response.code} #{response.response.message}"
31
+ end
32
+ end
33
+
34
+ def contains_json?(response)
35
+ content_type = response.headers['Content-Type']
36
+ content_type&.start_with?('application/json')
37
+ end
38
+ end
39
+
40
+ ##
41
+ # Generic (HTTP Status 400) error
42
+ class BadRequestError < RequestError
43
+ end
44
+
45
+ ##
46
+ # HTTP status 401 Error
47
+ class AuthorizationFailedError < RequestError
48
+
49
+ private
50
+
51
+ def message_from(response)
52
+ response.headers['www-authenticate'].to_s.split(/error_description=/, -1).last.delete('"')
53
+ end
54
+ end
55
+
56
+ ##
57
+ # HTTP status 404 Error
58
+ class NotFoundError < RequestError
59
+ end
60
+
61
+ ##
62
+ # HTTP status 422 Error
63
+ class UnprocessableEntityError < RequestError
64
+ end
65
+
66
+ ##
67
+ # HTTP status 429 error
68
+ class TooManyRequestsError < RequestError
69
+ end
70
+
71
+ ##
72
+ # Generic (HTTP Status 500) Error
73
+ class InternalServerError < RequestError
74
+ end
75
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+
5
+ # mandatory: company name, contact name, line1, postcode country
6
+ #
7
+ module Structs
8
+ Address = Struct.new(:company_name, :contact_name, :line1, :line2, :city, :postal_code, :state, :country)
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ module Structs
5
+ Buyer = Struct.new(:name, :email_address)
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ # mandatory company_name, login_email? contact_name, address (company name, contact name, line1, postcode country)
5
+ module Structs
6
+ Customer = Struct.new(:id, :company_name, :created_at, :status, :reference, :buyers, :phone, :email_addresses,
7
+ :tax_number, :tax_rate_id, :addresses, :minimum_spend, :payment_terms_id,
8
+ :customer_group_id, :price_list_id)
9
+
10
+ CustomerList = Struct.new(:customers, :has_more)
11
+
12
+ class CustomerValidator
13
+ def self.validate(customer)
14
+ return unless customer.company_name.nil?
15
+
16
+ raise ValidationFailedError, 'Validation failed: Company name cannot be blank'
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ module Structs
5
+ Event = Struct.new(:event, :data)
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ module Structs
5
+
6
+ OauthCredentials = Struct.new(:access_token, :token_type, :expires_in, :scope)
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ module Structs
5
+ Order = Struct.new(:id, :number, :created, :status, :customer_id, :company_name, :phone, :email_addresses,
6
+ :delivery_date, :reference, :internal_note, :customer_po_number, :customer_note,
7
+ :standing_order_id, :shipping_type, :shipping_address, :billing_address, :order_lines,
8
+ :currency, :net_total, :gross_total)
9
+ OrderLine = Struct.new(:id, :sku, :name, :options, :grouping_category, :shipping, :quantity, :unit_price,
10
+ :sub_total, :tax_name, :tax_rate, :tax_amount, :on_hold, :invoiced, :paid, :dispatched)
11
+ OrderList = Struct.new(:orders, :has_more)
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ module Structs
5
+ Webhook = Struct.new(:id, :endpoint, :events, :signing_key, :deleted)
6
+
7
+ WebhookList = Struct.new(:webhooks)
8
+ end
9
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ ##
5
+ # The structs module scopes the structs returned and sent to the Orderspace API
6
+ module Structs
7
+ ##
8
+ # Converts (if possible) a json payload into the desired struct
9
+ # @param json [object] a json object
10
+ # @param struct [Struct] the desired struct
11
+ # @return [Struct] the fully initialized struct
12
+ def self.from(json, struct)
13
+ if json.is_a? Array
14
+ json.collect {|element| assign_values_to_struct(element, struct)}
15
+ else
16
+ assign_values_to_struct(json, struct)
17
+ end
18
+ end
19
+
20
+ ##
21
+ # Converts a struct into a hash
22
+ # @param struct [Struct] the struct we want to convert
23
+ # @return [Hash] the hash representation of the struct
24
+ def self.hashify(struct)
25
+ hash_dump(struct)
26
+ end
27
+
28
+ ##
29
+ # Used to make sure the struct is valid before it's posted to the server
30
+ # @param struct [Struct] the struct we want to validate
31
+ # @raise [ValidationFailedError] with the error message
32
+ def self.validate(struct)
33
+ validator = eval(struct.class.to_s + 'Validator')
34
+ validator.validate(struct)
35
+ end
36
+
37
+ private
38
+
39
+ def self.assign_values_to_struct(json, struct)
40
+ struct.new.tap do |new_object|
41
+ json.each do |key, value|
42
+ method_name = "#{key}="
43
+ if value.is_a? Array
44
+ begin
45
+ build_structs(key, method_name, new_object, value)
46
+ rescue
47
+ new_object.send(method_name.to_sym, value)
48
+ end
49
+ elsif address?(key)
50
+ new_object.send(method_name.to_sym, Orderspace::Structs.from(value, Orderspace::Structs::Address))
51
+ elsif data?(key)
52
+ event_struct = assign_values_to_struct(value[value.keys.first], eval_to_struct(value.keys.first.capitalize))
53
+ new_object.send(method_name.to_sym, event_struct)
54
+ elsif new_object.respond_to? method_name
55
+ new_object.send(method_name.to_sym, value)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.address?(key)
62
+ key.eql?('shipping_address') || key.eql?('billing_address')
63
+ end
64
+
65
+ def self.data?(key)
66
+ key.eql? 'data'
67
+ end
68
+
69
+ def self.hash_dump(struct)
70
+ hash = {}
71
+
72
+ struct.members.collect do |member|
73
+ value = extract_value_from(struct, member)
74
+ hash[member.to_sym] = value unless value.nil?
75
+ end
76
+ hash
77
+ end
78
+
79
+ def self.build_structs(key, method_name, new_object, value)
80
+ clazz = infer_class(key)
81
+ return unless new_object.respond_to? method_name
82
+
83
+ new_object.send(method_name.to_sym, value.map do |data|
84
+ Orderspace::Structs.from(data, eval_to_struct(clazz))
85
+ end)
86
+ end
87
+
88
+ def self.eval_to_struct(clazz)
89
+ class_eval("Orderspace::Structs::#{clazz}", __FILE__, __LINE__)
90
+ end
91
+
92
+ def self.infer_class(key)
93
+ if key.include? '_'
94
+ clazz = key.chomp('s').split('_').map{|e| e.capitalize}.join
95
+ elsif key.end_with?('es')
96
+ clazz = key.capitalize.chomp('es')
97
+ elsif key.end_with?('s')
98
+ clazz = key.capitalize.chomp('s')
99
+ end
100
+ clazz
101
+ end
102
+
103
+ def self.extract_value_from(struct, member)
104
+ if struct.send(member.to_sym).is_a? Array
105
+ begin
106
+ struct.send(member.to_sym).map { |member| hash_dump(member) }
107
+ rescue
108
+ struct.send(member.to_sym)
109
+ end
110
+ else
111
+ struct.send(member.to_sym)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ require_relative 'struct/address'
118
+ require_relative 'struct/buyer'
119
+ require_relative 'struct/customer'
120
+ require_relative 'struct/event'
121
+ require_relative 'struct/oauth_credentials'
122
+ require_relative 'struct/order'
123
+ require_relative 'struct/webhook'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orderspace
4
+ ##
5
+ # The current version of this gem
6
+ VERSION = '0.1.0'
7
+ end
data/lib/orderspace.rb ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # This module represents the overarching scope of the gem
5
+ #
6
+ module Orderspace
7
+ end
8
+
9
+ require 'orderspace/version'
10
+ require 'orderspace/default'
11
+ require 'orderspace/error'
12
+
13
+ require 'orderspace/structs'
14
+ require 'orderspace/endpoints'
15
+ require 'orderspace/client'
Binary file
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: orderspace-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Enrique Comba Riepenhausen
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-12-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.20.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.20.0
27
+ description: The orderspace ruby client allows you to connect to orderspace using
28
+ Ruby
29
+ email:
30
+ - enrique@beanmind.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".rspec"
36
+ - ".standard.yml"
37
+ - CHANGELOG.md
38
+ - CODE_OF_CONDUCT.md
39
+ - Gemfile
40
+ - Gemfile.lock
41
+ - LICENSE.txt
42
+ - README.md
43
+ - Rakefile
44
+ - beanmind.svg
45
+ - lib/orderspace.rb
46
+ - lib/orderspace/client.rb
47
+ - lib/orderspace/default.rb
48
+ - lib/orderspace/endpoint/customers.rb
49
+ - lib/orderspace/endpoint/endpoint.rb
50
+ - lib/orderspace/endpoint/oauth.rb
51
+ - lib/orderspace/endpoint/orders.rb
52
+ - lib/orderspace/endpoint/webhooks.rb
53
+ - lib/orderspace/endpoints.rb
54
+ - lib/orderspace/error.rb
55
+ - lib/orderspace/struct/address.rb
56
+ - lib/orderspace/struct/buyer.rb
57
+ - lib/orderspace/struct/customer.rb
58
+ - lib/orderspace/struct/event.rb
59
+ - lib/orderspace/struct/oauth_credentials.rb
60
+ - lib/orderspace/struct/order.rb
61
+ - lib/orderspace/struct/webhook.rb
62
+ - lib/orderspace/structs.rb
63
+ - lib/orderspace/version.rb
64
+ - orderspace-logo.png
65
+ homepage: https://github.com/bean-mind/orderspace-ruby
66
+ licenses:
67
+ - MIT
68
+ metadata:
69
+ homepage_uri: https://github.com/bean-mind/orderspace-ruby
70
+ source_code_uri: https://github.com/bean-mind/orderspace-ruby
71
+ changelog_uri: https://github.com/bean-mind/orderspace-ruby/CHANGELOG.md
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 3.1.2
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubygems_version: 3.3.7
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Connect to your Orderspace API with ruby
91
+ test_files: []