quilt_rails 3.1.1 → 3.4.1

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: 3c49aaaa50e7e7884ce87e9fcff516a4875ab6cfbe07f2ba8a4f22df640f7f72
4
- data.tar.gz: 292705d4cd8345c1b764b6c0964745ec1da057b9c2a717ee67903099b578c08d
3
+ metadata.gz: 0a6933fd12f6ae25d25f4afab855ba022287ac3c2e353d3b1d1aa2764adb6e40
4
+ data.tar.gz: 88e908022a12e1ed55bcd8859bc7be736e9d844832ed7df30f81caf3f822c875
5
5
  SHA512:
6
- metadata.gz: 43205a9ffd5c5cac51f039681a968f18a4e550f2f90d28e67f70ccea467086be5d69fd904a48eaf15503f3cd4e21f9a0bbe76ee47cebdbc25e7ef4c3eea55642
7
- data.tar.gz: 524c21913e16f8ed7420a9154703e8173c30ede53d7e1acee5ecad9b33785d2dc002f25905021f5b4a310819c7f60afd1635d984d6982b9a29a1a9307809cadc
6
+ metadata.gz: b2e02a1233697cb16ef35ec291de7736b3e0721d516bcd566c309c88704e996fc5ce40c3ccb72abc54c6dbf1b2fbe384c41bf333a760e1e889b7ee280331f5ba
7
+ data.tar.gz: 506bfd185f702ad39e7f6d21713524b002bc90e45e0e1aaed0832d6aee2f5d0d998a104c46b9272ab001040fd1ed49be41a788107cc9c0fea9145697dffb10ff
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # quilt_rails
2
2
 
3
- A turn-key solution for integrating Quilt client-side libraries into your Rails app, with support for server-side-rendering using [`@shopify/react-server`](https://www.npmjs.com/package/@shopify/react-server), integration with [`@shopify/sewing-kit`](https://github.com/Shopify/sewing-kit) for building, testing and linting, and front-end performance tracking through [`@shopify/performance`](https://www.npmjs.com/package/@shopify/performance).
3
+ A turn-key solution for integrating [Quilt](https://github.com/Shopify/quilt) client-side libraries into your Rails app, with support for server-side-rendering using [`@shopify/react-server`](https://www.npmjs.com/package/@shopify/react-server), integration with [`@shopify/sewing-kit`](https://github.com/Shopify/sewing-kit) for building, testing and linting, and front-end performance tracking through [`@shopify/performance`](https://www.npmjs.com/package/@shopify/performance).
4
4
 
5
5
  ## Table of Contents
6
6
 
@@ -67,9 +67,9 @@ Follow [this guide](./docs/manual-installation.md) on how to do manual setup wit
67
67
 
68
68
  For fast tests with consistent results, test front-end components using the tools provided by sewing-kit instead of Rails integration tests.
69
69
 
70
- Use [`sewing-kit test`](https://github.com/Shopify/sewing-kit/blob/master/docs/commands/test.md#L3) to run all `.test.{js|ts}x` files in the `app/ui` directory. [Jest](https://jestjs.io/) is used as a test runner, with customization available via [its sewing-kit plugin](https://github.com/Shopify/sewing-kit/blob/master/docs/plugins/jest.md).
70
+ Use [`sewing-kit test`](https://github.com/Shopify/sewing-kit/blob/main/docs/commands/test.md#L3) to run all `.test.{js|ts}x` files in the `app/ui` directory. [Jest](https://jestjs.io/) is used as a test runner, with customization available via [its sewing-kit plugin](https://github.com/Shopify/sewing-kit/blob/main/docs/plugins/jest.md).
71
71
 
72
- For testing React applications we provide and support [`@shopify/react-testing`](https://github.com/Shopify/quilt/tree/master/packages/react-testing).
72
+ For testing React applications we provide and support [`@shopify/react-testing`](https://github.com/Shopify/quilt/tree/main/packages/react-testing).
73
73
 
74
74
  ##### Example
75
75
 
@@ -102,11 +102,11 @@ describe('MyComponent', () => {
102
102
 
103
103
  Often you will want to hook up custom polyfills, global mocks, or other logic that needs to run either before the initialization of the test environment, or once for each test suite.
104
104
 
105
- By default, sewing-kit will look for such test setup files under `/app/ui/tests`. Check out the [documentation](https://github.com/Shopify/sewing-kit/blob/master/docs/plugins/jest.md#smart-defaults) for more details.
105
+ By default, sewing-kit will look for such test setup files under `/app/ui/tests`. Check out the [documentation](https://github.com/Shopify/sewing-kit/blob/main/docs/plugins/jest.md#smart-defaults) for more details.
106
106
 
107
107
  ##### Interacting with the request and response in React code
108
108
 
109
- React-server sets up [@shopify/react-network](https://github.com/Shopify/quilt/blob/master/packages/react-network) automatically, so most interactions with the request or response can be done from inside the React app.
109
+ React-server sets up [@shopify/react-network](https://github.com/Shopify/quilt/blob/main/packages/react-network) automatically, so most interactions with the request or response can be done from inside the React app.
110
110
 
111
111
  ##### Example: getting headers
112
112
 
@@ -131,7 +131,7 @@ function App() {
131
131
  export default App;
132
132
  ```
133
133
 
134
- **Note:** This solution works out of the box for initial server-side renders. If you wish to have consistent access to request headers on subsequent client-side renders, take a look at [`NetworkUniversalProvider`](https://github.com/Shopify/quilt/tree/master/packages/react-network#networkuniversalprovider).
134
+ **Note:** This solution works out of the box for initial server-side renders. If you wish to have consistent access to request headers on subsequent client-side renders, take a look at [`NetworkUniversalProvider`](https://github.com/Shopify/quilt/tree/main/packages/react-network#networkuniversalprovider).
135
135
 
136
136
  ##### Example: sending custom headers from Rails controller
137
137
 
@@ -147,7 +147,7 @@ class ReactController < ApplicationController
147
147
  end
148
148
  ```
149
149
 
150
- 🗒️ if you don't have a controller. Follow the [instruction](./docs/manual-installation#add-a-react-controller-and-routes) to setup `quilt_rails` in a controller instead of using the engine.
150
+ 🗒️ if you don't have a controller. Follow the [instruction](./docs/manual-installation.md#option-2-add-a-react-controller-and-routes) to setup `quilt_rails` in a controller instead of using the engine.
151
151
 
152
152
  Headers can be accessed during server-side-rendering with the `useRequestHeader` hook from `@shopify/react-network`.
153
153
 
@@ -171,6 +171,8 @@ In some cases you may want to send basic data from Rails to your React server. Q
171
171
 
172
172
  **Note:** The data passed should be data that is unlikely or will never change over the course of the session before they render any React components.
173
173
 
174
+ **Note:** Please note the minimal dependencies require to use this feature is listed in [CHANGELOG](./CHANGELOG.md#[1.12.0]-2020-05-07)
175
+
174
176
  ```ruby
175
177
  class ReactController < ApplicationController
176
178
  include Quilt::ReactRenderable
@@ -181,7 +183,7 @@ class ReactController < ApplicationController
181
183
  end
182
184
  ```
183
185
 
184
- 🗒️ if you don't have a controller. Follow the [instruction](./docs/manual-installation#add-a-react-controller-and-routes) to setup `quilt_rails` in a controller instead of using the engine.
186
+ 🗒️ if you don't have a controller. Follow the [instruction](./docs/manual-installation.md#option-2-add-a-react-controller-and-routes) to setup `quilt_rails` in a controller instead of using the engine.
185
187
 
186
188
  If using `react-server` without a customized server & client file, this will be automatically passed into your application as the `data` prop. If `react-server` is not being used or a customized server / client file was provided, check out [`react-server/webpack-plugin`](../../packages/react-server/src/webpack-plugin/webpack-plugin.ts) on how to pass the data to React.
187
189
 
@@ -220,9 +222,9 @@ export default App;
220
222
 
221
223
  #### Isomorphic state
222
224
 
223
- With SSR enabled React apps, state must be serialized on the server and deserialized on the client to keep it consistent. When using `@shopify/react-server`, the best tool for this job is [`@shopify/react-html`](https://github.com/Shopify/quilt/tree/master/packages/react-html)'s [`useSerialized`](https://github.com/Shopify/quilt/tree/master/packages/react-html#in-your-application-code) hook.
225
+ With SSR enabled React apps, state must be serialized on the server and deserialized on the client to keep it consistent. When using `@shopify/react-server`, the best tool for this job is [`@shopify/react-html`](https://github.com/Shopify/quilt/tree/main/packages/react-html)'s [`useSerialized`](https://github.com/Shopify/quilt/tree/main/packages/react-html#in-your-application-code) hook.
224
226
 
225
- `useSerialized` can be used to implement [universal-providers](https://github.com/Shopify/quilt/tree/master/packages/react-universal-provider#what-is-a-universal-provider-), allowing application code to manage what is persisted between the server and client without adding any custom code to client or server entrypoints. We offer some for common use cases such as [GraphQL](https://github.com/Shopify/quilt/tree/master/packages/react-graphql-universal-provider), and [I18n](https://github.com/Shopify/quilt/tree/master/packages/react-i18n-universal-provider).
227
+ `useSerialized` can be used to implement [universal-providers](https://github.com/Shopify/quilt/tree/main/packages/react-universal-provider#what-is-a-universal-provider-), allowing application code to manage what is persisted between the server and client without adding any custom code to client or server entrypoints. We offer some for common use cases such as [GraphQL](https://github.com/Shopify/quilt/tree/main/packages/react-graphql-universal-provider), and [I18n](https://github.com/Shopify/quilt/tree/main/packages/react-i18n-universal-provider).
226
228
 
227
229
  #### Customizing the Node server
228
230
 
@@ -287,7 +289,7 @@ end
287
289
 
288
290
  #### Exception monitoring with Bugsnag
289
291
 
290
- For an opinionated universal Bugsnag+React setup we provide and support [`@shopify/react-bugsnag`](https://github.com/Shopify/quilt/tree/master/packages/react-bugsnag).
292
+ For an opinionated universal Bugsnag+React setup we provide and support [`@shopify/react-bugsnag`](https://github.com/Shopify/quilt/tree/main/packages/react-bugsnag).
291
293
 
292
294
  ##### Example
293
295
 
data/Rakefile CHANGED
@@ -24,3 +24,5 @@ Rake::TestTask.new do |t|
24
24
  t.name = 'test:unit'
25
25
  t.pattern = 'test/quilt_rails/**/*_test.rb'
26
26
  end
27
+
28
+ task(default: %i(test))
@@ -8,9 +8,9 @@ module Quilt
8
8
  def create
9
9
  process_report
10
10
 
11
- render json: { result: 'success' }, status: 200
11
+ render(json: { result: 'success' }, status: 200)
12
12
  rescue ActionController::ParameterMissing => error
13
- render json: { error: error.message, status: 422 }
13
+ render(json: { error: error.message, status: 422 })
14
14
  end
15
15
  end
16
16
  end
@@ -3,9 +3,19 @@
3
3
  module Quilt
4
4
  class UiController < ApplicationController
5
5
  include Quilt::ReactRenderable
6
+ layout(false)
6
7
 
7
8
  def index
8
9
  render_react
10
+ rescue Quilt::ReactRenderable::ReactServerNoResponseError
11
+ sleep(1)
12
+ retry if execution_count < 10
13
+ raise
14
+ end
15
+
16
+ def execution_count
17
+ @times ||= 0
18
+ @times = @times.next
9
19
  end
10
20
  end
11
21
  end
@@ -12,7 +12,7 @@ module Quilt
12
12
  if File.exist?(procfile_path)
13
13
  append_file(procfile_path, File.read(File.expand_path(find_in_source_paths(procfile_path))))
14
14
  else
15
- copy_file procfile_path
15
+ copy_file(procfile_path)
16
16
  end
17
17
  end
18
18
 
@@ -20,12 +20,12 @@ module Quilt
20
20
  routes_path = "config/routes.rb"
21
21
 
22
22
  if File.exist?(routes_path)
23
- route "mount Quilt::Engine, at: '/'"
23
+ route("mount Quilt::Engine, at: '/'")
24
24
  else
25
- copy_file "routes.rb", routes_path
25
+ copy_file("routes.rb", routes_path)
26
26
  end
27
27
 
28
- say "Added Quilt engine mount"
28
+ say("Added Quilt engine mount")
29
29
  end
30
30
  end
31
31
  end
@@ -3,17 +3,20 @@
3
3
  module Quilt
4
4
  class ReactSetupGenerator < Rails::Generators::Base
5
5
  source_root File.expand_path('templates', __dir__)
6
+ class_option :skip_yarn, type: :boolean, default: false
6
7
 
7
8
  desc "This generator adds a React app."
8
9
 
9
10
  def install_js_dependencies
10
- say "Installing react and types dependencies"
11
+ return if options.skip_yarn?
12
+
13
+ say("Installing react and types dependencies")
11
14
  system("yarn add "\
12
15
  "typescript@~3.8.0 "\
13
16
  "react@~16.11.0 "\
14
17
  "react-dom@~16.11.0 "\
15
18
  "@types/react@~16.9.0 "\
16
- "@types/react-dom@~16.9.0 ") unless Rails.env.test?
19
+ "@types/react-dom@~16.9.0 ")
17
20
  end
18
21
 
19
22
  def create_tsconfig
data/lib/quilt_rails.rb CHANGED
@@ -3,11 +3,12 @@ module Quilt
3
3
  end
4
4
 
5
5
  require "quilt_rails/version"
6
- require "quilt_rails/engine"
7
6
  require "quilt_rails/logger"
8
7
  require "quilt_rails/configuration"
9
8
  require "quilt_rails/react_renderable"
10
9
  require "quilt_rails/performance"
11
10
  require "quilt_rails/trusted_ui_server_csrf_strategy"
12
11
  require "quilt_rails/header_csrf_strategy"
12
+
13
+ require "quilt_rails/engine"
13
14
  require "quilt_rails/monkey_patches/active_support_reloader" if Rails.env.development?
@@ -1,23 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Quilt
4
- class Configuration
5
- attr_accessor :react_server_host, :react_server_protocol
3
+ require "active_support/ordered_options"
6
4
 
5
+ module Quilt
6
+ class Configuration < ActiveSupport::OrderedOptions
7
7
  def initialize
8
- ip = ENV['REACT_SERVER_IP'] || 'localhost'
9
- port = ENV['REACT_SERVER_PORT'] || 8081
8
+ super
9
+ react_server_ip = ENV['REACT_SERVER_IP'] || "localhost"
10
+ react_server_port = ENV['REACT_SERVER_PORT'] || 8081
10
11
 
11
- @react_server_host = "#{ip}:#{port}"
12
- @react_server_protocol = ENV['REACT_SERVER_PROTOCOL'] || 'http'
12
+ self.react_server_host = "#{react_server_ip}:#{react_server_port}"
13
+ self.react_server_protocol = ENV['REACT_SERVER_PROTOCOL'] || "http"
14
+ self.logger = ::Logger.new($stdout)
15
+ self.mount = true
13
16
  end
14
- end
15
17
 
16
- def self.configuration
17
- @configuration ||= Configuration.new
18
+ def mount?
19
+ mount
20
+ end
18
21
  end
19
22
 
20
- def self.configure
21
- yield(configuration)
23
+ class << self
24
+ def configuration
25
+ @configuration ||= Configuration.new
26
+ end
27
+
28
+ def configure
29
+ yield(configuration)
30
+ end
22
31
  end
23
32
  end
@@ -3,5 +3,19 @@
3
3
  module Quilt
4
4
  class Engine < ::Rails::Engine
5
5
  isolate_namespace Quilt
6
+
7
+ config.quilt = Quilt.configuration
8
+
9
+ initializer(:initialize_quilt_logger, after: :initialize_logger) do
10
+ config.quilt.logger = ::Rails.logger
11
+ end
12
+
13
+ initializer(:mount_quilt, before: :add_builtin_route) do |app|
14
+ if config.quilt.mount?
15
+ app.routes.append do
16
+ mount(Quilt::Engine, at: '/') unless has_named_route?(:quilt)
17
+ end
18
+ end
19
+ end
6
20
  end
7
21
  end
@@ -25,9 +25,10 @@ module Quilt
25
25
 
26
26
  class NoSameSiteHeaderError < StandardError
27
27
  def initialize
28
- # rubocop:disable LineLength
29
- super "CSRF verification failed. This request is missing the `x-shopify-react-xhr` header, or it does not have the expected value."
30
- # rubocop:enable LineLength
28
+ super(<<~MSG.squish)
29
+ CSRF verification failed. This request is missing the
30
+ `x-shopify-react-xhr` header, or it does not have the expected value.
31
+ MSG
31
32
  end
32
33
  end
33
34
  end
@@ -3,11 +3,14 @@
3
3
  module Quilt
4
4
  module Logger
5
5
  def self.log(string)
6
- if defined? Rails && Rails.logger.nil?
7
- puts string
8
- else
9
- Rails.logger.info(string)
10
- end
6
+ ActiveSupport::Deprecation.warn(<<~MSG.squish)
7
+ Quilt::Logger.log is deprecated. Please use Quilt.logger instead.
8
+ MSG
9
+ Quilt.configuration.logger.info(string)
11
10
  end
12
11
  end
12
+
13
+ class << self
14
+ delegate(:logger, to: :configuration)
15
+ end
13
16
  end
@@ -7,25 +7,39 @@ module Quilt
7
7
  attr_accessor :navigations
8
8
  attr_accessor :connection
9
9
 
10
- def self.from_params(params)
11
- params.transform_keys! { |key| key.underscore.to_sym }
12
- params[:connection] = { effectiveType: 'unknown' } if params[:connection].blank?
10
+ class << self
11
+ def from_params(params)
12
+ params.transform_keys! { |key| key.underscore.to_sym }
13
+ params[:connection] = { effectiveType: 'unknown' } if params[:connection].blank?
13
14
 
14
- connection = Connection.from_params(params[:connection])
15
+ connection = Connection.from_params(params[:connection])
15
16
 
16
- Report.new(
17
- connection: connection,
18
- navigations: (params[:navigations] || []).map do |navigation|
17
+ Report.new(
18
+ connection: connection,
19
+ navigations: build_navigations(params[:navigations], connection: connection),
20
+ events: build_events(params[:events], connection: connection),
21
+ )
22
+ end
23
+
24
+ private
25
+
26
+ def build_navigations(navigations_params, connection:)
27
+ navigations_params ||= []
28
+ navigations_params.map do |navigation|
19
29
  navigation = Navigation.from_params(navigation)
20
30
  navigation.connection = connection
21
31
  navigation
22
- end,
23
- events: (params[:events] || []).map do |event|
32
+ end
33
+ end
34
+
35
+ def build_events(events_params, connection:)
36
+ events_params ||= []
37
+ events_params.map do |event|
24
38
  event = Event.from_params(event)
25
39
  event.connection = connection
26
40
  event
27
- end,
28
- )
41
+ end
42
+ end
29
43
  end
30
44
 
31
45
  def initialize(events:, navigations:, connection:)
@@ -30,19 +30,19 @@ module Quilt
30
30
 
31
31
  def proxy(headers, data)
32
32
  url = "#{Quilt.configuration.react_server_protocol}://#{Quilt.configuration.react_server_host}"
33
- Quilt::Logger.log("[ReactRenderable] proxying to React server at #{url}")
33
+ Quilt.logger.info("[ReactRenderable] proxying to React server at #{url}")
34
34
 
35
35
  unless headers.blank?
36
- Quilt::Logger.log("[ReactRenderable] applying custom headers #{headers.inspect}")
36
+ Quilt.logger.info("[ReactRenderable] applying custom headers #{headers.inspect}")
37
37
  end
38
38
 
39
39
  begin
40
40
  reverse_proxy(
41
41
  url,
42
- headers: headers.merge('X-Quilt-Data': data.to_json)
42
+ headers: headers.merge('X-Request-ID': request.request_id, 'X-Quilt-Data': data.to_json)
43
43
  ) do |callbacks|
44
44
  callbacks.on_response do |status_code, _response|
45
- Quilt::Logger.log("[ReactRenderable] #{url} returned #{status_code}")
45
+ Quilt.logger.info("[ReactRenderable] #{url} returned #{status_code}")
46
46
  end
47
47
  end
48
48
  rescue Errno::ECONNREFUSED
@@ -52,17 +52,19 @@ module Quilt
52
52
 
53
53
  class ReactServerNoResponseError < StandardError
54
54
  def initialize(url)
55
- # rubocop:disable LineLength
56
- super "Errno::ECONNREFUSED: Waiting for React server to boot up. If this error persists verify that @shopify/react-server is configured on #{url}"
57
- # rubocop:enable LineLength
55
+ super(<<~MSG.squish)
56
+ Errno::ECONNREFUSED: Waiting for React server to boot up.
57
+ If this error persists verify that @shopify/react-server is configured on #{url}"
58
+ MSG
58
59
  end
59
60
  end
60
61
 
61
62
  class DoNotIntegrationTestError < StandardError
62
63
  def initialize
63
- # rubocop:disable LineLength
64
- super "Do not try to use Rails integration tests on your quilt_rails app. Instead use Jest and @shopify/react-testing to test your React application directly."
65
- # rubocop:enable LineLength
64
+ super(<<~MSG.squish)
65
+ Do not try to use Rails integration tests on your quilt_rails app.
66
+ Instead use Jest and @shopify/react-testing to test your React application directly."
67
+ MSG
66
68
  end
67
69
  end
68
70
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Quilt
3
- VERSION = "3.1.1"
3
+ VERSION = "3.4.1"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quilt_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathew Allen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-24 00:00:00.000000000 Z
11
+ date: 2021-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 3.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 3.2.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rails-reverse-proxy
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -123,7 +137,7 @@ files:
123
137
  - lib/quilt_rails/react_renderable.rb
124
138
  - lib/quilt_rails/trusted_ui_server_csrf_strategy.rb
125
139
  - lib/quilt_rails/version.rb
126
- homepage: https://github.com/Shopify/quilt/tree/master/gems/quilt_rails
140
+ homepage: https://github.com/Shopify/quilt/tree/main/gems/quilt_rails
127
141
  licenses:
128
142
  - MIT
129
143
  metadata: