shopify_app 12.0.6 → 13.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -6
  3. data/.travis.yml +4 -3
  4. data/CHANGELOG.md +31 -0
  5. data/Gemfile +3 -0
  6. data/README.md +98 -42
  7. data/Rakefile +1 -0
  8. data/app/controllers/concerns/shopify_app/authenticated.rb +1 -1
  9. data/app/controllers/shopify_app/authenticated_controller.rb +1 -0
  10. data/app/controllers/shopify_app/callback_controller.rb +15 -11
  11. data/app/controllers/shopify_app/sessions_controller.rb +35 -9
  12. data/app/controllers/shopify_app/webhooks_controller.rb +6 -5
  13. data/config/locales/fi.yml +1 -1
  14. data/config/locales/nl.yml +7 -7
  15. data/config/routes.rb +1 -0
  16. data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +5 -3
  17. data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +1 -0
  18. data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +2 -1
  19. data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +4 -4
  20. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +5 -4
  21. data/lib/generators/shopify_app/add_webhook/templates/{webhook_job.rb → webhook_job.rb.tt} +5 -0
  22. data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +4 -3
  23. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +3 -3
  24. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +10 -9
  25. data/lib/generators/shopify_app/controllers/controllers_generator.rb +1 -0
  26. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +4 -3
  27. data/lib/generators/shopify_app/home_controller/templates/index.html.erb +1 -1
  28. data/lib/generators/shopify_app/install/install_generator.rb +10 -9
  29. data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +1 -1
  30. data/lib/generators/shopify_app/install/templates/omniauth.rb +2 -1
  31. data/lib/generators/shopify_app/install/templates/{shopify_app.rb → shopify_app.rb.tt} +1 -1
  32. data/lib/generators/shopify_app/install/templates/shopify_provider.rb +1 -1
  33. data/lib/generators/shopify_app/install/templates/user_agent.rb +2 -1
  34. data/lib/generators/shopify_app/routes/routes_generator.rb +1 -0
  35. data/lib/generators/shopify_app/routes/templates/routes.rb +10 -9
  36. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +12 -7
  37. data/lib/generators/shopify_app/shop_model/templates/shop.rb +2 -1
  38. data/lib/generators/shopify_app/shopify_app_generator.rb +4 -3
  39. data/lib/generators/shopify_app/user_model/templates/user.rb +2 -1
  40. data/lib/generators/shopify_app/user_model/user_model_generator.rb +12 -7
  41. data/lib/generators/shopify_app/views/views_generator.rb +1 -0
  42. data/lib/shopify_app.rb +9 -4
  43. data/lib/shopify_app/configuration.rb +21 -17
  44. data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +3 -2
  45. data/lib/shopify_app/controller_concerns/embedded_app.rb +3 -2
  46. data/lib/shopify_app/controller_concerns/localization.rb +1 -0
  47. data/lib/shopify_app/controller_concerns/login_protection.rb +72 -27
  48. data/lib/shopify_app/controller_concerns/webhook_verification.rb +2 -1
  49. data/lib/shopify_app/engine.rb +1 -0
  50. data/lib/shopify_app/jobs/scripttags_manager_job.rb +1 -1
  51. data/lib/shopify_app/jobs/webhooks_manager_job.rb +1 -1
  52. data/lib/shopify_app/managers/scripttags_manager.rb +4 -3
  53. data/lib/shopify_app/managers/webhooks_manager.rb +4 -3
  54. data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +2 -1
  55. data/lib/shopify_app/session/in_memory_session_store.rb +7 -3
  56. data/lib/shopify_app/session/in_memory_shop_session_store.rb +14 -0
  57. data/lib/shopify_app/session/in_memory_user_session_store.rb +14 -0
  58. data/lib/shopify_app/session/jwt.rb +61 -0
  59. data/lib/shopify_app/session/null_user_session_store.rb +22 -0
  60. data/lib/shopify_app/session/session_repository.rb +36 -14
  61. data/lib/shopify_app/session/session_storage.rb +1 -10
  62. data/lib/shopify_app/session/shop_session_storage.rb +42 -0
  63. data/lib/shopify_app/session/user_session_storage.rb +42 -0
  64. data/lib/shopify_app/test_helpers/all.rb +2 -0
  65. data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
  66. data/lib/shopify_app/utils.rb +6 -5
  67. data/lib/shopify_app/version.rb +2 -1
  68. data/package-lock.json +1231 -1210
  69. data/package.json +1 -1
  70. data/shopify_app.gemspec +12 -8
  71. data/yarn.lock +3 -3
  72. metadata +35 -14
  73. data/lib/shopify_app/session/storage_strategies/shop_storage_strategy.rb +0 -23
  74. data/lib/shopify_app/session/storage_strategies/user_storage_strategy.rb +0 -24
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
- class SessionsController < ActionController::Base # rubocop:disable Metrics/ClassLength
3
+ class SessionsController < ActionController::Base
3
4
  include ShopifyApp::LoginProtection
4
5
 
5
6
  layout false, only: :new
7
+
6
8
  after_action only: [:new, :create] do |controller|
7
9
  controller.response.headers.except!('X-Frame-Options')
8
10
  end
@@ -16,7 +18,7 @@ module ShopifyApp
16
18
  end
17
19
 
18
20
  def enable_cookies
19
- return unless validate_shop
21
+ return unless validate_shop_presence
20
22
 
21
23
  render(:enable_cookies, layout: false, locals: {
22
24
  does_not_have_storage_access_url: top_level_interaction_path(
@@ -28,17 +30,17 @@ module ShopifyApp
28
30
  shop: sanitized_shop_name,
29
31
  return_to: params[:return_to]
30
32
  ),
31
- current_shopify_domain: current_shopify_domain
33
+ current_shopify_domain: current_shopify_domain,
32
34
  })
33
35
  end
34
36
 
35
37
  def top_level_interaction
36
38
  @url = login_url_with_optional_shop(top_level: true)
37
- validate_shop
39
+ validate_shop_presence
38
40
  end
39
41
 
40
42
  def granted_storage_access
41
- return unless validate_shop
43
+ return unless validate_shop_presence
42
44
 
43
45
  session['shopify.granted_storage_access'] = true
44
46
 
@@ -61,6 +63,8 @@ module ShopifyApp
61
63
 
62
64
  copy_return_to_param_to_session
63
65
 
66
+ set_user_tokens_option
67
+
64
68
  if user_agent_can_partition_cookies
65
69
  authenticate_with_partitioning
66
70
  else
@@ -88,7 +92,29 @@ module ShopifyApp
88
92
  end
89
93
  end
90
94
 
91
- def validate_shop
95
+ # rubocop:disable Lint/SuppressedException
96
+ def set_user_tokens_option
97
+ if shop_session.blank?
98
+ session[:user_tokens] = false
99
+ return
100
+ end
101
+
102
+ session[:user_tokens] = ShopifyApp::SessionRepository.user_storage.present?
103
+
104
+ ShopifyAPI::Session.temp(
105
+ domain: shop_session.domain,
106
+ token: shop_session.token,
107
+ api_version: shop_session.api_version
108
+ ) do
109
+ ShopifyAPI::Metafield.find(:token_validity_bogus_check)
110
+ end
111
+ rescue ActiveResource::UnauthorizedAccess
112
+ session[:user_tokens] = false
113
+ rescue StandardError
114
+ end
115
+ # rubocop:enable Lint/SuppressedException
116
+
117
+ def validate_shop_presence
92
118
  @shop = sanitized_shop_name
93
119
  unless @shop
94
120
  render_invalid_shop_error
@@ -104,7 +130,7 @@ module ShopifyApp
104
130
 
105
131
  def render_invalid_shop_error
106
132
  flash[:error] = I18n.t('invalid_shop_url')
107
- redirect_to return_address
133
+ redirect_to(return_address)
108
134
  end
109
135
 
110
136
  def enable_cookie_access
@@ -115,7 +141,7 @@ module ShopifyApp
115
141
  end
116
142
 
117
143
  def authenticate_in_context
118
- redirect_to "#{main_app.root_path}auth/shopify"
144
+ redirect_to("#{main_app.root_path}auth/shopify")
119
145
  end
120
146
 
121
147
  def authenticate_at_top_level
@@ -150,7 +176,7 @@ module ShopifyApp
150
176
  shop: sanitized_shop_name,
151
177
  return_to: session[:return_to]
152
178
  ),
153
- current_shopify_domain: current_shopify_domain
179
+ current_shopify_domain: current_shopify_domain,
154
180
  }
155
181
  )
156
182
  end
@@ -1,14 +1,15 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
3
+ class MissingWebhookJobError < StandardError; end
4
+
2
5
  class WebhooksController < ActionController::Base
3
6
  include ShopifyApp::WebhookVerification
4
7
 
5
- class ShopifyApp::MissingWebhookJobError < StandardError; end
6
-
7
8
  def receive
8
9
  params.permit!
9
- job_args = {shop_domain: shop_domain, webhook: webhook_params.to_h}
10
+ job_args = { shop_domain: shop_domain, webhook: webhook_params.to_h }
10
11
  webhook_job_klass.perform_later(job_args)
11
- head :no_content
12
+ head(:no_content)
12
13
  end
13
14
 
14
15
  private
@@ -18,7 +19,7 @@ module ShopifyApp
18
19
  end
19
20
 
20
21
  def webhook_job_klass
21
- webhook_job_klass_name.safe_constantize or raise ShopifyApp::MissingWebhookJobError
22
+ webhook_job_klass_name.safe_constantize || raise(ShopifyApp::MissingWebhookJobError)
22
23
  end
23
24
 
24
25
  def webhook_job_klass_name(type = webhook_type)
@@ -15,6 +15,6 @@ fi:
15
15
  top_level_interaction_action: Jatka
16
16
  request_storage_access_heading: "%{app} edellyttää evästeiden käyttöä"
17
17
  request_storage_access_body: Näin sovellus voi todentaa sinut tallentamalla henkilötietosi
18
- tilapäisesti. Napsauta Jatka ja salli evästeet sovelluksen käyttämiseksi.
18
+ tilapäisesti. Klikkaa Jatka ja salli evästeet sovelluksen käyttämiseksi.
19
19
  request_storage_access_footer: Evästeet vanhenevat 30 päivän kuluttua.
20
20
  request_storage_access_action: Jatka
@@ -1,20 +1,20 @@
1
1
  ---
2
2
  nl:
3
- logged_out: u bent afgemeld
3
+ logged_out: je bentafgemeld
4
4
  could_not_log_in: Kon niet aanmelden bij Shopify-winkel
5
5
  invalid_shop_url: Ongeldig winkeldomein
6
6
  enable_cookies_heading: Schakel cookies in van %{app}
7
- enable_cookies_body: U moet cookies in deze browser handmatig inschakelen om %{app}
7
+ enable_cookies_body: Je moet cookies in deze browser handmatig inschakelen om %{app}
8
8
  binnen Shopify te gebruiken.
9
- enable_cookies_footer: Met cookies kan de app u verifiëren door uw voorkeuren en
9
+ enable_cookies_footer: Met cookies kan de app je verifiëren door je voorkeuren en
10
10
  persoonlijke informatie tijdelijk op te slaan. Ze vervallen na 30 dagen.
11
11
  enable_cookies_action: Schakel cookies in
12
- top_level_interaction_heading: Uw browser moet %{app} verifiëren
13
- top_level_interaction_body: Uw browser heeft apps nodig zoals %{app} om u toegang
14
- te vragen tot cookies voordat Shopify het voor u kan openen.
12
+ top_level_interaction_heading: Je browser moet %{app} verifiëren
13
+ top_level_interaction_body: Je browser heeft apps nodig zoals %{app} om je toegang
14
+ te vragen tot cookies voordat Shopify het voor je kan openen.
15
15
  top_level_interaction_action: Doorgaan
16
16
  request_storage_access_heading: "%{app} heeft toegang tot cookies nodig"
17
- request_storage_access_body: Hiermee kan de app u verifiëren door uw persoonlijke
17
+ request_storage_access_body: Hiermee kan de app je verifiëren door je persoonlijke
18
18
  gegevens tijdelijk op te slaan. Klik op Doorgaan en sta cookies toe om de app
19
19
  te gebruiken.
20
20
  request_storage_access_footer: Cookies verlopen na 30 dagen.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ShopifyApp::Engine.routes.draw do
2
3
  controller :sessions do
3
4
  get 'login' => :new, :as => :login
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -6,7 +7,7 @@ module ShopifyApp
6
7
  source_root File.expand_path('../templates', __FILE__)
7
8
 
8
9
  hook_for :test_framework, as: :job, in: :rails do |instance, generator|
9
- instance.invoke generator, [ instance.send(:job_file_name) ]
10
+ instance.invoke(generator, [instance.send(:job_file_name)])
10
11
  end
11
12
 
12
13
  def init_after_authenticate_config
@@ -23,12 +24,13 @@ module ShopifyApp
23
24
  )
24
25
 
25
26
  unless initializer.include?(after_authenticate_job_config)
26
- shell.say("Error adding after_authenticate_job to config. Add this line manually: #{after_authenticate_job_config}", :red)
27
+ shell.say("Error adding after_authenticate_job to config. Add this line manually: "\
28
+ "#{after_authenticate_job_config}", :red)
27
29
  end
28
30
  end
29
31
 
30
32
  def add_after_authenticate_job
31
- template 'after_authenticate_job.rb', "app/jobs/#{job_file_name}_job.rb"
33
+ template('after_authenticate_job.rb', "app/jobs/#{job_file_name}_job.rb")
32
34
  end
33
35
 
34
36
  private
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shopify
2
3
  class AfterAuthenticateJob < ActiveJob::Base
3
4
  def perform(shop_domain:)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -6,7 +7,7 @@ module ShopifyApp
6
7
  source_root File.expand_path('../templates', __FILE__)
7
8
 
8
9
  def generate_app_extension
9
- template "marketing_activities_controller.rb", "app/controllers/marketing_activities_controller.rb"
10
+ template("marketing_activities_controller.rb", "app/controllers/marketing_activities_controller.rb")
10
11
  generate_routes
11
12
  end
12
13
 
@@ -3,7 +3,7 @@
3
3
  class MarketingActivitiesController < ShopifyApp::ExtensionVerificationController
4
4
  def preload_form_data
5
5
  preload_data = {
6
- "form_data": {}
6
+ "form_data": {},
7
7
  }
8
8
  render(json: preload_data, status: :ok)
9
9
  end
@@ -31,14 +31,14 @@ class MarketingActivitiesController < ShopifyApp::ExtensionVerificationControlle
31
31
  "preview_url": placeholder_img,
32
32
  "content_type": "text/html",
33
33
  "width": 360,
34
- "height": 200
34
+ "height": 200,
35
35
  },
36
36
  "mobile": {
37
37
  "preview_url": placeholder_img,
38
38
  "content_type": "text/html",
39
39
  "width": 360,
40
- "height": 200
41
- }
40
+ "height": 200,
41
+ },
42
42
  }
43
43
  render(json: preview_response, status: :ok)
44
44
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -8,7 +9,7 @@ module ShopifyApp
8
9
  class_option :address, type: :string, aliases: "-a", required: true
9
10
 
10
11
  hook_for :test_framework, as: :job, in: :rails do |instance, generator|
11
- instance.invoke generator, [ instance.send(:job_file_name) ]
12
+ instance.invoke(generator, [instance.send(:job_file_name)])
12
13
  end
13
14
 
14
15
  def init_webhook_config
@@ -32,14 +33,14 @@ module ShopifyApp
32
33
  initializer = load_initializer
33
34
 
34
35
  unless initializer.include?(webhook_config)
35
- shell.say "Error adding webhook to config. Add this line manually: #{webhook_config}", :red
36
+ shell.say("Error adding webhook to config. Add this line manually: #{webhook_config}", :red)
36
37
  end
37
38
  end
38
39
 
39
40
  def add_webhook_job
40
41
  @job_file_name = job_file_name + '_job'
41
- @job_class_name = @job_file_name.classify
42
- template 'webhook_job.rb', "app/jobs/#{@job_file_name}.rb"
42
+ @job_class_name = @job_file_name.classify
43
+ template('webhook_job.rb', "app/jobs/#{@job_file_name}.rb")
43
44
  end
44
45
 
45
46
  private
@@ -2,6 +2,11 @@ class <%= @job_class_name %> < ActiveJob::Base
2
2
  def perform(shop_domain:, webhook:)
3
3
  shop = Shop.find_by(shopify_domain: shop_domain)
4
4
 
5
+ if shop.nil?
6
+ logger.error("#{self.class} failed: cannot find shop with domain '#{shop_domain}'")
7
+ return
8
+ end
9
+
5
10
  shop.with_shopify_session do
6
11
  end
7
12
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -6,11 +7,11 @@ module ShopifyApp
6
7
  source_root File.expand_path('../templates', __FILE__)
7
8
 
8
9
  def create_app_proxy_controller
9
- template 'app_proxy_controller.rb', 'app/controllers/app_proxy_controller.rb'
10
+ template('app_proxy_controller.rb', 'app/controllers/app_proxy_controller.rb')
10
11
  end
11
12
 
12
13
  def create_app_proxy_index_view
13
- copy_file 'index.html.erb', 'app/views/app_proxy/index.html.erb'
14
+ copy_file('index.html.erb', 'app/views/app_proxy/index.html.erb')
14
15
  end
15
16
 
16
17
  def add_app_proxy_route
@@ -18,7 +19,7 @@ module ShopifyApp
18
19
  'config/routes.rb',
19
20
  File.read(File.expand_path(find_in_source_paths('app_proxy_route.rb'))),
20
21
  after: "mount ShopifyApp::Engine, at: '/'\n"
21
- )
22
+ )
22
23
  end
23
24
  end
24
25
  end
@@ -1,8 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  class AppProxyController < ApplicationController
2
- include ShopifyApp::AppProxyVerification
3
+ include ShopifyApp::AppProxyVerification
3
4
 
4
5
  def index
5
- render layout: false, content_type: 'application/liquid'
6
+ render(layout: false, content_type: 'application/liquid')
6
7
  end
7
-
8
8
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
 
2
- namespace :app_proxy do
3
- root action: 'index'
4
- # simple routes without a specified controller will go to AppProxyController
5
-
6
- # more complex routes will go to controllers in the AppProxy namespace
7
- # resources :reviews
8
- # GET /app_proxy/reviews will now be routed to
9
- # AppProxy::ReviewsController#index, for example
10
- end
3
+ namespace :app_proxy do
4
+ root action: 'index'
5
+ # simple routes without a specified controller will go to AppProxyController
6
+
7
+ # more complex routes will go to controllers in the AppProxy namespace
8
+ # resources :reviews
9
+ # GET /app_proxy/reviews will now be routed to
10
+ # AppProxy::ReviewsController#index, for example
11
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -6,15 +7,15 @@ module ShopifyApp
6
7
  source_root File.expand_path('../templates', __FILE__)
7
8
 
8
9
  def create_home_controller
9
- template 'home_controller.rb', 'app/controllers/home_controller.rb'
10
+ template('home_controller.rb', 'app/controllers/home_controller.rb')
10
11
  end
11
12
 
12
13
  def create_home_index_view
13
- copy_file 'index.html.erb', 'app/views/home/index.html.erb'
14
+ copy_file('index.html.erb', 'app/views/home/index.html.erb')
14
15
  end
15
16
 
16
17
  def add_home_index_route
17
- route "root :to => 'home#index'"
18
+ route("root :to => 'home#index'")
18
19
  end
19
20
 
20
21
  def embedded_app?
@@ -2,7 +2,7 @@
2
2
 
3
3
  <ul>
4
4
  <% @products.each do |product| %>
5
- <li><%= link_to product.title, "https://#{@shop_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
5
+ <li><%= link_to product.title, "https://#{@current_shopify_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
6
6
  <% end %>
7
7
  </ul>
8
8
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -16,7 +17,7 @@ module ShopifyApp
16
17
  @scope = format_array_argument(options['scope'])
17
18
  @api_version = options['api_version'] || ShopifyAPI::Meta.admin_versions.find(&:latest_supported).handle
18
19
 
19
- template 'shopify_app.rb', 'config/initializers/shopify_app.rb'
20
+ template('shopify_app.rb', 'config/initializers/shopify_app.rb')
20
21
  end
21
22
 
22
23
  def create_session_store_initializer
@@ -24,28 +25,28 @@ module ShopifyApp
24
25
  end
25
26
 
26
27
  def create_and_inject_into_omniauth_initializer
27
- unless File.exist? "config/initializers/omniauth.rb"
28
- copy_file 'omniauth.rb', 'config/initializers/omniauth.rb'
28
+ unless File.exist?("config/initializers/omniauth.rb")
29
+ copy_file('omniauth.rb', 'config/initializers/omniauth.rb')
29
30
  end
30
31
 
31
32
  inject_into_file(
32
33
  'config/initializers/omniauth.rb',
33
34
  File.read(File.expand_path(find_in_source_paths('shopify_provider.rb'))),
34
- after: "Rails.application.config.middleware.use OmniAuth::Builder do\n"
35
+ after: "Rails.application.config.middleware.use(OmniAuth::Builder) do\n"
35
36
  )
36
37
  end
37
38
 
38
39
  def create_embedded_app_layout
39
40
  return unless embedded_app?
40
41
 
41
- copy_file 'embedded_app.html.erb', 'app/views/layouts/embedded_app.html.erb'
42
- copy_file '_flash_messages.html.erb', 'app/views/layouts/_flash_messages.html.erb'
42
+ copy_file('embedded_app.html.erb', 'app/views/layouts/embedded_app.html.erb')
43
+ copy_file('_flash_messages.html.erb', 'app/views/layouts/_flash_messages.html.erb')
43
44
 
44
45
  if ShopifyApp.use_webpacker?
45
46
  copy_file('shopify_app.js', 'app/javascript/shopify_app/shopify_app.js')
46
47
  copy_file('flash_messages.js', 'app/javascript/shopify_app/flash_messages.js')
47
48
  copy_file('shopify_app_index.js', 'app/javascript/shopify_app/index.js')
48
- append_to_file('app/javascript/packs/application.js', 'require("shopify_app")')
49
+ append_to_file('app/javascript/packs/application.js', "require(\"shopify_app\")\n")
49
50
  else
50
51
  copy_file('shopify_app.js', 'app/assets/javascripts/shopify_app.js')
51
52
  copy_file('flash_messages.js', 'app/assets/javascripts/flash_messages.js')
@@ -53,11 +54,11 @@ module ShopifyApp
53
54
  end
54
55
 
55
56
  def create_user_agent_initializer
56
- template 'user_agent.rb', 'config/initializers/user_agent.rb'
57
+ template('user_agent.rb', 'config/initializers/user_agent.rb')
57
58
  end
58
59
 
59
60
  def mount_engine
60
- route "mount ShopifyApp::Engine, at: '/'"
61
+ route("mount ShopifyApp::Engine, at: '/'")
61
62
  end
62
63
 
63
64
  def insert_hosts_into_development_config