sinja 1.1.0.pre3 → 1.1.0.pre4

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
  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