shopify-cli 1.13.1 → 2.1.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 (200) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/CONTRIBUTING.md +7 -7
  4. data/.github/DESIGN.md +3 -3
  5. data/.github/workflows/build.yml +1 -1
  6. data/.gitignore +3 -0
  7. data/.rubocop.yml +3 -1
  8. data/.ruby-version +1 -1
  9. data/CHANGELOG.md +60 -26
  10. data/Gemfile +4 -0
  11. data/Gemfile.lock +32 -0
  12. data/LICENSE +4 -1
  13. data/README.md +94 -26
  14. data/RELEASING.md +31 -7
  15. data/Rakefile +2 -2
  16. data/SECURITY.md +1 -1
  17. data/THEMEKIT_MIGRATION.md +18 -0
  18. data/bin/load_shopify.rb +1 -1
  19. data/bin/shopify +3 -3
  20. data/dev.yml +1 -1
  21. data/docs/app/node/index.md +1 -1
  22. data/docs/app/rails/index.md +1 -1
  23. data/docs/core/index.md +1 -1
  24. data/docs/getting-started/index.md +1 -1
  25. data/docs/getting-started/install/index.md +1 -1
  26. data/docs/getting-started/migrate/index.md +1 -1
  27. data/docs/getting-started/uninstall/index.md +1 -1
  28. data/docs/getting-started/upgrade/index.md +1 -1
  29. data/docs/help/start-app/index.md +1 -1
  30. data/docs/index.md +1 -1
  31. data/ext/shopify-cli/extconf.rb +17 -5
  32. data/install.sh +1 -1
  33. data/lib/docgen/index_template.md.erb +2 -2
  34. data/lib/graphql/all_orgs_with_extensions.graphql +37 -0
  35. data/lib/graphql/api_versions.graphql +1 -1
  36. data/lib/graphql/find_organization.graphql +2 -1
  37. data/lib/project_types/extension/cli.rb +19 -15
  38. data/lib/project_types/extension/commands/build.rb +4 -5
  39. data/lib/project_types/extension/commands/check.rb +44 -0
  40. data/lib/project_types/extension/commands/connect.rb +35 -0
  41. data/lib/project_types/extension/commands/create.rb +12 -16
  42. data/lib/project_types/extension/commands/extension_command.rb +2 -2
  43. data/lib/project_types/extension/commands/info.rb +86 -0
  44. data/lib/project_types/extension/commands/push.rb +8 -7
  45. data/lib/project_types/extension/commands/register.rb +4 -5
  46. data/lib/project_types/extension/commands/serve.rb +5 -8
  47. data/lib/project_types/extension/commands/tunnel.rb +3 -1
  48. data/lib/project_types/extension/errors.rb +9 -0
  49. data/lib/project_types/extension/extension_project.rb +24 -1
  50. data/lib/project_types/extension/extension_project_keys.rb +1 -0
  51. data/lib/project_types/extension/features/argo.rb +6 -6
  52. data/lib/project_types/extension/features/argo_runtime.rb +22 -66
  53. data/lib/project_types/extension/features/argo_serve.rb +25 -18
  54. data/lib/project_types/extension/forms/connect.rb +42 -0
  55. data/lib/project_types/extension/forms/questions/ask_name.rb +14 -6
  56. data/lib/project_types/extension/forms/questions/ask_registration.rb +51 -0
  57. data/lib/project_types/extension/messages/messages.rb +84 -16
  58. data/lib/project_types/extension/models/specification.rb +1 -0
  59. data/lib/project_types/extension/models/specification_handlers/{checkout_argo_extension.rb → checkout_ui_extension.rb} +3 -1
  60. data/lib/project_types/extension/models/specification_handlers/default.rb +13 -3
  61. data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +89 -0
  62. data/lib/project_types/extension/models/specifications.rb +1 -0
  63. data/lib/project_types/extension/tasks/configure_features.rb +6 -7
  64. data/lib/project_types/extension/tasks/configure_options.rb +20 -0
  65. data/lib/project_types/extension/tasks/get_extensions.rb +32 -0
  66. data/lib/project_types/node/cli.rb +9 -21
  67. data/lib/project_types/node/commands/connect.rb +8 -2
  68. data/lib/project_types/node/commands/create.rb +9 -5
  69. data/lib/project_types/node/commands/deploy.rb +15 -5
  70. data/lib/project_types/node/commands/deploy/heroku.rb +29 -29
  71. data/lib/project_types/node/commands/generate.rb +4 -2
  72. data/lib/project_types/node/commands/open.rb +4 -2
  73. data/lib/project_types/node/commands/serve.rb +3 -2
  74. data/lib/project_types/node/commands/tunnel.rb +4 -2
  75. data/lib/project_types/node/messages/messages.rb +47 -90
  76. data/lib/project_types/rails/cli.rb +9 -21
  77. data/lib/project_types/rails/commands/connect.rb +8 -2
  78. data/lib/project_types/rails/commands/create.rb +10 -6
  79. data/lib/project_types/rails/commands/deploy.rb +15 -5
  80. data/lib/project_types/rails/commands/deploy/heroku.rb +84 -82
  81. data/lib/project_types/rails/commands/generate.rb +15 -5
  82. data/lib/project_types/rails/commands/generate/webhook.rb +28 -26
  83. data/lib/project_types/rails/commands/open.rb +4 -2
  84. data/lib/project_types/rails/commands/serve.rb +3 -2
  85. data/lib/project_types/rails/commands/tunnel.rb +4 -2
  86. data/lib/project_types/rails/messages/messages.rb +72 -119
  87. data/lib/project_types/script/cli.rb +6 -8
  88. data/lib/project_types/script/commands/create.rb +3 -1
  89. data/lib/project_types/script/commands/push.rb +7 -4
  90. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +9 -3
  91. data/lib/project_types/script/layers/application/create_script.rb +4 -3
  92. data/lib/project_types/script/layers/domain/errors.rb +6 -11
  93. data/lib/project_types/script/layers/domain/push_package.rb +4 -8
  94. data/lib/project_types/script/layers/domain/script_json.rb +32 -0
  95. data/lib/project_types/script/layers/domain/script_project.rb +1 -1
  96. data/lib/project_types/script/layers/infrastructure/errors.rb +13 -17
  97. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +29 -21
  98. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +2 -4
  99. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +45 -34
  100. data/lib/project_types/script/layers/infrastructure/script_service.rb +37 -16
  101. data/lib/project_types/script/messages/messages.rb +64 -54
  102. data/lib/project_types/script/tasks/ensure_env.rb +3 -1
  103. data/lib/project_types/script/ui/error_handler.rb +32 -32
  104. data/lib/project_types/theme/cli.rb +16 -27
  105. data/lib/project_types/theme/commands/check.rb +33 -0
  106. data/lib/project_types/theme/commands/delete.rb +64 -0
  107. data/lib/project_types/theme/commands/init.rb +42 -0
  108. data/lib/project_types/theme/commands/language_server.rb +16 -0
  109. data/lib/project_types/theme/commands/package.rb +55 -0
  110. data/lib/project_types/theme/commands/publish.rb +43 -0
  111. data/lib/project_types/theme/commands/pull.rb +51 -0
  112. data/lib/project_types/theme/commands/push.rb +58 -32
  113. data/lib/project_types/theme/commands/serve.rb +8 -16
  114. data/lib/project_types/theme/forms/confirm_store.rb +15 -0
  115. data/lib/project_types/theme/forms/select.rb +59 -0
  116. data/lib/project_types/theme/messages/messages.rb +118 -103
  117. data/lib/project_types/theme/ui/sync_progress_bar.rb +20 -0
  118. data/lib/shopify-cli/admin_api.rb +57 -38
  119. data/lib/shopify-cli/admin_api/populate_resource_command.rb +6 -14
  120. data/lib/shopify-cli/admin_api/schema.rb +1 -10
  121. data/lib/shopify-cli/api.rb +29 -14
  122. data/lib/shopify-cli/command.rb +15 -3
  123. data/lib/shopify-cli/commands.rb +7 -2
  124. data/lib/shopify-cli/commands/help.rb +2 -29
  125. data/lib/shopify-cli/commands/login.rb +95 -0
  126. data/lib/shopify-cli/commands/logout.rb +24 -8
  127. data/lib/shopify-cli/commands/populate.rb +23 -0
  128. data/lib/{project_types/node → shopify-cli}/commands/populate/customer.rb +2 -8
  129. data/lib/{project_types/node → shopify-cli}/commands/populate/draft_order.rb +2 -2
  130. data/lib/{project_types/node → shopify-cli}/commands/populate/product.rb +2 -8
  131. data/lib/shopify-cli/commands/store.rb +15 -0
  132. data/lib/shopify-cli/commands/switch.rb +39 -0
  133. data/lib/shopify-cli/commands/system.rb +12 -0
  134. data/lib/shopify-cli/commands/whoami.rb +28 -0
  135. data/lib/shopify-cli/connect.rb +32 -0
  136. data/lib/shopify-cli/context.rb +65 -4
  137. data/lib/shopify-cli/core/entry_point.rb +3 -22
  138. data/lib/shopify-cli/core/monorail.rb +6 -2
  139. data/lib/shopify-cli/db.rb +4 -4
  140. data/lib/shopify-cli/http_request.rb +16 -0
  141. data/lib/shopify-cli/identity_auth.rb +282 -0
  142. data/lib/shopify-cli/{oauth → identity_auth}/servlet.rb +11 -12
  143. data/lib/shopify-cli/messages/messages.rb +140 -46
  144. data/lib/shopify-cli/packager.rb +5 -5
  145. data/lib/shopify-cli/partners_api.rb +21 -44
  146. data/lib/shopify-cli/partners_api/organizations.rb +8 -0
  147. data/lib/shopify-cli/project_commands.rb +16 -0
  148. data/lib/shopify-cli/project_type.rb +0 -31
  149. data/lib/shopify-cli/shopifolk.rb +8 -11
  150. data/lib/shopify-cli/sub_command.rb +1 -0
  151. data/lib/shopify-cli/tasks.rb +3 -0
  152. data/lib/shopify-cli/tasks/confirm_store.rb +18 -0
  153. data/lib/shopify-cli/tasks/create_api_client.rb +2 -2
  154. data/lib/shopify-cli/tasks/ensure_authenticated.rb +13 -0
  155. data/lib/shopify-cli/tasks/ensure_loopback_url.rb +1 -1
  156. data/lib/shopify-cli/tasks/ensure_project_type.rb +12 -0
  157. data/lib/shopify-cli/tasks/select_org_and_shop.rb +0 -3
  158. data/lib/shopify-cli/theme/dev_server.rb +98 -0
  159. data/lib/shopify-cli/theme/dev_server/certificate_manager.rb +79 -0
  160. data/lib/shopify-cli/theme/dev_server/header_hash.rb +94 -0
  161. data/lib/shopify-cli/theme/dev_server/hot-reload.js +93 -0
  162. data/lib/shopify-cli/theme/dev_server/hot_reload.rb +76 -0
  163. data/lib/shopify-cli/theme/dev_server/local_assets.rb +87 -0
  164. data/lib/shopify-cli/theme/dev_server/proxy.rb +205 -0
  165. data/lib/shopify-cli/theme/dev_server/sse.rb +75 -0
  166. data/lib/shopify-cli/theme/dev_server/watcher.rb +59 -0
  167. data/lib/shopify-cli/theme/dev_server/web_server.rb +140 -0
  168. data/lib/shopify-cli/theme/development_theme.rb +69 -0
  169. data/lib/shopify-cli/theme/file.rb +112 -0
  170. data/lib/shopify-cli/theme/ignore_filter.rb +109 -0
  171. data/lib/shopify-cli/theme/mime_type.rb +34 -0
  172. data/lib/shopify-cli/theme/syncer.rb +332 -0
  173. data/lib/shopify-cli/theme/theme.rb +204 -0
  174. data/lib/shopify-cli/tunnel.rb +1 -1
  175. data/lib/shopify-cli/version.rb +1 -1
  176. data/lib/shopify_cli.rb +18 -11
  177. data/shopify-cli.gemspec +12 -5
  178. data/shopify.fish +1 -1
  179. data/shopify.sh +1 -1
  180. metadata +92 -35
  181. data/.github/workflows/release.yml +0 -59
  182. data/lib/project_types/extension/features/argo_serve_options.rb +0 -42
  183. data/lib/project_types/node/commands/populate.rb +0 -23
  184. data/lib/project_types/rails/commands/populate.rb +0 -23
  185. data/lib/project_types/rails/commands/populate/customer.rb +0 -31
  186. data/lib/project_types/rails/commands/populate/draft_order.rb +0 -28
  187. data/lib/project_types/rails/commands/populate/product.rb +0 -30
  188. data/lib/project_types/script/layers/domain/config_ui.rb +0 -16
  189. data/lib/project_types/theme/commands/connect.rb +0 -54
  190. data/lib/project_types/theme/commands/create.rb +0 -48
  191. data/lib/project_types/theme/commands/deploy.rb +0 -38
  192. data/lib/project_types/theme/commands/generate.rb +0 -20
  193. data/lib/project_types/theme/commands/generate/env.rb +0 -79
  194. data/lib/project_types/theme/forms/connect.rb +0 -34
  195. data/lib/project_types/theme/forms/create.rb +0 -22
  196. data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +0 -78
  197. data/lib/project_types/theme/themekit.rb +0 -113
  198. data/lib/shopify-cli/commands/connect.rb +0 -64
  199. data/lib/shopify-cli/commands/create.rb +0 -50
  200. data/lib/shopify-cli/oauth.rb +0 -198
@@ -17,6 +17,7 @@ module Extension
17
17
 
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
+ next if feature_attributes.nil?
20
21
  feature_set[identifier] = ShopifyCli::ResolveConstant
21
22
  .call(identifier, namespace: Features)
22
23
  .rescue { OpenStruct }
@@ -3,7 +3,7 @@
3
3
  module Extension
4
4
  module Models
5
5
  module SpecificationHandlers
6
- class CheckoutArgoExtension < Default
6
+ class CheckoutUiExtension < Default
7
7
  PERMITTED_CONFIG_KEYS = [:metafields, :extension_points]
8
8
 
9
9
  def config(context)
@@ -13,6 +13,8 @@ module Extension
13
13
  }
14
14
  end
15
15
  end
16
+
17
+ CheckoutArgoExtension = CheckoutUiExtension
16
18
  end
17
19
  end
18
20
  end
@@ -30,7 +30,7 @@ module Extension
30
30
  argo.config(context)
31
31
  end
32
32
 
33
- def create(directory_name, context)
33
+ def create(directory_name, context, **_args)
34
34
  argo.create(directory_name, identifier, context)
35
35
  end
36
36
 
@@ -43,11 +43,11 @@ module Extension
43
43
  end
44
44
 
45
45
  def choose_port?(context)
46
- argo_runtime(context).accepts_port?
46
+ argo_runtime(context).supports?(:port)
47
47
  end
48
48
 
49
49
  def establish_tunnel?(context)
50
- argo_runtime(context).accepts_tunnel_url?
50
+ argo_runtime(context).supports?(:public_url)
51
51
  end
52
52
 
53
53
  def serve(context:, port:, tunnel_url:)
@@ -80,6 +80,16 @@ module Extension
80
80
  .unwrap { |_e| context.abort(context.message("errors.package_not_found", cli_package_name)) }
81
81
  end
82
82
 
83
+ def message_for_extension(key, *params)
84
+ override_key = "overrides.#{key}"
85
+ key_parts = override_key.split(".").map(&:to_sym)
86
+ if (str = messages.dig(*key_parts))
87
+ str % params
88
+ else
89
+ ShopifyCli::Context.message(key, *params)
90
+ end
91
+ end
92
+
83
93
  protected
84
94
 
85
95
  def argo
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+ require "base64"
3
+ require "json"
4
+
5
+ module Extension
6
+ module Models
7
+ module SpecificationHandlers
8
+ class ThemeAppExtension < Default
9
+ SUPPORTED_BUCKETS = %w(assets blocks snippets)
10
+ BUNDLE_SIZE_LIMIT = 10 * 1024 * 1024 # 10MB
11
+ LIQUID_SIZE_LIMIT = 100 * 1024 # 100kb
12
+ SUPPORTED_ASSET_EXTS = %w(.jpg .js .css .png .svg)
13
+
14
+ def create(directory_name, context, getting_started: false)
15
+ context.root = File.join(context.root, directory_name)
16
+
17
+ if getting_started
18
+ ShopifyCli::Git.clone("https://github.com/Shopify/theme-extension-getting-started", context.root)
19
+ context.rm_r(".git")
20
+ else
21
+ FileUtils.makedirs(SUPPORTED_BUCKETS.map { |b| File.join(context.root, b) })
22
+ end
23
+ end
24
+
25
+ def config(context)
26
+ current_size = 0
27
+ current_liquid_size = 0
28
+ Dir.chdir(context.root) do
29
+ Dir["**/*"].select { |filename| File.file?(filename) && validate(filename) }
30
+ .map do |filename|
31
+ dirname = File.dirname(filename)
32
+ if dirname == "assets"
33
+ # Assets should be read as binary data, since they could be images
34
+ mode = "rb"
35
+ encoding = "BINARY"
36
+ else
37
+ # Other assets should be treated as UTF-8 encoded text
38
+ mode = "rt"
39
+ encoding = "UTF-8"
40
+ current_liquid_size += File.size(filename)
41
+ end
42
+ current_size += File.size(filename)
43
+ if current_size > BUNDLE_SIZE_LIMIT
44
+ raise Extension::Errors::BundleTooLargeError,
45
+ "Total size of all files must be less than #{CLI::Kit::Util.to_filesize(BUNDLE_SIZE_LIMIT)}"
46
+ end
47
+ if current_liquid_size > LIQUID_SIZE_LIMIT
48
+ raise Extension::Errors::BundleTooLargeError,
49
+ "Total size of all liquid must be less than #{CLI::Kit::Util.to_filesize(LIQUID_SIZE_LIMIT)}"
50
+ end
51
+ [filename, Base64.encode64(File.read(filename, mode: mode, encoding: encoding))]
52
+ end
53
+ .yield_self do |encoded_files_by_name|
54
+ { "theme_extension" => { "files" => encoded_files_by_name.to_h } }
55
+ end
56
+ end
57
+ end
58
+
59
+ def name
60
+ "Theme App Extension"
61
+ end
62
+
63
+ private
64
+
65
+ def validate(filename)
66
+ dirname = File.dirname(filename)
67
+ # Skip files in the root of the directory tree
68
+ return false if dirname == "."
69
+
70
+ unless SUPPORTED_BUCKETS.include?(dirname)
71
+ raise Extension::Errors::InvalidFilenameError, "Invalid directory: #{dirname}"
72
+ end
73
+
74
+ ext = File.extname(filename)
75
+ if dirname == "assets"
76
+ unless SUPPORTED_ASSET_EXTS.include?(ext)
77
+ raise Extension::Errors::InvalidFilenameError,
78
+ "Invalid filename: #{filename}; #{ext} is not supported"
79
+ end
80
+ elsif ext != ".liquid"
81
+ raise Extension::Errors::InvalidFilenameError,
82
+ "Invalid filename: #{filename}; Only .liquid allowed in #{dirname}"
83
+ end
84
+ true
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -44,6 +44,7 @@ module Extension
44
44
  .map(&ShopifyCli::TransformDataStructure.new(symbolize_keys: true, underscore_keys: true))
45
45
  .then(&method(:select_cli_extensions))
46
46
  .then(&Tasks::ConfigureFeatures)
47
+ .then(&Tasks::ConfigureOptions)
47
48
  .then(&method(:ensure_legacy_compatibility))
48
49
  .then(&method(:build_specifications))
49
50
  .then(&method(:require_handler_implementations))
@@ -38,16 +38,15 @@ module Extension
38
38
  def surface_area_configurations
39
39
  {
40
40
  admin: {
41
- git_template: "https://github.com/Shopify/argo-admin-template.git",
42
- renderer_package_name: "@shopify/argo-admin",
41
+ git_template: "https://github.com/Shopify/admin-ui-extensions-template",
42
+ renderer_package_name: "@shopify/admin-ui-extensions",
43
43
  required_fields: [:shop, :api_key],
44
- required_shop_beta_flags: [:argo_admin_beta],
45
- cli_package_name: "@shopify/argo-admin-cli",
44
+ cli_package_name: "@shopify/admin-ui-extensions-run",
46
45
  },
47
46
  checkout: {
48
- git_template: "https://github.com/Shopify/argo-checkout-template.git",
49
- renderer_package_name: "@shopify/argo-checkout",
50
- cli_package_name: "@shopify/argo-run",
47
+ git_template: "https://github.com/Shopify/checkout-ui-extensions-template",
48
+ renderer_package_name: "@shopify/checkout-ui-extensions",
49
+ cli_package_name: "@shopify/checkout-ui-extensions-run",
51
50
  },
52
51
  }
53
52
  end
@@ -0,0 +1,20 @@
1
+ module Extension
2
+ module Tasks
3
+ class ConfigureOptions
4
+ include ShopifyCli::MethodObject
5
+
6
+ def call(specification_attribute_sets)
7
+ specification_attribute_sets.each do |attributes|
8
+ attributes[:options] ||= {}
9
+ configure_skip_build(attributes)
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def configure_skip_build(attributes)
16
+ attributes[:options].merge!(skip_build: attributes[:identifier] == "theme_app_extension")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Tasks
6
+ class GetExtensions < ShopifyCli::Task
7
+ def call(context:, type:)
8
+ organizations = ShopifyCli::PartnersAPI::Organizations.fetch_with_extensions(context, type)
9
+ extensions_from_organizations(organizations, context: context)
10
+ end
11
+
12
+ private
13
+
14
+ def extensions_from_organizations(organizations, context:)
15
+ organizations.flat_map do |organization|
16
+ extensions_owned_by_organization(organization, context: context)
17
+ end
18
+ end
19
+
20
+ def extensions_owned_by_organization(organization, context:)
21
+ return [] unless organization.key?("apps") && organization["apps"].any?
22
+
23
+ organization["apps"].flat_map do |app|
24
+ app["extensionRegistrations"].map do |registration|
25
+ [Converters::AppConverter.from_hash(app, organization),
26
+ Converters::RegistrationConverter.from_hash(context, registration)]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,33 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
  module Node
3
3
  class Project < ShopifyCli::ProjectType
4
- title("Node.js App")
5
- creator("Node::Commands::Create")
6
- connector("Node::Commands::Connect")
7
-
8
- register_command("Node::Commands::Deploy", "deploy")
9
- register_command("Node::Commands::Generate", "generate")
10
- register_command("Node::Commands::Open", "open")
11
- register_command("Node::Commands::Populate", "populate")
12
- register_command("Node::Commands::Serve", "serve")
13
- register_command("Node::Commands::Tunnel", "tunnel")
14
- # register_task('Node::Tasks::NodeTask', 'node_task')
15
-
16
4
  require Project.project_filepath("messages/messages")
17
5
  register_messages(Node::Messages::MESSAGES)
18
6
  end
19
7
 
20
8
  # define/autoload project specific Commands
21
- module Commands
22
- autoload :Connect, Project.project_filepath("commands/connect")
23
- autoload :Create, Project.project_filepath("commands/create")
24
- autoload :Deploy, Project.project_filepath("commands/deploy")
25
- autoload :Generate, Project.project_filepath("commands/generate")
26
- autoload :Open, Project.project_filepath("commands/open")
27
- autoload :Populate, Project.project_filepath("commands/populate")
28
- autoload :Serve, Project.project_filepath("commands/serve")
29
- autoload :Tunnel, Project.project_filepath("commands/tunnel")
9
+ class Command < ShopifyCli::ProjectCommands
10
+ subcommand :Connect, "connect", Project.project_filepath("commands/connect")
11
+ subcommand :Create, "create", Project.project_filepath("commands/create")
12
+ subcommand :Deploy, "deploy", Project.project_filepath("commands/deploy")
13
+ subcommand :Generate, "generate", Project.project_filepath("commands/generate")
14
+ subcommand :Open, "open", Project.project_filepath("commands/open")
15
+ subcommand :Serve, "serve", Project.project_filepath("commands/serve")
16
+ subcommand :Tunnel, "tunnel", Project.project_filepath("commands/tunnel")
30
17
  end
18
+ ShopifyCli::Commands.register("Node::Command", "node")
31
19
 
32
20
  # define/autoload project specific Tasks
33
21
  module Tasks
@@ -1,15 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
  module Node
3
- module Commands
3
+ class Command
4
4
  class Connect < ShopifyCli::SubCommand
5
+ prerequisite_task ensure_project_type: :node
6
+
5
7
  def call(*)
6
8
  if ShopifyCli::Project.has_current? && ShopifyCli::Project.current.env
7
9
  @ctx.puts(@ctx.message("node.connect.production_warning"))
8
10
  end
9
11
 
10
- app = ShopifyCli::Commands::Connect.new.default_connect("node")
12
+ app = ShopifyCli::Connect.new(@ctx).default_connect("node")
11
13
  @ctx.done(@ctx.message("node.connect.connected", app))
12
14
  end
15
+
16
+ def self.help
17
+ ShopifyCli::Context.message("node.connect.help", ShopifyCli::TOOL_NAME, ShopifyCli::TOOL_NAME)
18
+ end
13
19
  end
14
20
  end
15
21
  end
@@ -1,16 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
  module Node
3
- module Commands
3
+ class Command
4
4
  class Create < ShopifyCli::SubCommand
5
+ prerequisite_task :ensure_authenticated
6
+
5
7
  options do |parser, flags|
6
8
  # backwards compatibility allow 'title' for now
7
9
  parser.on("--title=TITLE") { |t| flags[:title] = t }
8
10
  parser.on("--name=NAME") { |t| flags[:title] = t }
9
- parser.on("--organization_id=ID") { |url| flags[:organization_id] = url }
10
- parser.on("--organization-id=ID") { |url| flags[:organization_id] = url }
11
+ parser.on("--organization_id=ID") { |id| flags[:organization_id] = id }
12
+ parser.on("--organization-id=ID") { |id| flags[:organization_id] = id }
13
+ parser.on("--store=MYSHOPIFYDOMAIN") { |url| flags[:shop_domain] = url }
14
+ # backwards compatibility allow 'shop domain' for now
11
15
  parser.on("--shop_domain=MYSHOPIFYDOMAIN") { |url| flags[:shop_domain] = url }
12
16
  parser.on("--shop-domain=MYSHOPIFYDOMAIN") { |url| flags[:shop_domain] = url }
13
- parser.on("--type=APPTYPE") { |url| flags[:type] = url }
17
+ parser.on("--type=APPTYPE") { |type| flags[:type] = type }
14
18
  parser.on("--verbose") { flags[:verbose] = true }
15
19
  end
16
20
 
@@ -45,7 +49,7 @@ module Node
45
49
  partners_url = ShopifyCli::PartnersAPI.partners_url_for(form.organization_id, api_client["id"], local_debug?)
46
50
 
47
51
  @ctx.puts(@ctx.message("apps.create.info.created", form.title, partners_url))
48
- @ctx.puts(@ctx.message("apps.create.info.serve", form.name, ShopifyCli::TOOL_NAME))
52
+ @ctx.puts(@ctx.message("apps.create.info.serve", form.name, ShopifyCli::TOOL_NAME, "node"))
49
53
  unless ShopifyCli::Shopifolk.acting_as_shopify_organization?
50
54
  @ctx.puts(@ctx.message("apps.create.info.install", partners_url, form.title))
51
55
  end
@@ -2,12 +2,22 @@
2
2
  require "shopify_cli"
3
3
 
4
4
  module Node
5
- module Commands
6
- class Deploy < ShopifyCli::Command
7
- subcommand :Heroku, "heroku", Project.project_filepath("commands/deploy/heroku")
5
+ class Command
6
+ class Deploy < ShopifyCli::SubCommand
7
+ prerequisite_task ensure_project_type: :node
8
8
 
9
- def call(*)
10
- @ctx.puts(self.class.help)
9
+ autoload :Heroku, Project.project_filepath("commands/deploy/heroku")
10
+
11
+ HEROKU = "heroku"
12
+
13
+ def call(args, _name)
14
+ subcommand = args.shift
15
+ case subcommand
16
+ when HEROKU
17
+ Node::Command::Deploy::Heroku.start(@ctx)
18
+ else
19
+ @ctx.puts(self.class.help)
20
+ end
11
21
  end
12
22
 
13
23
  def self.help
@@ -2,81 +2,81 @@
2
2
  require "shopify_cli"
3
3
 
4
4
  module Node
5
- module Commands
5
+ class Command
6
6
  class Deploy
7
- class Heroku < ShopifyCli::SubCommand
7
+ class Heroku
8
8
  def self.help
9
9
  ShopifyCli::Context.message("node.deploy.heroku.help", ShopifyCli::TOOL_NAME)
10
10
  end
11
11
 
12
- def call(*)
12
+ def self.start(ctx)
13
13
  spin_group = CLI::UI::SpinGroup.new
14
- heroku_service = ShopifyCli::Heroku.new(@ctx)
14
+ heroku_service = ShopifyCli::Heroku.new(ctx)
15
15
 
16
- spin_group.add(@ctx.message("node.deploy.heroku.downloading")) do |spinner|
16
+ spin_group.add(ctx.message("node.deploy.heroku.downloading")) do |spinner|
17
17
  heroku_service.download
18
- spinner.update_title(@ctx.message("node.deploy.heroku.downloaded"))
18
+ spinner.update_title(ctx.message("node.deploy.heroku.downloaded"))
19
19
  end
20
20
  spin_group.wait
21
21
 
22
- install_message = @ctx.message(
23
- @ctx.windows? ? "node.deploy.heroku.installing_windows" : "node.deploy.heroku.installing"
22
+ install_message = ctx.message(
23
+ ctx.windows? ? "node.deploy.heroku.installing_windows" : "node.deploy.heroku.installing"
24
24
  )
25
25
  spin_group.add(install_message) do |spinner|
26
26
  heroku_service.install
27
- spinner.update_title(@ctx.message("node.deploy.heroku.installed"))
27
+ spinner.update_title(ctx.message("node.deploy.heroku.installed"))
28
28
  end
29
29
  spin_group.wait
30
30
 
31
- spin_group.add(@ctx.message("node.deploy.heroku.git.checking")) do |spinner|
32
- ShopifyCli::Git.init(@ctx)
33
- spinner.update_title(@ctx.message("node.deploy.heroku.git.initialized"))
31
+ spin_group.add(ctx.message("node.deploy.heroku.git.checking")) do |spinner|
32
+ ShopifyCli::Git.init(ctx)
33
+ spinner.update_title(ctx.message("node.deploy.heroku.git.initialized"))
34
34
  end
35
35
  spin_group.wait
36
36
 
37
37
  if (account = heroku_service.whoami)
38
- @ctx.puts(@ctx.message("node.deploy.heroku.authenticated_with_account", account))
38
+ ctx.puts(ctx.message("node.deploy.heroku.authenticated_with_account", account))
39
39
  else
40
40
  CLI::UI::Frame.open(
41
- @ctx.message("node.deploy.heroku.authenticating"),
42
- success_text: @ctx.message("node.deploy.heroku.authenticated")
41
+ ctx.message("node.deploy.heroku.authenticating"),
42
+ success_text: ctx.message("node.deploy.heroku.authenticated")
43
43
  ) do
44
44
  heroku_service.authenticate
45
45
  end
46
46
  end
47
47
 
48
48
  if (app_name = heroku_service.app)
49
- @ctx.puts(@ctx.message("node.deploy.heroku.app.selected", app_name))
49
+ ctx.puts(ctx.message("node.deploy.heroku.app.selected", app_name))
50
50
  else
51
- app_type = CLI::UI::Prompt.ask(@ctx.message("node.deploy.heroku.app.no_apps_found")) do |handler|
52
- handler.option(@ctx.message("node.deploy.heroku.app.create")) { :new }
53
- handler.option(@ctx.message("node.deploy.heroku.app.select")) { :existing }
51
+ app_type = CLI::UI::Prompt.ask(ctx.message("node.deploy.heroku.app.no_apps_found")) do |handler|
52
+ handler.option(ctx.message("node.deploy.heroku.app.create")) { :new }
53
+ handler.option(ctx.message("node.deploy.heroku.app.select")) { :existing }
54
54
  end
55
55
 
56
56
  if app_type == :existing
57
- app_name = CLI::UI::Prompt.ask(@ctx.message("node.deploy.heroku.app.name"))
57
+ app_name = CLI::UI::Prompt.ask(ctx.message("node.deploy.heroku.app.name"))
58
58
  CLI::UI::Frame.open(
59
- @ctx.message("node.deploy.heroku.app.selecting", app_name),
60
- success_text: @ctx.message("node.deploy.heroku.app.selected", app_name)
59
+ ctx.message("node.deploy.heroku.app.selecting", app_name),
60
+ success_text: ctx.message("node.deploy.heroku.app.selected", app_name)
61
61
  ) do
62
62
  heroku_service.select_existing_app(app_name)
63
63
  end
64
64
  elsif app_type == :new
65
65
  CLI::UI::Frame.open(
66
- @ctx.message("node.deploy.heroku.app.creating"),
67
- success_text: @ctx.message("node.deploy.heroku.app.created")
66
+ ctx.message("node.deploy.heroku.app.creating"),
67
+ success_text: ctx.message("node.deploy.heroku.app.created")
68
68
  ) do
69
69
  heroku_service.create_new_app
70
70
  end
71
71
  end
72
72
  end
73
73
 
74
- branches = ShopifyCli::Git.branches(@ctx)
74
+ branches = ShopifyCli::Git.branches(ctx)
75
75
  if branches.length == 1
76
76
  branch_to_deploy = branches[0]
77
- @ctx.puts(@ctx.message("node.deploy.heroku.git.branch_selected", branch_to_deploy))
77
+ ctx.puts(ctx.message("node.deploy.heroku.git.branch_selected", branch_to_deploy))
78
78
  else
79
- branch_to_deploy = CLI::UI::Prompt.ask(@ctx.message("node.deploy.heroku.git.what_branch")) do |handler|
79
+ branch_to_deploy = CLI::UI::Prompt.ask(ctx.message("node.deploy.heroku.git.what_branch")) do |handler|
80
80
  branches.each do |branch|
81
81
  handler.option(branch) { branch }
82
82
  end
@@ -84,8 +84,8 @@ module Node
84
84
  end
85
85
 
86
86
  CLI::UI::Frame.open(
87
- @ctx.message("node.deploy.heroku.deploying"),
88
- success_text: @ctx.message("node.deploy.heroku.deployed")
87
+ ctx.message("node.deploy.heroku.deploying"),
88
+ success_text: ctx.message("node.deploy.heroku.deployed")
89
89
  ) do
90
90
  heroku_service.deploy(branch_to_deploy)
91
91
  end