sanity-ruby 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 99698b9c87c062e3b1ba260579a51d00913b28690bba2eef557c5ab3ffe43a61
4
- data.tar.gz: 0cc88772721d519604f1ffb3fecd38d456c4fcff8b5de036dbf7f932b537d13f
3
+ metadata.gz: 6992c7a949150c3c6d2fc4f927e74f18b2b00d7158cb26905e195eb7d91da627
4
+ data.tar.gz: 0c2e2088e770fe98cff7a1522c6a39076a8efc43410ea9eb241311e2611cd1fe
5
5
  SHA512:
6
- metadata.gz: b2f9cf2fd8dece545f5ac80878fa99910b440b9ac78dc318b26f619da6103f9940c477a4431b7129626fd1c157b31a2ee6679fe32092e7be0add78d926a93f52
7
- data.tar.gz: 7bda92a9734b5415abb245067dc1971b6a2239bdcd66b6710b14e5cb10fada6e4bb73c71e47a0fd4e65500c5bb7406b3e8274c4648c5cdde47ced1904d72cf09
6
+ metadata.gz: 2fff7714db16558133549a6cc8ed496cc2e157b17b533a44501ad125a0f7636d1575c9766939989711c7f957de7e6167cbd285963bbf8aac19bcdb7c2cde9377
7
+ data.tar.gz: 360d11148a57b4880b7cc661e4f7b7a51b8e2be937f991a4f1a6546fb21be348bd11123bba3d46eb71178a8c6aa628bcc107e7cee55ebeb613f4a80b4df5cdbe
data/.dockerignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle
2
+ /vendor/
3
+ Gemfile.lock
4
+
5
+ /log/*
6
+ /tmp/*
7
+ !/log/.keep
8
+ !/tmp/.keep
9
+
10
+
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  Gemfile.lock
10
+ vendor/
data/Dockerfile-2.6 ADDED
@@ -0,0 +1,30 @@
1
+ FROM ruby:2.6-alpine as base
2
+
3
+ RUN apk add --update --no-cache \
4
+ build-base \
5
+ cmake \
6
+ tzdata \
7
+ bash \
8
+ git
9
+
10
+ ENV APP_PATH /var/www/sanity-ruby
11
+ RUN mkdir -p $APP_PATH
12
+
13
+ # Build intermediate
14
+ FROM base as intermediate
15
+
16
+ WORKDIR $APP_PATH
17
+
18
+ RUN rm -rf /var/cache/apk/*
19
+
20
+ FROM base as development
21
+
22
+ COPY --from=intermediate $APP_PATH $APP_PATH
23
+
24
+ WORKDIR $APP_PATH
25
+
26
+ ENV GEM_HOME $APP_PATH/vendor/bundle
27
+ ENV BUNDLE_PATH vendor/bundle
28
+
29
+ COPY . ./
30
+ RUN bundle check || bundle install
data/Dockerfile-2.7 ADDED
@@ -0,0 +1,31 @@
1
+ FROM ruby:2.7-alpine as base
2
+
3
+ RUN apk add --update --no-cache \
4
+ build-base \
5
+ cmake \
6
+ tzdata \
7
+ bash \
8
+ git
9
+
10
+ ENV APP_PATH /var/www/sanity-ruby
11
+ RUN mkdir -p $APP_PATH
12
+
13
+ # Build intermediate
14
+ FROM base as intermediate
15
+
16
+ WORKDIR $APP_PATH
17
+
18
+ RUN rm -rf /var/cache/apk/*
19
+
20
+ FROM base as development
21
+
22
+ COPY --from=intermediate $APP_PATH $APP_PATH
23
+
24
+ WORKDIR $APP_PATH
25
+
26
+ ENV GEM_HOME $APP_PATH/vendor/bundle
27
+ ENV BUNDLE_PATH vendor/bundle
28
+
29
+ COPY . ./
30
+ RUN bundle check || bundle install
31
+
data/Dockerfile-3.0 ADDED
@@ -0,0 +1,30 @@
1
+ FROM ruby:3.0-alpine as base
2
+
3
+ RUN apk add --update --no-cache \
4
+ build-base \
5
+ cmake \
6
+ tzdata \
7
+ bash \
8
+ git
9
+
10
+ ENV APP_PATH /var/www/sanity-ruby
11
+ RUN mkdir -p $APP_PATH
12
+
13
+ # Build intermediate
14
+ FROM base as intermediate
15
+
16
+ WORKDIR $APP_PATH
17
+
18
+ RUN rm -rf /var/cache/apk/*
19
+
20
+ FROM base as development
21
+
22
+ COPY --from=intermediate $APP_PATH $APP_PATH
23
+
24
+ WORKDIR $APP_PATH
25
+
26
+ ENV GEM_HOME $APP_PATH/vendor/bundle
27
+ ENV BUNDLE_PATH vendor/bundle
28
+
29
+ COPY . ./
30
+ RUN bundle check || bundle install
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in sanity.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 12.0"
6
+ gem "rake", ">= 12.0"
7
7
  gem "minitest", "~> 5.0"
8
8
  gem "minitest-reporters", ">= 1.4"
9
9
  gem "mocha", ">= 1.12"
data/README.md CHANGED
@@ -9,7 +9,7 @@ The library also provides other features, like:
9
9
 
10
10
  - Easy configuration for fast setup and use.
11
11
  - A pre-defined class to help make any PORO a "sanity resource"
12
- - Extensibility in overriding the wrapper of your API response results
12
+ - Extensibility in overriding the serializer for the API response results
13
13
  - A small DSL around GROQ queries
14
14
 
15
15
  ## Contents
@@ -17,6 +17,7 @@ The library also provides other features, like:
17
17
  - [Sanity](#sanity)
18
18
  - [Contents](#contents)
19
19
  - [Getting Started](#getting-started)
20
+ - [Serialization](#serialization)
20
21
  - [Mutating](#mutating)
21
22
  - [Querying](#querying)
22
23
  - [Development](#development)
@@ -100,6 +101,63 @@ class User
100
101
  end
101
102
  ```
102
103
 
104
+ ## Serialization
105
+
106
+ When using a PORO, you can opt-in to automatically serialize your results. You
107
+ must define all attributes that should be serialized.
108
+
109
+ ```ruby
110
+ class User < Sanity::Resource
111
+ auto_serialize
112
+ ...
113
+ end
114
+ ```
115
+
116
+ Additionally, you can configure a custom serializer. See how to define a custom
117
+ serializer [below](#custom-serializer).
118
+
119
+ ```ruby
120
+ class User < Sanity::Resource
121
+ serializer UserSerializer
122
+ ...
123
+ end
124
+ ```
125
+
126
+ Finally, at query time you can also pass in a serializer. A serializer specified
127
+ at query time will take priority over any other configuration.
128
+
129
+ ```ruby
130
+ User.where(active: true, serializer: UserSerializer)
131
+ ```
132
+
133
+ where `UserSerializer` might look like:
134
+
135
+ ```ruby
136
+ class UserSerializer
137
+ class << self
138
+ def call(...)
139
+ new(...).call
140
+ end
141
+ end
142
+
143
+ attr_reader :results
144
+
145
+ def initialize(args)
146
+ @results = args["result"]
147
+ end
148
+
149
+ def call
150
+ results.map do |result|
151
+ User.new(
152
+ _id: result["_id"],
153
+ _type: result["_type"]
154
+ )
155
+ end
156
+ end
157
+ end
158
+ ```
159
+
160
+
103
161
  ## Mutating
104
162
 
105
163
  To [create a document](https://www.sanity.io/docs/http-mutations#c732f27330a4):
@@ -137,7 +195,7 @@ Sanity::Document.patch(params: { _id: "1234-321", set: { first_name: "Carl" }})
137
195
  To [find document(s) by id](https://www.sanity.io/docs/http-doc):
138
196
 
139
197
  ```ruby
140
- Sanity::Document.find(_id: "1234-321")
198
+ Sanity::Document.find(id: "1234-321")
141
199
  ```
142
200
 
143
201
  To find documents based on certain fields:
@@ -218,12 +276,24 @@ GROQ
218
276
  Sanity::Document.where(groq: groq_query, variables: {name: "Monsters, Inc."})
219
277
  ```
220
278
 
279
+
221
280
  ## Development
222
281
 
223
282
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
224
283
 
225
284
  To install this gem onto your local machine, run `bundle exec rake install`.
226
285
 
286
+ ### Testing across all supported versions:
287
+
288
+ To run tests across all gem supported ruby versions (requires Docker):
289
+ ```sh
290
+ bin/dev-test
291
+ ```
292
+ To run lint across all gem supported ruby versions (requires Docker):
293
+ ```sh
294
+ bin/dev-lint
295
+ ```
296
+
227
297
  ## Contributing
228
298
 
229
299
  Bug reports and pull requests are welcome on GitHub at https://github.com/morning-brew/sanity-ruby.
data/bin/dev-lint ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ system "docker-compose run --rm 2.6 bin/standardrb && docker-compose run --rm 2.7 bin/standardrb && docker-compose run --rm 3.0 bin/standardrb"
data/bin/dev-test ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ system "docker-compose run --rm 2.6 bundle exec rake test && docker-compose run --rm 2.7 bundle exec rake test && docker-compose run --rm 3.0 bundle exec rake test"
@@ -0,0 +1,46 @@
1
+ version: '3.9'
2
+
3
+ services:
4
+ '2.6':
5
+ build:
6
+ context: .
7
+ dockerfile: Dockerfile-2.6
8
+ tty: true
9
+ stdin_open: true
10
+ volumes:
11
+ - ./bin:/var/www/sanity-ruby/bin/
12
+ - ./lib:/var/www/sanity-ruby/lib/
13
+ - ./test:/var/www/sanity-ruby/test/
14
+ container_name: sanity-ruby-2.6
15
+ command: bash
16
+
17
+ '2.7':
18
+ build:
19
+ context: .
20
+ dockerfile: Dockerfile-2.7
21
+ tty: true
22
+ stdin_open: true
23
+ volumes:
24
+ - ./bin:/var/www/sanity-ruby/bin/
25
+ - ./lib:/var/www/sanity-ruby/lib/
26
+ - ./test:/var/www/sanity-ruby/test/
27
+ container_name: sanity-ruby-2.7
28
+ command: bash
29
+
30
+ '3.0':
31
+ build:
32
+ context: .
33
+ dockerfile: Dockerfile-3.0
34
+ tty: true
35
+ stdin_open: true
36
+ volumes:
37
+ - ./bin:/var/www/sanity-ruby/bin/
38
+ - ./lib:/var/www/sanity-ruby/lib/
39
+ - ./test:/var/www/sanity-ruby/test/
40
+ container_name: sanity-ruby-3.0
41
+ command: bash
42
+
43
+ volumes:
44
+ bin:
45
+ lib:
46
+ test:
@@ -68,6 +68,8 @@ module Sanity
68
68
  filter_value << "#{filter(key: nested_key)} #{key} #{equal} #{cast_value(val)}"
69
69
  elsif val.is_a?(Array) && !val[0].is_a?(Hash)
70
70
  filter_value << "#{key} in #{val.map(&:to_s)}"
71
+ elsif [true, false].include?(val)
72
+ filter_value << "#{filter(key: nested_key)} #{key} #{equal} #{val}"
71
73
  elsif LOGICAL_OPERATORS.key?(key)
72
74
  if val.is_a?(Array)
73
75
  val.each { |hsh| iterate(hsh, nested_key: key) }
@@ -24,7 +24,7 @@ module Sanity
24
24
  def call
25
25
  return "" unless limit
26
26
 
27
- !offset ? zero_index_to_limit : offset_to_limit
27
+ (!offset) ? zero_index_to_limit : offset_to_limit
28
28
  end
29
29
 
30
30
  private
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "set"
3
4
  using Sanity::Refinements::Strings
4
5
  using Sanity::Refinements::Arrays
5
6
 
@@ -34,13 +35,18 @@ module Sanity
34
35
  visibility: :sync
35
36
  }.freeze
36
37
 
37
- attr_reader :options, :params, :resource_klass, :query_set, :result_wrapper
38
+ attr_reader :options, :params, :resource_klass, :query_set, :serializer
38
39
 
39
40
  def initialize(**args)
40
41
  @resource_klass = args.delete(:resource_klass)
41
42
  @params = args.delete(:params)
42
43
  @query_set = Set.new
43
- @result_wrapper = args.delete(:result_wrapper) || Sanity::Http::Results
44
+
45
+ warn RESULT_WRAPPER_DEPRECATION_WARNING if args[:result_wrapper]
46
+ @serializer = args.delete(:serializer) ||
47
+ args.delete(:result_wrapper) || # kept for backwards compatibility
48
+ klass_serializer ||
49
+ Sanity::Http::Results
44
50
 
45
51
  raise ArgumentError, "resource_klass must be defined" unless resource_klass
46
52
  raise ArgumentError, "params argument is missing" unless params
@@ -59,10 +65,15 @@ module Sanity
59
65
 
60
66
  def call
61
67
  Net::HTTP.post(uri, {"#{REQUEST_KEY}": body}.to_json, headers).then do |result|
62
- block_given? ? yield(result_wrapper.call(result)) : result_wrapper.call(result)
68
+ block_given? ? yield(serializer.call(result)) : serializer.call(result)
63
69
  end
64
70
  end
65
71
 
72
+ def result_wrapper
73
+ warn RESULT_WRAPPER_DEPRECATION_WARNING
74
+ serializer
75
+ end
76
+
66
77
  private
67
78
 
68
79
  def base_url
@@ -88,6 +99,12 @@ module Sanity
88
99
  }
89
100
  end
90
101
 
102
+ def klass_serializer
103
+ return unless @resource_klass.respond_to?(:default_serializer)
104
+
105
+ @resource_klass.default_serializer
106
+ end
107
+
91
108
  def query_params
92
109
  camelize_query_set.map do |key, val|
93
110
  "#{key}=#{val}"
@@ -21,12 +21,17 @@ module Sanity
21
21
  end
22
22
  end
23
23
 
24
- attr_reader :resource_klass, :result_wrapper
24
+ attr_reader :resource_klass, :serializer
25
25
 
26
26
  # @todo Add query support
27
27
  def initialize(**args)
28
28
  @resource_klass = args.delete(:resource_klass)
29
- @result_wrapper = args.delete(:result_wrapper) || Sanity::Http::Results
29
+
30
+ warn RESULT_WRAPPER_DEPRECATION_WARNING if args[:result_wrapper]
31
+ @serializer = args.delete(:serializer) ||
32
+ args.delete(:result_wrapper) || # kept for backwards compatibility
33
+ klass_serializer ||
34
+ Sanity::Http::Results
30
35
  end
31
36
 
32
37
  # @todo Add query support
@@ -42,10 +47,15 @@ module Sanity
42
47
  http.request(request).then do |result|
43
48
  data = JSON.parse(result.body)
44
49
 
45
- block_given? ? yield(result_wrapper.call(data)) : result_wrapper.call(data)
50
+ block_given? ? yield(serializer.call(data)) : serializer.call(data)
46
51
  end
47
52
  end
48
53
 
54
+ def result_wrapper
55
+ warn RESULT_WRAPPER_DEPRECATION_WARNING
56
+ serializer
57
+ end
58
+
49
59
  private
50
60
 
51
61
  def request_body
@@ -66,6 +76,12 @@ module Sanity
66
76
  }
67
77
  end
68
78
 
79
+ def klass_serializer
80
+ return unless @resource_klass.respond_to?(:default_serializer)
81
+
82
+ @resource_klass.default_serializer
83
+ end
84
+
69
85
  def uri
70
86
  URI(base_url)
71
87
  end
@@ -18,7 +18,9 @@ module Sanity
18
18
  @variables = args.delete(:variables) || {}
19
19
  @use_post = args.delete(:use_post) || false
20
20
 
21
- @groq_attributes = args.except(:groq, :use_post, :resource_klass, :result_wrapper)
21
+ @groq_attributes = args.except(
22
+ :groq, :use_post, :resource_klass, :serializer, :result_wrapper
23
+ )
22
24
  end
23
25
 
24
26
  private
@@ -17,7 +17,7 @@ module Sanity
17
17
  refine String do
18
18
  def camelize_lower
19
19
  split("_")[0..].each_with_index.map do |val, idx|
20
- idx != 0 ? val.capitalize : val
20
+ (idx != 0) ? val.capitalize : val
21
21
  end.join
22
22
  end
23
23
 
@@ -8,6 +8,7 @@ module Sanity
8
8
  # Sanity::Attributable
9
9
  # Sanity::Mutatable
10
10
  # Sanity::Queryable
11
+ # Sanity::Serializable
11
12
  #
12
13
  # Sanity::Document and Sanity::Asset both inherit
13
14
  # from Sanity::Resource
@@ -26,5 +27,6 @@ module Sanity
26
27
  include Sanity::Attributable
27
28
  include Sanity::Mutatable
28
29
  include Sanity::Queryable
30
+ include Sanity::Serializable
29
31
  end
30
32
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sanity
4
+ # Serializable is responsible for configuring auto serialization or a default
5
+ # serializer. It also defines the default class serializer used when auto
6
+ # serialization is enabled.
7
+ #
8
+ # The auto_serialize macro is used to enable auto serialization.
9
+ #
10
+ # @example enables auto serialization
11
+ # auto_serialize
12
+ #
13
+ # The serializer marco is used to define the default serializer.
14
+ #
15
+ # @example default to using a custom defined UserSerializer
16
+ # serializer UserSerializer
17
+ #
18
+ module Serializable
19
+ class << self
20
+ def included(base)
21
+ base.extend(ClassMethods)
22
+ end
23
+ end
24
+
25
+ module ClassMethods
26
+ def default_serializer
27
+ @default_serializer ||=
28
+ if auto_serialize?
29
+ class_serializer
30
+ elsif defined?(@serializer)
31
+ @serializer
32
+ end
33
+ end
34
+
35
+ def auto_serialize?
36
+ return @auto_serialize if defined?(@auto_serialize)
37
+
38
+ superclass.respond_to?(:auto_serialize?) && superclass.auto_serialize?
39
+ end
40
+
41
+ private
42
+
43
+ def auto_serialize
44
+ @auto_serialize = true
45
+ end
46
+
47
+ def serializer(serializer)
48
+ @serializer = serializer
49
+ end
50
+
51
+ def class_serializer
52
+ @class_serializer ||= proc do |results|
53
+ results["result"].map do |result|
54
+ attributes = result.slice(*self.attributes.map(&:to_s))
55
+ new(**attributes.transform_keys(&:to_sym))
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sanity
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/sanity.rb CHANGED
@@ -12,10 +12,13 @@ require "sanity/http"
12
12
  require "sanity/attributable"
13
13
  require "sanity/mutatable"
14
14
  require "sanity/queryable"
15
+ require "sanity/serializable"
15
16
 
16
17
  require "sanity/resource"
17
18
  require "sanity/resources"
18
19
 
19
20
  module Sanity
20
21
  class Error < StandardError; end
22
+
23
+ RESULT_WRAPPER_DEPRECATION_WARNING = "DEPRECATION: `result_wrapper` is deprecated. Please use `serializer` instead."
21
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanity-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Morning Brew
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-25 00:00:00.000000000 Z
11
+ date: 2023-10-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ''
14
14
  email: tech@morningbrew.com
@@ -16,16 +16,23 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
+ - ".dockerignore"
19
20
  - ".github/workflows/ci.yml"
20
21
  - ".gitignore"
21
22
  - ".standard.yml"
23
+ - Dockerfile-2.6
24
+ - Dockerfile-2.7
25
+ - Dockerfile-3.0
22
26
  - Gemfile
23
27
  - LICENSE.txt
24
28
  - README.md
25
29
  - Rakefile
26
30
  - bin/console
31
+ - bin/dev-lint
32
+ - bin/dev-test
27
33
  - bin/setup
28
34
  - bin/standardrb
35
+ - docker-compose.yml
29
36
  - lib/sanity-ruby.rb
30
37
  - lib/sanity.rb
31
38
  - lib/sanity/attributable.rb
@@ -56,6 +63,7 @@ files:
56
63
  - lib/sanity/resources.rb
57
64
  - lib/sanity/resources/asset.rb
58
65
  - lib/sanity/resources/document.rb
66
+ - lib/sanity/serializable.rb
59
67
  - lib/sanity/version.rb
60
68
  - sanity.gemspec
61
69
  homepage: https://github.com/morning-brew/sanity-ruby
@@ -80,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
88
  - !ruby/object:Gem::Version
81
89
  version: '0'
82
90
  requirements: []
83
- rubygems_version: 3.1.4
91
+ rubygems_version: 3.4.17
84
92
  signing_key:
85
93
  specification_version: 4
86
94
  summary: Ruby bindings for the Sanity API