shopify-cli 1.4.1 → 1.8.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.
Files changed (303) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +2 -2
  3. data/.github/CONTRIBUTING.md +9 -1
  4. data/.github/PULL_REQUEST_TEMPLATE.md +3 -2
  5. data/.github/workflows/release.yml +0 -1
  6. data/.github/workflows/triage.yml +22 -0
  7. data/.rubocop.yml +21 -7
  8. data/.rubocop_todo.yml +2 -15
  9. data/.travis.yml +1 -1
  10. data/CHANGELOG.md +28 -0
  11. data/Gemfile +12 -11
  12. data/Gemfile.lock +17 -14
  13. data/README.md +39 -7
  14. data/RELEASING.md +5 -13
  15. data/Rakefile +32 -28
  16. data/bin/load_shopify.rb +6 -6
  17. data/bin/shopify +2 -2
  18. data/dev.yml +2 -2
  19. data/docs/_config.yml +1 -18
  20. data/docs/app/node/commands/index.md +2 -80
  21. data/docs/app/node/index.md +2 -33
  22. data/docs/app/rails/commands/index.md +2 -78
  23. data/docs/app/rails/index.md +2 -34
  24. data/docs/core/index.md +2 -84
  25. data/docs/getting-started/index.md +2 -25
  26. data/docs/getting-started/install/index.md +1 -118
  27. data/docs/getting-started/migrate/index.md +2 -94
  28. data/docs/getting-started/uninstall/index.md +2 -35
  29. data/docs/getting-started/upgrade/index.md +2 -39
  30. data/docs/help/start-app/index.md +2 -4
  31. data/docs/index.md +2 -24
  32. data/ext/shopify-cli/extconf.rb +7 -7
  33. data/install.sh +1 -1
  34. data/lib/docgen/markdown.rb +12 -12
  35. data/lib/graphql/fetch_specifications.graphql +14 -0
  36. data/lib/{project_types/extension/graphql → graphql}/get_app_by_api_key.graphql +0 -0
  37. data/lib/project_types/extension/cli.rb +54 -47
  38. data/lib/project_types/extension/commands/build.rb +3 -3
  39. data/lib/project_types/extension/commands/create.rb +17 -10
  40. data/lib/project_types/extension/commands/extension_command.rb +12 -5
  41. data/lib/project_types/extension/commands/push.rb +8 -8
  42. data/lib/project_types/extension/commands/register.rb +19 -30
  43. data/lib/project_types/extension/commands/serve.rb +31 -3
  44. data/lib/project_types/extension/commands/tunnel.rb +12 -12
  45. data/lib/project_types/extension/extension_project.rb +8 -4
  46. data/lib/project_types/extension/extension_project_keys.rb +4 -4
  47. data/lib/project_types/extension/features/argo.rb +117 -0
  48. data/lib/project_types/extension/features/argo_config.rb +5 -5
  49. data/lib/project_types/extension/features/argo_dependencies.rb +5 -5
  50. data/lib/project_types/extension/features/argo_setup.rb +2 -2
  51. data/lib/project_types/extension/features/argo_setup_steps.rb +4 -4
  52. data/lib/project_types/extension/forms/create.rb +28 -34
  53. data/lib/project_types/extension/forms/questions/ask_app.rb +53 -0
  54. data/lib/project_types/extension/forms/questions/ask_name.rb +40 -0
  55. data/lib/project_types/extension/forms/questions/ask_type.rb +47 -0
  56. data/lib/project_types/extension/messages/messages.rb +55 -52
  57. data/lib/project_types/extension/models/lazy_specification_handler.rb +12 -0
  58. data/lib/project_types/extension/models/specification.rb +37 -0
  59. data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +19 -0
  60. data/lib/project_types/extension/models/specification_handlers/default.rb +67 -0
  61. data/lib/project_types/extension/models/specifications.rb +88 -0
  62. data/lib/project_types/extension/tasks/configure_features.rb +52 -0
  63. data/lib/project_types/extension/tasks/converters/app_converter.rb +6 -6
  64. data/lib/project_types/extension/tasks/converters/registration_converter.rb +6 -6
  65. data/lib/project_types/extension/tasks/converters/validation_error_converter.rb +4 -4
  66. data/lib/project_types/extension/tasks/converters/version_converter.rb +7 -7
  67. data/lib/project_types/extension/tasks/create_extension.rb +4 -4
  68. data/lib/project_types/extension/tasks/fetch_specifications.rb +18 -0
  69. data/lib/project_types/extension/tasks/get_app.rb +4 -4
  70. data/lib/project_types/extension/tasks/get_apps.rb +3 -3
  71. data/lib/project_types/extension/tasks/update_draft.rb +4 -4
  72. data/lib/project_types/extension/tasks/user_errors.rb +4 -4
  73. data/lib/project_types/node/cli.rb +19 -16
  74. data/lib/project_types/node/commands/connect.rb +15 -0
  75. data/lib/project_types/node/commands/create.rb +44 -41
  76. data/lib/project_types/node/commands/deploy.rb +4 -4
  77. data/lib/project_types/node/commands/deploy/heroku.rb +24 -24
  78. data/lib/project_types/node/commands/generate.rb +9 -18
  79. data/lib/project_types/node/commands/open.rb +2 -2
  80. data/lib/project_types/node/commands/populate.rb +6 -6
  81. data/lib/project_types/node/commands/populate/customer.rb +5 -5
  82. data/lib/project_types/node/commands/populate/draft_order.rb +5 -5
  83. data/lib/project_types/node/commands/populate/product.rb +5 -5
  84. data/lib/project_types/node/commands/serve.rb +9 -9
  85. data/lib/project_types/node/commands/tunnel.rb +7 -7
  86. data/lib/project_types/node/forms/create.rb +17 -8
  87. data/lib/project_types/node/messages/messages.rb +20 -53
  88. data/lib/project_types/rails/cli.rb +21 -18
  89. data/lib/project_types/rails/commands/connect.rb +15 -0
  90. data/lib/project_types/rails/commands/create.rb +58 -57
  91. data/lib/project_types/rails/commands/deploy.rb +4 -4
  92. data/lib/project_types/rails/commands/deploy/heroku.rb +30 -30
  93. data/lib/project_types/rails/commands/generate.rb +7 -7
  94. data/lib/project_types/rails/commands/generate/webhook.rb +6 -6
  95. data/lib/project_types/rails/commands/open.rb +2 -2
  96. data/lib/project_types/rails/commands/populate.rb +6 -6
  97. data/lib/project_types/rails/commands/populate/customer.rb +5 -5
  98. data/lib/project_types/rails/commands/populate/draft_order.rb +5 -5
  99. data/lib/project_types/rails/commands/populate/product.rb +5 -5
  100. data/lib/project_types/rails/commands/serve.rb +11 -11
  101. data/lib/project_types/rails/commands/tunnel.rb +7 -7
  102. data/lib/project_types/rails/forms/create.rb +35 -25
  103. data/lib/project_types/rails/gem.rb +24 -24
  104. data/lib/project_types/rails/messages/messages.rb +13 -9
  105. data/lib/project_types/rails/ruby.rb +2 -2
  106. data/lib/project_types/script/cli.rb +44 -38
  107. data/lib/project_types/script/commands/create.rb +15 -10
  108. data/lib/project_types/script/commands/disable.rb +3 -3
  109. data/lib/project_types/script/commands/enable.rb +19 -9
  110. data/lib/project_types/script/commands/push.rb +10 -17
  111. data/lib/project_types/script/config/extension_points.yml +30 -12
  112. data/lib/project_types/script/errors.rb +22 -0
  113. data/lib/project_types/script/forms/create.rb +29 -5
  114. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +12 -1
  115. data/lib/project_types/script/layers/application/build_script.rb +19 -19
  116. data/lib/project_types/script/layers/application/create_script.rb +45 -12
  117. data/lib/project_types/script/layers/application/disable_script.rb +2 -2
  118. data/lib/project_types/script/layers/application/enable_script.rb +2 -2
  119. data/lib/project_types/script/layers/application/extension_points.rb +24 -0
  120. data/lib/project_types/script/layers/application/project_dependencies.rb +4 -4
  121. data/lib/project_types/script/layers/application/push_script.rb +15 -18
  122. data/lib/project_types/script/layers/domain/config_ui.rb +16 -0
  123. data/lib/project_types/script/layers/domain/errors.rb +23 -0
  124. data/lib/project_types/script/layers/domain/extension_point.rb +67 -7
  125. data/lib/project_types/script/layers/domain/metadata.rb +55 -0
  126. data/lib/project_types/script/layers/domain/push_package.rb +29 -6
  127. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +45 -55
  128. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +41 -45
  129. data/lib/project_types/script/layers/infrastructure/config_ui_repository.rb +46 -0
  130. data/lib/project_types/script/layers/infrastructure/errors.rb +32 -5
  131. data/lib/project_types/script/layers/infrastructure/extension_point_repository.rb +12 -6
  132. data/lib/project_types/script/layers/infrastructure/project_creator.rb +2 -1
  133. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +20 -13
  134. data/lib/project_types/script/layers/infrastructure/rust_project_creator.rb +72 -0
  135. data/lib/project_types/script/layers/infrastructure/rust_task_runner.rb +59 -0
  136. data/lib/project_types/script/layers/infrastructure/script_service.rb +39 -17
  137. data/lib/project_types/script/layers/infrastructure/task_runner.rb +4 -3
  138. data/lib/project_types/script/messages/messages.rb +76 -10
  139. data/lib/project_types/script/script_project.rb +26 -16
  140. data/lib/project_types/script/ui/error_handler.rb +135 -50
  141. data/lib/project_types/script/ui/printing_spinner.rb +1 -1
  142. data/lib/project_types/script/ui/strict_spinner.rb +1 -1
  143. data/lib/project_types/theme/cli.rb +40 -0
  144. data/lib/project_types/theme/commands/connect.rb +54 -0
  145. data/lib/project_types/theme/commands/create.rb +48 -0
  146. data/lib/project_types/theme/commands/deploy.rb +38 -0
  147. data/lib/project_types/theme/commands/generate.rb +20 -0
  148. data/lib/project_types/theme/commands/generate/env.rb +79 -0
  149. data/lib/project_types/theme/commands/push.rb +55 -0
  150. data/lib/project_types/theme/commands/serve.rb +31 -0
  151. data/lib/project_types/theme/forms/connect.rb +34 -0
  152. data/lib/project_types/theme/forms/create.rb +22 -0
  153. data/lib/project_types/theme/messages/messages.rb +147 -0
  154. data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +78 -0
  155. data/lib/project_types/theme/themekit.rb +113 -0
  156. data/lib/rubygems_plugin.rb +3 -3
  157. data/lib/shopify-cli/admin_api.rb +52 -12
  158. data/lib/shopify-cli/admin_api/populate_resource_command.rb +17 -17
  159. data/lib/shopify-cli/admin_api/schema.rb +3 -3
  160. data/lib/shopify-cli/api.rb +36 -31
  161. data/lib/shopify-cli/command.rb +1 -1
  162. data/lib/shopify-cli/commands.rb +9 -9
  163. data/lib/shopify-cli/commands/config.rb +28 -28
  164. data/lib/shopify-cli/commands/connect.rb +35 -18
  165. data/lib/shopify-cli/commands/create.rb +5 -5
  166. data/lib/shopify-cli/commands/help.rb +6 -6
  167. data/lib/shopify-cli/commands/logout.rb +3 -3
  168. data/lib/shopify-cli/commands/system.rb +33 -33
  169. data/lib/shopify-cli/commands/version.rb +2 -2
  170. data/lib/shopify-cli/context.rb +43 -22
  171. data/lib/shopify-cli/core.rb +4 -4
  172. data/lib/shopify-cli/core/entry_point.rb +5 -5
  173. data/lib/shopify-cli/core/executor.rb +1 -1
  174. data/lib/shopify-cli/core/help_resolver.rb +2 -2
  175. data/lib/shopify-cli/core/monorail.rb +17 -16
  176. data/lib/shopify-cli/db.rb +2 -2
  177. data/lib/shopify-cli/feature.rb +1 -3
  178. data/lib/shopify-cli/form.rb +1 -1
  179. data/lib/shopify-cli/git.rb +17 -17
  180. data/lib/shopify-cli/helpers.rb +1 -1
  181. data/lib/shopify-cli/helpers/haikunator.rb +1 -1
  182. data/lib/shopify-cli/heroku.rb +28 -28
  183. data/lib/shopify-cli/http_request.rb +21 -9
  184. data/lib/shopify-cli/js_deps.rb +13 -13
  185. data/lib/shopify-cli/js_system.rb +5 -5
  186. data/lib/shopify-cli/lazy_delegator.rb +55 -0
  187. data/lib/shopify-cli/messages/messages.rb +21 -10
  188. data/lib/shopify-cli/method_object.rb +104 -0
  189. data/lib/shopify-cli/oauth.rb +25 -25
  190. data/lib/shopify-cli/oauth/servlet.rb +9 -9
  191. data/lib/shopify-cli/options.rb +3 -3
  192. data/lib/shopify-cli/packager.rb +24 -24
  193. data/lib/shopify-cli/partners_api.rb +38 -16
  194. data/lib/shopify-cli/partners_api/organizations.rb +10 -10
  195. data/lib/shopify-cli/process_supervision.rb +8 -8
  196. data/lib/shopify-cli/project.rb +27 -23
  197. data/lib/shopify-cli/project_type.rb +21 -5
  198. data/lib/shopify-cli/resolve_constant.rb +25 -0
  199. data/lib/shopify-cli/resources.rb +1 -1
  200. data/lib/shopify-cli/resources/env_file.rb +9 -9
  201. data/lib/shopify-cli/result.rb +432 -0
  202. data/lib/shopify-cli/shopifolk.rb +35 -18
  203. data/lib/shopify-cli/sub_command.rb +1 -1
  204. data/lib/shopify-cli/task.rb +9 -1
  205. data/lib/shopify-cli/tasks.rb +7 -7
  206. data/lib/shopify-cli/tasks/create_api_client.rb +13 -4
  207. data/lib/shopify-cli/tasks/ensure_dev_store.rb +12 -12
  208. data/lib/shopify-cli/tasks/ensure_env.rb +18 -15
  209. data/lib/shopify-cli/tasks/ensure_loopback_url.rb +4 -4
  210. data/lib/shopify-cli/tasks/select_org_and_shop.rb +28 -24
  211. data/lib/shopify-cli/tasks/update_dashboard_urls.rb +10 -10
  212. data/lib/shopify-cli/transform_data_structure.rb +86 -0
  213. data/lib/shopify-cli/tunnel.rb +36 -30
  214. data/lib/shopify-cli/version.rb +1 -1
  215. data/lib/shopify_cli.rb +57 -52
  216. data/shopify-cli.gemspec +6 -6
  217. data/shopify.fish +1 -1
  218. data/shopify.sh +1 -1
  219. data/vendor/deps/cli-kit/REVISION +1 -1
  220. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +2 -2
  221. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +3 -3
  222. data/vendor/deps/cli-ui/REVISION +1 -1
  223. data/vendor/deps/cli-ui/lib/cli/ui.rb +26 -22
  224. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +4 -6
  225. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -3
  226. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_stack.rb +8 -9
  227. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -1
  228. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +1 -0
  229. data/vendor/deps/cli-ui/lib/cli/ui/printer.rb +15 -3
  230. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +4 -11
  231. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -5
  232. data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +10 -10
  233. data/vendor/deps/cli-ui/lib/cli/ui/version.rb +1 -1
  234. data/vendor/deps/cli-ui/lib/cli/ui/wrap.rb +56 -0
  235. data/vendor/deps/webrick/.gitignore +9 -0
  236. data/vendor/deps/webrick/Gemfile +3 -0
  237. data/vendor/deps/webrick/LICENSE.txt +22 -0
  238. data/vendor/deps/webrick/README.md +61 -0
  239. data/vendor/deps/webrick/Rakefile +10 -0
  240. data/vendor/deps/webrick/lib/webrick.rb +232 -0
  241. data/vendor/deps/webrick/lib/webrick/accesslog.rb +157 -0
  242. data/vendor/deps/webrick/lib/webrick/cgi.rb +313 -0
  243. data/vendor/deps/webrick/lib/webrick/compat.rb +36 -0
  244. data/vendor/deps/webrick/lib/webrick/config.rb +158 -0
  245. data/vendor/deps/webrick/lib/webrick/cookie.rb +172 -0
  246. data/vendor/deps/webrick/lib/webrick/htmlutils.rb +30 -0
  247. data/vendor/deps/webrick/lib/webrick/httpauth.rb +96 -0
  248. data/vendor/deps/webrick/lib/webrick/httpauth/authenticator.rb +117 -0
  249. data/vendor/deps/webrick/lib/webrick/httpauth/basicauth.rb +116 -0
  250. data/vendor/deps/webrick/lib/webrick/httpauth/digestauth.rb +395 -0
  251. data/vendor/deps/webrick/lib/webrick/httpauth/htdigest.rb +132 -0
  252. data/vendor/deps/webrick/lib/webrick/httpauth/htgroup.rb +97 -0
  253. data/vendor/deps/webrick/lib/webrick/httpauth/htpasswd.rb +158 -0
  254. data/vendor/deps/webrick/lib/webrick/httpauth/userdb.rb +53 -0
  255. data/vendor/deps/webrick/lib/webrick/httpproxy.rb +354 -0
  256. data/vendor/deps/webrick/lib/webrick/httprequest.rb +636 -0
  257. data/vendor/deps/webrick/lib/webrick/httpresponse.rb +564 -0
  258. data/vendor/deps/webrick/lib/webrick/https.rb +152 -0
  259. data/vendor/deps/webrick/lib/webrick/httpserver.rb +294 -0
  260. data/vendor/deps/webrick/lib/webrick/httpservlet.rb +23 -0
  261. data/vendor/deps/webrick/lib/webrick/httpservlet/abstract.rb +152 -0
  262. data/vendor/deps/webrick/lib/webrick/httpservlet/cgi_runner.rb +47 -0
  263. data/vendor/deps/webrick/lib/webrick/httpservlet/cgihandler.rb +126 -0
  264. data/vendor/deps/webrick/lib/webrick/httpservlet/erbhandler.rb +88 -0
  265. data/vendor/deps/webrick/lib/webrick/httpservlet/filehandler.rb +552 -0
  266. data/vendor/deps/webrick/lib/webrick/httpservlet/prochandler.rb +47 -0
  267. data/vendor/deps/webrick/lib/webrick/httpstatus.rb +194 -0
  268. data/vendor/deps/webrick/lib/webrick/httputils.rb +512 -0
  269. data/vendor/deps/webrick/lib/webrick/httpversion.rb +76 -0
  270. data/vendor/deps/webrick/lib/webrick/log.rb +156 -0
  271. data/vendor/deps/webrick/lib/webrick/server.rb +381 -0
  272. data/vendor/deps/webrick/lib/webrick/ssl.rb +215 -0
  273. data/vendor/deps/webrick/lib/webrick/utils.rb +265 -0
  274. data/vendor/deps/webrick/lib/webrick/version.rb +18 -0
  275. data/vendor/deps/webrick/webrick.gemspec +74 -0
  276. data/vendor/gen/template/bin/update-deps +9 -9
  277. metadata +83 -29
  278. data/docs/Gemfile +0 -5
  279. data/docs/Gemfile.lock +0 -258
  280. data/docs/_data/nav.yml +0 -35
  281. data/docs/_includes/footer.html +0 -15
  282. data/docs/_includes/head.html +0 -19
  283. data/docs/_includes/sidebar_nav.html +0 -22
  284. data/docs/_includes/toc.html +0 -112
  285. data/docs/_layouts/default.html +0 -79
  286. data/docs/css/docs.css +0 -157
  287. data/docs/images/header.png +0 -0
  288. data/docs/installing-ruby.md +0 -28
  289. data/lib/project_types/extension/features/argo/admin.rb +0 -20
  290. data/lib/project_types/extension/features/argo/base.rb +0 -129
  291. data/lib/project_types/extension/features/argo/checkout.rb +0 -20
  292. data/lib/project_types/extension/forms/register.rb +0 -47
  293. data/lib/project_types/extension/models/type.rb +0 -81
  294. data/lib/project_types/extension/models/types/checkout_post_purchase.rb +0 -23
  295. data/lib/project_types/extension/models/types/product_subscription.rb +0 -24
  296. data/lib/project_types/node/commands/generate/billing.rb +0 -39
  297. data/lib/project_types/node/commands/generate/page.rb +0 -59
  298. data/lib/project_types/node/commands/generate/webhook.rb +0 -37
  299. data/lib/project_types/script/layers/domain/script.rb +0 -18
  300. data/lib/project_types/script/layers/infrastructure/assemblyscript_tsconfig.rb +0 -38
  301. data/lib/project_types/script/layers/infrastructure/script_repository.rb +0 -59
  302. data/lib/project_types/script/templates/ts/as-pect.config.js +0 -27
  303. data/lib/project_types/script/templates/ts/as-pect.d.ts +0 -1
@@ -3,7 +3,7 @@
3
3
  module Extension
4
4
  module Features
5
5
  class ArgoConfig
6
- CONFIG_FILE_NAME = 'extension.config.yml'
6
+ CONFIG_FILE_NAME = "extension.config.yml"
7
7
 
8
8
  class << self
9
9
  def parse_yaml(context, permitted_keys = [])
@@ -11,7 +11,7 @@ module Extension
11
11
 
12
12
  return {} unless File.size?(file_name)
13
13
 
14
- require 'yaml' # takes 20ms, so deferred as late as possible.
14
+ require "yaml" # takes 20ms, so deferred as late as possible.
15
15
  begin
16
16
  config = YAML.load_file(file_name)
17
17
 
@@ -21,7 +21,7 @@ module Extension
21
21
  return {} if config.nil?
22
22
 
23
23
  unless config.is_a?(Hash)
24
- raise ShopifyCli::Abort, ShopifyCli::Context.message('core.yaml.error.not_hash', CONFIG_FILE_NAME)
24
+ raise ShopifyCli::Abort, ShopifyCli::Context.message("core.yaml.error.not_hash", CONFIG_FILE_NAME)
25
25
  end
26
26
 
27
27
  config.transform_keys!(&:to_sym)
@@ -31,7 +31,7 @@ module Extension
31
31
  rescue Psych::SyntaxError => e
32
32
  raise(
33
33
  ShopifyCli::Abort,
34
- ShopifyCli::Context.message('core.yaml.error.invalid', CONFIG_FILE_NAME, e.message)
34
+ ShopifyCli::Context.message("core.yaml.error.invalid", CONFIG_FILE_NAME, e.message)
35
35
  )
36
36
  end
37
37
  end
@@ -47,7 +47,7 @@ module Extension
47
47
  raise(
48
48
  ShopifyCli::Abort,
49
49
  ShopifyCli::Context.message(
50
- 'features.argo.config.unpermitted_keys',
50
+ "features.argo.config.unpermitted_keys",
51
51
  CONFIG_FILE_NAME,
52
52
  unpermitted_keys.map { |k| "\n- #{k}" }.join
53
53
  )
@@ -5,21 +5,21 @@ module Extension
5
5
  class ArgoDependencies
6
6
  def self.node_installed(min_major:, min_minor: nil)
7
7
  -> (context) do
8
- out, status = CLI::Kit::System.capture2('node', '-v')
9
- context.abort(context.message('features.argo.dependencies.node.node_not_installed')) unless status.success?
8
+ out, status = CLI::Kit::System.capture2("node", "-v")
9
+ context.abort(context.message("features.argo.dependencies.node.node_not_installed")) unless status.success?
10
10
 
11
- min_version = 'v' + min_major .to_s + '.' + (min_minor.nil? ? 'x' : min_minor.to_s) + '.x'
11
+ min_version = "v" + min_major .to_s + "." + (min_minor.nil? ? "x" : min_minor.to_s) + ".x"
12
12
  version = out.strip
13
13
  parsed_version = version.match(/v(?<major>\d+).(?<minor>\d+).(?<patch>\d+)/)
14
14
 
15
15
  unless min_major.nil? || parsed_version[:major].to_i >= min_major
16
- context.abort(context.message('features.argo.dependencies.node.version_too_low', version, min_version))
16
+ context.abort(context.message("features.argo.dependencies.node.version_too_low", version, min_version))
17
17
  end
18
18
 
19
19
  return if parsed_version[:major].to_i > min_major
20
20
 
21
21
  unless min_minor.nil? || parsed_version[:minor].to_i >= min_minor
22
- context.abort(context.message('features.argo.dependencies.node.version_too_low', version, min_version))
22
+ context.abort(context.message("features.argo.dependencies.node.version_too_low", version, min_version))
23
23
  end
24
24
  end
25
25
  end
@@ -5,8 +5,8 @@ module Extension
5
5
  class ArgoSetup
6
6
  include SmartProperties
7
7
 
8
- GIT_DIRECTORY = '.git'
9
- SCRIPTS_DIRECTORY = 'scripts'
8
+ GIT_DIRECTORY = ".git"
9
+ SCRIPTS_DIRECTORY = "scripts"
10
10
 
11
11
  property! :git_template, accepts: String
12
12
  property! :dependency_checks, default: []
@@ -5,7 +5,7 @@ module Extension
5
5
  module ArgoSetupSteps
6
6
  YARN_INITIALIZE_COMMAND = %w(generate).freeze
7
7
  NPM_INITIALIZE_COMMAND = %w(run generate --).freeze
8
- INITIALIZE_TYPE_PARAMETER = '--type=%s'
8
+ INITIALIZE_TYPE_PARAMETER = "--type=%s"
9
9
 
10
10
  def self.check_dependencies(dependency_checks)
11
11
  ArgoSetupStep.always_successful do |context, _identifier, _directory_name, _js_system|
@@ -21,7 +21,7 @@ module Extension
21
21
  ShopifyCli::Git.clone(git_template, directory_name, ctx: context)
22
22
  context.root = File.join(context.root, directory_name)
23
23
  rescue StandardError
24
- context.puts('{{x}} Unable to clone the repository.')
24
+ context.puts("{{x}} Unable to clone the repository.")
25
25
  end
26
26
  end
27
27
  end
@@ -34,8 +34,8 @@ module Extension
34
34
 
35
35
  def self.initialize_project
36
36
  ArgoSetupStep.default do |context, identifier, _directory_name, js_system|
37
- frame_title = context.message('create.setup_project_frame_title')
38
- failure_message = context.message('features.argo.initialization_error')
37
+ frame_title = context.message("create.setup_project_frame_title")
38
+ failure_message = context.message("features.argo.initialization_error")
39
39
 
40
40
  result = true
41
41
  CLI::UI::Frame.open(frame_title, failure_text: failure_message) do
@@ -3,50 +3,44 @@
3
3
  module Extension
4
4
  module Forms
5
5
  class Create < ShopifyCli::Form
6
- flag_arguments :name, :type
6
+ flag_arguments :name, :type, :api_key
7
7
 
8
- def ask
9
- self.type = ask_type
10
- self.name = ask_name
11
- end
8
+ attr_reader :app
12
9
 
13
- def directory_name
14
- @directory_name ||= name.strip.gsub(/( )/, '_').downcase
15
- end
10
+ class ExtensionProjectDetails
11
+ include SmartProperties
16
12
 
17
- private
13
+ property :app, accepts: Models::App
14
+ property :name, accepts: String
15
+ property :type, accepts: Models::SpecificationHandlers::Default
18
16
 
19
- def ask_name
20
- ask_with_reprompt(
21
- initial_value: name,
22
- break_condition: -> (current_name) { Models::Registration.valid_title?(current_name) },
23
- prompt_message: ctx.message('create.ask_name'),
24
- reprompt_message: ctx.message('create.invalid_name', Models::Registration::MAX_TITLE_LENGTH)
25
- )
17
+ def complete?
18
+ !!(app && name && type)
19
+ end
26
20
  end
27
21
 
28
- def ask_type
29
- return Models::Type.load_type(type) if Models::Type.valid?(type)
30
- ctx.puts(ctx.message('create.invalid_type')) unless type.nil?
31
-
32
- CLI::UI::Prompt.ask(ctx.message('create.ask_type')) do |handler|
33
- Models::Type.repository.values.each do |type|
34
- handler.option("#{type.name} #{type.tagline}") { type }
22
+ def ask
23
+ ShopifyCli::Result.wrap(ExtensionProjectDetails.new)
24
+ .then(&Questions::AskApp.new(ctx: ctx, api_key: api_key))
25
+ .then(&Questions::AskType.new(ctx: ctx, type: type))
26
+ .then(&Questions::AskName.new(ctx: ctx, name: name))
27
+ .unwrap { |e| raise e }
28
+ .tap do |project_details|
29
+ ctx.abort(ctx.message("create.incomplete_configuration")) unless project_details.complete?
30
+
31
+ self.app = project_details.app
32
+ self.type = project_details.type
33
+ self.name = project_details.name
35
34
  end
36
- end
37
35
  end
38
36
 
39
- def ask_with_reprompt(initial_value:, break_condition:, prompt_message:, reprompt_message:)
40
- value = initial_value
41
- reprompt = false
42
-
43
- until break_condition.call(value)
44
- ctx.puts(reprompt_message) if reprompt
45
- value = CLI::UI::Prompt.ask(prompt_message)&.strip
46
- reprompt = true
47
- end
48
- value
37
+ def directory_name
38
+ name.strip.gsub(/( )/, "_").downcase
49
39
  end
40
+
41
+ private
42
+
43
+ attr_writer :app
50
44
  end
51
45
  end
52
46
  end
@@ -0,0 +1,53 @@
1
+ module Extension
2
+ module Forms
3
+ module Questions
4
+ class AskApp
5
+ include ShopifyCli::MethodObject
6
+
7
+ property! :ctx
8
+ property :api_key
9
+ property! :prompt,
10
+ converts: :to_proc,
11
+ default: -> { CLI::UI::Prompt.method(:ask) }
12
+
13
+ def call(project_details)
14
+ project_details.tap(&method(:prompt_for_app))
15
+ end
16
+
17
+ private
18
+
19
+ def prompt_for_app(project_details)
20
+ project_details.app =
21
+ api_key.nil? ? choose_interactively(load_apps) : validate_app_ownership(api_key)
22
+ end
23
+
24
+ def validate_app_ownership(api_key)
25
+ found_app = Tasks::GetApp.call(context: ctx, api_key: api_key)
26
+ ctx.abort(ctx.message("create.invalid_api_key", api_key)) if found_app.nil?
27
+ found_app
28
+ end
29
+
30
+ def choose_interactively(apps)
31
+ prompt.call(ctx.message("create.ask_app")) do |handler|
32
+ apps.each do |app|
33
+ handler.option("#{app.title} by #{app.business_name}") { app }
34
+ end
35
+ end
36
+ end
37
+
38
+ def load_apps
39
+ ctx.puts(@ctx.message("create.loading_apps"))
40
+ apps = Tasks::GetApps.call(context: ctx)
41
+
42
+ apps.empty? ? abort_no_apps : apps
43
+ end
44
+
45
+ def abort_no_apps
46
+ ctx.puts(@ctx.message("create.no_apps"))
47
+ ctx.puts(@ctx.message("create.learn_about_apps"))
48
+ raise ShopifyCli::AbortSilent
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,40 @@
1
+ module Extension
2
+ module Forms
3
+ module Questions
4
+ class AskName
5
+ include ShopifyCli::MethodObject
6
+
7
+ property! :ctx
8
+ property :name
9
+ property :prompt,
10
+ accepts: ->(prompt) { prompt.respond_to?(:call) },
11
+ default: -> { CLI::UI::Prompt.method(:ask) }
12
+
13
+ def call(project_details)
14
+ project_details.name = ask_with_reprompt(
15
+ initial_value: name,
16
+ break_condition: -> (current_name) { Models::Registration.valid_title?(current_name) },
17
+ prompt_message: ctx.message("create.ask_name"),
18
+ reprompt_message: ctx.message("create.invalid_name", Models::Registration::MAX_TITLE_LENGTH)
19
+ )
20
+ project_details
21
+ end
22
+
23
+ private
24
+
25
+ def ask_with_reprompt(initial_value:, break_condition:, prompt_message:, reprompt_message:)
26
+ value = initial_value
27
+ reprompt = false
28
+
29
+ until break_condition.call(value)
30
+ ctx.puts(reprompt_message) if reprompt
31
+ value = prompt.call(prompt_message)&.strip
32
+ reprompt = true
33
+ end
34
+
35
+ value
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,47 @@
1
+ module Extension
2
+ module Forms
3
+ module Questions
4
+ class AskType
5
+ include ShopifyCli::MethodObject
6
+
7
+ property! :ctx
8
+ property :type
9
+ property :prompt,
10
+ converts: :to_proc,
11
+ default: -> { CLI::UI::Prompt.method(:ask) }
12
+
13
+ def call(project_details)
14
+ specifications = Models::Specifications.new(
15
+ fetch_specifications: Tasks::FetchSpecifications.new(context: ctx, api_key: project_details.app.api_key)
16
+ )
17
+
18
+ project_details.tap do |p|
19
+ p.type = type.nil? ? choose_type(specifications) : validate_given_type(specifications, type)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def validate_given_type(specifications, type)
26
+ return specifications[type] if specifications.valid?(type)
27
+ ctx.abort(ctx.message("create.invalid_type")) unless type.nil?
28
+ end
29
+
30
+ def choose_type(specifications)
31
+ abort_due_to_missing_specifications if specifications.none?
32
+
33
+ prompt.call(ctx.message("create.ask_type")) do |handler|
34
+ specifications.each do |type|
35
+ handler.option("#{type.name} #{type.tagline}") { type }
36
+ end
37
+ end
38
+ end
39
+
40
+ def abort_due_to_missing_specifications
41
+ ctx.puts(@ctx.message("create.no_available_extensions"))
42
+ raise ShopifyCli::AbortSilent
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
- require 'shopify_cli'
2
+ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  module Messages
6
6
  MESSAGES = {
7
7
  create: {
8
- ask_name: 'Extension name',
9
- invalid_name: 'Extension name must be under %s characters',
10
- ask_type: 'What type of extension are you creating?',
11
- invalid_type: 'Extension type is invalid.',
12
- setup_project_frame_title: 'Initializing project',
8
+ ask_name: "Extension name",
9
+ invalid_name: "Extension name must be under %s characters",
10
+ ask_type: "What type of extension are you creating?",
11
+ invalid_type: "Extension type is invalid.",
12
+ setup_project_frame_title: "Initializing project",
13
13
  ready_to_start: <<~MESSAGE,
14
14
  {{v}} A new folder was generated at {{green:./%s}}.
15
15
  {{*}} You’re ready to start building {{green:%s}}!
@@ -19,49 +19,52 @@ module Extension
19
19
  {{*}} Once you're ready to version and publish your extension,
20
20
  run {{command:shopify register}} to register this extension with one of your apps.
21
21
  MESSAGE
22
- try_again: '{{*}} Fix the errors and run {{command:shopify create extension}} again.',
22
+ try_again: "{{*}} Fix the errors and run {{command:shopify create extension}} again.",
23
23
  errors: {
24
- directory_exists: 'Directory ‘%s’ already exists. Please remove it or choose a new name for your project.',
24
+ directory_exists: "Directory ‘%s’ already exists. Please remove it or choose a new name for your project.",
25
25
  },
26
+ incomplete_configuration: "Cannot create extension due to missing configuration information",
27
+ invalid_api_key: "The API key %s does not match any of your apps.",
28
+ ask_app: "Which app would you like to register this extension with?",
29
+ no_apps: "{{x}} You don’t have any apps.",
30
+ learn_about_apps: "{{*}} Learn more about building apps at <https://shopify.dev/concepts/apps>, " \
31
+ "or try creating a new app using {{command:shopify create}}.",
32
+ loading_apps: "Loading your apps...",
33
+ no_available_extensions: "{{x}} There are no available extensions for this app.",
26
34
  },
27
35
  build: {
28
- frame_title: 'Building extension with: %s...',
29
- build_failure_message: 'Failed to build extension code.',
36
+ frame_title: "Building extension with: %s...",
37
+ build_failure_message: "Failed to build extension code.",
30
38
  },
31
39
  register: {
32
- frame_title: 'Registering Extension',
33
- waiting_text: 'Registering with Shopify...',
34
- already_registered: 'Extension is already registered.',
35
- loading_apps: 'Loading your apps...',
36
- ask_app: 'Which app would you like to register this extension with?',
37
- no_apps: '{{x}} You don’t have any apps.',
38
- learn_about_apps: '{{*}} Learn more about building apps at <https://shopify.dev/concepts/apps>, ' \
39
- 'or try creating a new app using {{command:shopify create}}.',
40
- invalid_api_key: 'The API key %s does not match any of your apps.',
41
- confirm_info: 'This will create a new extension registration for %s, which can’t be undone.',
42
- confirm_question: 'Would you like to register this extension with {{green:%s}}? (y/n)',
43
- confirm_abort: 'Extension was not registered.',
44
- success: '{{v}} Registered {{green:%s}} with {{green:%s}}.',
45
- success_info: '{{*}} Run {{command:shopify push}} to push your extension to Shopify.',
40
+ frame_title: "Registering Extension",
41
+ waiting_text: "Registering with Shopify...",
42
+ already_registered: "Extension is already registered.",
43
+ confirm_info: "This will create a new extension registration for %s, which can’t be undone.",
44
+ confirm_question: "Would you like to register this extension? (y/n)",
45
+ confirm_abort: "Extension was not registered.",
46
+ success: "{{v}} Registered {{green:%s}}.",
47
+ success_info: "{{*}} Run {{command:shopify push}} to push your extension to Shopify.",
46
48
  },
47
49
  push: {
48
- frame_title: 'Pushing your extension to Shopify',
49
- waiting_text: 'Pushing code to Shopify...',
50
- pushed_with_errors: '{{x}} Code pushed to Shopify with errors on %s.',
51
- push_with_errors_info: '{{*}} Fix these errors and run {{command:shopify push}} to revalidate your extension.',
52
- success_confirmation: '{{v}} Pushed {{green:%s}} to a draft on %s.',
53
- success_info: '{{*}} Visit %s to version and publish your extension.',
50
+ frame_title: "Pushing your extension to Shopify",
51
+ waiting_text: "Pushing code to Shopify...",
52
+ pushed_with_errors: "{{x}} Code pushed to Shopify with errors on %s.",
53
+ push_with_errors_info: "{{*}} Fix these errors and run {{command:shopify push}} to revalidate your extension.",
54
+ success_confirmation: "{{v}} Pushed {{green:%s}} to a draft on %s.",
55
+ success_info: "{{*}} Visit %s to version and publish your extension.",
54
56
  },
55
57
  serve: {
56
- frame_title: 'Serving extension...',
57
- serve_failure_message: 'Failed to run extension code.',
58
+ frame_title: "Serving extension...",
59
+ serve_failure_message: "Failed to run extension code.",
60
+ serve_missing_information: "Missing shop or api_key.",
58
61
  },
59
62
  tunnel: {
60
- missing_token: '{{x}} {{red:auth requires a token argument}}. '\
61
- 'Find it on your ngrok dashboard: {{underline:https://dashboard.ngrok.com/auth/your-authtoken}}.',
62
- invalid_port: '%s is not a valid port.',
63
- no_tunnel_running: 'No tunnel running.',
64
- tunnel_running_at: 'Tunnel running at: {{underline:%s}}',
63
+ missing_token: "{{x}} {{red:auth requires a token argument}}. "\
64
+ "Find it on your ngrok dashboard: {{underline:https://dashboard.ngrok.com/auth/your-authtoken}}.",
65
+ invalid_port: "%s is not a valid port.",
66
+ no_tunnel_running: "No tunnel running.",
67
+ tunnel_running_at: "Tunnel running at: {{underline:%s}}",
65
68
  help: <<~HELP,
66
69
  Start or stop an http tunnel to your local development extension using ngrok.
67
70
  Usage: {{command:%s tunnel [ auth | start | stop | status ]}}
@@ -69,7 +72,7 @@ module Extension
69
72
  extended_help: <<~HELP,
70
73
  {{bold:Subcommands:}}
71
74
 
72
- {{cyan:auth}}: Writes an ngrok auth token to ~/.ngrok2/ngrok.yml to connect with an ngrok account.
75
+ {{cyan:auth}}: Writes an ngrok auth token to ~/.ngrok2/ngrok.yml to connect with an ngrok account.
73
76
  Visit https://dashboard.ngrok.com/signup to sign up.
74
77
  Usage: {{command:%1$s tunnel auth <token>}}
75
78
 
@@ -87,48 +90,48 @@ module Extension
87
90
  },
88
91
  features: {
89
92
  argo: {
90
- missing_file_error: 'Could not find built extension file.',
91
- script_prepare_error: 'An error occurred while attempting to prepare your script.',
92
- initialization_error: '{{x}} There was an error while initializing the project.',
93
+ missing_file_error: "Could not find built extension file.",
94
+ script_prepare_error: "An error occurred while attempting to prepare your script.",
95
+ initialization_error: "{{x}} There was an error while initializing the project.",
93
96
  dependencies: {
94
97
  node: {
95
- node_not_installed: 'Node must be installed to create this extension.',
96
- version_too_low: 'Your node version %s does not meet the minimum required version %s',
98
+ node_not_installed: "Node must be installed to create this extension.",
99
+ version_too_low: "Your node version %s does not meet the minimum required version %s",
97
100
  },
98
- argo_missing_renderer_package_error: '%s Install the missing package and try again.',
101
+ argo_missing_renderer_package_error: "%s Install the missing package and try again.",
99
102
  argo_renderer_package_invalid_version_error: <<~MESSAGE,
100
103
  The renderer package version is not a valid SemVer Version (http://semver.org)
101
104
  MESSAGE
102
105
  yarn_install_error: "Something went wrong while running 'yarn install'. %s.",
103
- yarn_run_script_error: 'Something went wrong while running script. %s.',
106
+ yarn_run_script_error: "Something went wrong while running script. %s.",
104
107
  },
105
108
  config: {
106
- unpermitted_keys: '`%s` contains the following unpermitted keys: %s',
109
+ unpermitted_keys: "`%s` contains the following unpermitted keys: %s",
107
110
  },
108
111
  },
109
112
  },
110
113
  tasks: {
111
114
  errors: {
112
- parse_error: 'Unable to parse response from Partners Dashboard.',
115
+ parse_error: "Unable to parse response from Partners Dashboard.",
113
116
  },
114
117
  },
115
118
  errors: {
116
- unknown_type: 'Unknown extension type %s',
119
+ unknown_type: "Unknown extension type %s",
117
120
  },
118
121
  }
119
122
 
120
123
  TYPES = {
121
124
  product_subscription: {
122
- name: 'Product Subscription',
123
- tagline: '(limit 1 per app)',
125
+ name: "Product Subscription",
126
+ tagline: "(limit 1 per app)",
124
127
  overrides: {
125
128
  register: {
126
- confirm_info: 'You can only create one %s extension per app, which can’t be undone.',
129
+ confirm_info: "You can only create one %s extension per app, which can’t be undone.",
127
130
  },
128
131
  },
129
132
  },
130
133
  checkout_post_purchase: {
131
- name: 'Checkout Post Purchase',
134
+ name: "Checkout Post Purchase",
132
135
  },
133
136
  }
134
137
  end