disco_app 0.15.2 → 0.18.1

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.
Files changed (310) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -5
  3. data/app/clients/disco_app/api_client.rb +25 -19
  4. data/app/clients/disco_app/graphql_client.rb +85 -0
  5. data/app/controllers/disco_app/admin/app_settings_controller.rb +2 -0
  6. data/app/controllers/disco_app/admin/application_controller.rb +1 -0
  7. data/app/controllers/disco_app/admin/concerns/app_settings_controller.rb +2 -1
  8. data/app/controllers/disco_app/admin/concerns/authenticated_controller.rb +5 -3
  9. data/app/controllers/disco_app/admin/concerns/plans_controller.rb +3 -2
  10. data/app/controllers/disco_app/admin/concerns/shops_controller.rb +1 -0
  11. data/app/controllers/disco_app/admin/concerns/sources_controller.rb +2 -1
  12. data/app/controllers/disco_app/admin/concerns/subscriptions_controller.rb +3 -2
  13. data/app/controllers/disco_app/admin/plans_controller.rb +2 -0
  14. data/app/controllers/disco_app/admin/resources/shops_controller.rb +2 -0
  15. data/app/controllers/disco_app/admin/shops_controller.rb +2 -0
  16. data/app/controllers/disco_app/admin/sources_controller.rb +2 -0
  17. data/app/controllers/disco_app/admin/subscriptions_controller.rb +2 -0
  18. data/app/controllers/disco_app/charges_controller.rb +6 -7
  19. data/app/controllers/disco_app/concerns/app_proxy_controller.rb +6 -6
  20. data/app/controllers/disco_app/concerns/authenticated_controller.rb +26 -27
  21. data/app/controllers/disco_app/concerns/carrier_request_controller.rb +22 -11
  22. data/app/controllers/disco_app/concerns/user_authenticated_controller.rb +1 -0
  23. data/app/controllers/disco_app/concerns/webhooks_controller.rb +13 -12
  24. data/app/controllers/disco_app/flow/actions_controller.rb +9 -0
  25. data/app/controllers/disco_app/flow/concerns/actions_controller.rb +23 -0
  26. data/app/controllers/disco_app/flow/concerns/trigger_usage_controller.rb +29 -0
  27. data/app/controllers/disco_app/flow/concerns/verifies_flow_payload.rb +39 -0
  28. data/app/controllers/disco_app/flow/trigger_usage_controller.rb +9 -0
  29. data/app/controllers/disco_app/frame_controller.rb +0 -1
  30. data/app/controllers/disco_app/install_controller.rb +3 -6
  31. data/app/controllers/disco_app/subscriptions_controller.rb +12 -4
  32. data/app/controllers/disco_app/user_sessions_controller.rb +1 -0
  33. data/app/controllers/disco_app/webhooks_controller.rb +2 -0
  34. data/app/controllers/sessions_controller.rb +5 -6
  35. data/app/helpers/disco_app/application_helper.rb +7 -7
  36. data/app/jobs/disco_app/app_installed_job.rb +2 -0
  37. data/app/jobs/disco_app/app_uninstalled_job.rb +2 -0
  38. data/app/jobs/disco_app/concerns/app_installed_job.rb +2 -3
  39. data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +2 -1
  40. data/app/jobs/disco_app/concerns/customers_data_request_job.rb +13 -0
  41. data/app/jobs/disco_app/concerns/customers_redact_job.rb +13 -0
  42. data/app/jobs/disco_app/concerns/render_asset_group_job.rb +1 -0
  43. data/app/jobs/disco_app/concerns/shop_redact_job.rb +13 -0
  44. data/app/jobs/disco_app/concerns/shop_update_job.rb +9 -2
  45. data/app/jobs/disco_app/concerns/subscription_changed_job.rb +2 -1
  46. data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +8 -7
  47. data/app/jobs/disco_app/concerns/synchronise_resources_job.rb +1 -0
  48. data/app/jobs/disco_app/concerns/synchronise_users_job.rb +6 -3
  49. data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +24 -11
  50. data/app/jobs/disco_app/customers_data_request_job.rb +5 -0
  51. data/app/jobs/disco_app/customers_redact_job.rb +5 -0
  52. data/app/jobs/disco_app/flow/process_action_job.rb +11 -0
  53. data/app/jobs/disco_app/flow/process_trigger_job.rb +11 -0
  54. data/app/jobs/disco_app/render_asset_group_job.rb +2 -0
  55. data/app/jobs/disco_app/shop_job.rb +10 -10
  56. data/app/jobs/disco_app/shop_redact_job.rb +5 -0
  57. data/app/jobs/disco_app/shop_update_job.rb +2 -0
  58. data/app/jobs/disco_app/subscription_changed_job.rb +2 -0
  59. data/app/jobs/disco_app/synchronise_carrier_service_job.rb +2 -0
  60. data/app/jobs/disco_app/synchronise_resources_job.rb +2 -0
  61. data/app/jobs/disco_app/synchronise_users_job.rb +2 -0
  62. data/app/jobs/disco_app/synchronise_webhooks_job.rb +2 -0
  63. data/app/models/application_record.rb +2 -0
  64. data/app/models/disco_app/app_settings.rb +2 -0
  65. data/app/models/disco_app/application_charge.rb +1 -1
  66. data/app/models/disco_app/concerns/app_settings.rb +2 -0
  67. data/app/models/disco_app/concerns/can_be_liquified.rb +29 -14
  68. data/app/models/disco_app/concerns/has_metafields.rb +1 -2
  69. data/app/models/disco_app/concerns/plan.rb +3 -4
  70. data/app/models/disco_app/concerns/plan_code.rb +1 -2
  71. data/app/models/disco_app/concerns/renders_assets.rb +15 -21
  72. data/app/models/disco_app/concerns/shop.rb +20 -14
  73. data/app/models/disco_app/concerns/source.rb +2 -3
  74. data/app/models/disco_app/concerns/subscription.rb +3 -3
  75. data/app/models/disco_app/concerns/synchronises.rb +10 -15
  76. data/app/models/disco_app/concerns/taggable.rb +1 -0
  77. data/app/models/disco_app/concerns/user.rb +3 -2
  78. data/app/models/disco_app/flow/action.rb +9 -0
  79. data/app/models/disco_app/flow/concerns/action.rb +27 -0
  80. data/app/models/disco_app/flow/concerns/trigger.rb +28 -0
  81. data/app/models/disco_app/flow/concerns/trigger_usage.rb +17 -0
  82. data/app/models/disco_app/flow/trigger.rb +9 -0
  83. data/app/models/disco_app/flow/trigger_usage.rb +9 -0
  84. data/app/models/disco_app/plan.rb +2 -0
  85. data/app/models/disco_app/plan_code.rb +2 -0
  86. data/app/models/disco_app/session_storage.rb +5 -2
  87. data/app/models/disco_app/shop.rb +2 -0
  88. data/app/models/disco_app/source.rb +2 -0
  89. data/app/models/disco_app/subscription.rb +2 -0
  90. data/app/models/disco_app/user.rb +2 -0
  91. data/app/resources/disco_app/admin/resources/concerns/shop_resource.rb +12 -15
  92. data/app/resources/disco_app/admin/resources/shop_resource.rb +1 -0
  93. data/app/services/disco_app/carrier_request_service.rb +3 -3
  94. data/app/services/disco_app/charges_service.rb +26 -34
  95. data/app/services/disco_app/flow/create_action.rb +35 -0
  96. data/app/services/disco_app/flow/create_trigger.rb +34 -0
  97. data/app/services/disco_app/flow/process_action.rb +50 -0
  98. data/app/services/disco_app/flow/process_trigger.rb +72 -0
  99. data/app/services/disco_app/flow/update_trigger_usage.rb +42 -0
  100. data/app/services/disco_app/partner_app_service.rb +1 -1
  101. data/app/services/disco_app/proxy_service.rb +2 -2
  102. data/app/services/disco_app/request_validation_service.rb +2 -2
  103. data/app/services/disco_app/subscription_service.rb +60 -32
  104. data/app/services/disco_app/webhook_service.rb +9 -11
  105. data/app/views/layouts/admin.html.erb +1 -2
  106. data/app/views/layouts/application.html.erb +1 -2
  107. data/app/views/layouts/embedded_app.html.erb +2 -4
  108. data/app/views/layouts/embedded_app_modal.html.erb +2 -3
  109. data/app/views/shopify_app/sessions/new.html.erb +2 -4
  110. data/config/routes.rb +11 -3
  111. data/db/migrate/20150525000000_create_shops_if_not_existent.rb +80 -80
  112. data/db/migrate/20170315062548_create_disco_app_sources.rb +2 -0
  113. data/db/migrate/20170315062629_add_sources_to_shop_subscriptions.rb +3 -1
  114. data/db/migrate/20170327214540_create_disco_app_users.rb +2 -1
  115. data/db/migrate/20170606160751_fix_disco_app_users_index.rb +2 -0
  116. data/db/migrate/20181229100327_create_flow_actions_and_triggers.rb +32 -0
  117. data/db/migrate/20200405000000_create_flow_trigger_usages.rb +16 -0
  118. data/lib/disco_app/configuration.rb +12 -5
  119. data/lib/disco_app/constants.rb +4 -2
  120. data/lib/disco_app/engine.rb +1 -1
  121. data/lib/disco_app/session.rb +1 -0
  122. data/lib/disco_app/support/file_fixtures.rb +2 -1
  123. data/lib/disco_app/version.rb +3 -1
  124. data/lib/generators/disco_app/install/USAGE +5 -0
  125. data/lib/generators/disco_app/install/install_generator.rb +297 -0
  126. data/lib/generators/disco_app/{templates → install/templates}/assets/javascripts/application.js +0 -0
  127. data/lib/generators/disco_app/{templates → install/templates}/assets/javascripts/components.js +0 -0
  128. data/lib/generators/disco_app/{templates → install/templates}/assets/stylesheets/application.scss +0 -0
  129. data/lib/generators/disco_app/install/templates/config/appsignal.yml +12 -0
  130. data/lib/generators/disco_app/install/templates/config/cable.yml.tt +11 -0
  131. data/lib/generators/disco_app/{templates → install/templates}/config/database.yml.tt +6 -3
  132. data/lib/generators/disco_app/install/templates/config/environments/staging.rb +108 -0
  133. data/lib/generators/disco_app/{templates → install/templates}/config/puma.rb +0 -0
  134. data/lib/generators/disco_app/{templates → install/templates}/controllers/home_controller.rb +1 -0
  135. data/lib/generators/disco_app/{templates → install/templates}/initializers/disco_app.rb +5 -0
  136. data/lib/generators/disco_app/install/templates/initializers/session_store.rb +2 -0
  137. data/lib/generators/disco_app/install/templates/initializers/shopify_app.rb +11 -0
  138. data/lib/generators/disco_app/{templates → install/templates}/initializers/shopify_session_repository.rb +0 -0
  139. data/lib/generators/disco_app/install/templates/initializers/timber.rb +4 -0
  140. data/lib/generators/disco_app/{templates → install/templates}/root/.editorconfig +0 -0
  141. data/lib/generators/disco_app/{templates → install/templates}/root/.env +7 -0
  142. data/lib/generators/disco_app/{templates → install/templates}/root/.env.local +4 -0
  143. data/lib/generators/disco_app/{templates → install/templates}/root/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  144. data/lib/generators/disco_app/{templates → install/templates}/root/.gitignore +6 -0
  145. data/lib/generators/disco_app/install/templates/root/.rspec +1 -0
  146. data/lib/generators/disco_app/{templates → install/templates}/root/.rubocop.yml +315 -217
  147. data/lib/generators/disco_app/install/templates/root/.tool-versions +2 -0
  148. data/lib/generators/disco_app/{templates → install/templates}/root/CHECKS +0 -0
  149. data/lib/generators/disco_app/{templates → install/templates}/root/Procfile +0 -0
  150. data/lib/generators/disco_app/{templates → install/templates}/root/README.md +0 -0
  151. data/lib/generators/disco_app/install/templates/root/package.json.tt +17 -0
  152. data/lib/generators/disco_app/install/templates/spec/rails_helper.rb +40 -0
  153. data/lib/generators/disco_app/install/templates/spec/spec_helper.rb +24 -0
  154. data/lib/generators/disco_app/install/templates/spec/support/active_job.rb +13 -0
  155. data/lib/generators/disco_app/install/templates/spec/support/coveralls.rb +3 -0
  156. data/lib/generators/disco_app/install/templates/spec/support/database_cleaner.rb +17 -0
  157. data/lib/generators/disco_app/install/templates/spec/support/factory_bot.rb +3 -0
  158. data/lib/generators/disco_app/install/templates/spec/support/helpers/json_helper.rb +13 -0
  159. data/lib/generators/disco_app/install/templates/spec/support/shared_examples/a_synchronise_job.rb +12 -0
  160. data/lib/generators/disco_app/install/templates/spec/support/shoulda.rb +6 -0
  161. data/lib/generators/disco_app/install/templates/spec/support/vcr.rb +14 -0
  162. data/lib/generators/disco_app/install/templates/spec/support/webmock.rb +8 -0
  163. data/lib/generators/disco_app/{templates → install/templates}/views/home/index.html.erb +0 -0
  164. data/lib/generators/disco_app/react/USAGE +5 -0
  165. data/lib/generators/disco_app/react/react_generator.rb +108 -0
  166. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/base_controller.rb +18 -0
  167. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/home_controller.rb +10 -0
  168. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/shops_controller.rb +11 -0
  169. data/lib/generators/disco_app/react/templates/app/controllers/embedded/api/users_controller.rb +11 -0
  170. data/lib/generators/disco_app/react/templates/app/controllers/embedded/home_controller.rb +13 -0
  171. data/lib/generators/disco_app/react/templates/app/models/api_response.rb +107 -0
  172. data/lib/generators/disco_app/react/templates/app/serializers/disco_app/shop_serializer.rb +13 -0
  173. data/lib/generators/disco_app/react/templates/app/serializers/disco_app/user_serializer.rb +13 -0
  174. data/lib/generators/disco_app/react/templates/app/serializers/empty_serializer.rb +5 -0
  175. data/lib/generators/disco_app/react/templates/app/serializers/error_serializer.rb +76 -0
  176. data/lib/generators/disco_app/react/templates/app/views/embedded/home/index.html.erb +12 -0
  177. data/lib/generators/disco_app/react/templates/app/views/layouts/embedded.html.erb +10 -0
  178. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/App.jsx +77 -0
  179. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/HomePage.jsx +34 -0
  180. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/EmbeddedPage.jsx +70 -0
  181. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/ErrorBanner.jsx +58 -0
  182. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/PaginationWrapper.jsx +10 -0
  183. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/Shared/ScrollToTop.jsx +23 -0
  184. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/components/withApi.jsx +125 -0
  185. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/index.jsx +39 -0
  186. data/lib/generators/disco_app/react/templates/app/webpack/javascripts/embedded/utils.js +19 -0
  187. data/lib/generators/disco_app/react/templates/app/webpack/packs/embedded.js +2 -0
  188. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/banners.scss +7 -0
  189. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/busy.scss +3 -0
  190. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/index.scss +3 -0
  191. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded/shared/pagination.scss +5 -0
  192. data/lib/generators/disco_app/react/templates/app/webpack/stylesheets/embedded.scss +2 -0
  193. data/lib/generators/disco_app/react/templates/config/initializers/mime_types.rb +13 -0
  194. data/lib/generators/disco_app/react/templates/config/initializers/omniauth.rb +27 -0
  195. data/lib/generators/disco_app/react/templates/config/initializers/version.rb.tt +7 -0
  196. data/lib/generators/disco_app/react/templates/config/webpack/staging.js +5 -0
  197. data/lib/generators/disco_app/react/templates/config/webpack/test.js +5 -0
  198. data/lib/generators/disco_app/react/templates/config/webpacker.yml +96 -0
  199. data/lib/generators/disco_app/react/templates/root/.eslintignore +5 -0
  200. data/lib/generators/disco_app/react/templates/root/.eslintrc +69 -0
  201. data/lib/generators/disco_app/react/templates/root/.prettierrc +3 -0
  202. data/lib/generators/disco_app/react/templates/root/VERSION +1 -0
  203. data/lib/generators/disco_app/react/templates/root/babel.config.js +72 -0
  204. data/lib/generators/disco_app/react/templates/root/package.json.tt +84 -0
  205. data/lib/generators/disco_app/react/templates/root/postcss.config.js +14 -0
  206. data/lib/tasks/api.rake +0 -2
  207. data/lib/tasks/carrier_service.rake +0 -2
  208. data/lib/tasks/database.rake +1 -1
  209. data/lib/tasks/sessions.rake +0 -2
  210. data/lib/tasks/shops.rake +0 -2
  211. data/lib/tasks/users.rake +0 -2
  212. data/lib/tasks/webhooks.rake +0 -2
  213. data/test/clients/disco_app/api_client_test.rb +3 -3
  214. data/test/controllers/disco_app/admin/shops_controller_test.rb +1 -0
  215. data/test/controllers/disco_app/charges_controller_test.rb +8 -9
  216. data/test/controllers/disco_app/flow/trigger_usage_controller_test.rb +41 -0
  217. data/test/controllers/disco_app/install_controller_test.rb +2 -1
  218. data/test/controllers/disco_app/subscriptions_controller_test.rb +2 -1
  219. data/test/controllers/disco_app/webhooks_controller_test.rb +1 -0
  220. data/test/controllers/home_controller_test.rb +1 -1
  221. data/test/disco_app_test.rb +3 -1
  222. data/test/dummy/Rakefile +1 -1
  223. data/test/dummy/app/assets/config/manifest.js +2 -0
  224. data/test/dummy/app/controllers/application_controller.rb +2 -0
  225. data/test/dummy/app/controllers/carrier_request_controller.rb +1 -0
  226. data/test/dummy/app/controllers/disco_app/admin/shops_controller.rb +1 -0
  227. data/test/dummy/app/controllers/home_controller.rb +1 -0
  228. data/test/dummy/app/controllers/proxy_controller.rb +1 -0
  229. data/test/dummy/app/javascript/packs/application.js +18 -0
  230. data/test/dummy/app/jobs/disco_app/app_installed_job.rb +2 -3
  231. data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +1 -0
  232. data/test/dummy/app/models/application_record.rb +2 -0
  233. data/test/dummy/app/models/cart.rb +4 -3
  234. data/test/dummy/app/models/disco_app/shop.rb +4 -5
  235. data/test/dummy/app/models/js_configuration.rb +1 -0
  236. data/test/dummy/app/models/product.rb +3 -2
  237. data/test/dummy/app/models/widget_configuration.rb +1 -0
  238. data/test/dummy/babel.config.js +72 -0
  239. data/test/dummy/bin/bundle +1 -1
  240. data/test/dummy/bin/rails +1 -1
  241. data/test/dummy/bin/setup +8 -8
  242. data/test/dummy/bin/webpack +19 -0
  243. data/test/dummy/bin/webpack-dev-server +19 -0
  244. data/test/dummy/config/application.rb +4 -3
  245. data/test/dummy/config/boot.rb +2 -2
  246. data/test/dummy/config/database.yml +3 -0
  247. data/test/dummy/config/environment.rb +1 -1
  248. data/test/dummy/config/environments/staging.rb +85 -0
  249. data/test/dummy/config/initializers/disco_app.rb +8 -1
  250. data/test/dummy/config/initializers/omniauth.rb +3 -4
  251. data/test/dummy/config/initializers/session_store.rb +1 -1
  252. data/test/dummy/config/initializers/shopify_app.rb +1 -0
  253. data/test/dummy/config/routes.rb +0 -2
  254. data/test/dummy/config/secrets.yml +3 -0
  255. data/test/dummy/config/webpack/development.js +5 -0
  256. data/test/dummy/config/webpack/environment.js +3 -0
  257. data/test/dummy/config/webpack/production.js +5 -0
  258. data/test/dummy/config/webpack/test.js +5 -0
  259. data/test/dummy/config/webpacker.yml +95 -0
  260. data/test/dummy/db/migrate/20160307182229_create_products.rb +3 -1
  261. data/test/dummy/db/migrate/20160530160739_create_asset_models.rb +3 -1
  262. data/test/dummy/db/migrate/20161105054746_create_carts.rb +2 -1
  263. data/test/dummy/db/schema.rb +45 -6
  264. data/test/dummy/package.json +8 -0
  265. data/test/dummy/postcss.config.js +12 -0
  266. data/test/dummy/yarn.lock +7244 -0
  267. data/test/fixtures/api/subscriptions/valid_request.json +1 -1
  268. data/test/fixtures/api/widget_store/empty_webhooks.json +3 -0
  269. data/test/fixtures/api/widget_store/existing_webhooks.json +43 -0
  270. data/test/fixtures/disco_app/shops.yml +3 -0
  271. data/test/fixtures/webhooks/flow/trigger_usage.json +7 -0
  272. data/test/integration/synchronises_test.rb +2 -1
  273. data/test/jobs/disco_app/app_installed_job_test.rb +28 -9
  274. data/test/jobs/disco_app/app_uninstalled_job_test.rb +5 -2
  275. data/test/jobs/disco_app/send_subscription_job_test.rb +3 -2
  276. data/test/jobs/disco_app/synchronise_carrier_service_job_test.rb +1 -0
  277. data/test/jobs/disco_app/synchronise_users_job_test.rb +1 -0
  278. data/test/jobs/disco_app/synchronise_webhooks_job_test.rb +70 -13
  279. data/test/models/disco_app/can_be_liquified_test.rb +3 -1
  280. data/test/models/disco_app/has_metafields_test.rb +37 -18
  281. data/test/models/disco_app/renders_assets_test.rb +2 -1
  282. data/test/models/disco_app/session_test.rb +2 -2
  283. data/test/models/disco_app/shop_test.rb +1 -1
  284. data/test/services/disco_app/charges_service_test.rb +7 -8
  285. data/test/services/disco_app/flow/create_action_test.rb +51 -0
  286. data/test/services/disco_app/flow/create_trigger_test.rb +56 -0
  287. data/test/services/disco_app/flow/process_action_test.rb +68 -0
  288. data/test/services/disco_app/flow/process_trigger_test.rb +94 -0
  289. data/test/services/disco_app/flow/update_trigger_usage_test.rb +87 -0
  290. data/test/services/disco_app/subscription_service_test.rb +3 -2
  291. data/test/support/test_file_fixtures.rb +2 -2
  292. data/test/support/test_shopify_api.rb +1 -1
  293. data/test/test_helper.rb +10 -7
  294. data/test/vcr/flow_trigger_invalid_title.yml +35 -0
  295. data/test/vcr/flow_trigger_valid.yml +38 -0
  296. data/test/vcr/webhook_failure.yml +13 -13
  297. metadata +282 -148
  298. data/app/clients/disco_app/disco_api_error.rb +0 -2
  299. data/app/clients/disco_app/rollbar_client.rb +0 -53
  300. data/app/clients/disco_app/rollbar_client_error.rb +0 -2
  301. data/lib/generators/disco_app/USAGE +0 -5
  302. data/lib/generators/disco_app/disco_app_generator.rb +0 -236
  303. data/lib/generators/disco_app/templates/config/newrelic.yml +0 -26
  304. data/lib/generators/disco_app/templates/initializers/rollbar.rb +0 -23
  305. data/lib/generators/disco_app/templates/initializers/session_store.rb +0 -2
  306. data/lib/generators/disco_app/templates/initializers/shopify_app.rb +0 -6
  307. data/lib/generators/disco_app/templates/root/.codeclimate.yml +0 -7
  308. data/lib/generators/disco_app/templates/root/.ruby-version +0 -1
  309. data/lib/tasks/rollbar.rake +0 -24
  310. data/test/fixtures/api/widget_store/webhooks.json +0 -1
@@ -1,10 +1,10 @@
1
1
  require 'jsonapi/resource'
2
2
 
3
3
  module DiscoApp::Admin::Resources::Concerns::ShopResource
4
+
4
5
  extend ActiveSupport::Concern
5
6
 
6
7
  included do
7
-
8
8
  attributes :domain, :status, :created_at
9
9
  attributes :email, :country_name, :currency, :plan_display_name
10
10
  attributes :current_subscription_id, :current_subscription_display_amount, :current_subscription_display_plan, :current_subscription_display_plan_code, :current_subscription_source
@@ -15,33 +15,33 @@ module DiscoApp::Admin::Resources::Concerns::ShopResource
15
15
  filters :query, :status
16
16
 
17
17
  # Adjust the base records method to ensure only models for the authenticated domain are retrieved.
18
- def self.records(options = {})
18
+ def self.records(_options = {})
19
19
  records = DiscoApp::Shop.order(created_at: :desc)
20
20
  records
21
21
  end
22
22
 
23
23
  # Apply filters.
24
- def self.apply_filter(records, filter, value, options)
24
+ def self.apply_filter(records, filter, value, _options)
25
25
  return records if value.blank?
26
26
 
27
27
  # Perform appropriate filtering.
28
28
  case filter
29
- when :query
30
- return records.where('name LIKE ? OR shopify_domain LIKE ? OR domain LIKE ?', "%#{value.first}%", "%#{value.first}%", "%#{value.first}%")
31
- when :status
32
- return records.where(status: value.map { |v| DiscoApp::Shop.statuses[v.to_sym] } )
33
- else
34
- return super(records, filter, value)
29
+ when :query
30
+ return records.where('name LIKE ? OR shopify_domain LIKE ? OR domain LIKE ?', "%#{value.first}%", "%#{value.first}%", "%#{value.first}%")
31
+ when :status
32
+ return records.where(status: value.map { |v| DiscoApp::Shop.statuses[v.to_sym] })
33
+ else
34
+ return super(records, filter, value)
35
35
  end
36
36
  end
37
37
 
38
38
  # Don't allow the update of any fields via the API.
39
- def self.updatable_fields(context)
39
+ def self.updatable_fields(_context)
40
40
  []
41
41
  end
42
42
 
43
43
  # Don't allow the creation of any fields via the API.
44
- def self.creatable_fields(context)
44
+ def self.creatable_fields(_context)
45
45
  []
46
46
  end
47
47
 
@@ -62,9 +62,7 @@ module DiscoApp::Admin::Resources::Concerns::ShopResource
62
62
  end
63
63
 
64
64
  def current_subscription_id
65
- if @model.current_subscription?
66
- @model.current_subscription.id
67
- end
65
+ @model.current_subscription.id if @model.current_subscription?
68
66
  end
69
67
 
70
68
  def current_subscription_display_amount
@@ -94,7 +92,6 @@ module DiscoApp::Admin::Resources::Concerns::ShopResource
94
92
  '-'
95
93
  end
96
94
  end
97
-
98
95
  end
99
96
 
100
97
  end
@@ -1,4 +1,5 @@
1
1
  class DiscoApp::Admin::Resources::ShopResource < JSONAPI::Resource
2
+
2
3
  include DiscoApp::Admin::Resources::Concerns::ShopResource
3
4
 
4
5
  end
@@ -2,13 +2,13 @@ class DiscoApp::CarrierRequestService
2
2
 
3
3
  # Return true iff the provided hmac_to_verify matches that calculated from the
4
4
  # given data and secret.
5
- def self.is_valid_hmac?(body, secret, hmac_to_verify)
6
- ActiveSupport::SecurityUtils.secure_compare(self.calculated_hmac(body, secret), hmac_to_verify.to_s)
5
+ def self.valid_hmac?(body, secret, hmac_to_verify)
6
+ ActiveSupport::SecurityUtils.secure_compare(calculated_hmac(body, secret), hmac_to_verify.to_s)
7
7
  end
8
8
 
9
9
  # Calculate the HMAC for the given data and secret.
10
10
  def self.calculated_hmac(body, secret)
11
- digest = OpenSSL::Digest.new('sha256')
11
+ digest = OpenSSL::Digest.new('sha256')
12
12
  Base64.encode64(OpenSSL::HMAC.digest(digest, secret, body)).strip
13
13
  end
14
14
 
@@ -6,24 +6,22 @@ class DiscoApp::ChargesService
6
6
  # Create the charge object locally first.
7
7
  charge = subscription.charge_class.create!(
8
8
  shop: shop,
9
- subscription: subscription,
9
+ subscription: subscription
10
10
  )
11
11
 
12
12
  # Create the charge object on Shopify.
13
- shopify_charge = shop.with_api_context {
13
+ shopify_charge = shop.with_api_context do
14
14
  subscription.shopify_charge_class.create(
15
15
  name: subscription.plan.name,
16
- price: '%.2f' % (subscription.amount.to_f / 100.0),
16
+ price: format('%.2f', (subscription.amount.to_f / 100.0)),
17
17
  trial_days: subscription.plan.has_trial? ? subscription.trial_period_days : nil,
18
18
  return_url: charge.activate_url,
19
19
  test: !DiscoApp.configuration.real_charges?
20
20
  )
21
- }
21
+ end
22
22
 
23
23
  # If we couldn't create the charge on Shopify, return nil.
24
- if shopify_charge.nil?
25
- return nil
26
- end
24
+ return nil if shopify_charge.nil?
27
25
 
28
26
  # Update the local record of the charge from Shopify's created charge, then
29
27
  # return it.
@@ -37,45 +35,39 @@ class DiscoApp::ChargesService
37
35
  # Attempt to activate the given Shopify charge for the given Shop using the
38
36
  # Shopify API. Returns true on successful activation, false otherwise.
39
37
  def self.activate(shop, charge)
40
- begin
41
- # Start by fetching the Shopify charge to check that it was accepted.
42
- shopify_charge = shop.with_api_context {
43
- charge.subscription.shopify_charge_class.find(charge.shopify_id)
44
- }
38
+ # Start by fetching the Shopify charge to check that it was accepted.
39
+ shopify_charge = shop.with_api_context do
40
+ charge.subscription.shopify_charge_class.find(charge.shopify_id)
41
+ end
45
42
 
46
- # Update the status of the local charge based on the Shopify charge.
47
- charge.send("#{shopify_charge.status}!") if charge.respond_to? "#{shopify_charge.status}!"
43
+ # Update the status of the local charge based on the Shopify charge.
44
+ charge.send("#{shopify_charge.status}!") if charge.respond_to? "#{shopify_charge.status}!"
48
45
 
49
- # If the charge wasn't accepted, fail and return.
50
- return false unless charge.accepted?
46
+ # If the charge wasn't accepted, fail and return.
47
+ return false unless charge.accepted?
51
48
 
52
- # If the charge was indeed accepted, activate it via Shopify.
53
- charge.shop.with_api_context {
54
- shopify_charge.activate
55
- }
49
+ # If the charge was indeed accepted, activate it via Shopify.
50
+ charge.shop.with_api_context do
51
+ shopify_charge.activate
52
+ end
56
53
 
57
- # If the charge was recurring, make sure that all other local recurring
58
- # charges are marked inactive.
59
- if charge.recurring?
60
- self.cancel_recurring_charges(shop, charge)
61
- end
54
+ # If the charge was recurring, make sure that all other local recurring
55
+ # charges are marked inactive.
56
+ cancel_recurring_charges(shop, charge) if charge.recurring?
62
57
 
63
- charge.active!
58
+ charge.active!
64
59
 
65
- true
66
- rescue
67
- false
68
- end
60
+ true
61
+ rescue StandardError
62
+ false
69
63
  end
70
64
 
71
65
  # Cancel all recurring charges for the given shop. If the optional charge
72
66
  # parameter is given, it will be excluded from the cancellation.
73
67
  def self.cancel_recurring_charges(shop, charge = nil)
74
68
  charges = DiscoApp::RecurringApplicationCharge.where(shop: shop)
75
- if charge.present?
76
- charges = charges.where.not(id: charge)
77
- end
78
- charges.update_all(status: DiscoApp::RecurringApplicationCharge.statuses[:cancelled])
69
+ charges = charges.where.not(id: charge) if charge.present?
70
+ charges.update_all(status: DiscoApp::RecurringApplicationCharge.statuses[:cancelled]) # rubocop:disable Rails/SkipsModelValidations
79
71
  end
80
72
 
81
73
  end
@@ -0,0 +1,35 @@
1
+ require 'interactor'
2
+
3
+ module DiscoApp
4
+ module Flow
5
+ class CreateAction
6
+
7
+ include Interactor
8
+
9
+ delegate :shop, :action_id, :action_run_id, :properties, to: :context
10
+ delegate :action, to: :context
11
+
12
+ def call
13
+ create_action
14
+ enqueue_process_action_job
15
+ end
16
+
17
+ private
18
+
19
+ def create_action
20
+ context.action = shop.flow_actions.create!(
21
+ action_id: action_id,
22
+ action_run_id: action_run_id,
23
+ properties: properties
24
+ )
25
+ rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation
26
+ context.fail!
27
+ end
28
+
29
+ def enqueue_process_action_job
30
+ ProcessActionJob.perform_later(shop, action)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,34 @@
1
+ require 'interactor'
2
+
3
+ module DiscoApp
4
+ module Flow
5
+ class CreateTrigger
6
+
7
+ include Interactor
8
+
9
+ delegate :shop, :title, :resource_name, :resource_url, :properties, to: :context
10
+ delegate :trigger, to: :context
11
+
12
+ def call
13
+ create_trigger
14
+ enqueue_process_trigger_job
15
+ end
16
+
17
+ private
18
+
19
+ def create_trigger
20
+ context.trigger = shop.flow_triggers.create!(
21
+ title: title,
22
+ resource_name: resource_name,
23
+ resource_url: resource_url,
24
+ properties: properties
25
+ )
26
+ end
27
+
28
+ def enqueue_process_trigger_job
29
+ ProcessTriggerJob.perform_later(shop, trigger)
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,50 @@
1
+ require 'interactor'
2
+
3
+ module DiscoApp
4
+ module Flow
5
+ class ProcessAction
6
+
7
+ include Interactor
8
+
9
+ delegate :action, to: :context
10
+ delegate :action_service_class, to: :context
11
+
12
+ def call
13
+ validate_action
14
+ find_action_service_class
15
+ execute_action_service_class
16
+ end
17
+
18
+ private
19
+
20
+ def validate_action
21
+ context.fail! unless action.pending?
22
+ end
23
+
24
+ def find_action_service_class
25
+ context.action_service_class =
26
+ action.action_id.classify.safe_constantize ||
27
+ %(Flow::Actions::#{action.action_id.to_s.classify}).safe_constantize
28
+
29
+ return unless action_service_class.nil?
30
+
31
+ update_action(false, ["Could not find service class for #{action.action_id}"])
32
+ context.fail!
33
+ end
34
+
35
+ def execute_action_service_class
36
+ result = action_service_class.call(shop: action.shop, properties: action.properties)
37
+ update_action(result.success?, result.errors)
38
+ end
39
+
40
+ def update_action(success, errors)
41
+ action.update!(
42
+ status: success ? Action.statuses[:succeeded] : Action.statuses[:failed],
43
+ processing_errors: success ? [] : errors,
44
+ processed_at: Time.current
45
+ )
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,72 @@
1
+ require 'interactor'
2
+
3
+ module DiscoApp
4
+ module Flow
5
+ class ProcessTrigger
6
+
7
+ include Interactor
8
+
9
+ delegate :trigger, to: :context
10
+ delegate :api_success, :api_errors, to: :context
11
+
12
+ def call
13
+ validate_trigger
14
+ make_api_request unless trigger_not_in_use?
15
+ update_trigger
16
+ fail_if_errors_present
17
+ end
18
+
19
+ private
20
+
21
+ def validate_trigger
22
+ context.fail! unless trigger.pending?
23
+ end
24
+
25
+ def make_api_request
26
+ context.api_success, context.api_errors = api_client.create_flow_trigger(
27
+ trigger.title,
28
+ trigger.resource_name,
29
+ trigger.resource_url,
30
+ trigger.properties
31
+ )
32
+ end
33
+
34
+ def update_trigger
35
+ trigger.update!(
36
+ status: trigger_status,
37
+ processing_errors: processing_errors,
38
+ processed_at: Time.current
39
+ )
40
+ end
41
+
42
+ def trigger_status
43
+ return Trigger.statuses[:skipped] if trigger_not_in_use?
44
+
45
+ api_success ? Trigger.statuses[:succeeded] : Trigger.statuses[:failed]
46
+ end
47
+
48
+ def processing_errors
49
+ return [] if trigger_not_in_use?
50
+ return [] if api_success
51
+ api_errors
52
+ end
53
+
54
+ def fail_if_errors_present
55
+ context.fail! unless trigger_not_in_use? || api_success
56
+ end
57
+
58
+ def api_client
59
+ @api_client ||= DiscoApp::GraphqlClient.new(trigger.shop)
60
+ end
61
+
62
+ def trigger_not_in_use?
63
+ trigger_usage.present? && !trigger_usage.has_enabled_flow?
64
+ end
65
+
66
+ def trigger_usage
67
+ @trigger_usage ||= TriggerUsage.find_by(shop: trigger.shop, flow_trigger_definition_id: trigger.title)
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,42 @@
1
+ require 'interactor'
2
+
3
+ module DiscoApp
4
+ module Flow
5
+ class UpdateTriggerUsage
6
+
7
+ include Interactor
8
+
9
+ delegate :shop, :flow_trigger_definition_id, :has_enabled_flow, :timestamp, to: :context
10
+ delegate :trigger_usage, to: :context
11
+
12
+ def call
13
+ find_or_create_trigger_usage
14
+ update_trigger_usage
15
+ end
16
+
17
+ private
18
+
19
+ def find_or_create_trigger_usage
20
+ context.trigger_usage = shop.flow_trigger_usages.create_or_find_by!(
21
+ flow_trigger_definition_id: flow_trigger_definition_id
22
+ )
23
+ rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation
24
+ context.fail!
25
+ end
26
+
27
+ def update_trigger_usage
28
+ return if existing_timestamp_is_newer?
29
+
30
+ trigger_usage.update(
31
+ has_enabled_flow: has_enabled_flow,
32
+ timestamp: timestamp
33
+ )
34
+ end
35
+
36
+ def existing_timestamp_is_newer?
37
+ trigger_usage.timestamp.present? && timestamp < trigger_usage.timestamp
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -79,7 +79,7 @@ module DiscoApp
79
79
  form['create_form[application_url]'] = @app_url
80
80
 
81
81
  # Accept TOS
82
- unless form['create_form[accepted]'].blank?
82
+ if form['create_form[accepted]'].present?
83
83
  form['create_form[accepted]'] = '1'
84
84
  form.hiddens.last.value = 1
85
85
  end
@@ -5,12 +5,12 @@ class DiscoApp::ProxyService
5
5
  def self.proxy_signature_is_valid?(query_string, secret)
6
6
  query_hash = Rack::Utils.parse_query(query_string)
7
7
  signature = query_hash.delete('signature').to_s
8
- ActiveSupport::SecurityUtils.secure_compare(self.calculated_signature(query_hash, secret), signature)
8
+ ActiveSupport::SecurityUtils.secure_compare(calculated_signature(query_hash, secret), signature)
9
9
  end
10
10
 
11
11
  # Return the calculated signature for the given query hash and secret.
12
12
  def self.calculated_signature(query_hash, secret)
13
- sorted_params = query_hash.collect{ |k, v| "#{k}=#{Array(v).join(',')}" }.sort.join
13
+ sorted_params = query_hash.map{ |k, v| "#{k}=#{Array(v).join(',')}" }.sort.join
14
14
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), secret, sorted_params)
15
15
  end
16
16
 
@@ -3,12 +3,12 @@ class DiscoApp::RequestValidationService
3
3
  def self.hmac_valid?(query_string, secret)
4
4
  query_hash = Rack::Utils.parse_query(query_string)
5
5
  hmac = query_hash.delete('hmac').to_s
6
- ActiveSupport::SecurityUtils.secure_compare(self.calculated_hmac(query_hash, secret), hmac)
6
+ ActiveSupport::SecurityUtils.secure_compare(calculated_hmac(query_hash, secret), hmac)
7
7
  end
8
8
 
9
9
  # Return the calculated hmac for the given query hash and secret.
10
10
  def self.calculated_hmac(query_hash, secret)
11
- sorted_params = query_hash.collect{ |k, v| "#{k}=#{Array(v).join(',')}" }.sort.join('&')
11
+ sorted_params = query_hash.map{ |k, v| "#{k}=#{Array(v).join(',')}" }.sort.join('&')
12
12
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), secret, sorted_params)
13
13
  end
14
14
 
@@ -3,50 +3,78 @@ class DiscoApp::SubscriptionService
3
3
  # Subscribe the given shop to the given plan, optionally using the given plan
4
4
  # code and optionally tracking the subscription source.
5
5
  def self.subscribe(shop, plan, plan_code = nil, source_name = nil)
6
+ new(shop, plan, plan_code, source_name).subscribe
7
+ end
8
+
9
+ attr_reader :shop, :plan, :plan_code, :source_name
10
+
11
+ def initialize(shop, plan, plan_code = nil, source_name = nil)
12
+ @shop = shop
13
+ @plan = plan
14
+ @plan_code = plan_code
15
+ @source_name = source_name
16
+ end
17
+
18
+ def subscribe
19
+ cancel_existing_subscriptions
20
+
21
+ # Create the new subscription.
22
+ new_subscription = create_new_subscription
23
+
24
+ # Enqueue the subscription changed background job.
25
+ DiscoApp::SubscriptionChangedJob.perform_later(shop, new_subscription)
26
+
27
+ # Return the new subscription.
28
+ new_subscription
29
+ end
30
+
31
+ private
6
32
 
7
33
  # If a plan code was provided, fetch it for the given plan.
8
- plan_code_instance = nil
9
- if plan_code.present?
10
- plan_code_instance = DiscoApp::PlanCode.available.find_by(plan: plan, code: plan_code)
34
+ def plan_code_instance
35
+ return if plan_code.blank?
36
+
37
+ @plan_code_instance ||= DiscoApp::PlanCode.available.find_by(plan: plan, code: plan_code)
11
38
  end
12
39
 
13
40
  # If a source name has been provided, fetch or create it
14
- source_instance = nil
15
- if source_name.present?
16
- source_instance = DiscoApp::Source.find_or_create_by(source: source_name)
41
+ def source_instance
42
+ return if source_name.blank?
43
+
44
+ @source_instance ||= DiscoApp::Source.find_or_create_by(source: source_name)
17
45
  end
18
46
 
19
47
  # Cancel any existing current subscriptions.
20
- shop.subscriptions.current.update_all(
21
- status: DiscoApp::Subscription.statuses[:cancelled],
22
- cancelled_at: Time.now
23
- )
48
+ def cancel_existing_subscriptions
49
+ shop.subscriptions.current.update_all( # rubocop:disable Rails/SkipsModelValidations
50
+ status: DiscoApp::Subscription.statuses[:cancelled],
51
+ cancelled_at: Time.zone.now
52
+ )
53
+ end
24
54
 
25
55
  # Get the amount that should be charged for the subscription.
26
- subscription_amount = plan_code_instance.present? ? plan_code_instance.amount : plan.amount
56
+ def subscription_amount
57
+ plan_code_instance.present? ? plan_code_instance.amount : plan.amount
58
+ end
27
59
 
28
60
  # Get the date the subscription trial should end.
29
- subscription_trial_period_days = plan_code_instance.present? ? plan_code_instance.trial_period_days : plan.trial_period_days
30
-
31
- # Create the new subscription.
32
- new_subscription = DiscoApp::Subscription.create!(
33
- shop: shop,
34
- plan: plan,
35
- plan_code: plan_code_instance,
36
- status: DiscoApp::Subscription.statuses[plan.has_trial? ? :trial : :active],
37
- subscription_type: plan.plan_type,
38
- amount: subscription_amount,
39
- trial_period_days: plan.has_trial? ? subscription_trial_period_days : nil,
40
- trial_start_at: plan.has_trial? ? Time.now : nil,
41
- trial_end_at: plan.has_trial? ? subscription_trial_period_days.days.from_now : nil,
42
- source: source_instance
43
- )
44
-
45
- # Enqueue the subscription changed background job.
46
- DiscoApp::SubscriptionChangedJob.perform_later(shop, new_subscription)
61
+ def subscription_trial_period_days
62
+ plan_code_instance.present? ? plan_code_instance.trial_period_days : plan.trial_period_days
63
+ end
47
64
 
48
- # Return the new subscription.
49
- new_subscription
50
- end
65
+ def create_new_subscription
66
+ DiscoApp::Subscription.create!(
67
+ shop: shop,
68
+ plan: plan,
69
+ plan_code: plan_code_instance,
70
+ status: DiscoApp::Subscription.statuses[plan.has_trial? ? :trial : :active],
71
+ subscription_type: plan.plan_type,
72
+ amount: subscription_amount,
73
+ trial_period_days: plan.has_trial? ? subscription_trial_period_days : nil,
74
+ trial_start_at: plan.has_trial? ? Time.zone.now : nil,
75
+ trial_end_at: plan.has_trial? ? subscription_trial_period_days.days.from_now : nil,
76
+ source: source_instance
77
+ )
78
+ end
51
79
 
52
80
  end
@@ -2,28 +2,26 @@ class DiscoApp::WebhookService
2
2
 
3
3
  # Return true iff the provided hmac_to_verify matches that calculated from the
4
4
  # given data and secret.
5
- def self.is_valid_hmac?(body, secret, hmac_to_verify)
6
- ActiveSupport::SecurityUtils.secure_compare(self.calculated_hmac(body, secret), hmac_to_verify.to_s)
5
+ def self.valid_hmac?(body, secret, hmac_to_verify)
6
+ ActiveSupport::SecurityUtils.secure_compare(calculated_hmac(body, secret), hmac_to_verify.to_s)
7
7
  end
8
8
 
9
9
  # Calculate the HMAC for the given data and secret.
10
10
  def self.calculated_hmac(body, secret)
11
- digest = OpenSSL::Digest.new('sha256')
11
+ digest = OpenSSL::Digest.new('sha256')
12
12
  Base64.encode64(OpenSSL::HMAC.digest(digest, secret, body)).strip
13
13
  end
14
14
 
15
15
  # Try to find a job class for the given webhook topic.
16
16
  def self.find_job_class(topic)
17
+ # First try to find a top-level matching job class.
18
+ "#{topic}_job".tr('/', '_').classify.constantize
19
+ rescue NameError
20
+ # If that fails, try to find a DiscoApp:: prefixed job class.
17
21
  begin
18
- # First try to find a top-level matching job class.
19
- "#{topic}_job".gsub('/', '_').classify.constantize
22
+ %(DiscoApp::#{"#{topic}_job".tr('/', '_').classify}).constantize
20
23
  rescue NameError
21
- # If that fails, try to find a DiscoApp:: prefixed job class.
22
- begin
23
- %Q{DiscoApp::#{"#{topic}_job".gsub('/', '_').classify}}.constantize
24
- rescue NameError
25
- nil
26
- end
24
+ nil
27
25
  end
28
26
  end
29
27
 
@@ -3,8 +3,7 @@
3
3
  <head>
4
4
  <title><%= yield(:title) %></title>
5
5
  <%= stylesheet_link_tag 'disco_app/admin', media: 'all', 'data-turbolinks-track' => true %>
6
- <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
7
-
6
+ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
8
7
  <%= csrf_meta_tags %>
9
8
  </head>
10
9
  <body class="next-ui">
@@ -4,7 +4,7 @@
4
4
  <title><%= yield(:title) %></title>
5
5
 
6
6
  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
7
-
7
+ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
8
8
  <%= csrf_meta_tags %>
9
9
 
10
10
  <%= yield :extra_head %>
@@ -13,6 +13,5 @@
13
13
 
14
14
  <%= yield %>
15
15
 
16
- <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
17
16
  </body>
18
17
  </html>