shopify_app 13.5.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 +7 -0
- data/.babelrc +5 -0
- data/.github/CODEOWNERS +1 -0
- data/.github/ISSUE_TEMPLATE.md +14 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +6 -0
- data/.github/probots.yml +2 -0
- data/.github/workflows/rubocop.yml +28 -0
- data/.gitignore +16 -0
- data/.nvmrc +1 -0
- data/.rubocop.yml +17 -0
- data/.ruby-version +1 -0
- data/.travis.yml +28 -0
- data/CHANGELOG.md +505 -0
- data/Gemfile +11 -0
- data/LICENSE +19 -0
- data/README.md +620 -0
- data/Rakefile +7 -0
- data/SECURITY.md +59 -0
- data/app/assets/images/storage_access.svg +2 -0
- data/app/assets/javascripts/shopify_app/enable_cookies.js +3 -0
- data/app/assets/javascripts/shopify_app/itp_helper.js +40 -0
- data/app/assets/javascripts/shopify_app/partition_cookies.js +8 -0
- data/app/assets/javascripts/shopify_app/redirect.js +33 -0
- data/app/assets/javascripts/shopify_app/request_storage_access.js +3 -0
- data/app/assets/javascripts/shopify_app/storage_access.js +153 -0
- data/app/assets/javascripts/shopify_app/storage_access_redirect.js +17 -0
- data/app/assets/javascripts/shopify_app/top_level.js +2 -0
- data/app/assets/javascripts/shopify_app/top_level_interaction.js +11 -0
- data/app/controllers/concerns/shopify_app/authenticated.rb +16 -0
- data/app/controllers/concerns/shopify_app/require_known_shop.rb +39 -0
- data/app/controllers/shopify_app/authenticated_controller.rb +8 -0
- data/app/controllers/shopify_app/callback_controller.rb +140 -0
- data/app/controllers/shopify_app/extension_verification_controller.rb +15 -0
- data/app/controllers/shopify_app/sessions_controller.rb +184 -0
- data/app/controllers/shopify_app/webhooks_controller.rb +37 -0
- data/app/views/shopify_app/partials/_button_styles.html.erb +104 -0
- data/app/views/shopify_app/partials/_card_styles.html.erb +33 -0
- data/app/views/shopify_app/partials/_empty_state_styles.html.erb +129 -0
- data/app/views/shopify_app/partials/_layout_styles.html.erb +167 -0
- data/app/views/shopify_app/partials/_typography_styles.html.erb +35 -0
- data/app/views/shopify_app/sessions/enable_cookies.html.erb +75 -0
- data/app/views/shopify_app/sessions/new.html.erb +123 -0
- data/app/views/shopify_app/sessions/request_storage_access.html.erb +68 -0
- data/app/views/shopify_app/sessions/top_level_interaction.html.erb +64 -0
- data/app/views/shopify_app/shared/redirect.html.erb +23 -0
- data/config/locales/cs.yml +23 -0
- data/config/locales/da.yml +20 -0
- data/config/locales/de.yml +22 -0
- data/config/locales/en.yml +15 -0
- data/config/locales/es.yml +22 -0
- data/config/locales/fi.yml +20 -0
- data/config/locales/fr.yml +23 -0
- data/config/locales/hi.yml +23 -0
- data/config/locales/it.yml +21 -0
- data/config/locales/ja.yml +17 -0
- data/config/locales/ko.yml +19 -0
- data/config/locales/ms.yml +22 -0
- data/config/locales/nb.yml +21 -0
- data/config/locales/nl.yml +21 -0
- data/config/locales/pl.yml +21 -0
- data/config/locales/pt-BR.yml +21 -0
- data/config/locales/pt-PT.yml +22 -0
- data/config/locales/sv.yml +21 -0
- data/config/locales/th.yml +20 -0
- data/config/locales/tr.yml +22 -0
- data/config/locales/zh-CN.yml +16 -0
- data/config/locales/zh-TW.yml +16 -0
- data/config/routes.rb +23 -0
- data/docs/Quickstart.md +93 -0
- data/docs/Releasing.md +18 -0
- data/docs/Troubleshooting.md +16 -0
- data/docs/install-on-dev-shop.png +0 -0
- data/docs/test-your-app.png +0 -0
- data/images/app-proxy-screenshot.png +0 -0
- data/karma.conf.js +44 -0
- data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +47 -0
- data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +11 -0
- data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +40 -0
- data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +62 -0
- data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +69 -0
- data/lib/generators/shopify_app/add_webhook/templates/webhook_job.rb.tt +13 -0
- data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +26 -0
- data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +8 -0
- data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +11 -0
- data/lib/generators/shopify_app/app_proxy_controller/templates/index.html.erb +19 -0
- data/lib/generators/shopify_app/authenticated_controller/authenticated_controller_generator.rb +15 -0
- data/lib/generators/shopify_app/authenticated_controller/templates/authenticated_controller.rb +5 -0
- data/lib/generators/shopify_app/controllers/controllers_generator.rb +30 -0
- data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +26 -0
- data/lib/generators/shopify_app/home_controller/templates/home_controller.rb +8 -0
- data/lib/generators/shopify_app/home_controller/templates/index.html.erb +21 -0
- data/lib/generators/shopify_app/install/install_generator.rb +83 -0
- data/lib/generators/shopify_app/install/templates/_flash_messages.html.erb +3 -0
- data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +41 -0
- data/lib/generators/shopify_app/install/templates/flash_messages.js +24 -0
- data/lib/generators/shopify_app/install/templates/omniauth.rb +3 -0
- data/lib/generators/shopify_app/install/templates/session_store.rb +4 -0
- data/lib/generators/shopify_app/install/templates/shopify_app.js +15 -0
- data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +15 -0
- data/lib/generators/shopify_app/install/templates/shopify_app_index.js +2 -0
- data/lib/generators/shopify_app/install/templates/shopify_provider.rb +20 -0
- data/lib/generators/shopify_app/install/templates/user_agent.rb +6 -0
- data/lib/generators/shopify_app/rotate_shopify_token_job/rotate_shopify_token_job_generator.rb +16 -0
- data/lib/generators/shopify_app/rotate_shopify_token_job/templates/rotate_shopify_token.rake +17 -0
- data/lib/generators/shopify_app/rotate_shopify_token_job/templates/rotate_shopify_token_job.rb +42 -0
- data/lib/generators/shopify_app/routes/routes_generator.rb +32 -0
- data/lib/generators/shopify_app/routes/templates/routes.rb +12 -0
- data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +43 -0
- data/lib/generators/shopify_app/shop_model/templates/db/migrate/create_shops.erb +15 -0
- data/lib/generators/shopify_app/shop_model/templates/shop.rb +8 -0
- data/lib/generators/shopify_app/shop_model/templates/shops.yml +3 -0
- data/lib/generators/shopify_app/shopify_app_generator.rb +18 -0
- data/lib/generators/shopify_app/user_model/templates/db/migrate/create_users.erb +16 -0
- data/lib/generators/shopify_app/user_model/templates/user.rb +8 -0
- data/lib/generators/shopify_app/user_model/templates/users.yml +4 -0
- data/lib/generators/shopify_app/user_model/user_model_generator.rb +43 -0
- data/lib/generators/shopify_app/views/views_generator.rb +30 -0
- data/lib/shopify_app.rb +61 -0
- data/lib/shopify_app/configuration.rb +94 -0
- data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +38 -0
- data/lib/shopify_app/controller_concerns/csrf_protection.rb +15 -0
- data/lib/shopify_app/controller_concerns/embedded_app.rb +20 -0
- data/lib/shopify_app/controller_concerns/itp.rb +45 -0
- data/lib/shopify_app/controller_concerns/localization.rb +23 -0
- data/lib/shopify_app/controller_concerns/login_protection.rb +231 -0
- data/lib/shopify_app/controller_concerns/payload_verification.rb +24 -0
- data/lib/shopify_app/controller_concerns/webhook_verification.rb +23 -0
- data/lib/shopify_app/engine.rb +25 -0
- data/lib/shopify_app/jobs/scripttags_manager_job.rb +16 -0
- data/lib/shopify_app/jobs/webhooks_manager_job.rb +16 -0
- data/lib/shopify_app/managers/scripttags_manager.rb +78 -0
- data/lib/shopify_app/managers/webhooks_manager.rb +62 -0
- data/lib/shopify_app/middleware/jwt_middleware.rb +42 -0
- data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +34 -0
- data/lib/shopify_app/session/in_memory_session_store.rb +31 -0
- data/lib/shopify_app/session/in_memory_shop_session_store.rb +14 -0
- data/lib/shopify_app/session/in_memory_user_session_store.rb +14 -0
- data/lib/shopify_app/session/jwt.rb +61 -0
- data/lib/shopify_app/session/null_user_session_store.rb +22 -0
- data/lib/shopify_app/session/session_repository.rb +56 -0
- data/lib/shopify_app/session/session_storage.rb +20 -0
- data/lib/shopify_app/session/shop_session_storage.rb +42 -0
- data/lib/shopify_app/session/user_session_storage.rb +42 -0
- data/lib/shopify_app/test_helpers/all.rb +2 -0
- data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
- data/lib/shopify_app/utils.rb +24 -0
- data/lib/shopify_app/version.rb +4 -0
- data/package-lock.json +7177 -0
- data/package.json +28 -0
- data/service.yml +7 -0
- data/shipit.rubygems.yml +4 -0
- data/shopify_app.gemspec +37 -0
- data/translation.yml +7 -0
- data/webpack.config.js +24 -0
- data/yarn.lock +5263 -0
- metadata +420 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'rails/generators/base'
|
|
3
|
+
|
|
4
|
+
module ShopifyApp
|
|
5
|
+
module Generators
|
|
6
|
+
class AddWebhookGenerator < Rails::Generators::Base
|
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
8
|
+
class_option :topic, type: :string, aliases: "-t", required: true
|
|
9
|
+
class_option :address, type: :string, aliases: "-a", required: true
|
|
10
|
+
|
|
11
|
+
hook_for :test_framework, as: :job, in: :rails do |instance, generator|
|
|
12
|
+
instance.invoke(generator, [instance.send(:job_file_name)])
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def init_webhook_config
|
|
16
|
+
initializer = load_initializer
|
|
17
|
+
return if initializer.include?("config.webhooks")
|
|
18
|
+
|
|
19
|
+
inject_into_file(
|
|
20
|
+
'config/initializers/shopify_app.rb',
|
|
21
|
+
" config.webhooks = [\n ]\n",
|
|
22
|
+
before: 'end'
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def inject_webhook_to_shopify_app_initializer
|
|
27
|
+
inject_into_file(
|
|
28
|
+
'config/initializers/shopify_app.rb',
|
|
29
|
+
webhook_config,
|
|
30
|
+
after: "config.webhooks = ["
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
initializer = load_initializer
|
|
34
|
+
|
|
35
|
+
unless initializer.include?(webhook_config)
|
|
36
|
+
shell.say("Error adding webhook to config. Add this line manually: #{webhook_config}", :red)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def add_webhook_job
|
|
41
|
+
@job_file_name = job_file_name + '_job'
|
|
42
|
+
@job_class_name = @job_file_name.classify
|
|
43
|
+
template('webhook_job.rb', "app/jobs/#{@job_file_name}.rb")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def job_file_name
|
|
49
|
+
address.split('/').last
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def load_initializer
|
|
53
|
+
File.read(File.join(destination_root, 'config/initializers/shopify_app.rb'))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def webhook_config
|
|
57
|
+
"\n {topic: '#{topic}', address: '#{address}', format: 'json'},"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def topic
|
|
61
|
+
options['topic']
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def address
|
|
65
|
+
options['address']
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class <%= @job_class_name %> < ActiveJob::Base
|
|
2
|
+
def perform(shop_domain:, webhook:)
|
|
3
|
+
shop = Shop.find_by(shopify_domain: shop_domain)
|
|
4
|
+
|
|
5
|
+
if shop.nil?
|
|
6
|
+
logger.error("#{self.class} failed: cannot find shop with domain '#{shop_domain}'")
|
|
7
|
+
return
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
shop.with_shopify_session do
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'rails/generators/base'
|
|
3
|
+
|
|
4
|
+
module ShopifyApp
|
|
5
|
+
module Generators
|
|
6
|
+
class AppProxyControllerGenerator < Rails::Generators::Base
|
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
8
|
+
|
|
9
|
+
def create_app_proxy_controller
|
|
10
|
+
template('app_proxy_controller.rb', 'app/controllers/app_proxy_controller.rb')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create_app_proxy_index_view
|
|
14
|
+
copy_file('index.html.erb', 'app/views/app_proxy/index.html.erb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_app_proxy_route
|
|
18
|
+
inject_into_file(
|
|
19
|
+
'config/routes.rb',
|
|
20
|
+
File.read(File.expand_path(find_in_source_paths('app_proxy_route.rb'))),
|
|
21
|
+
after: "mount ShopifyApp::Engine, at: '/'\n"
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
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
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<h2>App Proxy Page</h2>
|
|
2
|
+
|
|
3
|
+
<p>Congratulations! You have successfully configured App Proxy for your shopify application.</p>
|
|
4
|
+
<p>Any valid liquid code included in this page will be parsed and rendered by Shopify.</p>
|
|
5
|
+
|
|
6
|
+
<br>
|
|
7
|
+
|
|
8
|
+
<pre>
|
|
9
|
+
Your Shop Details:
|
|
10
|
+
<hr>
|
|
11
|
+
Shop Name : {{ shop.name }}
|
|
12
|
+
myshopify name : {{ shop.permanent_domain }}
|
|
13
|
+
Primary Domain of Shop : {{ shop.domain }}
|
|
14
|
+
Shop URL : {{ shop.url }}
|
|
15
|
+
Shop Currency : {{ shop.currency }}
|
|
16
|
+
No. of products in this shop : {{ shop.products_count }}
|
|
17
|
+
<br>
|
|
18
|
+
<hr>
|
|
19
|
+
</pre>
|
data/lib/generators/shopify_app/authenticated_controller/authenticated_controller_generator.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/generators/base'
|
|
4
|
+
|
|
5
|
+
module ShopifyApp
|
|
6
|
+
module Generators
|
|
7
|
+
class AuthenticatedControllerGenerator < Rails::Generators::Base
|
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
9
|
+
|
|
10
|
+
def create_home_controller
|
|
11
|
+
template('authenticated_controller.rb', 'app/controllers/authenticated_controller.rb')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'rails/generators/base'
|
|
3
|
+
|
|
4
|
+
module ShopifyApp
|
|
5
|
+
module Generators
|
|
6
|
+
class ControllersGenerator < Rails::Generators::Base
|
|
7
|
+
source_root File.expand_path("../../../../..", __FILE__)
|
|
8
|
+
|
|
9
|
+
def create_controllers
|
|
10
|
+
controllers.each do |controller|
|
|
11
|
+
copy_file controller
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def controllers
|
|
18
|
+
files_within_root('.', 'app/controllers/shopify_app/*.*')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def files_within_root(prefix, glob)
|
|
22
|
+
root = "#{self.class.source_root}/#{prefix}"
|
|
23
|
+
|
|
24
|
+
Dir["#{root}/#{glob}"].sort.map do |full_path|
|
|
25
|
+
full_path.sub(root, '.').gsub('/./', '/')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'rails/generators/base'
|
|
3
|
+
|
|
4
|
+
module ShopifyApp
|
|
5
|
+
module Generators
|
|
6
|
+
class HomeControllerGenerator < Rails::Generators::Base
|
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
8
|
+
|
|
9
|
+
def create_home_controller
|
|
10
|
+
template('home_controller.rb', 'app/controllers/home_controller.rb')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create_home_index_view
|
|
14
|
+
copy_file('index.html.erb', 'app/views/home/index.html.erb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_home_index_route
|
|
18
|
+
route("root :to => 'home#index'")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def embedded_app?
|
|
22
|
+
ShopifyApp.configuration.embedded_app?
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<h2>Products</h2>
|
|
2
|
+
|
|
3
|
+
<ul>
|
|
4
|
+
<% @products.each do |product| %>
|
|
5
|
+
<li><%= link_to product.title, "https://#{@current_shopify_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
|
|
6
|
+
<% end %>
|
|
7
|
+
</ul>
|
|
8
|
+
|
|
9
|
+
<hr>
|
|
10
|
+
|
|
11
|
+
<h2>Webhooks</h2>
|
|
12
|
+
|
|
13
|
+
<% if @webhooks.present? %>
|
|
14
|
+
<ul>
|
|
15
|
+
<% @webhooks.each do |webhook| %>
|
|
16
|
+
<li><%= webhook.topic %> : <%= webhook.address %></li>
|
|
17
|
+
<% end %>
|
|
18
|
+
</ul>
|
|
19
|
+
<% else %>
|
|
20
|
+
<p>This app has not created any webhooks for this Shop. Add webhooks to your ShopifyApp initializer if you need webhooks</p>
|
|
21
|
+
<% end %>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'rails/generators/base'
|
|
3
|
+
|
|
4
|
+
module ShopifyApp
|
|
5
|
+
module Generators
|
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
|
7
|
+
include Rails::Generators::Migration
|
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
9
|
+
|
|
10
|
+
class_option :application_name, type: :array, default: ['My', 'Shopify', 'App']
|
|
11
|
+
class_option :scope, type: :array, default: ['read_products']
|
|
12
|
+
class_option :embedded, type: :string, default: 'true'
|
|
13
|
+
class_option :api_version, type: :string, default: nil
|
|
14
|
+
|
|
15
|
+
def create_shopify_app_initializer
|
|
16
|
+
@application_name = format_array_argument(options['application_name'])
|
|
17
|
+
@scope = format_array_argument(options['scope'])
|
|
18
|
+
@api_version = options['api_version'] || ShopifyAPI::Meta.admin_versions.find(&:latest_supported).handle
|
|
19
|
+
|
|
20
|
+
template('shopify_app.rb', 'config/initializers/shopify_app.rb')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def create_session_store_initializer
|
|
24
|
+
copy_file('session_store.rb', 'config/initializers/session_store.rb')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def create_and_inject_into_omniauth_initializer
|
|
28
|
+
unless File.exist?("config/initializers/omniauth.rb")
|
|
29
|
+
copy_file('omniauth.rb', 'config/initializers/omniauth.rb')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
inject_into_file(
|
|
33
|
+
'config/initializers/omniauth.rb',
|
|
34
|
+
File.read(File.expand_path(find_in_source_paths('shopify_provider.rb'))),
|
|
35
|
+
after: "Rails.application.config.middleware.use(OmniAuth::Builder) do\n"
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def create_embedded_app_layout
|
|
40
|
+
return unless embedded_app?
|
|
41
|
+
|
|
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')
|
|
44
|
+
|
|
45
|
+
if ShopifyApp.use_webpacker?
|
|
46
|
+
copy_file('shopify_app.js', 'app/javascript/shopify_app/shopify_app.js')
|
|
47
|
+
copy_file('flash_messages.js', 'app/javascript/shopify_app/flash_messages.js')
|
|
48
|
+
copy_file('shopify_app_index.js', 'app/javascript/shopify_app/index.js')
|
|
49
|
+
append_to_file('app/javascript/packs/application.js', "require(\"shopify_app\")\n")
|
|
50
|
+
else
|
|
51
|
+
copy_file('shopify_app.js', 'app/assets/javascripts/shopify_app.js')
|
|
52
|
+
copy_file('flash_messages.js', 'app/assets/javascripts/flash_messages.js')
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def create_user_agent_initializer
|
|
57
|
+
template('user_agent.rb', 'config/initializers/user_agent.rb')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def mount_engine
|
|
61
|
+
route("mount ShopifyApp::Engine, at: '/'")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def insert_hosts_into_development_config
|
|
65
|
+
inject_into_file(
|
|
66
|
+
'config/environments/development.rb',
|
|
67
|
+
" config.hosts = (config.hosts rescue []) << /\\h+.ngrok.io/\n",
|
|
68
|
+
after: "Rails.application.configure do\n"
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def embedded_app?
|
|
75
|
+
options['embedded'] == 'true'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def format_array_argument(array)
|
|
79
|
+
array.join(' ').tr('"', '')
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<% application_name = ShopifyApp.configuration.application_name %>
|
|
6
|
+
<title><%= application_name %></title>
|
|
7
|
+
<%= stylesheet_link_tag 'application' %>
|
|
8
|
+
<% if ShopifyApp.use_webpacker? %>
|
|
9
|
+
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
|
10
|
+
<% else %>
|
|
11
|
+
<%= javascript_include_tag 'application', "data-turbolinks-track" => true %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<%= csrf_meta_tags %>
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<div class="app-wrapper">
|
|
18
|
+
<div class="app-content">
|
|
19
|
+
<main role="main">
|
|
20
|
+
<%= yield %>
|
|
21
|
+
</main>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<%= render 'layouts/flash_messages' %>
|
|
26
|
+
|
|
27
|
+
<script src="https://unpkg.com/@shopify/app-bridge"></script>
|
|
28
|
+
|
|
29
|
+
<%= content_tag(:div, nil, id: 'shopify-app-init', data: {
|
|
30
|
+
api_key: ShopifyApp.configuration.api_key,
|
|
31
|
+
shop_origin: (@current_shopify_session.domain if @current_shopify_session),
|
|
32
|
+
debug: Rails.env.development?
|
|
33
|
+
} ) %>
|
|
34
|
+
|
|
35
|
+
<% if content_for?(:javascript) %>
|
|
36
|
+
<div id="ContentForJavascript" data-turbolinks-temporary>
|
|
37
|
+
<%= yield :javascript %>
|
|
38
|
+
</div>
|
|
39
|
+
<% end %>
|
|
40
|
+
</body>
|
|
41
|
+
</html>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var eventName = typeof(Turbolinks) !== 'undefined' ? 'turbolinks:load' : 'DOMContentLoaded';
|
|
2
|
+
|
|
3
|
+
if (!document.documentElement.hasAttribute("data-turbolinks-preview")) {
|
|
4
|
+
document.addEventListener(eventName, function flash() {
|
|
5
|
+
var flashData = JSON.parse(document.getElementById('shopify-app-flash').dataset.flash);
|
|
6
|
+
|
|
7
|
+
var Toast = window['app-bridge'].actions.Toast;
|
|
8
|
+
|
|
9
|
+
if (flashData.notice) {
|
|
10
|
+
Toast.create(app, {
|
|
11
|
+
message: flashData.notice,
|
|
12
|
+
duration: 5000,
|
|
13
|
+
}).dispatch(Toast.Action.SHOW);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (flashData.error) {
|
|
17
|
+
Toast.create(app, {
|
|
18
|
+
message: flashData.error,
|
|
19
|
+
duration: 5000,
|
|
20
|
+
isError: true,
|
|
21
|
+
}).dispatch(Toast.Action.SHOW);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
2
|
+
var data = document.getElementById('shopify-app-init').dataset;
|
|
3
|
+
var AppBridge = window['app-bridge'];
|
|
4
|
+
var createApp = AppBridge.default;
|
|
5
|
+
window.app = createApp({
|
|
6
|
+
apiKey: data.apiKey,
|
|
7
|
+
shopOrigin: data.shopOrigin,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
var actions = AppBridge.actions;
|
|
11
|
+
var TitleBar = actions.TitleBar;
|
|
12
|
+
TitleBar.create(app, {
|
|
13
|
+
title: data.page,
|
|
14
|
+
});
|
|
15
|
+
});
|