sinja 1.1.0.pre3 → 1.1.0.pre4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c2b7704d06378c377a7668407ccfe7dd391bf22c
4
- data.tar.gz: 2a26bd92d8b7357d8561204654030e89398223d3
3
+ metadata.gz: a86013c139ad0c6cd3555443076a4c813c8cedc6
4
+ data.tar.gz: 7c3dc7d285fb817bb9e4c6003bc24c0cb8d2b1f2
5
5
  SHA512:
6
- metadata.gz: c7541478e11cd932871936c7bb470169fafcc4f24133d77c2a8559c5ba5fae07e0f0a5cfd03be94b0efa6222b19cf97f452a14a87300760738fb028b13b58f96
7
- data.tar.gz: abc9e3d5c75bc8324537f5d5cecad33c61c84eb82f98e2f24ba048fb74de128b5de377f7c272d3078da0dabe9c06578e0827097b358942337636fdbb5dd3d1f9
6
+ metadata.gz: 86a0909d1e859b4f2177de1d71c91b60fa5bc0160c8b1568f94acc100ce84c01157439633e89124eed2e09318a3b4ffb0aa6596fc7bae3a09ee88a4e9132ca43
7
+ data.tar.gz: 21f0f20bda31d9a6954437f66848eb47f7c13dd8e8250992bb259c9791f7cb3fa7b39f6ba8291101f7128bf8b7add9b8e87b32c768d95d3924a839fee90627c6
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/sinja.svg)](https://badge.fury.io/rb/sinja)
4
4
  [![Build Status](https://travis-ci.org/mwpastore/sinja.svg?branch=master)](https://travis-ci.org/mwpastore/sinja)
5
+ [![Chat](https://badges.gitter.im/sinja-rb/Lobby.svg)](https://gitter.im/sinja-rb/Lobby)
5
6
 
6
7
  Sinja is a [Sinatra][1] [extension][10] for quickly building [RESTful][11],
7
8
  [{json:api}][2]-[compliant][7] web services, leveraging the excellent
@@ -313,7 +314,7 @@ application.
313
314
 
314
315
  **dedasherize**
315
316
  : Takes a string or symbol and returns the string or symbol with any and all
316
- dashes transliterated to underscores.
317
+ dashes transliterated to underscores, and camelCase converted to snake_case.
317
318
 
318
319
  **dedasherize_names**
319
320
  : Takes a hash and returns the hash with its keys dedasherized (deeply).
data/demo-app/app.rb CHANGED
@@ -17,16 +17,14 @@ configure_jsonapi do |c|
17
17
  Sinja::Helpers::Sequel.config(c)
18
18
  end
19
19
 
20
- helpers Sinja::Helpers::Sequel do
20
+ helpers do
21
+ prepend Sinja::Helpers::Sequel
22
+
21
23
  def current_user
22
24
  # TESTING/DEMO PURPOSES ONLY -- DO NOT DO THIS IN PRODUCTION
23
25
  Author.first_by_email(env['HTTP_X_EMAIL']) if env.key?('HTTP_X_EMAIL')
24
26
  end
25
27
 
26
- def database
27
- DB
28
- end
29
-
30
28
  def role
31
29
  [].tap do |a|
32
30
  a << :logged_in if current_user
data/lib/sinja/errors.rb CHANGED
@@ -42,7 +42,7 @@ module Sinja
42
42
  def initialize(*args) super(405, *args) end
43
43
  end
44
44
 
45
- class NotAcceptibleError < HttpError
45
+ class NotAcceptableError < HttpError
46
46
  def initialize(*args) super(406, *args) end
47
47
  end
48
48
 
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
+ require 'forwardable'
2
3
  require 'sequel/model/inflections'
3
4
 
4
5
  module Sinja
5
6
  module Helpers
6
7
  module Sequel
7
8
  include ::Sequel::Inflections
9
+ extend Forwardable
8
10
 
9
11
  def self.config(c)
10
12
  c.conflict_exceptions << ::Sequel::ConstraintViolation
@@ -19,17 +21,8 @@ module Sinja
19
21
  } if ::Sequel::Database::EXTENSIONS.key?(:pagination)
20
22
  end
21
23
 
22
- def validate!
23
- raise ::Sequel::ValidationFailed, resource unless resource.valid?
24
- end
25
-
26
- def database
27
- ::Sequel::DATABASES.first
28
- end
29
-
30
- def filter(collection, fields)
31
- collection.where(fields)
32
- end
24
+ def_delegator ::Sequel::Model, :db, :database
25
+ def_delegator :database, :transaction
33
26
 
34
27
  def sort(collection, fields)
35
28
  collection.order(*fields.map { |k, v| ::Sequel.send(v, k) })
@@ -60,12 +53,11 @@ module Sinja
60
53
  return collection, pagination
61
54
  end if ::Sequel::Database::EXTENSIONS.key?(:pagination)
62
55
 
63
- def finalize(collection)
64
- collection.all
65
- end
56
+ define_method :filter, proc(&:where)
57
+ define_method :finalize, proc(&:all)
66
58
 
67
- def transaction(&block)
68
- database.transaction(&block)
59
+ def validate!
60
+ raise ::Sequel::ValidationFailed, resource unless resource.valid?
69
61
  end
70
62
 
71
63
  def next_pk(resource, **opts)
@@ -7,8 +7,10 @@ require 'set'
7
7
  module Sinja
8
8
  module Helpers
9
9
  module Serializers
10
+ VALID_PAGINATION_KEYS = Set.new(%i[self first prev next last]).freeze
11
+
10
12
  def dedasherize(s=nil)
11
- s.to_s.tr('-', '_').send(Symbol === s ? :to_sym : :itself)
13
+ s.to_s.underscore.send(Symbol === s ? :to_sym : :itself)
12
14
  end
13
15
 
14
16
  def dedasherize_names(*args)
@@ -110,38 +112,50 @@ module Sinja
110
112
  end
111
113
  end
112
114
 
113
- def serialize_models(models=[], options={})
115
+ def serialize_models(models=[], options={}, pagination=nil)
114
116
  options[:is_collection] = true
115
117
  options[:include] = include_exclude!(options)
116
118
  options[:fields] ||= params[:fields] unless params[:fields].empty?
117
119
  options = settings._sinja.serializer_opts.merge(options)
118
120
 
119
- if options.key?(:links) && pagination = options[:links].delete(:pagination)
121
+ if pagination
122
+ # Whitelist pagination keys and dasherize query parameter names
123
+ pagination = VALID_PAGINATION_KEYS
124
+ .select { |outer_key| pagination.key?(outer_key) }
125
+ .map! do |outer_key|
126
+ [outer_key, pagination[outer_key].map do |inner_key, value|
127
+ [inner_key.to_s.dasherize.to_sym, value]
128
+ end.to_h]
129
+ end.to_h
130
+
131
+ options[:meta] ||= {}
132
+ options[:meta][:pagination] = pagination
133
+
134
+ options[:links] ||= {}
120
135
  options[:links][:self] = request.url unless pagination.key?(:self)
121
136
 
122
- query = Rack::Utils.build_nested_query \
137
+ base_query = Rack::Utils.build_nested_query \
123
138
  env['rack.request.query_hash'].dup.tap { |h| h.delete('page') }
139
+
124
140
  self_link, join_char =
125
- if query.empty?
141
+ if base_query.empty?
126
142
  [request.path, ??]
127
143
  else
128
- ["#{request.path}?#{query}", ?&]
144
+ ["#{request.path}?#{base_query}", ?&]
129
145
  end
130
146
 
131
- %i[self first prev next last].each do |key|
132
- next unless pagination.key?(key)
133
- query = Rack::Utils.build_nested_query \
134
- :page=>pagination[key]
135
- options[:links][key] = "#{self_link}#{join_char}#{query}"
136
- end
147
+ options[:links].merge!(pagination.map do |key, value|
148
+ [key, [self_link,
149
+ Rack::Utils.build_nested_query(:page=>value)].join(join_char)]
150
+ end.to_h)
137
151
  end
138
152
 
139
153
  ::JSONAPI::Serializer.serialize([*models], options)
140
154
  end
141
155
 
142
- def serialize_models?(models=[], options={})
156
+ def serialize_models?(models=[], options={}, pagination=nil)
143
157
  if [*models].any?
144
- body serialize_models(models, options)
158
+ body serialize_models(models, options, pagination)
145
159
  elsif options.key?(:meta)
146
160
  body serialize_models([], :meta=>options[:meta])
147
161
  else
@@ -184,11 +198,7 @@ module Sinja
184
198
  end
185
199
 
186
200
  def exception_title(e)
187
- if e.respond_to?(:title)
188
- e.title
189
- else
190
- e.class.name.split('::').last.split(/(?=[[:upper:]])/).join(' ')
191
- end
201
+ e.respond_to?(:title) ? e.title : e.class.name.demodulize.titleize
192
202
  end
193
203
 
194
204
  def serialize_errors(&block)
@@ -25,9 +25,8 @@ module Sinja
25
25
  app.get '', :qparams=>%i[include fields filter sort page], :actions=>:fetch do
26
26
  filter_sort_page?(:fetch)
27
27
  collection, opts = fetch
28
- collection, links = filter_sort_page(collection)
29
- (opts[:links] ||= {}).merge!(links)
30
- serialize_models(collection, opts)
28
+ collection, pagination = filter_sort_page(collection)
29
+ serialize_models(collection, opts, pagination)
31
30
  end
32
31
 
33
32
  app.patch '', :nullif=>proc(&:empty?), :actions=>:clear do
@@ -105,8 +105,7 @@ module Sinja
105
105
  end
106
106
  end
107
107
 
108
- register RelationshipRoutes.const_get \
109
- rel_type.to_s.split('_').map(&:capitalize).join.to_sym
108
+ register RelationshipRoutes.const_get(rel_type.to_s.camelize)
110
109
 
111
110
  instance_eval(&block) if block
112
111
  end
@@ -41,9 +41,8 @@ module Sinja
41
41
  app.get '', :qparams=>%i[include fields filter sort page], :actions=>:index do
42
42
  filter_sort_page?(:index)
43
43
  collection, opts = index
44
- collection, links = filter_sort_page(collection)
45
- (opts[:links] ||= {}).merge!(links)
46
- serialize_models(collection, opts)
44
+ collection, pagination = filter_sort_page(collection)
45
+ serialize_models(collection, opts, pagination)
47
46
  end
48
47
 
49
48
  app.post '', :qparams=>:include, :actions=>:create do
data/lib/sinja/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Sinja
3
- VERSION = '1.1.0.pre3'
3
+ VERSION = '1.1.0.pre4'
4
4
  end
data/lib/sinja.rb CHANGED
@@ -18,7 +18,7 @@ module Sinja
18
18
  ForbiddenError,
19
19
  NotFoundError,
20
20
  MethodNotAllowedError,
21
- NotAcceptibleError,
21
+ NotAcceptableError,
22
22
  ConflictError,
23
23
  UnsupportedTypeError
24
24
  ].map! { |c| [c.new.http_status, c] }.to_h.tap do |h|
@@ -275,7 +275,7 @@ module Sinja
275
275
 
276
276
  collection = finalize(collection) if respond_to?(:finalize)
277
277
 
278
- return collection, :pagination=>pagination
278
+ return collection, pagination
279
279
  end
280
280
 
281
281
  def halt(code, body=nil)
@@ -319,7 +319,7 @@ module Sinja
319
319
 
320
320
  app.before do
321
321
  unless sideloaded?
322
- raise NotAcceptibleError unless request.preferred_type.entry == MIME_TYPE
322
+ raise NotAcceptableError unless request.preferred_type.entry == MIME_TYPE
323
323
  raise UnsupportedTypeError if content? && (
324
324
  request.media_type != MIME_TYPE || request.media_type_params.keys.any? { |k| k != 'charset' }
325
325
  )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinja
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0.pre3
4
+ version: 1.1.0.pre4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Pastore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-07 00:00:00.000000000 Z
11
+ date: 2016-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport