shopify-cli 2.2.2 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE.md +0 -4
  4. data/.github/workflows/shopify.yml +104 -0
  5. data/.gitignore +3 -0
  6. data/.rubocop.yml +14 -14
  7. data/.rubocop_todo.yml +3 -3
  8. data/CHANGELOG.md +30 -0
  9. data/CONTRIBUTING.md +23 -0
  10. data/Dockerfile +17 -0
  11. data/Gemfile +1 -0
  12. data/Gemfile.lock +67 -24
  13. data/RELEASING.md +1 -1
  14. data/Rakefile +75 -18
  15. data/bin/console +11 -0
  16. data/bin/shopify +16 -4
  17. data/dev.yml +14 -1
  18. data/ext/shopify-cli/extconf.rb +2 -0
  19. data/ext/shopify-extensions/extconf.rb +21 -0
  20. data/ext/shopify-extensions/shopify_extensions.rb +152 -0
  21. data/ext/shopify-extensions/version +1 -0
  22. data/lib/project_types/extension/cli.rb +19 -3
  23. data/lib/project_types/extension/commands/build.rb +32 -3
  24. data/lib/project_types/extension/commands/check.rb +2 -2
  25. data/lib/project_types/extension/commands/connect.rb +1 -1
  26. data/lib/project_types/extension/commands/create.rb +59 -16
  27. data/lib/project_types/extension/commands/extension_command.rb +1 -1
  28. data/lib/project_types/extension/commands/info.rb +1 -1
  29. data/lib/project_types/extension/commands/push.rb +1 -1
  30. data/lib/project_types/extension/commands/register.rb +2 -2
  31. data/lib/project_types/extension/commands/serve.rb +5 -5
  32. data/lib/project_types/extension/commands/tunnel.rb +6 -6
  33. data/lib/project_types/extension/extension_project.rb +4 -4
  34. data/lib/project_types/extension/features/argo.rb +3 -3
  35. data/lib/project_types/extension/features/argo_config.rb +5 -5
  36. data/lib/project_types/extension/features/argo_serve.rb +21 -6
  37. data/lib/project_types/extension/features/argo_setup.rb +1 -1
  38. data/lib/project_types/extension/features/argo_setup_step.rb +1 -1
  39. data/lib/project_types/extension/features/argo_setup_steps.rb +2 -2
  40. data/lib/project_types/extension/forms/connect.rb +2 -2
  41. data/lib/project_types/extension/forms/create.rb +6 -3
  42. data/lib/project_types/extension/forms/questions/ask_app.rb +2 -2
  43. data/lib/project_types/extension/forms/questions/ask_name.rb +1 -1
  44. data/lib/project_types/extension/forms/questions/ask_registration.rb +2 -2
  45. data/lib/project_types/extension/forms/questions/ask_template.rb +44 -0
  46. data/lib/project_types/extension/forms/questions/ask_type.rb +2 -2
  47. data/lib/project_types/extension/messages/message_loading.rb +2 -2
  48. data/lib/project_types/extension/messages/messages.rb +3 -0
  49. data/lib/project_types/extension/models/development_server.rb +78 -0
  50. data/lib/project_types/extension/models/development_server_requirements.rb +35 -0
  51. data/lib/project_types/extension/models/lazy_specification_handler.rb +1 -1
  52. data/lib/project_types/extension/models/server_config/base.rb +31 -0
  53. data/lib/project_types/extension/models/server_config/development.rb +23 -0
  54. data/lib/project_types/extension/models/server_config/development_entries.rb +38 -0
  55. data/lib/project_types/extension/models/server_config/development_renderer.rb +30 -0
  56. data/lib/project_types/extension/models/server_config/extension.rb +35 -0
  57. data/lib/project_types/extension/models/server_config/root.rb +18 -0
  58. data/lib/project_types/extension/models/server_config/user.rb +10 -0
  59. data/lib/project_types/extension/models/specification.rb +1 -1
  60. data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +1 -1
  61. data/lib/project_types/extension/models/specification_handlers/default.rb +14 -2
  62. data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +1 -1
  63. data/lib/project_types/extension/models/specifications.rb +4 -4
  64. data/lib/project_types/extension/tasks/choose_next_available_port.rb +2 -2
  65. data/lib/project_types/extension/tasks/configure_features.rb +1 -1
  66. data/lib/project_types/extension/tasks/configure_options.rb +1 -1
  67. data/lib/project_types/extension/tasks/converters/product_converter.rb +1 -1
  68. data/lib/project_types/extension/tasks/converters/server_config_converter.rb +31 -0
  69. data/lib/project_types/extension/tasks/create_extension.rb +2 -2
  70. data/lib/project_types/extension/tasks/fetch_specifications.rb +2 -2
  71. data/lib/project_types/extension/tasks/find_npm_packages.rb +5 -5
  72. data/lib/project_types/extension/tasks/get_app.rb +2 -2
  73. data/lib/project_types/extension/tasks/get_apps.rb +2 -2
  74. data/lib/project_types/extension/tasks/get_extensions.rb +2 -2
  75. data/lib/project_types/extension/tasks/get_product.rb +2 -2
  76. data/lib/project_types/extension/tasks/load_server_config.rb +23 -0
  77. data/lib/project_types/extension/tasks/run_extension_command.rb +81 -0
  78. data/lib/project_types/extension/tasks/update_draft.rb +2 -2
  79. data/lib/project_types/node/cli.rb +3 -3
  80. data/lib/project_types/node/commands/connect.rb +4 -4
  81. data/lib/project_types/node/commands/create.rb +10 -14
  82. data/lib/project_types/node/commands/deploy/heroku.rb +4 -4
  83. data/lib/project_types/node/commands/deploy.rb +3 -3
  84. data/lib/project_types/node/commands/generate.rb +2 -2
  85. data/lib/project_types/node/commands/open.rb +3 -3
  86. data/lib/project_types/node/commands/serve.rb +15 -7
  87. data/lib/project_types/node/commands/tunnel.rb +6 -6
  88. data/lib/project_types/node/forms/create.rb +3 -3
  89. data/lib/project_types/node/messages/messages.rb +3 -0
  90. data/lib/project_types/php/cli.rb +27 -0
  91. data/lib/project_types/php/commands/connect.rb +19 -0
  92. data/lib/project_types/php/commands/create.rb +143 -0
  93. data/lib/project_types/php/commands/deploy/heroku.rb +129 -0
  94. data/lib/project_types/php/commands/deploy.rb +32 -0
  95. data/lib/project_types/php/commands/open.rb +16 -0
  96. data/lib/project_types/php/commands/serve.rb +51 -0
  97. data/lib/project_types/php/commands/tunnel.rb +37 -0
  98. data/lib/project_types/php/forms/create.rb +45 -0
  99. data/lib/project_types/php/messages/messages.rb +191 -0
  100. data/lib/project_types/rails/cli.rb +3 -3
  101. data/lib/project_types/rails/commands/connect.rb +4 -4
  102. data/lib/project_types/rails/commands/create.rb +12 -16
  103. data/lib/project_types/rails/commands/deploy/heroku.rb +4 -4
  104. data/lib/project_types/rails/commands/deploy.rb +3 -3
  105. data/lib/project_types/rails/commands/generate/webhook.rb +3 -3
  106. data/lib/project_types/rails/commands/generate.rb +3 -3
  107. data/lib/project_types/rails/commands/open.rb +3 -3
  108. data/lib/project_types/rails/commands/serve.rb +8 -8
  109. data/lib/project_types/rails/commands/tunnel.rb +6 -6
  110. data/lib/project_types/rails/forms/create.rb +3 -3
  111. data/lib/project_types/rails/gem.rb +1 -1
  112. data/lib/project_types/rails/ruby.rb +1 -1
  113. data/lib/project_types/script/cli.rb +16 -6
  114. data/lib/project_types/script/commands/create.rb +4 -2
  115. data/lib/project_types/script/commands/push.rb +2 -2
  116. data/lib/project_types/script/config/extension_points.yml +30 -29
  117. data/lib/project_types/script/forms/create.rb +1 -1
  118. data/lib/project_types/script/layers/application/create_script.rb +32 -12
  119. data/lib/project_types/script/layers/application/extension_points.rb +4 -4
  120. data/lib/project_types/script/layers/application/push_script.rb +13 -1
  121. data/lib/project_types/script/layers/domain/extension_point.rb +13 -45
  122. data/lib/project_types/script/layers/domain/push_package.rb +0 -12
  123. data/lib/project_types/script/layers/domain/script_project.rb +2 -2
  124. data/lib/project_types/script/layers/infrastructure/api_clients/partners_proxy_api_client.rb +57 -0
  125. data/lib/project_types/script/layers/infrastructure/api_clients/script_service_api_client.rb +35 -0
  126. data/lib/project_types/script/layers/infrastructure/command_runner.rb +1 -1
  127. data/lib/project_types/script/layers/infrastructure/errors.rb +5 -0
  128. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +10 -90
  129. data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +76 -11
  130. data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +1 -1
  131. data/lib/project_types/script/layers/infrastructure/languages/typescript_project_creator.rb +33 -0
  132. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +105 -0
  133. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +1 -1
  134. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +6 -6
  135. data/lib/project_types/script/layers/infrastructure/script_service.rb +25 -144
  136. data/lib/project_types/script/layers/infrastructure/script_uploader.rb +27 -0
  137. data/lib/project_types/script/layers/infrastructure/service_locator.rb +20 -0
  138. data/lib/project_types/script/messages/messages.rb +4 -0
  139. data/lib/project_types/script/tasks/ensure_env.rb +7 -7
  140. data/lib/project_types/script/ui/error_handler.rb +84 -76
  141. data/lib/project_types/script/ui/printing_spinner.rb +1 -1
  142. data/lib/project_types/theme/cli.rb +3 -3
  143. data/lib/project_types/theme/commands/check.rb +3 -3
  144. data/lib/project_types/theme/commands/delete.rb +7 -7
  145. data/lib/project_types/theme/commands/init.rb +3 -3
  146. data/lib/project_types/theme/commands/language_server.rb +2 -2
  147. data/lib/project_types/theme/commands/package.rb +2 -2
  148. data/lib/project_types/theme/commands/publish.rb +5 -5
  149. data/lib/project_types/theme/commands/pull.rb +15 -9
  150. data/lib/project_types/theme/commands/push.rb +18 -12
  151. data/lib/project_types/theme/commands/serve.rb +4 -4
  152. data/lib/project_types/theme/forms/confirm_store.rb +1 -1
  153. data/lib/project_types/theme/forms/select.rb +2 -2
  154. data/lib/{shopify-cli → shopify_cli}/admin_api/populate_resource_command.rb +3 -3
  155. data/lib/{shopify-cli → shopify_cli}/admin_api/schema.rb +4 -4
  156. data/lib/{shopify-cli → shopify_cli}/admin_api.rb +27 -27
  157. data/lib/{shopify-cli → shopify_cli}/api.rb +8 -8
  158. data/lib/shopify_cli/command/app_sub_command.rb +16 -0
  159. data/lib/{shopify-cli → shopify_cli}/command.rb +3 -3
  160. data/lib/{shopify-cli → shopify_cli}/commands/config.rb +14 -14
  161. data/lib/{shopify-cli → shopify_cli}/commands/help.rb +4 -4
  162. data/lib/{shopify-cli → shopify_cli}/commands/login.rb +7 -7
  163. data/lib/shopify_cli/commands/logout.rb +39 -0
  164. data/lib/{shopify-cli → shopify_cli}/commands/populate/customer.rb +4 -4
  165. data/lib/{shopify-cli → shopify_cli}/commands/populate/draft_order.rb +4 -4
  166. data/lib/{shopify-cli → shopify_cli}/commands/populate/product.rb +4 -4
  167. data/lib/shopify_cli/commands/populate.rb +23 -0
  168. data/lib/shopify_cli/commands/store.rb +15 -0
  169. data/lib/{shopify-cli → shopify_cli}/commands/switch.rb +5 -5
  170. data/lib/{shopify-cli → shopify_cli}/commands/system.rb +10 -10
  171. data/lib/shopify_cli/commands/version.rb +15 -0
  172. data/lib/{shopify-cli → shopify_cli}/commands/whoami.rb +7 -7
  173. data/lib/shopify_cli/commands.rb +34 -0
  174. data/lib/{shopify-cli → shopify_cli}/connect.rb +3 -3
  175. data/lib/shopify_cli/constants.rb +54 -0
  176. data/lib/{shopify-cli → shopify_cli}/context.rb +6 -6
  177. data/lib/{shopify-cli → shopify_cli}/core/entry_point.rb +7 -7
  178. data/lib/{shopify-cli → shopify_cli}/core/executor.rb +8 -4
  179. data/lib/{shopify-cli → shopify_cli}/core/finalize.rb +1 -1
  180. data/lib/{shopify-cli → shopify_cli}/core/help_resolver.rb +2 -2
  181. data/lib/{shopify-cli → shopify_cli}/core/monorail.rb +8 -8
  182. data/lib/shopify_cli/core.rb +8 -0
  183. data/lib/{shopify-cli → shopify_cli}/db.rb +8 -8
  184. data/lib/shopify_cli/environment.rb +91 -0
  185. data/lib/shopify_cli/exception_reporter/permission_controller.rb +54 -0
  186. data/lib/shopify_cli/exception_reporter.rb +55 -0
  187. data/lib/{shopify-cli → shopify_cli}/feature.rb +8 -8
  188. data/lib/{shopify-cli → shopify_cli}/form.rb +2 -2
  189. data/lib/{shopify-cli → shopify_cli}/git.rb +38 -8
  190. data/lib/{shopify-cli → shopify_cli}/helpers/haikunator.rb +1 -1
  191. data/lib/shopify_cli/helpers.rb +5 -0
  192. data/lib/{shopify-cli → shopify_cli}/heroku.rb +38 -13
  193. data/lib/{shopify-cli → shopify_cli}/http_request.rb +1 -1
  194. data/lib/{shopify-cli → shopify_cli}/identity_auth/servlet.rb +1 -1
  195. data/lib/{shopify-cli → shopify_cli}/identity_auth.rb +24 -31
  196. data/lib/{shopify-cli → shopify_cli}/js_deps.rb +7 -7
  197. data/lib/{shopify-cli → shopify_cli}/js_system.rb +10 -10
  198. data/lib/{shopify-cli → shopify_cli}/lazy_delegator.rb +2 -2
  199. data/lib/{shopify-cli → shopify_cli}/messages/messages.rb +44 -2
  200. data/lib/{shopify-cli → shopify_cli}/method_object.rb +15 -8
  201. data/lib/shopify_cli/migrator/migration.rb +27 -0
  202. data/lib/shopify_cli/migrator/migrations/1631709766_noop.rb +13 -0
  203. data/lib/shopify_cli/migrator.rb +48 -0
  204. data/lib/{shopify-cli → shopify_cli}/options.rb +1 -1
  205. data/lib/{shopify-cli → shopify_cli}/packager.rb +8 -8
  206. data/lib/{shopify-cli → shopify_cli}/partners_api/organizations.rb +1 -1
  207. data/lib/{shopify-cli → shopify_cli}/partners_api.rb +16 -40
  208. data/lib/shopify_cli/php_deps.rb +102 -0
  209. data/lib/{shopify-cli → shopify_cli}/process_supervision.rb +23 -21
  210. data/lib/{shopify-cli → shopify_cli}/project.rb +15 -15
  211. data/lib/{shopify-cli → shopify_cli}/project_commands.rb +3 -3
  212. data/lib/{shopify-cli → shopify_cli}/project_type.rb +5 -5
  213. data/lib/{shopify-cli → shopify_cli}/resolve_constant.rb +5 -5
  214. data/lib/{shopify-cli → shopify_cli}/resources/env_file.rb +1 -1
  215. data/lib/shopify_cli/resources.rb +5 -0
  216. data/lib/{shopify-cli → shopify_cli}/result.rb +11 -11
  217. data/lib/{shopify-cli → shopify_cli}/shopifolk.rb +6 -6
  218. data/lib/{shopify-cli → shopify_cli}/sub_command.rb +1 -1
  219. data/lib/{shopify-cli → shopify_cli}/task.rb +1 -1
  220. data/lib/{shopify-cli → shopify_cli}/tasks/confirm_store.rb +3 -3
  221. data/lib/{shopify-cli → shopify_cli}/tasks/create_api_client.rb +4 -4
  222. data/lib/shopify_cli/tasks/ensure_authenticated.rb +13 -0
  223. data/lib/{shopify-cli → shopify_cli}/tasks/ensure_dev_store.rb +5 -5
  224. data/lib/{shopify-cli → shopify_cli}/tasks/ensure_env.rb +3 -3
  225. data/lib/{shopify-cli → shopify_cli}/tasks/ensure_loopback_url.rb +4 -4
  226. data/lib/{shopify-cli → shopify_cli}/tasks/ensure_project_type.rb +3 -3
  227. data/lib/{shopify-cli → shopify_cli}/tasks/select_org_and_shop.rb +8 -8
  228. data/lib/{shopify-cli → shopify_cli}/tasks/update_dashboard_urls.rb +6 -6
  229. data/lib/{shopify-cli → shopify_cli}/tasks.rb +10 -10
  230. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/certificate_manager.rb +5 -5
  231. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/header_hash.rb +5 -1
  232. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/hot-reload.js +0 -0
  233. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/hot_reload.rb +5 -6
  234. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/local_assets.rb +1 -1
  235. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/proxy.rb +15 -3
  236. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/sse.rb +1 -1
  237. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/watcher.rb +1 -1
  238. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/web_server.rb +1 -1
  239. data/lib/{shopify-cli → shopify_cli}/theme/dev_server.rb +3 -3
  240. data/lib/shopify_cli/theme/development_theme.rb +83 -0
  241. data/lib/{shopify-cli → shopify_cli}/theme/file.rb +12 -4
  242. data/lib/{shopify-cli → shopify_cli}/theme/ignore_filter.rb +8 -1
  243. data/lib/{shopify-cli → shopify_cli}/theme/mime_type.rb +1 -1
  244. data/lib/{shopify-cli → shopify_cli}/theme/syncer.rb +7 -7
  245. data/lib/{shopify-cli → shopify_cli}/theme/theme.rb +4 -4
  246. data/lib/{shopify-cli → shopify_cli}/transform_data_structure.rb +4 -4
  247. data/lib/{shopify-cli → shopify_cli}/tunnel.rb +14 -14
  248. data/lib/shopify_cli/version.rb +3 -0
  249. data/lib/shopify_cli.rb +61 -50
  250. data/shopify-cli.gemspec +13 -5
  251. data/utilities/docker.rb +47 -0
  252. data/utilities/utilities.rb +5 -0
  253. metadata +155 -97
  254. data/.github/workflows/build.yml +0 -28
  255. data/lib/project_types/script/layers/infrastructure/languages/rust_project_creator.rb +0 -73
  256. data/lib/project_types/script/layers/infrastructure/languages/rust_task_runner.rb +0 -60
  257. data/lib/shopify-cli/commands/logout.rb +0 -39
  258. data/lib/shopify-cli/commands/populate.rb +0 -23
  259. data/lib/shopify-cli/commands/store.rb +0 -15
  260. data/lib/shopify-cli/commands/version.rb +0 -15
  261. data/lib/shopify-cli/commands.rb +0 -34
  262. data/lib/shopify-cli/core.rb +0 -8
  263. data/lib/shopify-cli/helpers.rb +0 -5
  264. data/lib/shopify-cli/resources.rb +0 -5
  265. data/lib/shopify-cli/tasks/ensure_authenticated.rb +0 -13
  266. data/lib/shopify-cli/theme/development_theme.rb +0 -69
  267. data/lib/shopify-cli/version.rb +0 -3
@@ -7,11 +7,11 @@ module Extension
7
7
  NPM_SERVE_COMMAND = %w(run-script server)
8
8
 
9
9
  property! :specification_handler, accepts: Extension::Models::SpecificationHandlers::Default
10
- property! :argo_runtime, accepts: -> (runtime) { runtime.class < Features::Runtimes::Base }
11
- property! :context, accepts: ShopifyCli::Context
10
+ property :argo_runtime, accepts: -> (runtime) { runtime.class < Features::Runtimes::Base }
11
+ property! :context, accepts: ShopifyCLI::Context
12
12
  property! :port, accepts: Integer, default: 39351
13
13
  property :tunnel_url, accepts: String, default: nil
14
- property! :js_system, accepts: ->(jss) { jss.respond_to?(:call) }, default: ShopifyCli::JsSystem
14
+ property! :js_system, accepts: ->(jss) { jss.respond_to?(:call) }, default: ShopifyCLI::JsSystem
15
15
  property :resource_url, accepts: String, default: nil
16
16
 
17
17
  def call
@@ -30,6 +30,7 @@ module Extension
30
30
  private
31
31
 
32
32
  def start_server
33
+ return new_serve_flow if supports_development_server?
33
34
  js_system.call(context, yarn: yarn_serve_command, npm: npm_serve_command)
34
35
  end
35
36
 
@@ -58,8 +59,8 @@ module Extension
58
59
 
59
60
  return if required_fields.none?
60
61
 
61
- ShopifyCli::Tasks::EnsureEnv.call(context, required: required_fields)
62
- ShopifyCli::Tasks::EnsureDevStore.call(context) if required_fields.include?(:shop)
62
+ ShopifyCLI::Tasks::EnsureEnv.call(context, required: required_fields)
63
+ ShopifyCLI::Tasks::EnsureDevStore.call(context) if required_fields.include?(:shop)
63
64
 
64
65
  project = ExtensionProject.current
65
66
  ensure_resource_resource_url! if specification_handler.supplies_resource_url?
@@ -90,7 +91,7 @@ module Extension
90
91
  def ensure_resource_resource_url!
91
92
  project = ExtensionProject.current(force_reload: true)
92
93
 
93
- ShopifyCli::Result
94
+ ShopifyCLI::Result
94
95
  .wrap(project.resource_url)
95
96
  .rescue { specification_handler.build_resource_url(shop: project.env.shop, context: context) }
96
97
  .then(&method(:persist_resource_url))
@@ -108,6 +109,20 @@ module Extension
108
109
  ExtensionProject.update_env_file(context: context, resource_url: resource_url)
109
110
  resource_url
110
111
  end
112
+
113
+ def new_serve_flow
114
+ Tasks::RunExtensionCommand.new(
115
+ type: specification_handler.specification.identifier,
116
+ command: "serve",
117
+ context: context,
118
+ port: port,
119
+ config_file_name: specification_handler.server_config_file,
120
+ ).call
121
+ end
122
+
123
+ def supports_development_server?
124
+ Models::DevelopmentServerRequirements.supported?(specification_handler.specification.identifier)
125
+ end
111
126
  end
112
127
  end
113
128
  end
@@ -26,7 +26,7 @@ module Extension
26
26
  end
27
27
 
28
28
  def run_install_steps(context, steps, identifier, directory_name)
29
- system = ShopifyCli::JsSystem.new(ctx: context)
29
+ system = ShopifyCLI::JsSystem.new(ctx: context)
30
30
 
31
31
  steps.inject(true) do |success, setup_step|
32
32
  success && setup_step.call(context, identifier, directory_name, system)
@@ -11,7 +11,7 @@ module Extension
11
11
  def call(context, identifier, directory_name, js_system)
12
12
  step_result = step.call(context, identifier, directory_name, js_system)
13
13
  can_fail? ? step_result : true
14
- rescue ShopifyCli::Abort => e
14
+ rescue ShopifyCLI::Abort => e
15
15
  context.puts(e.message)
16
16
  false
17
17
  rescue StandardError => e
@@ -18,7 +18,7 @@ module Extension
18
18
  def self.clone_template(git_template)
19
19
  ArgoSetupStep.default do |context, _identifier, directory_name, _js_system|
20
20
  begin
21
- ShopifyCli::Git.clone(git_template, directory_name, ctx: context)
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
24
  context.puts("{{x}} Unable to clone the repository.")
@@ -28,7 +28,7 @@ module Extension
28
28
 
29
29
  def self.install_dependencies
30
30
  ArgoSetupStep.default do |context, _identifier, _directory_name, js_system|
31
- ShopifyCli::JsDeps.new(ctx: context, system: js_system).install
31
+ ShopifyCLI::JsDeps.new(ctx: context, system: js_system).install
32
32
  end
33
33
  end
34
34
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Extension
4
4
  module Forms
5
- class Connect < ShopifyCli::Form
5
+ class Connect < ShopifyCLI::Form
6
6
  attr_reader :registration, :app
7
7
 
8
8
  flag_arguments :type
@@ -19,7 +19,7 @@ module Extension
19
19
  end
20
20
 
21
21
  def ask
22
- ShopifyCli::Result.wrap(ExtensionProjectDetails.new)
22
+ ShopifyCLI::Result.wrap(ExtensionProjectDetails.new)
23
23
  .then(&Questions::AskRegistration.new(ctx: ctx, type: type))
24
24
  .unwrap { |e| raise e }
25
25
  .tap do |project_details|
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Extension
4
4
  module Forms
5
- class Create < ShopifyCli::Form
6
- flag_arguments :name, :type, :api_key
5
+ class Create < ShopifyCLI::Form
6
+ flag_arguments :name, :type, :api_key, :template
7
7
 
8
8
  attr_reader :app
9
9
 
@@ -13,6 +13,7 @@ module Extension
13
13
  property :app, accepts: Models::App
14
14
  property :name, accepts: String
15
15
  property :type, accepts: Models::SpecificationHandlers::Default
16
+ property :template, accepts: String
16
17
 
17
18
  def complete?
18
19
  !!(app && name && type)
@@ -20,9 +21,10 @@ module Extension
20
21
  end
21
22
 
22
23
  def ask
23
- ShopifyCli::Result.wrap(ExtensionProjectDetails.new)
24
+ ShopifyCLI::Result.wrap(ExtensionProjectDetails.new)
24
25
  .then(&Questions::AskApp.new(ctx: ctx, api_key: api_key))
25
26
  .then(&Questions::AskType.new(ctx: ctx, type: type))
27
+ .then(&Questions::AskTemplate.new(ctx: ctx))
26
28
  .then(&Questions::AskName.new(ctx: ctx, name: name))
27
29
  .unwrap { |e| raise e }
28
30
  .tap do |project_details|
@@ -30,6 +32,7 @@ module Extension
30
32
 
31
33
  self.app = project_details.app
32
34
  self.type = project_details.type
35
+ self.template = project_details.template
33
36
  self.name = project_details.name
34
37
  end
35
38
  end
@@ -2,7 +2,7 @@ module Extension
2
2
  module Forms
3
3
  module Questions
4
4
  class AskApp
5
- include ShopifyCli::MethodObject
5
+ include ShopifyCLI::MethodObject
6
6
 
7
7
  property! :ctx
8
8
  property :api_key
@@ -45,7 +45,7 @@ module Extension
45
45
  def abort_no_apps
46
46
  ctx.puts(@ctx.message("create.no_apps"))
47
47
  ctx.puts(@ctx.message("create.learn_about_apps"))
48
- raise ShopifyCli::AbortSilent
48
+ raise ShopifyCLI::AbortSilent
49
49
  end
50
50
  end
51
51
  end
@@ -2,7 +2,7 @@ module Extension
2
2
  module Forms
3
3
  module Questions
4
4
  class AskName
5
- include ShopifyCli::MethodObject
5
+ include ShopifyCLI::MethodObject
6
6
 
7
7
  property! :ctx
8
8
  property :name
@@ -4,7 +4,7 @@ module Extension
4
4
  module Forms
5
5
  module Questions
6
6
  class AskRegistration
7
- include ShopifyCli::MethodObject
7
+ include ShopifyCLI::MethodObject
8
8
 
9
9
  property! :ctx
10
10
  property! :type
@@ -43,7 +43,7 @@ module Extension
43
43
  def abort_no_registrations
44
44
  ctx.puts(@ctx.message("connect.no_extensions", type))
45
45
  ctx.puts(@ctx.message("connect.learn_about_extensions"))
46
- raise ShopifyCli::AbortSilent
46
+ raise ShopifyCLI::AbortSilent
47
47
  end
48
48
  end
49
49
  end
@@ -0,0 +1,44 @@
1
+ module Extension
2
+ module Forms
3
+ module Questions
4
+ class AskTemplate
5
+ include ShopifyCLI::MethodObject
6
+
7
+ TEMPLATE_REQUIRED_TYPES = [
8
+ "checkout_ui_extension",
9
+ ]
10
+
11
+ property! :ctx
12
+ property :prompt,
13
+ accepts: ->(prompt) { prompt.respond_to?(:call) },
14
+ default: -> { CLI::UI::Prompt.method(:ask) }
15
+
16
+ def call(project_details)
17
+ return project_details unless template_required?(project_details)
18
+ project_details.template = choose_interactively
19
+ project_details
20
+ end
21
+
22
+ private
23
+
24
+ def template_required?(project_details)
25
+ return false unless extension_server_beta?
26
+ type = project_details&.type&.identifier
27
+ TEMPLATE_REQUIRED_TYPES.include?(type.downcase)
28
+ end
29
+
30
+ def extension_server_beta?
31
+ ShopifyCLI::Shopifolk.check && ShopifyCLI::Feature.enabled?(:extension_server_beta)
32
+ end
33
+
34
+ def choose_interactively
35
+ prompt.call(ctx.message("create.ask_template")) do |handler|
36
+ Models::ServerConfig::Development::VALID_TEMPLATES.each do |template|
37
+ handler.option(template) { template }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -2,7 +2,7 @@ module Extension
2
2
  module Forms
3
3
  module Questions
4
4
  class AskType
5
- include ShopifyCli::MethodObject
5
+ include ShopifyCLI::MethodObject
6
6
 
7
7
  property! :ctx
8
8
  property :type
@@ -39,7 +39,7 @@ module Extension
39
39
 
40
40
  def abort_due_to_missing_specifications
41
41
  ctx.puts(@ctx.message("create.no_available_extensions"))
42
- raise ShopifyCli::AbortSilent
42
+ raise ShopifyCLI::AbortSilent
43
43
  end
44
44
  end
45
45
  end
@@ -15,9 +15,9 @@ module Extension
15
15
  end
16
16
 
17
17
  def self.load_current_type_messages
18
- return unless ShopifyCli::Project.has_current?
18
+ return unless ShopifyCLI::Project.has_current?
19
19
  messages_for_type(
20
- ShopifyCli::Project.current.config[Extension::ExtensionProjectKeys::SPECIFICATION_IDENTIFIER_KEY]
20
+ ShopifyCLI::Project.current.config[Extension::ExtensionProjectKeys::SPECIFICATION_IDENTIFIER_KEY]
21
21
  )
22
22
  end
23
23
 
@@ -45,6 +45,7 @@ module Extension
45
45
  "or try creating a new app using {{command:shopify [node|rails] create}}.",
46
46
  loading_apps: "Loading your apps…",
47
47
  no_available_extensions: "{{x}} There are no available extensions for this app.",
48
+ ask_template: "Select a template to use for your extension",
48
49
  },
49
50
  connect: {
50
51
  connected: "Project now connected to {{green:%s: %s}}",
@@ -67,6 +68,8 @@ module Extension
67
68
  HELP
68
69
  frame_title: "Building extension with: %s…",
69
70
  build_failure_message: "Failed to build extension code.",
71
+ build_success_message: "Build was successful!",
72
+ directory_not_found: "Build directory not found.",
70
73
  },
71
74
  register: {
72
75
  help: <<~HELP,
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Models
5
+ class DevelopmentServer
6
+ class DevelopmentServerError < StandardError; end
7
+
8
+ include SmartProperties
9
+
10
+ EXECUTABLE_DIRECTORY = File.join(ShopifyCLI::ROOT, "ext", "shopify-extensions")
11
+
12
+ property :executable, converts: :to_s
13
+
14
+ def executable
15
+ super || begin
16
+ case RbConfig::CONFIG.fetch("host_os")
17
+ when /(linux)|(darwin)/
18
+ File.join(EXECUTABLE_DIRECTORY, "shopify-extensions")
19
+ else
20
+ File.join(EXECUTABLE_DIRECTORY, "shopify-extensions.exe")
21
+ end
22
+ end
23
+ end
24
+
25
+ def executable_installed?
26
+ File.exist?(executable)
27
+ end
28
+
29
+ def create(server_config)
30
+ CLI::Kit::System.capture3(executable, "create", "-", stdin_data: server_config.to_yaml)
31
+ rescue StandardError => error
32
+ raise error
33
+ end
34
+
35
+ def build(server_config)
36
+ _, error, status = CLI::Kit::System.capture3(executable, "build", "-", stdin_data: server_config.to_yaml)
37
+ return if status.success?
38
+ raise DevelopmentServerError, error
39
+ end
40
+
41
+ def serve(context, server_config)
42
+ CLI::Kit::System.popen3(executable, "serve", "-") do |input, out, err, status|
43
+ context.puts("Sending configuration data …")
44
+ input << server_config.to_yaml
45
+ input.close
46
+
47
+ forward_output_to_user(out, err, context)
48
+
49
+ status.value
50
+ end
51
+ end
52
+
53
+ def version
54
+ raise NotImplementedError
55
+ end
56
+
57
+ private
58
+
59
+ def forward_output_to_user(out, err, ctx)
60
+ ctx.puts("Starting monitoring threads …")
61
+
62
+ Thread.new do
63
+ ctx.puts("Ready to process standard output")
64
+ while (line = out.gets)
65
+ ctx.puts(line)
66
+ end
67
+ end
68
+
69
+ Thread.new do
70
+ ctx.puts("Ready to process standard error")
71
+ while (error = err.gets)
72
+ ctx.puts(error)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Models
6
+ class DevelopmentServerRequirements
7
+ SUPPORTED_EXTENSION_TYPES = [
8
+ "checkout_ui_extension",
9
+ ]
10
+
11
+ UNIX_NAME = "shopify-extensions"
12
+ WINDOWS_NAME = "shopify-extensions.exe"
13
+
14
+ class << self
15
+ def supported?(type)
16
+ binary_installed? && type_supported?(type) && beta_enabled?
17
+ end
18
+
19
+ private
20
+
21
+ def binary_installed?
22
+ Models::DevelopmentServer.new.executable_installed?
23
+ end
24
+
25
+ def type_supported?(type)
26
+ SUPPORTED_EXTENSION_TYPES.include?(type.downcase)
27
+ end
28
+
29
+ def beta_enabled?
30
+ ShopifyCLI::Shopifolk.check && ShopifyCLI::Feature.enabled?(:extension_server_beta)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,6 +1,6 @@
1
1
  module Extension
2
2
  module Models
3
- class LazySpecificationHandler < ShopifyCli::LazyDelegator
3
+ class LazySpecificationHandler < ShopifyCLI::LazyDelegator
4
4
  attr_reader :identifier
5
5
 
6
6
  def initialize(identifier, &specification_handler_initializer)
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Models
5
+ module ServerConfig
6
+ class Base
7
+ def to_h
8
+ to_hash
9
+ end
10
+
11
+ def to_hash
12
+ is_hashable = ->(obj) { obj.respond_to?(:to_hash) }
13
+ is_collection_of_hashables = ->(obj) { obj.is_a?(Enumerable) && obj.all?(&is_hashable) }
14
+
15
+ self.class.properties.each.reduce({}) do |data, (_, property)|
16
+ data.merge(property.name.to_s => send(property.reader).yield_self do |value|
17
+ case value
18
+ when is_collection_of_hashables
19
+ value.map { |element| element.to_hash.transform_keys(&:to_s) }
20
+ when is_hashable
21
+ value.to_hash.transform_keys(&:to_s)
22
+ else
23
+ value
24
+ end
25
+ end)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module Extension
2
+ module Models
3
+ module ServerConfig
4
+ class Development < Base
5
+ include SmartProperties
6
+ VALID_TEMPLATES = [
7
+ "javascript",
8
+ "javascript-react",
9
+ "typescript",
10
+ "typescript-react",
11
+ ]
12
+
13
+ CURRENT_DIRECTORY = "."
14
+
15
+ property :root_dir, accepts: String, default: CURRENT_DIRECTORY
16
+ property! :build_dir, accepts: String, default: "build"
17
+ property :template, accepts: VALID_TEMPLATES
18
+ property :renderer, accepts: ServerConfig::DevelopmentRenderer
19
+ property :entries, accepts: ServerConfig::DevelopmentEntries
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Models
5
+ module ServerConfig
6
+ class DevelopmentEntries < Base
7
+ include SmartProperties
8
+
9
+ JAVASCRIPT = "javascript"
10
+ JAVASCRIPT_REACT = "javascript-react"
11
+ TYPESCRIPT = "typescript"
12
+ TYPESCRIPT_REACT = "typescript-react"
13
+
14
+ VALID_ENTRY_POINTS = [
15
+ "src/index.js",
16
+ "src/index.jsx",
17
+ "src/index.ts",
18
+ "src/index.tsx",
19
+ ]
20
+
21
+ property! :main, accepts: VALID_ENTRY_POINTS
22
+
23
+ def self.find(template)
24
+ case template
25
+ when JAVASCRIPT
26
+ new(main: "src/index.js")
27
+ when JAVASCRIPT_REACT
28
+ new(main: "src/index.jsx")
29
+ when TYPESCRIPT
30
+ new(main: "src/index.ts")
31
+ when TYPESCRIPT_REACT
32
+ new(main: "src/index.tsx")
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Models
5
+ module ServerConfig
6
+ class DevelopmentRenderer < Base
7
+ include SmartProperties
8
+
9
+ VALID_RENDERERS = [
10
+ "@shopify/admin-ui-extensions",
11
+ "@shopify/post-purchase-ui-extensions",
12
+ "@shopify/checkout-ui-extensions",
13
+ ]
14
+
15
+ property! :name, accepts: VALID_RENDERERS
16
+
17
+ def self.find(type)
18
+ case type.downcase
19
+ when "admin_ui_extension"
20
+ new(name: "@shopify/admin-ui-extensions")
21
+ when "checkout_ui_extension"
22
+ new(name: "@shopify/checkout-ui-extensions")
23
+ when "checkout_post_purchase"
24
+ new(name: "@shopify/post-purchase-ui-extensions")
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,35 @@
1
+ require "securerandom"
2
+
3
+ module Extension
4
+ module Models
5
+ module ServerConfig
6
+ class Extension < Base
7
+ include SmartProperties
8
+ property! :uuid, accepts: String
9
+ property! :type, accepts: String
10
+ property! :user, accepts: ServerConfig::User
11
+ property! :development, accepts: ServerConfig::Development
12
+
13
+ def self.build(uuid: "", template:, type:, root_dir:)
14
+ renderer = ServerConfig::DevelopmentRenderer.find(type)
15
+ entry = ServerConfig::DevelopmentEntries.find(template)
16
+ new(
17
+ uuid: uuid.empty? ? generate_dev_uuid : uuid,
18
+ type: type.downcase,
19
+ user: ServerConfig::User.new,
20
+ development: ServerConfig::Development.new(
21
+ root_dir: root_dir,
22
+ template: template,
23
+ renderer: renderer,
24
+ entries: entry
25
+ )
26
+ )
27
+ end
28
+
29
+ def self.generate_dev_uuid
30
+ "dev-#{SecureRandom.uuid}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Models
5
+ module ServerConfig
6
+ class Root < Base
7
+ include SmartProperties
8
+
9
+ property! :port, accepts: Integer, default: 39351
10
+ property! :extensions, accepts: Array, default: -> { [] }
11
+
12
+ def to_yaml
13
+ to_h.to_yaml.gsub("---\n", "")
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ module Extension
2
+ module Models
3
+ module ServerConfig
4
+ class User < Base
5
+ include SmartProperties
6
+ property! :metafields, accepts: Array, default: -> { [] }
7
+ end
8
+ end
9
+ end
10
+ end
@@ -18,7 +18,7 @@ module Extension
18
18
  def self.build(feature_set_attributes)
19
19
  feature_set_attributes.each_with_object(OpenStruct.new) do |(identifier, feature_attributes), feature_set|
20
20
  next if feature_attributes.nil?
21
- feature_set[identifier] = ShopifyCli::ResolveConstant
21
+ feature_set[identifier] = ShopifyCLI::ResolveConstant
22
22
  .call(identifier, namespace: Features)
23
23
  .rescue { OpenStruct }
24
24
  .then { |c| c.new(**feature_attributes) }
@@ -4,7 +4,7 @@ module Extension
4
4
  module Models
5
5
  module SpecificationHandlers
6
6
  class CheckoutUiExtension < Default
7
- PERMITTED_CONFIG_KEYS = [:metafields, :extension_points]
7
+ PERMITTED_CONFIG_KEYS = [:extension_points, :metafields, :name]
8
8
 
9
9
  def config(context)
10
10
  {