go_puff-prodcat_api 0.9.3.pre.beta.1
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 +7 -0
- data/.bundle/config.example +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +64 -0
- data/Dockerfile +22 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +112 -0
- data/README.md +62 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/setup +8 -0
- data/dip.yml +23 -0
- data/docker-compose.yml +12 -0
- data/lefthook.yml +6 -0
- data/lib/go_puff/prodcat_api/configuration.rb +28 -0
- data/lib/go_puff/prodcat_api/errors.rb +27 -0
- data/lib/go_puff/prodcat_api/fetch_product.rb +21 -0
- data/lib/go_puff/prodcat_api/fetch_products.rb +158 -0
- data/lib/go_puff/prodcat_api/memo.rb +57 -0
- data/lib/go_puff/prodcat_api/product_hydration/look_up_by_barcode.rb +132 -0
- data/lib/go_puff/prodcat_api/structs.rb +58 -0
- data/lib/go_puff/prodcat_api/type_utility.rb +11 -0
- data/lib/go_puff/prodcat_api/version.rb +7 -0
- data/lib/go_puff/prodcat_api.rb +31 -0
- metadata +236 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: cafafb2612024979cba9817f96491e4e22b73130dcefb6c8350115b94ede645e
|
|
4
|
+
data.tar.gz: 0732ad8826d7700e2ae9fc2deb55253898fbbd75779d829ab6c15a0830b95322
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 20383f6ef52524106ddd987952c4ca6e621f56fb789e73ad7f28668b37c5258c8a99b61a705e0fa2803614feb9d984becf3b019aca4745f2f3527df51ef19dcb
|
|
7
|
+
data.tar.gz: 0af72f4671b63f556c4f691db1bb454940f96d08454d1667fdb728a7d9cc66c2076df46626e46a3689cb13b96ce92299a05a0900002782d7dd54f1b4d8c6b275
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require:
|
|
2
|
+
- rubocop-thread_safety
|
|
3
|
+
- rubocop-rspec
|
|
4
|
+
- rubocop-performance
|
|
5
|
+
|
|
6
|
+
AllCops:
|
|
7
|
+
NewCops: enable
|
|
8
|
+
TargetRubyVersion: 2.6.6
|
|
9
|
+
SuggestExtensions: false
|
|
10
|
+
|
|
11
|
+
Metrics/ClassLength:
|
|
12
|
+
Enabled: false
|
|
13
|
+
|
|
14
|
+
Metrics/MethodLength:
|
|
15
|
+
Enabled: false
|
|
16
|
+
|
|
17
|
+
Metrics/AbcSize:
|
|
18
|
+
Enabled: false
|
|
19
|
+
|
|
20
|
+
Layout/LineLength:
|
|
21
|
+
Enabled: false
|
|
22
|
+
|
|
23
|
+
Metrics/BlockLength:
|
|
24
|
+
Enabled: false
|
|
25
|
+
|
|
26
|
+
Style/Documentation:
|
|
27
|
+
Enabled: false
|
|
28
|
+
|
|
29
|
+
RSpec/ExampleLength:
|
|
30
|
+
Enabled: false
|
|
31
|
+
|
|
32
|
+
RSpec/NamedSubject:
|
|
33
|
+
Enabled: false
|
|
34
|
+
|
|
35
|
+
RSpec/VerifiedDoubles:
|
|
36
|
+
Enabled: false
|
|
37
|
+
|
|
38
|
+
RSpec/MultipleExpectations:
|
|
39
|
+
Max: 11
|
|
40
|
+
|
|
41
|
+
ThreadSafety/InstanceVariableInClassMethod:
|
|
42
|
+
Exclude:
|
|
43
|
+
- lib/go_puff/prodcat_api.rb
|
|
44
|
+
ThreadSafety/ClassAndModuleAttributes:
|
|
45
|
+
Exclude:
|
|
46
|
+
- lib/go_puff/prodcat_api.rb
|
|
47
|
+
RSpec/AnyInstance:
|
|
48
|
+
Exclude:
|
|
49
|
+
- spec/spec_helper.rb
|
|
50
|
+
- spec/go_puff/prodcat_api/configuration_spec.rb
|
|
51
|
+
|
|
52
|
+
RSpec/MultipleMemoizedHelpers:
|
|
53
|
+
Exclude:
|
|
54
|
+
- spec/go_puff/prodcat_api/memo_spec.rb
|
|
55
|
+
- spec/go_puff/prodcat_api/fetch_products_spec.rb
|
|
56
|
+
|
|
57
|
+
Metrics/CyclomaticComplexity:
|
|
58
|
+
Exclude:
|
|
59
|
+
- lib/go_puff/prodcat_api/fetch_products.rb
|
|
60
|
+
|
|
61
|
+
RSpec/NestedGroups:
|
|
62
|
+
Exclude:
|
|
63
|
+
- spec/go_puff/prodcat_api/structs_spec.rb
|
|
64
|
+
- spec/go_puff/prodcat_api/type_utility_spec.rb
|
data/Dockerfile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
FROM ruby:2.7-slim
|
|
2
|
+
|
|
3
|
+
RUN apt-get update \
|
|
4
|
+
&& apt-get install -y --no-install-recommends \
|
|
5
|
+
bash less git \
|
|
6
|
+
build-essential ruby-dev \
|
|
7
|
+
&& apt-get clean
|
|
8
|
+
|
|
9
|
+
ENV APP_HOME /app
|
|
10
|
+
|
|
11
|
+
ENV BUNDLE_GEMFILE=$APP_HOME/Gemfile \
|
|
12
|
+
BUNDLE_JOBS=8 \
|
|
13
|
+
BUNDLE_PATH=/gems
|
|
14
|
+
|
|
15
|
+
RUN mkdir $APP_HOME
|
|
16
|
+
|
|
17
|
+
WORKDIR $APP_HOME
|
|
18
|
+
|
|
19
|
+
ADD Gemfile $APP_HOME/Gemfile
|
|
20
|
+
ADD Gemfile.lock $APP_HOME/Gemfile.lock
|
|
21
|
+
|
|
22
|
+
RUN gem install bundler --no-document
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
go_puff-prodcat_api (0.9.3.pre.beta.1)
|
|
5
|
+
go_puff-http-client (~> 0.5)
|
|
6
|
+
retryable
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
remote: https://rubygems.pkg.github.com/gopuff/
|
|
11
|
+
specs:
|
|
12
|
+
addressable (2.8.0)
|
|
13
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
14
|
+
ast (2.4.2)
|
|
15
|
+
coderay (1.1.3)
|
|
16
|
+
connection_pool (2.3.0)
|
|
17
|
+
crack (0.4.5)
|
|
18
|
+
rexml
|
|
19
|
+
diff-lcs (1.5.0)
|
|
20
|
+
docile (1.4.0)
|
|
21
|
+
faraday (2.7.4)
|
|
22
|
+
faraday-net_http (>= 2.0, < 3.1)
|
|
23
|
+
ruby2_keywords (>= 0.0.4)
|
|
24
|
+
faraday-net_http (3.0.2)
|
|
25
|
+
faraday-net_http_persistent (2.1.0)
|
|
26
|
+
faraday (~> 2.5)
|
|
27
|
+
net-http-persistent (~> 4.0)
|
|
28
|
+
go_puff-http-client (0.5.1)
|
|
29
|
+
faraday (~> 2.5)
|
|
30
|
+
faraday-net_http_persistent (~> 2.1)
|
|
31
|
+
hashdiff (1.0.1)
|
|
32
|
+
method_source (1.0.0)
|
|
33
|
+
net-http-persistent (4.0.1)
|
|
34
|
+
connection_pool (~> 2.2)
|
|
35
|
+
parallel (1.22.1)
|
|
36
|
+
parser (3.1.2.0)
|
|
37
|
+
ast (~> 2.4.1)
|
|
38
|
+
pry (0.14.1)
|
|
39
|
+
coderay (~> 1.1)
|
|
40
|
+
method_source (~> 1.0)
|
|
41
|
+
public_suffix (4.0.7)
|
|
42
|
+
rainbow (3.1.1)
|
|
43
|
+
regexp_parser (2.4.0)
|
|
44
|
+
retryable (3.0.5)
|
|
45
|
+
rexml (3.2.5)
|
|
46
|
+
rspec (3.11.0)
|
|
47
|
+
rspec-core (~> 3.11.0)
|
|
48
|
+
rspec-expectations (~> 3.11.0)
|
|
49
|
+
rspec-mocks (~> 3.11.0)
|
|
50
|
+
rspec-core (3.11.0)
|
|
51
|
+
rspec-support (~> 3.11.0)
|
|
52
|
+
rspec-expectations (3.11.0)
|
|
53
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
54
|
+
rspec-support (~> 3.11.0)
|
|
55
|
+
rspec-mocks (3.11.1)
|
|
56
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
57
|
+
rspec-support (~> 3.11.0)
|
|
58
|
+
rspec-support (3.11.0)
|
|
59
|
+
rubocop (1.29.1)
|
|
60
|
+
parallel (~> 1.10)
|
|
61
|
+
parser (>= 3.1.0.0)
|
|
62
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
63
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
64
|
+
rexml (>= 3.2.5, < 4.0)
|
|
65
|
+
rubocop-ast (>= 1.17.0, < 2.0)
|
|
66
|
+
ruby-progressbar (~> 1.7)
|
|
67
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
68
|
+
rubocop-ast (1.17.0)
|
|
69
|
+
parser (>= 3.1.1.0)
|
|
70
|
+
rubocop-performance (1.13.3)
|
|
71
|
+
rubocop (>= 1.7.0, < 2.0)
|
|
72
|
+
rubocop-ast (>= 0.4.0)
|
|
73
|
+
rubocop-rspec (2.10.0)
|
|
74
|
+
rubocop (~> 1.19)
|
|
75
|
+
rubocop-thread_safety (0.4.4)
|
|
76
|
+
rubocop (>= 0.53.0)
|
|
77
|
+
ruby-progressbar (1.11.0)
|
|
78
|
+
ruby2_keywords (0.0.5)
|
|
79
|
+
simplecov (0.21.2)
|
|
80
|
+
docile (~> 1.1)
|
|
81
|
+
simplecov-html (~> 0.11)
|
|
82
|
+
simplecov_json_formatter (~> 0.1)
|
|
83
|
+
simplecov-html (0.12.3)
|
|
84
|
+
simplecov-lcov (0.8.0)
|
|
85
|
+
simplecov_json_formatter (0.1.4)
|
|
86
|
+
unicode-display_width (2.1.0)
|
|
87
|
+
webmock (3.14.0)
|
|
88
|
+
addressable (>= 2.8.0)
|
|
89
|
+
crack (>= 0.3.2)
|
|
90
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
91
|
+
|
|
92
|
+
PLATFORMS
|
|
93
|
+
aarch64-linux
|
|
94
|
+
x86_64-darwin-18
|
|
95
|
+
x86_64-darwin-22
|
|
96
|
+
x86_64-linux
|
|
97
|
+
|
|
98
|
+
DEPENDENCIES
|
|
99
|
+
bundler (~> 2.0)
|
|
100
|
+
go_puff-prodcat_api!
|
|
101
|
+
pry (~> 0.14)
|
|
102
|
+
rspec (~> 3.0)
|
|
103
|
+
rubocop (~> 1.25)
|
|
104
|
+
rubocop-performance
|
|
105
|
+
rubocop-rspec
|
|
106
|
+
rubocop-thread_safety (~> 0.4)
|
|
107
|
+
simplecov (~> 0.21)
|
|
108
|
+
simplecov-lcov (~> 0.8.0)
|
|
109
|
+
webmock (~> 3.5)
|
|
110
|
+
|
|
111
|
+
BUNDLED WITH
|
|
112
|
+
2.3.22
|
data/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# GoPuff::ProdcatApi
|
|
2
|
+
[](https://coveralls.io/github/gopuff/go_puff-prodcat_api?branch=main)
|
|
3
|
+
|
|
4
|
+
This Rails library is designed to work with product-catalog/pds api
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
Add this line to your application's Gemfile:
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
source 'https://rubygems.pkg.github.com/gopuff' do
|
|
12
|
+
gem 'go_puff-prodcat_api'
|
|
13
|
+
end
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
And then execute:
|
|
17
|
+
|
|
18
|
+
$ bundle install
|
|
19
|
+
|
|
20
|
+
## Set up
|
|
21
|
+
```ruby
|
|
22
|
+
# config/initializers/prodcat_api.rb
|
|
23
|
+
|
|
24
|
+
GoPuff::ProdcatApi.configure do |c|
|
|
25
|
+
c.logger = GoPuff::Logger
|
|
26
|
+
c.url = ENV.fetch('PDS_API_URL')
|
|
27
|
+
c.authorization_client_id = ENV.fetch('PRODCAT_API_AUTHORIZATION_CLIENT_ID')
|
|
28
|
+
c.user_agent_header = GoPuff::Http.config.user_agent_header
|
|
29
|
+
|
|
30
|
+
# config.requests.max_retries = 3 # default
|
|
31
|
+
# config.requests.retry_wait_time = 0.5 # default
|
|
32
|
+
# config.requests.retryable_exceptions = [EOFError, Errno::ECONNRESET, Timeout::Error, GoPuff::ProdcatApi::ServerError, GoPuff::ProdcatApi::ClientError, GoPuff::ProdcatApi::TimeoutError] # default
|
|
33
|
+
end
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Local development with docker
|
|
37
|
+
Authorize personal access token for Github by following the steps at https://docs.github.com/en/github/authenticating-to-github/authorizing-a-personal-access-token-for-use-with-saml-single-sign-on
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
cp .bundle/config.example .bundle/config
|
|
42
|
+
```
|
|
43
|
+
Add Github username and personal access token in `./bundle/config` and start project using:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
docker-compose run --rm go_puff-prodcat_api bash
|
|
47
|
+
```
|
|
48
|
+
or with [dip](https://github.com/bibendi/dip#installation)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
dip bash
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Contributing
|
|
55
|
+
|
|
56
|
+
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
|
|
57
|
+
|
|
58
|
+
1. Clone the Project
|
|
59
|
+
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
|
|
60
|
+
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
|
|
61
|
+
4. Push to the Branch (`git push origin feature/AmazingFeature`)
|
|
62
|
+
5. Open a Pull Request
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'go_puff/prodcat_api'
|
|
6
|
+
|
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
+
|
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
+
# require "pry"
|
|
12
|
+
# Pry.start
|
|
13
|
+
|
|
14
|
+
require 'irb'
|
|
15
|
+
IRB.start(__FILE__)
|
data/bin/rspec
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'pathname'
|
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
|
13
|
+
Pathname.new(__FILE__).realpath)
|
|
14
|
+
|
|
15
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
|
16
|
+
|
|
17
|
+
if File.file?(bundle_binstub)
|
|
18
|
+
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
|
|
19
|
+
load(bundle_binstub)
|
|
20
|
+
else
|
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require 'rubygems'
|
|
27
|
+
require 'bundler/setup'
|
|
28
|
+
|
|
29
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/bin/rubocop
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'pathname'
|
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
|
13
|
+
Pathname.new(__FILE__).realpath)
|
|
14
|
+
|
|
15
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
|
16
|
+
|
|
17
|
+
if File.file?(bundle_binstub)
|
|
18
|
+
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
|
|
19
|
+
load(bundle_binstub)
|
|
20
|
+
else
|
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require 'rubygems'
|
|
27
|
+
require 'bundler/setup'
|
|
28
|
+
|
|
29
|
+
load Gem.bin_path('rubocop', 'rubocop')
|
data/bin/setup
ADDED
data/dip.yml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
version: '2'
|
|
2
|
+
|
|
3
|
+
environment:
|
|
4
|
+
RAILS_ENV: development
|
|
5
|
+
|
|
6
|
+
compose:
|
|
7
|
+
files:
|
|
8
|
+
- docker-compose.yml
|
|
9
|
+
|
|
10
|
+
interaction:
|
|
11
|
+
bash:
|
|
12
|
+
service: go_puff-prodcat_api
|
|
13
|
+
command: /bin/bash
|
|
14
|
+
compose_run_options: [no-deps]
|
|
15
|
+
bundle:
|
|
16
|
+
service: go_puff-prodcat_api
|
|
17
|
+
command: bundle
|
|
18
|
+
rake:
|
|
19
|
+
service: go_puff-prodcat_api
|
|
20
|
+
command: bundle exec rake
|
|
21
|
+
rspec:
|
|
22
|
+
service: go_puff-prodcat_api
|
|
23
|
+
command: bundle exec rspec
|
data/docker-compose.yml
ADDED
data/lefthook.yml
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GoPuff
|
|
4
|
+
module ProdcatApi
|
|
5
|
+
class Configuration
|
|
6
|
+
attr_accessor :url, :authorization_client_id, :requests, :logger, :user_agent_header
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@requests = Struct.new(:max_retries, :retry_wait_time, :retryable_exceptions) do
|
|
10
|
+
def to_h
|
|
11
|
+
{
|
|
12
|
+
on: retryable_exceptions,
|
|
13
|
+
tries: max_retries,
|
|
14
|
+
sleep: retry_wait_time
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
end.new(3, 0.5, [GoPuff::ProdcatApi::InvalidJsonResponseError, GoPuff::ProdcatApi::HttpError])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def validate!
|
|
21
|
+
raise ConfigError, 'Undefined url configuration in config/initializers/prodcat_api.rb' if url.nil?
|
|
22
|
+
raise ConfigError, 'Undefined authorization_client_id configuration in config/initializers/prodcat_api.rb' if authorization_client_id.nil?
|
|
23
|
+
raise ConfigError, 'Undefined logger configuration in config/initializers/prodcat_api.rb' if logger.nil?
|
|
24
|
+
raise ConfigError, 'Undefined user_agent_header configuration in config/initializers/go_puff-http-client.rb' if user_agent_header.nil?
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GoPuff
|
|
4
|
+
module ProdcatApi
|
|
5
|
+
class Error < StandardError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class HttpError < Error
|
|
9
|
+
attr_reader :original
|
|
10
|
+
|
|
11
|
+
def initialize(msg, original = $ERROR_INFO)
|
|
12
|
+
super(msg)
|
|
13
|
+
@original = original
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class ConfigError < Error; end
|
|
18
|
+
|
|
19
|
+
class InvalidJsonResponseError < Error
|
|
20
|
+
def initialize(msg, code, body = nil)
|
|
21
|
+
msg += " | code: #{code}"
|
|
22
|
+
msg += " | body: #{body}" if body
|
|
23
|
+
super(msg)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GoPuff
|
|
4
|
+
module ProdcatApi
|
|
5
|
+
class FetchProduct < FetchProducts
|
|
6
|
+
def initialize(product_id:, location_id:, point_of_sale: 'US', headers: {}, thread: nil)
|
|
7
|
+
super(
|
|
8
|
+
product_ids: [product_id],
|
|
9
|
+
location_id: location_id,
|
|
10
|
+
point_of_sale: point_of_sale,
|
|
11
|
+
headers: headers,
|
|
12
|
+
thread: thread,
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
super&.first
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative './errors'
|
|
4
|
+
require_relative './memo'
|
|
5
|
+
require_relative './structs'
|
|
6
|
+
|
|
7
|
+
module GoPuff
|
|
8
|
+
module ProdcatApi
|
|
9
|
+
class FetchProducts
|
|
10
|
+
include Structs
|
|
11
|
+
|
|
12
|
+
attr_reader :time, :memo, :thread
|
|
13
|
+
|
|
14
|
+
TIMEOUT = 5
|
|
15
|
+
|
|
16
|
+
def initialize(product_ids:, location_id:, point_of_sale: 'US', headers: {}, thread: nil)
|
|
17
|
+
@location_id = location_id
|
|
18
|
+
@product_ids = product_ids.compact
|
|
19
|
+
@point_of_sale = point_of_sale
|
|
20
|
+
@headers = headers
|
|
21
|
+
@thread = thread
|
|
22
|
+
|
|
23
|
+
@memo = Memo.new(product_ids, location_id, point_of_sale, thread) if thread && web?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.call(*args, **kwargs, &block)
|
|
27
|
+
new(*args, **kwargs, &block).call
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def call
|
|
31
|
+
return [] if @product_ids.empty? || @location_id.nil?
|
|
32
|
+
|
|
33
|
+
return memo.products if web? && memo&.exist?
|
|
34
|
+
|
|
35
|
+
Retryable.retryable(GoPuff::ProdcatApi.config.requests.to_h) do
|
|
36
|
+
make_request
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
products = parse_response
|
|
40
|
+
|
|
41
|
+
memo&.add(products) if web?
|
|
42
|
+
|
|
43
|
+
products
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def make_request
|
|
49
|
+
@response = GoPuff::Http::Client.new(uri.to_s, adapter: :net_http_persistent, timeout: TIMEOUT).get(headers: headers, json: false)
|
|
50
|
+
raise(HttpError, "#{@response.error_message} | #{@response.status}") unless @response.success?
|
|
51
|
+
|
|
52
|
+
@response_json = JSON.parse(@response.body)
|
|
53
|
+
rescue JSON::ParserError => _e
|
|
54
|
+
raise InvalidJsonResponseError.new(uri.to_s, parse_code_from_body, @response.body)
|
|
55
|
+
rescue StandardError => e
|
|
56
|
+
raise HttpError, e
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def web?
|
|
60
|
+
return false unless defined?(Sidekiq)
|
|
61
|
+
|
|
62
|
+
!Sidekiq.server?.nil?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def uri
|
|
66
|
+
@uri ||= begin
|
|
67
|
+
uri = URI("#{url}/api/products")
|
|
68
|
+
uri.query = "product_ids=#{@product_ids.join(',')}&location_id=#{@location_id}&page_size=#{@product_ids.size}"
|
|
69
|
+
uri.query += '&datasource=eventing' if Flipper.enabled?(:puff_77780_change_split_for_bundles)
|
|
70
|
+
uri
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def url
|
|
75
|
+
GoPuff::ProdcatApi.config.url
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def parse_code_from_body
|
|
79
|
+
code = @response.body[/\d+/].to_i
|
|
80
|
+
return 500 if code.zero?
|
|
81
|
+
|
|
82
|
+
code
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def parse_response
|
|
86
|
+
@prodcat_products = @response_json['products'].map do |product|
|
|
87
|
+
ProductStruct.new.tap do |struct|
|
|
88
|
+
struct.product_id = product['product_id']
|
|
89
|
+
struct.price = product['price']
|
|
90
|
+
struct.offer = product['offer']
|
|
91
|
+
struct.cost = product['cost']
|
|
92
|
+
struct.kind = kind(product)
|
|
93
|
+
struct.is_rx = product['is_rx']
|
|
94
|
+
struct.is_sip = product['is_sip']
|
|
95
|
+
struct.is_digital = product['is_digital']
|
|
96
|
+
struct.currency = product['currency']
|
|
97
|
+
struct.subcategory_id = product['subcategory_id']
|
|
98
|
+
struct.primary_subcategory_id = product['primary_subcategory_id']
|
|
99
|
+
struct.quantity = product['quantity']
|
|
100
|
+
struct.available_for_bonus = product['available_for_bonus']
|
|
101
|
+
struct.bundle = product['bundle']
|
|
102
|
+
struct.is_sample = TypeUtility.to_boolean(product['is_sample'])
|
|
103
|
+
struct.classifications = product['classifications'] || []
|
|
104
|
+
|
|
105
|
+
struct.bundle_products = product['bundleProducts']&.map do |bundle_product|
|
|
106
|
+
BundleProductStruct.new.tap do |bp_struct|
|
|
107
|
+
bp_struct.product_id = bundle_product['product_id'].to_i
|
|
108
|
+
bp_struct.quantity = bundle_product['quantity']
|
|
109
|
+
bp_struct.cost = bundle_product['cost']
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
struct.images = product['images']&.map do |product_image|
|
|
113
|
+
ImageStruct.new.tap do |img_struct|
|
|
114
|
+
img_struct.small = product_image['small']
|
|
115
|
+
img_struct.thumb = product_image['thumb']
|
|
116
|
+
img_struct.medium = product_image['medium']
|
|
117
|
+
img_struct.xlarge = product_image['xlarge']
|
|
118
|
+
img_struct.tile_image_alt_text = product_image['tile_image_alt_text']
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
struct.avatar = AvatarStruct.new.tap do |avatar_struct|
|
|
122
|
+
avatar_struct.small = product.dig('avatar', 'small')
|
|
123
|
+
avatar_struct.thumb = product.dig('avatar', 'thumb')
|
|
124
|
+
avatar_struct.medium = product.dig('avatar', 'medium')
|
|
125
|
+
avatar_struct.xlarge = product.dig('avatar', 'xlarge')
|
|
126
|
+
avatar_struct.tile_image_alt_text = product.dig('avatar', 'tile_image_alt_text')
|
|
127
|
+
end
|
|
128
|
+
struct.upc_barcodes = product['upc']
|
|
129
|
+
GoPuff::ProdcatApi.config.logger.info('Prodcat api product item',
|
|
130
|
+
log_parent_key: :prodcat_api_product_item,
|
|
131
|
+
params: { **struct.to_h, point_of_sale: @point_of_sale })
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def headers
|
|
137
|
+
{
|
|
138
|
+
'Content-Type' => 'application/json',
|
|
139
|
+
'Authorization-Client-ID' => GoPuff::ProdcatApi.config.authorization_client_id,
|
|
140
|
+
'X-GP-Point-Of-Sale' => @point_of_sale,
|
|
141
|
+
'X-AMZN-TRACE-ID' => @headers['X-AMZN-TRACEID'],
|
|
142
|
+
'X-APPGW-TRACE-ID' => @headers['X-APPGW_TRACE-ID'],
|
|
143
|
+
'X-MS-REQUEST-ID' => @headers['X-MS-REQUEST-ID'],
|
|
144
|
+
'X-MS-REQUEST-ROOT-ID' => @headers['X-MS-REQUEST-ROOT-ID'],
|
|
145
|
+
'REQUEST-ID' => @headers['REQUEST-ID'],
|
|
146
|
+
'TRACEPARENT' => @headers['TRACEPARENT']
|
|
147
|
+
}.compact
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def kind(product)
|
|
151
|
+
return product['kind'] if product['bundle_info'].nil? || product['bundle_info'].empty?
|
|
152
|
+
return 'alcohol' if product['bundle_info']['products'].map { |item| item['kind'] }.include? 'alcohol'
|
|
153
|
+
|
|
154
|
+
product['bundle_info']['products'][0]['kind']
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GoPuff
|
|
4
|
+
module ProdcatApi
|
|
5
|
+
class Memo
|
|
6
|
+
CACHE_NAMESPACE = :pds_api_product_cache
|
|
7
|
+
|
|
8
|
+
attr_reader :product_ids, :location_id, :point_of_sale, :thread
|
|
9
|
+
|
|
10
|
+
def initialize(product_ids, location_id, point_of_sale, thread)
|
|
11
|
+
@product_ids = product_ids
|
|
12
|
+
@location_id = location_id
|
|
13
|
+
@point_of_sale = point_of_sale
|
|
14
|
+
@thread = thread
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def products
|
|
18
|
+
cache = thread[CACHE_NAMESPACE]
|
|
19
|
+
|
|
20
|
+
return if cache.nil?
|
|
21
|
+
|
|
22
|
+
product_ids.lazy.uniq.map { |id| product_key(id) }.map { |key| cache[key] }.to_a
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def exist?
|
|
26
|
+
cache = thread[CACHE_NAMESPACE]
|
|
27
|
+
|
|
28
|
+
return false if cache.nil?
|
|
29
|
+
|
|
30
|
+
product_ids.lazy.map { |id| product_key(id) }.all? { |key| cache[key] }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add(products)
|
|
34
|
+
thread[CACHE_NAMESPACE] ||= {}
|
|
35
|
+
cache = thread[CACHE_NAMESPACE]
|
|
36
|
+
|
|
37
|
+
products.each do |product|
|
|
38
|
+
key = product_key(product.product_id)
|
|
39
|
+
|
|
40
|
+
cache[key] = product
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def product_key(product_id)
|
|
47
|
+
"#{point_of_sale}_#{location_id}_#{product_id}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class << self
|
|
51
|
+
def delete
|
|
52
|
+
Thread.current[CACHE_NAMESPACE] = nil
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GoPuff
|
|
4
|
+
module ProdcatApi
|
|
5
|
+
module ProductHydration
|
|
6
|
+
class LookUpByBarcode
|
|
7
|
+
include Structs
|
|
8
|
+
|
|
9
|
+
TIMEOUT = 5
|
|
10
|
+
|
|
11
|
+
def initialize(barcode, point_of_sale: 'US')
|
|
12
|
+
@barcode = barcode
|
|
13
|
+
@point_of_sale = point_of_sale
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.call(*args, **kwargs, &block)
|
|
17
|
+
new(*args, **kwargs, &block).call
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call
|
|
21
|
+
return [] if @barcode.nil?
|
|
22
|
+
|
|
23
|
+
Retryable.retryable(GoPuff::ProdcatApi.config.requests.to_h) do
|
|
24
|
+
make_request
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
parse_response
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def make_request
|
|
33
|
+
@response = GoPuff::Http::Client.new(uri.to_s, adapter: :net_http_persistent, timeout: TIMEOUT).get(headers: headers, json: false)
|
|
34
|
+
|
|
35
|
+
raise(HttpError, "#{@response.error_message} | #{@response.status}") unless @response.success?
|
|
36
|
+
|
|
37
|
+
@response_json = JSON.parse(@response.body)
|
|
38
|
+
rescue JSON::ParserError => _e
|
|
39
|
+
raise InvalidJsonResponseError.new(uri.to_s, parse_code_from_body, @response.body)
|
|
40
|
+
rescue StandardError => e
|
|
41
|
+
raise HttpError, e
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def uri
|
|
45
|
+
@uri ||= begin
|
|
46
|
+
url_safe_barcode = ERB::Util.url_encode(@barcode.strip)
|
|
47
|
+
uri = URI("#{url}/product-hydration/upc/#{url_safe_barcode}")
|
|
48
|
+
uri.query = 'datasource=cosmos'
|
|
49
|
+
|
|
50
|
+
uri
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def url
|
|
55
|
+
GoPuff::ProdcatApi.config.url
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def parse_code_from_body
|
|
59
|
+
code = @response.body[/\d+/].to_i
|
|
60
|
+
return 500 if code.zero?
|
|
61
|
+
|
|
62
|
+
code
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def parse_response
|
|
66
|
+
@prodcat_products = @response_json['products'].map do |product|
|
|
67
|
+
product_mapper(product)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def headers
|
|
72
|
+
{
|
|
73
|
+
'Content-Type' => 'application/json',
|
|
74
|
+
'Authorization-Client-ID' => GoPuff::ProdcatApi.config.authorization_client_id,
|
|
75
|
+
'X-GP-Point-Of-Sale' => @point_of_sale
|
|
76
|
+
}.compact
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def product_mapper(product)
|
|
80
|
+
ProductStruct.new.tap do |struct|
|
|
81
|
+
struct.product_id = product['id']
|
|
82
|
+
struct.price = product['price']
|
|
83
|
+
struct.offer = product['offer']
|
|
84
|
+
struct.cost = product['cost']
|
|
85
|
+
struct.kind = product['kind']
|
|
86
|
+
struct.currency = product['currency']
|
|
87
|
+
struct.subcategory_id = product['subcategoryId']
|
|
88
|
+
struct.quantity = product['quantity']
|
|
89
|
+
struct.available_for_bonus = product['availableForBonus']
|
|
90
|
+
struct.bundle = product['bundle']
|
|
91
|
+
struct.upc_barcodes = product['upcs']
|
|
92
|
+
|
|
93
|
+
# structure mappers
|
|
94
|
+
struct.bundle_products = product.dig('bundleInfo', 'products')&.map(&method(:bundle_mapper))
|
|
95
|
+
struct.images = product['imagesOld']&.map(&method(:image_mapper))
|
|
96
|
+
struct.avatar = avatar_mapper(product['avatarOld'].to_h)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def bundle_mapper(bundle_product)
|
|
101
|
+
BundleProductStruct.new.tap do |bundle_struct|
|
|
102
|
+
bundle_struct.product_id = bundle_product['id'].to_i
|
|
103
|
+
bundle_struct.quantity = bundle_product['quantity']
|
|
104
|
+
bundle_struct.cost = bundle_product['price']
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def image_mapper(product_image)
|
|
109
|
+
ImageStruct.new.tap do |image_struct|
|
|
110
|
+
image_struct.small = product_image['small']
|
|
111
|
+
image_struct.thumb = product_image['thumb']
|
|
112
|
+
image_struct.medium = product_image['medium']
|
|
113
|
+
image_struct.large = product_image['large']
|
|
114
|
+
image_struct.xlarge = product_image['xlarge']
|
|
115
|
+
image_struct.tile_image_alt_text = product_image['tile_image_alt_text']
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def avatar_mapper(product_avatar)
|
|
120
|
+
ImageStruct.new.tap do |image_struct|
|
|
121
|
+
image_struct.small = product_avatar['small']
|
|
122
|
+
image_struct.thumb = product_avatar['thumb']
|
|
123
|
+
image_struct.medium = product_avatar['medium']
|
|
124
|
+
image_struct.large = product_avatar['large']
|
|
125
|
+
image_struct.xlarge = product_avatar['xlarge']
|
|
126
|
+
image_struct.tile_image_alt_text = product_avatar['tile_image_alt_text']
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GoPuff
|
|
4
|
+
module ProdcatApi
|
|
5
|
+
module Structs
|
|
6
|
+
PRODUCT_STRUCT_PARAMS = %i[
|
|
7
|
+
product_id
|
|
8
|
+
price
|
|
9
|
+
quantity
|
|
10
|
+
currency
|
|
11
|
+
offer
|
|
12
|
+
bundle
|
|
13
|
+
cost
|
|
14
|
+
available_for_bonus
|
|
15
|
+
bundle_products
|
|
16
|
+
kind
|
|
17
|
+
primary_subcategory_id
|
|
18
|
+
subcategory_id
|
|
19
|
+
is_sample
|
|
20
|
+
is_rx
|
|
21
|
+
is_sip
|
|
22
|
+
is_digital
|
|
23
|
+
classifications
|
|
24
|
+
images
|
|
25
|
+
avatar
|
|
26
|
+
upc_barcodes
|
|
27
|
+
].freeze
|
|
28
|
+
|
|
29
|
+
ProductStruct = Struct.new(*PRODUCT_STRUCT_PARAMS) do
|
|
30
|
+
def to_h
|
|
31
|
+
super.tap do |ps|
|
|
32
|
+
ps[:bundle_products] = ps[:bundle_products]&.map(&:to_h)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def rx?
|
|
37
|
+
TypeUtility.to_boolean(is_rx)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def sip?
|
|
41
|
+
TypeUtility.to_boolean(is_sip)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def digital?
|
|
45
|
+
TypeUtility.to_boolean(is_digital)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def sample?
|
|
49
|
+
TypeUtility.to_boolean(is_sample)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
BundleProductStruct = Struct.new(:product_id, :quantity, :cost)
|
|
54
|
+
ImageStruct = Struct.new(:small, :thumb, :medium, :large, :xlarge, :tile_image_alt_text)
|
|
55
|
+
AvatarStruct = Struct.new(:small, :thumb, :medium, :large, :xlarge, :tile_image_alt_text)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'retryable'
|
|
4
|
+
require 'benchmark'
|
|
5
|
+
require 'go_puff/http/client'
|
|
6
|
+
require_relative 'prodcat_api/version'
|
|
7
|
+
require_relative 'prodcat_api/errors'
|
|
8
|
+
require_relative 'prodcat_api/configuration'
|
|
9
|
+
require_relative 'prodcat_api/fetch_products'
|
|
10
|
+
require_relative 'prodcat_api/fetch_product'
|
|
11
|
+
require_relative 'prodcat_api/structs'
|
|
12
|
+
require_relative 'prodcat_api/type_utility'
|
|
13
|
+
require_relative 'prodcat_api/product_hydration/look_up_by_barcode'
|
|
14
|
+
|
|
15
|
+
module GoPuff
|
|
16
|
+
module ProdcatApi
|
|
17
|
+
class << self
|
|
18
|
+
attr_accessor :config
|
|
19
|
+
|
|
20
|
+
def configure
|
|
21
|
+
@config ||= Configuration.new
|
|
22
|
+
|
|
23
|
+
yield config if block_given?
|
|
24
|
+
config.validate!
|
|
25
|
+
GoPuff::Http.config.logger = config.logger
|
|
26
|
+
GoPuff::Http.config.user_agent_header = config.user_agent_header
|
|
27
|
+
config
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: go_puff-prodcat_api
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.9.3.pre.beta.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ruslan Tolstov
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2023-02-20 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: go_puff-http-client
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.5'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.5'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: retryable
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '2.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '2.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: pry
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0.14'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0.14'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rspec
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '3.0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '3.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rubocop
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1.25'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1.25'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rubocop-performance
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rubocop-rspec
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rubocop-thread_safety
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0.4'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0.4'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: simplecov
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0.21'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0.21'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: simplecov-lcov
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: 0.8.0
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: 0.8.0
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: webmock
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - "~>"
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '3.5'
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - "~>"
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '3.5'
|
|
181
|
+
description:
|
|
182
|
+
email:
|
|
183
|
+
executables: []
|
|
184
|
+
extensions: []
|
|
185
|
+
extra_rdoc_files: []
|
|
186
|
+
files:
|
|
187
|
+
- ".bundle/config.example"
|
|
188
|
+
- ".rspec"
|
|
189
|
+
- ".rubocop.yml"
|
|
190
|
+
- Dockerfile
|
|
191
|
+
- Gemfile
|
|
192
|
+
- Gemfile.lock
|
|
193
|
+
- README.md
|
|
194
|
+
- Rakefile
|
|
195
|
+
- bin/console
|
|
196
|
+
- bin/rspec
|
|
197
|
+
- bin/rubocop
|
|
198
|
+
- bin/setup
|
|
199
|
+
- dip.yml
|
|
200
|
+
- docker-compose.yml
|
|
201
|
+
- lefthook.yml
|
|
202
|
+
- lib/go_puff/prodcat_api.rb
|
|
203
|
+
- lib/go_puff/prodcat_api/configuration.rb
|
|
204
|
+
- lib/go_puff/prodcat_api/errors.rb
|
|
205
|
+
- lib/go_puff/prodcat_api/fetch_product.rb
|
|
206
|
+
- lib/go_puff/prodcat_api/fetch_products.rb
|
|
207
|
+
- lib/go_puff/prodcat_api/memo.rb
|
|
208
|
+
- lib/go_puff/prodcat_api/product_hydration/look_up_by_barcode.rb
|
|
209
|
+
- lib/go_puff/prodcat_api/structs.rb
|
|
210
|
+
- lib/go_puff/prodcat_api/type_utility.rb
|
|
211
|
+
- lib/go_puff/prodcat_api/version.rb
|
|
212
|
+
homepage: https://github.com/gopuff/go_puff-prodcat_api
|
|
213
|
+
licenses:
|
|
214
|
+
- ISC
|
|
215
|
+
metadata:
|
|
216
|
+
rubygems_mfa_required: 'true'
|
|
217
|
+
post_install_message:
|
|
218
|
+
rdoc_options: []
|
|
219
|
+
require_paths:
|
|
220
|
+
- lib
|
|
221
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
222
|
+
requirements:
|
|
223
|
+
- - ">="
|
|
224
|
+
- !ruby/object:Gem::Version
|
|
225
|
+
version: 2.6.0
|
|
226
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
227
|
+
requirements:
|
|
228
|
+
- - ">"
|
|
229
|
+
- !ruby/object:Gem::Version
|
|
230
|
+
version: 1.3.1
|
|
231
|
+
requirements: []
|
|
232
|
+
rubygems_version: 3.1.4
|
|
233
|
+
signing_key:
|
|
234
|
+
specification_version: 4
|
|
235
|
+
summary: This Rails library is designed to work with product-catalog/pds api
|
|
236
|
+
test_files: []
|