lucid-shopify-resource 0.8.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: d5e6b82b24ef7b83a7fe75a831a5fbe6c948273cee6aba4a44d8fb082237c81f
4
+ data.tar.gz: c797e482f078659810d1fe933a8ff988cc659cc59b76e30ef1056a768da27ea1
5
+ SHA512:
6
+ metadata.gz: 5d6489add0fc1676421b4b9bddfe3982cf410fd8fc0d63cc60c2af751a011a3fbea71d8372716aebd4d5fa05a6e84116ecbfda673db6b9cc4b4d2f7e5fa00ad0
7
+ data.tar.gz: 32171a0111ca911d45342ae930799a682c38089becf244fe89f22a9509d99914444da42409a57ca558a8c28d254cf9cdcefbf9f8f0e2b39ef27ea4f8a9f48427
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ lucid-shopify-resource
2
+ ======================
3
+
4
+ Installation
5
+ ------------
6
+
7
+ Add the gem to your ‘Gemfile’:
8
+
9
+ gem 'lucid-shopify'
10
+ gem 'lucid-shopify-resource'
11
+
12
+
13
+ Usage
14
+ -----
15
+
16
+ ### Create a resource
17
+
18
+ class OrderRepository
19
+ include Lucid::Shopify::Resource::Create
20
+
21
+ resource :orders
22
+ end
23
+
24
+ order_repo = OrderRepository.new
25
+
26
+ order_repo.create(credentials, new_order)
27
+
28
+
29
+ ### Delete a resource
30
+
31
+ class OrderRepository
32
+ include Lucid::Shopify::Resource::Delete
33
+
34
+ resource :orders
35
+ end
36
+
37
+ order_repo = OrderRepository.new
38
+
39
+ order_repo.delete(credentials, id)
40
+
41
+
42
+ ### Read a resource
43
+
44
+ Include and configure `Read`:
45
+
46
+ class OrderRepository
47
+ include Lucid::Shopify::Resource::Read
48
+
49
+ resource :orders
50
+
51
+ default_params fields: %w[id tags], limit: 250
52
+ end
53
+
54
+ order_repo = OrderRepository.new
55
+
56
+ order_repo.find(credentials, id)
57
+
58
+ The `OrderRepository` class is enumerable. Each page is fetched
59
+ from the API as needed, rather than all at once:
60
+
61
+ order_repo = OrderRepository.new
62
+
63
+ order_repo.each(credentials) |order|
64
+ # ...
65
+ end
66
+
67
+
68
+ ### Update a resource
69
+
70
+ class OrderRepository
71
+ include Lucid::Shopify::Resource::Update
72
+
73
+ resource :orders
74
+ end
75
+
76
+ order_repo = OrderRepository.new
77
+
78
+ order_repo.create(credentials, id, order)
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Primarily for Bundler.
4
+
5
+ require 'lucid/shopify/resource'
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lucid
4
+ module Shopify
5
+ module Resource
6
+ autoload :Create, 'lucid/shopify/resource/create'
7
+ autoload :Delete, 'lucid/shopify/resource/delete'
8
+ autoload :Read, 'lucid/shopify/resource/read'
9
+ autoload :Update, 'lucid/shopify/resource/update'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ require 'lucid/shopify/container'
6
+
7
+ module Lucid
8
+ module Shopify
9
+ module Resource
10
+ module Base
11
+ module ClassMethods
12
+ # Set the remote API resource name for the subclass. If a singular
13
+ # is not provided, the plural will be used, without any trailing 's'.
14
+ #
15
+ # @param resource_plural [String, #to_s]
16
+ # @param resource_singular [String, #to_s, nil]
17
+ #
18
+ # @example
19
+ # resource :orders
20
+ def resource(resource_plural, resource_singular = nil)
21
+ define_method(:resource) { resource_plural.to_s }
22
+ define_method(:resource_singular) do
23
+ resource_singular.nil? ? resource_plural.to_s.sub(/s$/, '') : resource_singular.to_s
24
+ end
25
+ end
26
+ end
27
+
28
+ # @param base [Class, Module]
29
+ def self.included(base)
30
+ base.extend(ClassMethods)
31
+ end
32
+
33
+ # @abstract Use {ClassMethods#resource} to implement (required)
34
+ #
35
+ # @return [String]
36
+ def resource
37
+ raise NotImplementedError
38
+ end
39
+
40
+ # @return [Client]
41
+ def client
42
+ @client ||= Container[:client]
43
+ end
44
+
45
+ # @param new_client [Client]
46
+ def client=(new_client)
47
+ @client = new_client
48
+ end
49
+
50
+ # @return [Logger]
51
+ def logger
52
+ @logger ||= Logger.new(IO::NULL)
53
+ end
54
+
55
+ # @param new_logger [Logger]
56
+ def logger=(new_logger)
57
+ @logger = new_logger
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lucid/shopify/resource/base'
4
+
5
+ module Lucid
6
+ module Shopify
7
+ module Resource
8
+ # @example
9
+ # class OrderRepository
10
+ # include Lucid::Shopify::Resource::Create
11
+ #
12
+ # resource :orders
13
+ #
14
+ # # ...
15
+ # end
16
+ module Create
17
+ # @param base [Class, Module]
18
+ def self.included(base)
19
+ base.include(Base)
20
+ end
21
+
22
+ # @param credentials [Credentials]
23
+ # @param data [Hash]
24
+ #
25
+ # @return [Integer] the new ID
26
+ def create(credentials, data)
27
+ data = client.post_json(credentials, resource, resource_singular => data).to_h
28
+
29
+ data.dig(resource_singular, 'id').tap do |id|
30
+ logger.info("Created #{resource_singular} id=#{id}")
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lucid/shopify/resource/base'
4
+
5
+ module Lucid
6
+ module Shopify
7
+ module Resource
8
+ # @example
9
+ # class OrderRepository
10
+ # include Lucid::Shopify::Resource::Delete
11
+ #
12
+ # resource :orders
13
+ #
14
+ # # ...
15
+ # end
16
+ module Delete
17
+ # @param base [Class, Module]
18
+ def self.included(base)
19
+ base.include(Base)
20
+ end
21
+
22
+ # @param credentials [Credentials]
23
+ # @param id [Integer]
24
+ def delete(credentials, id)
25
+ client.delete(credentials, "#{resource}/#{id}").tap do
26
+ logger.info("Deleted #{resource_singular} id=#{id}")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lucid/shopify/resource/base'
4
+
5
+ module Lucid
6
+ module Shopify
7
+ module Resource
8
+ # @example
9
+ # class OrderRepository
10
+ # include Lucid::Shopify::Resource::Read
11
+ #
12
+ # resource :orders
13
+ #
14
+ # default_params fields: %w[id tags]
15
+ #
16
+ # # ...
17
+ # end
18
+ module Read
19
+ module ClassMethods
20
+ # Set the default query params. Note that 'fields' may be passed as an
21
+ # array of strings.
22
+ #
23
+ # @param params [Hash]
24
+ #
25
+ # @example
26
+ # default_params fields: %w(id tags)
27
+ def default_params(params)
28
+ define_method(:default_params) { params }
29
+ end
30
+ end
31
+
32
+ include Enumerable
33
+
34
+ # @param base [Class, Module]
35
+ def self.included(base)
36
+ base.extend(ClassMethods)
37
+ base.include(Base)
38
+ end
39
+
40
+ # @abstract Use {ClassMethods#default_params} to implement (optional)
41
+ #
42
+ # @return [Hash]
43
+ def default_params
44
+ {}
45
+ end
46
+
47
+ # Defaults set by Shopify when not specified.
48
+ #
49
+ # @return [Hash]
50
+ def default_shopify_params
51
+ {
52
+ limit: 50,
53
+ }
54
+ end
55
+
56
+ # @param credentials [Credentials]
57
+ # @param id [Integer]
58
+ # @param params [Hash]
59
+ #
60
+ # @return [Hash]
61
+ def find(credentials, id, params = {})
62
+ params = finalise_params(params)
63
+
64
+ logger.info("Fetching #{resource_singular} id=#{id}")
65
+
66
+ client.get(credentials, "#{resource}/#{id}", params)[resource_singular]
67
+ end
68
+
69
+ # Iterate over results. If set, the 'fields' option must include 'id'. We
70
+ # would not need this if we used offset pagination, but offset pagination
71
+ # is unreliable.
72
+ #
73
+ # Throttling is always enabled.
74
+ #
75
+ # @param credentials [Credentials]
76
+ # @param params [Hash]
77
+ #
78
+ # @yield [Hash]
79
+ #
80
+ # @return [Enumerator]
81
+ #
82
+ # @raise [ArgumentError] if 'fields' does not include 'id'
83
+ def each(credentials, params = {})
84
+ return to_enum(__method__, credentials, params) unless block_given?
85
+
86
+ assert_fields_id!(params = finalise_params(params))
87
+
88
+ throttled_client = client.throttled
89
+
90
+ since_id = params.delete('since_id') || 1
91
+
92
+ loop do
93
+ logger.info("Fetching #{resource} since_id=#{since_id}")
94
+
95
+ results = throttled_client.get(credentials, resource, params.merge(since_id: since_id))[resource]
96
+ results.each do |result|
97
+ yield result
98
+ end
99
+
100
+ break if results.empty?
101
+
102
+ since_id = results.last['id']
103
+ end
104
+ end
105
+
106
+ # @param params [Hash] the finalised params (see {#finalise_params})
107
+ private def assert_fields_id!(params)
108
+ return unless params['fields']
109
+ return unless params['fields'] !~ /\bid\b/
110
+
111
+ raise ArgumentError, 'attempt to paginate without id field'
112
+ end
113
+
114
+ # @param credentials [Credentials]
115
+ # @param params [Hash]
116
+ #
117
+ # @return [Integer]
118
+ def count(credentials, params = {})
119
+ params = finalise_params(params)
120
+
121
+ logger.info("Fetching #{resource} count")
122
+
123
+ client.get(credentials, "#{resource}/count", params)['count']
124
+ end
125
+
126
+ # Merge with default params and format for query string.
127
+ #
128
+ # @param params [Hash]
129
+ #
130
+ # @return [Hash]
131
+ private def finalise_params(params)
132
+ params = default_shopify_params.merge(default_params).merge(params)
133
+
134
+ params.each_with_object({}) do |(k, v), h|
135
+ k = k.to_s
136
+ k == 'fields' && v.is_a?(Array) ? v.join(',') : v
137
+ h[k] = v
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lucid/shopify/resource/base'
4
+
5
+ module Lucid
6
+ module Shopify
7
+ module Resource
8
+ # @example
9
+ # class OrderRepository
10
+ # include Lucid::Shopify::Resource::Update
11
+ #
12
+ # resource :orders
13
+ #
14
+ # # ...
15
+ # end
16
+ module Update
17
+ # @param base [Class, Module]
18
+ def self.included(base)
19
+ base.include(Base)
20
+ end
21
+
22
+ # @param credentials [Credentials]
23
+ # @param id [Integer]
24
+ # @param data [Hash]
25
+ def update(credentials, id, data)
26
+ client.put_json(credentials, "#{resource}/#{id}", resource_singular => data).tap do
27
+ logger.info("Updated #{resource_singular} id=#{id}")
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lucid
4
+ module Shopify
5
+ module Resource
6
+ VERSION = '0.8.0'
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lucid-shopify-resource
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.0
5
+ platform: ruby
6
+ authors:
7
+ - Kelsey Judson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-10-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.52.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.52.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: lucid-shopify
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.34'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.34'
55
+ description:
56
+ email: kelsey@lucid.nz
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - README.md
62
+ - lib/lucid-shopify-resource.rb
63
+ - lib/lucid/shopify/resource.rb
64
+ - lib/lucid/shopify/resource/base.rb
65
+ - lib/lucid/shopify/resource/create.rb
66
+ - lib/lucid/shopify/resource/delete.rb
67
+ - lib/lucid/shopify/resource/read.rb
68
+ - lib/lucid/shopify/resource/update.rb
69
+ - lib/lucid/shopify/resource/version.rb
70
+ homepage: https://github.com/lucidnz/gem-lucid-shopify-resource
71
+ licenses:
72
+ - ISC
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubygems_version: 3.0.3
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Shopify client library resource helpers
93
+ test_files: []