apollo_upload_server 2.0.2 → 2.1.0

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
  SHA256:
3
- metadata.gz: 7dfe5737f6d9c1b447e8acefd1730560941d90ea0dc7b7347732123068b75f0b
4
- data.tar.gz: b1c6b5261aff9dfedd7b625eb99c79bf78223530058ae842954758281e258145
3
+ metadata.gz: cb57f161b850cddb8ce4641e36a78d7102a32964d5f36a2d51f5d82ff216c801
4
+ data.tar.gz: a24f022ce799d7514aa7e9af82a86df970f30c55d5125791e4e185330e3db1d7
5
5
  SHA512:
6
- metadata.gz: c1e4046d7cdd19a3b6b40030298a38241d3be1dff0c763a41c02887fc1a031568680ad900daea43f771704e53c25ab4835ea4d1b8250e1a3bead25287695d4ce
7
- data.tar.gz: c3ad8ad5a11a986f7738a52bae7fa277793ee99b3d46a060ec5d5bbce56b2546fe6319290971a24fd6e07d6612b83cd0a8dd7cbba5175820a041fb8921eafb8b
6
+ metadata.gz: '08c4fb78e2df11fc73311a9f577e17f5d17a077252afa0da821d3eb7975fc9d1bc2a6f6eaf2c87a324bd2e80a62d25100c94912aa6b8c7dc6545b6563bb5b1b7'
7
+ data.tar.gz: 9bc4906993275f180b09749f08991c156041b471314254e948afbe58b56c8a388107044a0639bcc8654035766d36c89aa5b3fb0615c62b44a9b133d63f4dc944
data/Gemfile.lock CHANGED
@@ -1,122 +1,57 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- apollo_upload_server (2.0.0.beta.3)
4
+ apollo_upload_server (2.1.0)
5
+ actionpack (>= 4.2)
5
6
  graphql (>= 1.8)
6
- rails (>= 4.2)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (6.0.2.2)
12
- actionpack (= 6.0.2.2)
13
- nio4r (~> 2.0)
14
- websocket-driver (>= 0.6.1)
15
- actionmailbox (6.0.2.2)
16
- actionpack (= 6.0.2.2)
17
- activejob (= 6.0.2.2)
18
- activerecord (= 6.0.2.2)
19
- activestorage (= 6.0.2.2)
20
- activesupport (= 6.0.2.2)
21
- mail (>= 2.7.1)
22
- actionmailer (6.0.2.2)
23
- actionpack (= 6.0.2.2)
24
- actionview (= 6.0.2.2)
25
- activejob (= 6.0.2.2)
26
- mail (~> 2.5, >= 2.5.4)
27
- rails-dom-testing (~> 2.0)
28
- actionpack (6.0.2.2)
29
- actionview (= 6.0.2.2)
30
- activesupport (= 6.0.2.2)
31
- rack (~> 2.0, >= 2.0.8)
11
+ actionpack (6.1.4)
12
+ actionview (= 6.1.4)
13
+ activesupport (= 6.1.4)
14
+ rack (~> 2.0, >= 2.0.9)
32
15
  rack-test (>= 0.6.3)
33
16
  rails-dom-testing (~> 2.0)
34
17
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
35
- actiontext (6.0.2.2)
36
- actionpack (= 6.0.2.2)
37
- activerecord (= 6.0.2.2)
38
- activestorage (= 6.0.2.2)
39
- activesupport (= 6.0.2.2)
40
- nokogiri (>= 1.8.5)
41
- actionview (6.0.2.2)
42
- activesupport (= 6.0.2.2)
18
+ actionview (6.1.4)
19
+ activesupport (= 6.1.4)
43
20
  builder (~> 3.1)
44
21
  erubi (~> 1.4)
45
22
  rails-dom-testing (~> 2.0)
46
23
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
47
- activejob (6.0.2.2)
48
- activesupport (= 6.0.2.2)
49
- globalid (>= 0.3.6)
50
- activemodel (6.0.2.2)
51
- activesupport (= 6.0.2.2)
52
- activerecord (6.0.2.2)
53
- activemodel (= 6.0.2.2)
54
- activesupport (= 6.0.2.2)
55
- activestorage (6.0.2.2)
56
- actionpack (= 6.0.2.2)
57
- activejob (= 6.0.2.2)
58
- activerecord (= 6.0.2.2)
59
- marcel (~> 0.3.1)
60
- activesupport (6.0.2.2)
24
+ activesupport (6.1.4)
61
25
  concurrent-ruby (~> 1.0, >= 1.0.2)
62
- i18n (>= 0.7, < 2)
63
- minitest (~> 5.1)
64
- tzinfo (~> 1.1)
65
- zeitwerk (~> 2.2)
26
+ i18n (>= 1.6, < 2)
27
+ minitest (>= 5.1)
28
+ tzinfo (~> 2.0)
29
+ zeitwerk (~> 2.3)
66
30
  builder (3.2.4)
67
- concurrent-ruby (1.1.6)
31
+ concurrent-ruby (1.1.9)
68
32
  crass (1.0.6)
69
33
  diff-lcs (1.3)
70
- erubi (1.9.0)
71
- globalid (0.4.2)
72
- activesupport (>= 4.2.0)
73
- graphql (1.8.13)
74
- i18n (1.8.2)
34
+ erubi (1.10.0)
35
+ graphql (1.12.14)
36
+ i18n (1.8.10)
75
37
  concurrent-ruby (~> 1.0)
76
- loofah (2.4.0)
38
+ loofah (2.11.0)
77
39
  crass (~> 1.0.2)
78
40
  nokogiri (>= 1.5.9)
79
- mail (2.7.1)
80
- mini_mime (>= 0.1.1)
81
- marcel (0.3.3)
82
- mimemagic (~> 0.3.2)
83
- method_source (1.0.0)
84
- mimemagic (0.3.4)
85
- mini_mime (1.0.2)
86
- mini_portile2 (2.4.0)
87
- minitest (5.14.0)
88
- nio4r (2.5.2)
89
- nokogiri (1.10.9)
90
- mini_portile2 (~> 2.4.0)
91
- rack (2.2.2)
41
+ mini_portile2 (2.6.1)
42
+ minitest (5.14.4)
43
+ nokogiri (1.12.1)
44
+ mini_portile2 (~> 2.6.1)
45
+ racc (~> 1.4)
46
+ racc (1.5.2)
47
+ rack (2.2.3)
92
48
  rack-test (1.1.0)
93
49
  rack (>= 1.0, < 3)
94
- rails (6.0.2.2)
95
- actioncable (= 6.0.2.2)
96
- actionmailbox (= 6.0.2.2)
97
- actionmailer (= 6.0.2.2)
98
- actionpack (= 6.0.2.2)
99
- actiontext (= 6.0.2.2)
100
- actionview (= 6.0.2.2)
101
- activejob (= 6.0.2.2)
102
- activemodel (= 6.0.2.2)
103
- activerecord (= 6.0.2.2)
104
- activestorage (= 6.0.2.2)
105
- activesupport (= 6.0.2.2)
106
- bundler (>= 1.3.0)
107
- railties (= 6.0.2.2)
108
- sprockets-rails (>= 2.0.0)
109
50
  rails-dom-testing (2.0.3)
110
51
  activesupport (>= 4.2.0)
111
52
  nokogiri (>= 1.6)
112
53
  rails-html-sanitizer (1.3.0)
113
54
  loofah (~> 2.3)
114
- railties (6.0.2.2)
115
- actionpack (= 6.0.2.2)
116
- activesupport (= 6.0.2.2)
117
- method_source
118
- rake (>= 0.8.7)
119
- thor (>= 0.20.3, < 2.0)
120
55
  rake (13.0.1)
121
56
  rspec (3.8.0)
122
57
  rspec-core (~> 3.8.0)
@@ -131,21 +66,9 @@ GEM
131
66
  diff-lcs (>= 1.2.0, < 2.0)
132
67
  rspec-support (~> 3.8.0)
133
68
  rspec-support (3.8.0)
134
- sprockets (4.0.0)
69
+ tzinfo (2.0.4)
135
70
  concurrent-ruby (~> 1.0)
136
- rack (> 1, < 3)
137
- sprockets-rails (3.2.1)
138
- actionpack (>= 4.0)
139
- activesupport (>= 4.0)
140
- sprockets (>= 3.0.0)
141
- thor (1.0.1)
142
- thread_safe (0.3.6)
143
- tzinfo (1.2.6)
144
- thread_safe (~> 0.1)
145
- websocket-driver (0.7.1)
146
- websocket-extensions (>= 0.1.0)
147
- websocket-extensions (0.1.4)
148
- zeitwerk (2.3.0)
71
+ zeitwerk (2.4.2)
149
72
 
150
73
  PLATFORMS
151
74
  ruby
data/README.md CHANGED
@@ -4,12 +4,13 @@ Middleware which allows you to upload files using [graphql-ruby](https://github.
4
4
 
5
5
  Note: this implementation uses [v2 of the GraphQL multipart request spec](https://github.com/jaydenseric/graphql-multipart-request-spec/tree/v2.0.0-alpha.2), so you should use apollo-upload-client library >= v7.0.0-alpha.3. If you need support for [v1 of the GraphQL multipart request spec](https://github.com/jaydenseric/graphql-multipart-request-spec/tree/v1.0.0), you must
6
6
  use [version 1.0.0](https://github.com/jetruby/apollo_upload_server-ruby/tree/1.0.0) of this gem.
7
+
7
8
  ## Installation
8
9
 
9
10
  Add this line to your application's Gemfile:
10
11
 
11
12
  ```ruby
12
- gem 'apollo_upload_server', '2.0.2'
13
+ gem 'apollo_upload_server', '2.1.0'
13
14
  ```
14
15
 
15
16
  And then execute:
@@ -24,12 +25,45 @@ Middleware will be used automatically.
24
25
 
25
26
  Gem adds custom `Upload` type to your GraphQL types.
26
27
  Use `ApolloUploadServer::Upload` type for your file as input field:
28
+
27
29
  ```ruby
28
30
  input_field :file, ApolloUploadServer::Upload
29
31
  ```
30
32
 
31
33
  That's all folks!
32
34
 
35
+ ## Configuration
36
+
37
+ The following configuration options are supported:
38
+
39
+ ### Strict Mode
40
+
41
+ This can be set on `ApolloUploadServer::Middleware`:
42
+
43
+ ```ruby
44
+ ApolloUploadServer::Middleware.strict_mode = true
45
+ ```
46
+
47
+ Doing so ensures that all mapped array values are present in the input. If this
48
+ is set to `true`, then for following request:
49
+
50
+ ```json
51
+ {
52
+ "operations": {
53
+ "query": "mutation { ... }",
54
+ "operationName": "SomeOperation",
55
+ "variables": {
56
+ "input": { "id": "123", "avatars": [null, null] }
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ A mapping for `variables.input.avatars.0` or `variables.input.avatars.1`, will work, but one for
63
+ `variables.input.avatars.100` will not, and will raise an error.
64
+
65
+ In strict mode, passing empty destination arrays will always fail.
66
+
33
67
  ## Contributing
34
68
 
35
69
  Bug reports and pull requests are welcome on GitHub at https://github.com/jetruby/apollo_upload_server-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -43,6 +77,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
43
77
  Everyone interacting in the ApolloUploadServer project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jetruby/apollo_upload_server-ruby/blob/master/CODE_OF_CONDUCT.md).
44
78
 
45
79
  ## About JetRuby
80
+
46
81
  ApolloUploadServer is maintained and founded by JetRuby Agency.
47
82
 
48
83
  We love open source software!
@@ -16,11 +16,9 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
17
  f.match(%r{^(test|spec|features)/})
18
18
  end
19
- spec.bindir = 'bin'
20
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
19
  spec.require_paths = ['lib']
22
20
 
23
- spec.add_dependency 'rails', '>= 4.2'
21
+ spec.add_dependency 'actionpack', '>= 4.2'
24
22
  spec.add_dependency 'graphql', '>= 1.8'
25
23
 
26
24
  spec.add_development_dependency 'bundler', '~> 2.1'
@@ -5,6 +5,12 @@ require 'apollo_upload_server/wrappers/uploaded_file'
5
5
 
6
6
  module ApolloUploadServer
7
7
  class GraphQLDataBuilder
8
+ OutOfBounds = Class.new(ArgumentError)
9
+
10
+ def initialize(strict_mode: false)
11
+ @strict_mode = strict_mode
12
+ end
13
+
8
14
  def call(params)
9
15
  operations = safe_json_parse(params['operations'])
10
16
  file_mapper = safe_json_parse(params['map'])
@@ -36,17 +42,26 @@ module ApolloUploadServer
36
42
 
37
43
  def multiple_transformation(file_mapper, operations, params)
38
44
  operations = operations.dup
45
+
39
46
  file_mapper.each do |file_index, paths|
40
47
  paths.each do |path|
41
48
  splited_path = path.split('.')
42
49
  # dig from second to penultimate key, and merge last key with value as file to operation with first key index
43
50
  field = operations[splited_path.first.to_i].dig(*splited_path[1..-2])
51
+
44
52
  assign_file(field, splited_path, params[file_index])
45
53
  end
46
54
  end
47
55
  operations
48
56
  end
49
57
 
58
+ def verify_array_index!(path, index, size)
59
+ return unless @strict_mode
60
+ return if 0 <= index && index < size
61
+
62
+ raise OutOfBounds, "Path #{path.join('.')} maps to out-of-bounds index: #{index}"
63
+ end
64
+
50
65
  def safe_json_parse(data)
51
66
  JSON.parse(data)
52
67
  rescue JSON::ParserError
@@ -73,8 +88,18 @@ module ApolloUploadServer
73
88
  if field.is_a? Hash
74
89
  field.merge!(splited_path.last => wrapped_file)
75
90
  elsif field.is_a? Array
76
- field[splited_path.last.to_i] = wrapped_file
91
+ index = parse_array_index(splited_path)
92
+ verify_array_index!(splited_path, index, field.size)
93
+ field[index] = wrapped_file
77
94
  end
78
95
  end
96
+
97
+ def parse_array_index(path)
98
+ return path.last.to_i unless @strict_mode
99
+
100
+ Integer(path.last)
101
+ rescue ArgumentError
102
+ raise OutOfBounds, "Not a valid path to an array value: #{path.join('.')}"
103
+ end
79
104
  end
80
105
  end
@@ -1,17 +1,29 @@
1
1
  require 'apollo_upload_server/graphql_data_builder'
2
+ require "active_support/configurable"
2
3
 
3
4
  module ApolloUploadServer
4
5
  class Middleware
6
+ include ActiveSupport::Configurable
7
+
8
+ # Strict mode requires that all mapped files are present in the mapping arrays.
9
+ config_accessor :strict_mode do
10
+ false
11
+ end
12
+
5
13
  def initialize(app)
6
14
  @app = app
7
15
  end
8
16
 
9
17
  def call(env)
18
+ unless env['CONTENT_TYPE'].to_s.include?('multipart/form-data')
19
+ return @app.call(env)
20
+ end
21
+
10
22
  request = ActionDispatch::Request.new(env)
11
23
  params = request.params
12
24
 
13
- if env['CONTENT_TYPE'].to_s.include?('multipart/form-data') && params['operations'].present? && params['map'].present?
14
- result = GraphQLDataBuilder.new.call(request.params)
25
+ if params['operations'].present? && params['map'].present?
26
+ result = GraphQLDataBuilder.new(strict_mode: self.class.strict_mode).call(request.params)
15
27
  result&.each do |key, value|
16
28
  request.update_param(key, value)
17
29
  end
@@ -7,7 +7,7 @@ module ApolloUploadServer
7
7
  graphql_name "Upload"
8
8
 
9
9
  def self.coerce_input(value, _ctx)
10
- raise GraphQL::CoercionError, "#{value.inspect} is not a valid upload" unless value.is_a?(::ApolloUploadServer::Wrappers::UploadedFile)
10
+ raise GraphQL::CoercionError, "#{value.inspect} is not a valid upload" unless value.nil? || value.is_a?(::ApolloUploadServer::Wrappers::UploadedFile)
11
11
 
12
12
  value
13
13
  end
@@ -1,3 +1,3 @@
1
1
  module ApolloUploadServer
2
- VERSION = '2.0.2'.freeze
2
+ VERSION = '2.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apollo_upload_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - JetRuby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-18 00:00:00.000000000 Z
11
+ date: 2021-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: actionpack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -83,9 +83,7 @@ dependencies:
83
83
  description: apollo-upload-server implementation for Ruby on Rails as middleware.
84
84
  email:
85
85
  - engineering@jetruby.com
86
- executables:
87
- - console
88
- - setup
86
+ executables: []
89
87
  extensions: []
90
88
  extra_rdoc_files: []
91
89
  files: