sanity-ruby 0.3.0 → 0.5.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: 6992c7a949150c3c6d2fc4f927e74f18b2b00d7158cb26905e195eb7d91da627
4
- data.tar.gz: 0c2e2088e770fe98cff7a1522c6a39076a8efc43410ea9eb241311e2611cd1fe
3
+ metadata.gz: a6bf214154655cc746cb50c817499ddef2dc104915633814fb4bbb60dbcf18d6
4
+ data.tar.gz: 0e906831bd32ae8b98431adb107a1aca54ea0b6baa30327807cb0764f0a35c25
5
5
  SHA512:
6
- metadata.gz: 2fff7714db16558133549a6cc8ed496cc2e157b17b533a44501ad125a0f7636d1575c9766939989711c7f957de7e6167cbd285963bbf8aac19bcdb7c2cde9377
7
- data.tar.gz: 360d11148a57b4880b7cc661e4f7b7a51b8e2be937f991a4f1a6546fb21be348bd11123bba3d46eb71178a8c6aa628bcc107e7cee55ebeb613f4a80b4df5cdbe
6
+ metadata.gz: 99db43870e1f4ac67f63e46b142545c5588657d93eaee2eb007352a33646f36f5d7b31d1992b8dbca12eb98f92b9bab27ae8c0122637b3d0a3815f3eb1543b02
7
+ data.tar.gz: 9c09be7fec031eda815290b3e6dab1c2e080a7cb053eaf0274989181661d8e9f84c264ef798c7d17ee9b828a1fd2abae9fe17547f137d1f6dcb167768d5425eb
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Sanity
2
2
 
3
- ![](https://github.com/morning-brew/sanity-ruby/actions/workflows/ci.yml/badge.svg)
4
- <a href="https://codeclimate.com/github/morning-brew/sanity-ruby/maintainability"><img src="https://api.codeclimate.com/v1/badges/1984ee6eb0bce46a2469/maintainability" /></a>
3
+ ![](https://github.com/dvmonroe/sanity-ruby/actions/workflows/ci.yml/badge.svg)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/24b96780b59c8a871e6e/maintainability)](https://codeclimate.com/github/dvmonroe/sanity-ruby/maintainability)
5
5
 
6
6
  The Sanity Ruby library provides convenient access to the Sanity API from applications written in Ruby. It includes a pre-defined set of classes for API resources.
7
7
 
@@ -44,6 +44,18 @@ Sanity.configure do |s|
44
44
  end
45
45
  ```
46
46
 
47
+ or you can set the following ENV variables at runtime:
48
+
49
+ ```bash
50
+ SANITY_TOKEN="yoursupersecrettoken"
51
+ SANITY_API_VERSION="v2021-03-25"
52
+ SANITY_PROJECT_ID="1234"
53
+ SANITY_DATASET="development"
54
+ SANITY_USE_CDN="false"
55
+ ```
56
+
57
+ The configuration object is thread safe meaning you can connect to multiple different projects across multiple threads. This may be useful if your application is interacting with multiple different Sanity projects.
58
+
47
59
  To create a new document:
48
60
 
49
61
  ```ruby
@@ -70,9 +82,26 @@ To make any PORO a sanity resource:
70
82
  ```ruby
71
83
  class User < Sanity::Resource
72
84
  attribute :_id, default: ""
73
- attribute :_type: default: ""
85
+ attribute :_type, default: ""
74
86
  mutatable only: %i(create delete)
75
87
  queryable
88
+ publishable
89
+ end
90
+ ```
91
+
92
+
93
+
94
+ Since `Sanity::Resource` includes `ActiveModel::Model` and
95
+ `ActiveModel::Attributes`, you're able to define types on attributes and use
96
+ methods like `alias_attribute`.
97
+
98
+ ```ruby
99
+ class User < Sanity::Resource
100
+ ...
101
+ attribute :name, :string, default: 'John Doe'
102
+ attribute :_createdAt, :datetime
103
+ alias_attribute :created_at, :_createdAt
104
+ ...
76
105
  end
77
106
  ```
78
107
 
@@ -190,6 +219,20 @@ To [patch a document](https://www.sanity.io/docs/http-mutations#2f480b2baca5):
190
219
  Sanity::Document.patch(params: { _id: "1234-321", set: { first_name: "Carl" }})
191
220
  ```
192
221
 
222
+ ## Publishing
223
+
224
+ To [publish a document](https://www.sanity.io/docs/scheduling-api#dcb47be520d0):
225
+
226
+ ```ruby
227
+ Sanity::Document.publish(["1234-321"])
228
+ ```
229
+
230
+ To [unpublish a document](https://www.sanity.io/docs/scheduling-api#64f3de350651):
231
+
232
+ ```ruby
233
+ Sanity::Document.unpublish(["1234-321", "1432432-545"])
234
+ ```
235
+
193
236
  ## Querying
194
237
 
195
238
  To [find document(s) by id](https://www.sanity.io/docs/http-doc):
@@ -296,7 +339,7 @@ bin/dev-lint
296
339
 
297
340
  ## Contributing
298
341
 
299
- Bug reports and pull requests are welcome on GitHub at https://github.com/morning-brew/sanity-ruby.
342
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dvmonroe/sanity-ruby.
300
343
 
301
344
  ## License
302
345
 
@@ -39,7 +39,7 @@ module Sanity
39
39
  def initialize(**args)
40
40
  self.class.default_attributes.merge(args).then do |attrs|
41
41
  attrs.each do |key, val|
42
- define_singleton_method("#{key}=") do |val|
42
+ define_singleton_method(:"#{key}=") do |val|
43
43
  args[key] = val
44
44
  attributes[key] = val
45
45
  end
@@ -18,11 +18,11 @@ module Sanity
18
18
  attr_accessor :use_cdn
19
19
 
20
20
  def initialize
21
- @project_id = ""
22
- @dataset = ""
23
- @api_version = ""
24
- @token = ""
25
- @use_cdn = false
21
+ @project_id = ENV.fetch("SANITY_PROJECT_ID", "")
22
+ @dataset = ENV.fetch("SANITY_DATASET", "")
23
+ @api_version = ENV.fetch("SANITY_API_VERSION", "")
24
+ @token = ENV.fetch("SANITY_TOKEN", "")
25
+ @use_cdn = ENV.fetch("SANITY_USE_CDN", false) == "true"
26
26
  end
27
27
 
28
28
  # @return [String] Api subdomain based on use_cdn flag
@@ -32,7 +32,7 @@ module Sanity
32
32
  end
33
33
 
34
34
  def self.configuration
35
- @configuration ||= Configuration.new
35
+ Thread.current[:sanity_configuration] ||= Configuration.new
36
36
  end
37
37
 
38
38
  class << self
@@ -40,7 +40,7 @@ module Sanity
40
40
  end
41
41
 
42
42
  def self.configuration=(config)
43
- @configuration = config
43
+ Thread.current[:sanity_configuration] = config
44
44
  end
45
45
 
46
46
  def self.configure
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sanity
4
+ module TypeHelper
5
+ def self.default_type(klass)
6
+ return nil if klass == Sanity::Document
7
+
8
+ type = klass.to_s
9
+ type[0].downcase + type[1..]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sanity/helpers/type_helper"
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
3
+ require "set" # rubocop:disable Lint/RedundantRequireStatement
4
4
  using Sanity::Refinements::Strings
5
5
  using Sanity::Refinements::Arrays
6
6
 
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ using Sanity::Refinements::Strings
4
+ using Sanity::Refinements::Arrays
5
+
6
+ module Sanity
7
+ module Http
8
+ module Publication
9
+ class << self
10
+ def included(base)
11
+ base.extend(ClassMethods)
12
+ base.extend(Forwardable)
13
+ base.delegate(%i[project_id dataset token] => :"Sanity.config")
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+ def call(args)
19
+ new(args).call
20
+ end
21
+ end
22
+
23
+ attr_reader :args
24
+
25
+ def initialize(args)
26
+ unless args.is_a?(String) || args.is_a?(Array)
27
+ raise ArgumentError, "args must be a string or an array"
28
+ end
29
+ @args = Array.wrap(args)
30
+ end
31
+
32
+ def body_key
33
+ "documentId"
34
+ end
35
+
36
+ def call
37
+ Net::HTTP.post(uri, body.to_json, headers).then do |result|
38
+ block_given? ? yield(result) : result
39
+ end
40
+ end
41
+
42
+ def publication_path
43
+ self.class.name.demodulize.underscore.camelize_lower
44
+ end
45
+
46
+ private
47
+
48
+ def base_url
49
+ "https://api.sanity.io/v1/#{publication_path}/#{project_id}/#{dataset}"
50
+ end
51
+
52
+ def body
53
+ Array.wrap(args.map { |arg| {"#{body_key}": arg} })
54
+ end
55
+
56
+ def headers
57
+ {
58
+ "Content-Type": "application/json",
59
+ Authorization: "Bearer #{token}"
60
+ }
61
+ end
62
+
63
+ def uri
64
+ URI(base_url)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sanity
4
+ module Http
5
+ class Publish
6
+ include Sanity::Http::Publication
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sanity
4
+ module Http
5
+ class Unpublish
6
+ include Sanity::Http::Publication
7
+ end
8
+ end
9
+ end
data/lib/sanity/http.rb CHANGED
@@ -6,6 +6,7 @@ require "uri"
6
6
 
7
7
  require "sanity/http/mutation"
8
8
  require "sanity/http/query"
9
+ require "sanity/http/publication"
9
10
 
10
11
  require "sanity/http/create"
11
12
  require "sanity/http/create_if_not_exists"
@@ -13,6 +14,9 @@ require "sanity/http/create_or_replace"
13
14
  require "sanity/http/delete"
14
15
  require "sanity/http/patch"
15
16
 
17
+ require "sanity/http/publish"
18
+ require "sanity/http/unpublish"
19
+
16
20
  require "sanity/http/find"
17
21
  require "sanity/http/where"
18
22
 
@@ -26,8 +26,9 @@ module Sanity
26
26
  end
27
27
 
28
28
  module ClassMethods
29
- DEFAULT_KLASS_MUTATIONS = %i[create create_or_replace create_if_not_exists patch delete].freeze
30
- DEFAULT_INSTANCE_MUTATIONS = %i[create create_or_replace create_if_not_exists delete].freeze
29
+ COMMON_MUTATIONS = %i[create create_or_replace create_if_not_exists delete].freeze
30
+ DEFAULT_KLASS_MUTATIONS = (COMMON_MUTATIONS + [:patch]).freeze
31
+ DEFAULT_INSTANCE_MUTATIONS = COMMON_MUTATIONS
31
32
  ALL_MUTATIONS = DEFAULT_KLASS_MUTATIONS | DEFAULT_INSTANCE_MUTATIONS
32
33
 
33
34
  private
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sanity
4
+ # Publishable is responsible for setting the appropriate class methods
5
+ # that invoke Sanity::Http's publishable actions
6
+ #
7
+ # The publishable macro can limit what actions are accessible to the
8
+ # publishable object
9
+ #
10
+ # @example provides default class methods
11
+ # publishable
12
+ #
13
+ # @example only add the `.publish` method
14
+ # publishable only: %i(publish)
15
+ #
16
+ # @example only add the `.unpublish`& `#unpublish` methods
17
+ # publishable only: %i(unpublish)
18
+ #
19
+ using Sanity::Refinements::Strings
20
+
21
+ module Publishable
22
+ class << self
23
+ def included(base)
24
+ base.extend(ClassMethods)
25
+ end
26
+ end
27
+
28
+ module ClassMethods
29
+ PUBLISHABLE_ACTIONS = %i[publish unpublish].freeze
30
+
31
+ private
32
+
33
+ def publishable(**options)
34
+ options.fetch(:only, PUBLISHABLE_ACTIONS).each do |action|
35
+ if PUBLISHABLE_ACTIONS.include? action.to_sym
36
+ define_singleton_method(action) do |args|
37
+ Module.const_get("Sanity::Http::#{action.to_s.classify}").call(args)
38
+ end
39
+ end
40
+
41
+ if PUBLISHABLE_ACTIONS.include? action.to_sym
42
+ define_method(action) do
43
+ Module.const_get("Sanity::Http::#{action.to_s.classify}").call(attributes["_id"])
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -36,15 +36,20 @@ module Sanity
36
36
 
37
37
  private
38
38
 
39
- # @private
40
39
  def queryable(**options)
41
40
  options.fetch(:only, DEFAULT_KLASS_QUERIES).each do |query|
42
- define_singleton_method(query) do |**args|
43
- Module.const_get("Sanity::Http::#{query.to_s.classify}").call(**args.merge(resource_klass: self))
44
- end
45
- define_singleton_method("#{query}_api_endpoint") { QUERY_ENDPOINTS[query] }
41
+ define_query_method(query)
46
42
  end
47
43
  end
44
+
45
+ def define_query_method(query)
46
+ define_singleton_method(query) do |**args|
47
+ default_type = args.key?(:_type) ? args[:_type] : Sanity::TypeHelper.default_type(self)
48
+ default_args = {resource_klass: self, _type: default_type}.compact
49
+ Module.const_get("Sanity::Http::#{query.to_s.classify}").call(**default_args.merge(args))
50
+ end
51
+ define_singleton_method(:"#{query}_api_endpoint") { QUERY_ENDPOINTS[query] }
52
+ end
48
53
  end
49
54
  end
50
55
  end
@@ -5,7 +5,6 @@ module Sanity
5
5
  # the sanity resources defined within this gem.
6
6
  #
7
7
  # Out of the box it includes the following mixins:
8
- # Sanity::Attributable
9
8
  # Sanity::Mutatable
10
9
  # Sanity::Queryable
11
10
  # Sanity::Serializable
@@ -24,9 +23,13 @@ module Sanity
24
23
  # end
25
24
  #
26
25
  class Resource
27
- include Sanity::Attributable
26
+ include ActiveModel::Model
27
+ include ActiveModel::Attributes
28
+
28
29
  include Sanity::Mutatable
29
30
  include Sanity::Queryable
31
+ include Sanity::Publishable
32
+
30
33
  include Sanity::Serializable
31
34
  end
32
35
  end
@@ -21,5 +21,6 @@ module Sanity
21
21
  # See https://www.sanity.io/docs/http-mutations#ac77879076d4
22
22
  mutatable api_endpoint: "data/mutate"
23
23
  queryable
24
+ publishable
24
25
  end
25
26
  end
@@ -50,8 +50,9 @@ module Sanity
50
50
 
51
51
  def class_serializer
52
52
  @class_serializer ||= proc do |results|
53
- results["result"].map do |result|
54
- attributes = result.slice(*self.attributes.map(&:to_s))
53
+ key = results.key?("result") ? "result" : "documents"
54
+ results[key].map do |result|
55
+ attributes = result.slice(*attribute_names)
55
56
  new(**attributes.transform_keys(&:to_sym))
56
57
  end
57
58
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sanity
4
- VERSION = "0.3.0"
4
+ VERSION = "0.5.0"
5
5
  end
data/lib/sanity.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
3
4
  require "forwardable"
4
5
  require "sanity/refinements"
5
6
 
@@ -8,11 +9,12 @@ require "sanity/configuration"
8
9
 
9
10
  require "sanity/groqify"
10
11
  require "sanity/http"
12
+ require "sanity/helpers"
11
13
 
12
- require "sanity/attributable"
13
14
  require "sanity/mutatable"
14
15
  require "sanity/queryable"
15
16
  require "sanity/serializable"
17
+ require "sanity/publishable"
16
18
 
17
19
  require "sanity/resource"
18
20
  require "sanity/resources"
data/sanity.gemspec CHANGED
@@ -5,12 +5,12 @@ require_relative "lib/sanity/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "sanity-ruby"
7
7
  spec.version = Sanity::VERSION
8
- spec.authors = "Morning Brew"
9
- spec.email = "tech@morningbrew.com"
8
+ spec.authors = "Drew Monroe"
9
+ spec.email = "drew@pinecreeklabs.com"
10
10
 
11
11
  spec.summary = "Ruby bindings for the Sanity API"
12
12
  spec.description = ""
13
- spec.homepage = "https://github.com/morning-brew/sanity-ruby"
13
+ spec.homepage = "https://github.com/dvmonroe/sanity-ruby"
14
14
  spec.license = "MIT"
15
15
  spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
16
16
 
@@ -26,4 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.bindir = "exe"
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "activemodel"
29
31
  end
metadata CHANGED
@@ -1,17 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanity-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
- - Morning Brew
7
+ - Drew Monroe
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-23 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2024-04-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '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'
13
27
  description: ''
14
- email: tech@morningbrew.com
28
+ email: drew@pinecreeklabs.com
15
29
  executables: []
16
30
  extensions: []
17
31
  extra_rdoc_files: []
@@ -42,6 +56,8 @@ files:
42
56
  - lib/sanity/groq/select.rb
43
57
  - lib/sanity/groq/slice.rb
44
58
  - lib/sanity/groqify.rb
59
+ - lib/sanity/helpers.rb
60
+ - lib/sanity/helpers/type_helper.rb
45
61
  - lib/sanity/http.rb
46
62
  - lib/sanity/http/create.rb
47
63
  - lib/sanity/http/create_if_not_exists.rb
@@ -50,10 +66,14 @@ files:
50
66
  - lib/sanity/http/find.rb
51
67
  - lib/sanity/http/mutation.rb
52
68
  - lib/sanity/http/patch.rb
69
+ - lib/sanity/http/publication.rb
70
+ - lib/sanity/http/publish.rb
53
71
  - lib/sanity/http/query.rb
54
72
  - lib/sanity/http/results.rb
73
+ - lib/sanity/http/unpublish.rb
55
74
  - lib/sanity/http/where.rb
56
75
  - lib/sanity/mutatable.rb
76
+ - lib/sanity/publishable.rb
57
77
  - lib/sanity/queryable.rb
58
78
  - lib/sanity/refinements.rb
59
79
  - lib/sanity/refinements/arrays.rb
@@ -66,13 +86,13 @@ files:
66
86
  - lib/sanity/serializable.rb
67
87
  - lib/sanity/version.rb
68
88
  - sanity.gemspec
69
- homepage: https://github.com/morning-brew/sanity-ruby
89
+ homepage: https://github.com/dvmonroe/sanity-ruby
70
90
  licenses:
71
91
  - MIT
72
92
  metadata:
73
- homepage_uri: https://github.com/morning-brew/sanity-ruby
74
- source_code_uri: https://github.com/morning-brew/sanity-ruby
75
- changelog_uri: https://github.com/morning-brew/sanity-ruby
93
+ homepage_uri: https://github.com/dvmonroe/sanity-ruby
94
+ source_code_uri: https://github.com/dvmonroe/sanity-ruby
95
+ changelog_uri: https://github.com/dvmonroe/sanity-ruby
76
96
  post_install_message:
77
97
  rdoc_options: []
78
98
  require_paths: