shopify-cli 0.9.1 → 1.0.2

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +3 -0
  3. data/CHANGELOG.md +24 -2
  4. data/RELEASING.md +4 -4
  5. data/docs/_config.yml +3 -0
  6. data/docs/_data/nav.yml +9 -0
  7. data/docs/getting-started/index.md +5 -40
  8. data/docs/getting-started/install/index.md +75 -0
  9. data/docs/getting-started/migrate/index.md +96 -0
  10. data/docs/getting-started/uninstall/index.md +37 -0
  11. data/docs/getting-started/upgrade/index.md +37 -0
  12. data/docs/index.md +5 -6
  13. data/lib/project_types/extension/cli.rb +2 -1
  14. data/lib/project_types/extension/commands/tunnel.rb +1 -1
  15. data/lib/project_types/extension/forms/register.rb +2 -3
  16. data/lib/project_types/extension/graphql/get_app_by_api_key.graphql +9 -0
  17. data/lib/project_types/extension/tasks/converters/app_converter.rb +27 -0
  18. data/lib/project_types/extension/tasks/get_app.rb +22 -0
  19. data/lib/project_types/extension/tasks/get_apps.rb +1 -6
  20. data/lib/project_types/node/forms/create.rb +3 -54
  21. data/lib/project_types/node/messages/messages.rb +3 -14
  22. data/lib/project_types/rails/forms/create.rb +3 -52
  23. data/lib/project_types/rails/messages/messages.rb +2 -13
  24. data/lib/project_types/script/cli.rb +5 -5
  25. data/lib/project_types/script/commands/create.rb +5 -4
  26. data/lib/project_types/script/commands/push.rb +1 -0
  27. data/lib/project_types/script/config/extension_points.yml +3 -3
  28. data/lib/project_types/script/errors.rb +1 -0
  29. data/lib/project_types/script/forms/create.rb +8 -4
  30. data/lib/project_types/script/layers/application/build_script.rb +7 -10
  31. data/lib/project_types/script/layers/application/create_script.rb +16 -14
  32. data/lib/project_types/script/layers/application/project_dependencies.rb +3 -9
  33. data/lib/project_types/script/layers/application/push_script.rb +13 -11
  34. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +106 -0
  35. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +64 -0
  36. data/lib/project_types/script/layers/infrastructure/errors.rb +2 -2
  37. data/lib/project_types/script/layers/infrastructure/project_creator.rb +23 -0
  38. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +6 -3
  39. data/lib/project_types/script/layers/infrastructure/script_repository.rb +8 -38
  40. data/lib/project_types/script/layers/infrastructure/task_runner.rb +18 -0
  41. data/lib/project_types/script/messages/messages.rb +5 -6
  42. data/lib/project_types/script/script_project.rb +22 -9
  43. data/lib/project_types/script/templates/ts/as-pect.d.ts +1 -0
  44. data/lib/project_types/script/ui/error_handler.rb +5 -0
  45. data/lib/shopify-cli/admin_api.rb +1 -2
  46. data/lib/shopify-cli/admin_api/populate_resource_command.rb +10 -1
  47. data/lib/shopify-cli/admin_api/schema.rb +11 -1
  48. data/lib/shopify-cli/api.rb +2 -0
  49. data/lib/shopify-cli/context.rb +60 -0
  50. data/lib/shopify-cli/core/entry_point.rb +6 -0
  51. data/lib/shopify-cli/core/finalize.rb +13 -0
  52. data/lib/shopify-cli/git.rb +14 -10
  53. data/lib/shopify-cli/messages/messages.rb +22 -2
  54. data/lib/shopify-cli/tasks.rb +1 -0
  55. data/lib/shopify-cli/tasks/select_org_and_shop.rb +77 -0
  56. data/lib/shopify-cli/tunnel.rb +33 -1
  57. data/lib/shopify-cli/version.rb +1 -1
  58. data/vendor/deps/cli-ui/REVISION +1 -1
  59. data/vendor/deps/cli-ui/lib/cli/ui.rb +52 -11
  60. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +11 -7
  61. data/vendor/deps/cli-ui/lib/cli/ui/formatter.rb +34 -21
  62. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +107 -149
  63. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_stack.rb +99 -0
  64. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +119 -0
  65. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +158 -0
  66. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +112 -0
  67. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +9 -15
  68. data/vendor/deps/cli-ui/lib/cli/ui/printer.rb +47 -0
  69. data/vendor/deps/cli-ui/lib/cli/ui/progress.rb +9 -7
  70. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +39 -14
  71. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +62 -44
  72. data/vendor/deps/cli-ui/lib/cli/ui/prompt/options_handler.rb +7 -2
  73. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +23 -3
  74. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +34 -10
  75. data/vendor/deps/cli-ui/lib/cli/ui/stdout_router.rb +12 -7
  76. data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +26 -16
  77. data/vendor/deps/cli-ui/lib/cli/ui/truncater.rb +3 -3
  78. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +75 -0
  79. data/vendor/deps/cli-ui/lib/cli/ui/widgets/base.rb +27 -0
  80. data/vendor/deps/cli-ui/lib/cli/ui/widgets/status.rb +61 -0
  81. metadata +24 -9
  82. data/lib/project_types/extension/features/tunnel_url.rb +0 -20
  83. data/lib/project_types/script/layers/infrastructure/assemblyscript_dependency_manager.rb +0 -73
  84. data/lib/project_types/script/layers/infrastructure/assemblyscript_wasm_builder.rb +0 -39
  85. data/lib/project_types/script/layers/infrastructure/dependency_manager.rb +0 -36
  86. data/lib/project_types/script/layers/infrastructure/script_builder.rb +0 -34
  87. data/lib/project_types/script/layers/infrastructure/test_suite_repository.rb +0 -59
  88. data/vendor/deps/cli-ui/lib/cli/ui/box.rb +0 -15
@@ -18,8 +18,12 @@ module Script
18
18
  invalid_context_cause: "Your .shopify-cli.yml file is not correct.",
19
19
  invalid_context_help: "See https://help.shopify.com",
20
20
 
21
+ invalid_script_name_cause: "Invalid script name.",
22
+ invalid_script_name_help: "Replace or remove unsupported characters. Valid characters "\
23
+ "are numbers, letters, hyphens, or underscores.",
24
+
21
25
  no_existing_apps_cause: "You don't have any apps.",
22
- no_existing_apps_help: "Please create an app with {{command:shopify create}} or"\
26
+ no_existing_apps_help: "Please create an app with {{command:shopify create}} or "\
23
27
  "visit https://partners.shopify.com/.",
24
28
 
25
29
  no_existing_orgs_cause: "You don't have any partner organizations.",
@@ -169,11 +173,6 @@ module Script
169
173
  create: {
170
174
  select_extension_point: "Which extension point do you want to use?",
171
175
  script_name: "Script Name",
172
-
173
- error: {
174
- invalid_name: "Invalid script name: replace or remove unsupported characters. Valid "\
175
- "characters are numbers, letters, spaces, hyphens, or underscores.",
176
- },
177
176
  },
178
177
  script_form: {
179
178
  ask_app_api_key_default: "Which app do you want this script to belong to?",
@@ -3,14 +3,28 @@
3
3
  module Script
4
4
  class ScriptProject < ShopifyCli::Project
5
5
  SUPPORTED_LANGUAGES = %w(ts)
6
+ SOURCE_DIR = "src"
6
7
 
7
8
  attr_reader :extension_point_type, :script_name, :language
8
9
 
9
- def initialize(dir)
10
- super(dir)
10
+ def initialize(*args)
11
+ super
11
12
  @extension_point_type = lookup_config('extension_point_type')
12
13
  @script_name = lookup_config('script_name')
13
14
  @language = 'ts'
15
+ ShopifyCli::Core::Monorail.metadata = {
16
+ "script_name" => @script_name,
17
+ "extension_point_type" => @extension_point_type,
18
+ "language" => @language,
19
+ }
20
+ end
21
+
22
+ def source_file
23
+ "#{SOURCE_DIR}/#{file_name}"
24
+ end
25
+
26
+ def file_name
27
+ "script.#{language}"
14
28
  end
15
29
 
16
30
  private
@@ -21,16 +35,15 @@ module Script
21
35
  end
22
36
 
23
37
  class << self
24
- def create(dir)
25
- raise Errors::ScriptProjectAlreadyExistsError, dir if Dir.exist?(dir)
26
-
27
- FileUtils.mkdir_p(dir)
28
- Dir.chdir(dir)
38
+ def create(ctx, dir)
39
+ raise Errors::ScriptProjectAlreadyExistsError, dir if ctx.dir_exist?(dir)
40
+ ctx.mkdir_p(dir)
41
+ ctx.chdir(dir)
29
42
  end
30
43
 
31
44
  def cleanup(ctx:, script_name:, root_dir:)
32
- Dir.chdir(root_dir)
33
- ctx.rm_r("#{root_dir}/#{script_name}") if Dir.exist?("#{root_dir}/#{script_name}")
45
+ ctx.chdir(root_dir)
46
+ ctx.rm_r("#{root_dir}/#{script_name}") if ctx.dir_exist?("#{root_dir}/#{script_name}")
34
47
  end
35
48
  end
36
49
  end
@@ -0,0 +1 @@
1
+ /// <reference types="@as-pect/assembly/types/as-pect" />
@@ -44,6 +44,11 @@ module Script
44
44
  cause_of_error: ShopifyCli::Context.message('script.error.invalid_context_cause'),
45
45
  help_suggestion: ShopifyCli::Context.message('script.error.invalid_context_help'),
46
46
  }
47
+ when Errors::InvalidScriptNameError
48
+ {
49
+ cause_of_error: ShopifyCli::Context.message('script.error.invalid_script_name_cause'),
50
+ help_suggestion: ShopifyCli::Context.message('script.error.invalid_script_name_help'),
51
+ }
47
52
  when Errors::NoExistingAppsError
48
53
  {
49
54
  cause_of_error: ShopifyCli::Context.message('script.error.no_existing_apps_cause'),
@@ -37,8 +37,7 @@ module ShopifyCli
37
37
  #
38
38
  # ShopifyCli::AdminAPI.query(@ctx, 'all_organizations')
39
39
  #
40
- def query(ctx, query_name, api_version: nil, shop: nil, **variables)
41
- shop ||= Project.current.env.shop
40
+ def query(ctx, query_name, shop:, api_version: nil, **variables)
42
41
  authenticated_req(ctx, shop) do
43
42
  api_client(ctx, api_version, shop).query(query_name, variables: variables)
44
43
  end
@@ -41,6 +41,8 @@ module ShopifyCli
41
41
  return @ctx.puts(output)
42
42
  end
43
43
 
44
+ @shop ||= Project.current.env.shop || get_shop(@ctx)
45
+
44
46
  if @silent
45
47
  spin_group = CLI::UI::SpinGroup.new
46
48
  spin_group.add(@ctx.message('core.populate.populating', @count, camel_case_resource_type)) do |spinner|
@@ -114,7 +116,7 @@ module ShopifyCli
114
116
 
115
117
  def run_mutation(data)
116
118
  kwargs = { input: data }
117
- kwargs[:shop] = @shop if @shop
119
+ kwargs[:shop] = @shop
118
120
  resp = AdminAPI.query(
119
121
  @ctx, "create_#{snake_case_resource_type}", kwargs
120
122
  )
@@ -145,6 +147,13 @@ module ShopifyCli
145
147
 
146
148
  private
147
149
 
150
+ def get_shop(ctx)
151
+ res = ShopifyCli::Tasks::SelectOrgAndShop.call(ctx)
152
+ domain = res[:shop_domain]
153
+ Project.current.env.update(ctx, :shop, domain)
154
+ domain
155
+ end
156
+
148
157
  def camel_case_resource_type
149
158
  @camel_case_resource_type ||= self.class.to_s.split('::').last
150
159
  end
@@ -5,7 +5,8 @@ module ShopifyCli
5
5
  class Schema < Hash
6
6
  def self.get(ctx)
7
7
  unless ShopifyCli::DB.exists?(:shopify_admin_schema)
8
- schema = AdminAPI.query(ctx, 'admin_introspection')
8
+ shop = Project.current.env.shop || get_shop(@ctx)
9
+ schema = AdminAPI.query(ctx, 'admin_introspection', shop: shop)
9
10
  ShopifyCli::DB.set(shopify_admin_schema: JSON.dump(schema))
10
11
  end
11
12
  # This is ruby magic for making a new hash with another hash.
@@ -27,6 +28,15 @@ module ShopifyCli
27
28
  object["name"]
28
29
  end
29
30
  end
31
+
32
+ private
33
+
34
+ def get_shop(ctx)
35
+ res = ShopifyCli::Tasks::SelectOrgAndShop.call(ctx)
36
+ domain = res[:shop_domain]
37
+ Project.current.env.update(ctx, :shop, domain)
38
+ domain
39
+ end
30
40
  end
31
41
  end
32
42
  end
@@ -32,6 +32,8 @@ module ShopifyCli
32
32
  )
33
33
  ctx.debug(resp)
34
34
  resp
35
+ rescue API::APIRequestServerError, API::APIRequestUnexpectedError
36
+ ctx.puts(ctx.message('core.api.error.internal_server_error'))
35
37
  end
36
38
 
37
39
  protected
@@ -131,6 +131,56 @@ module ShopifyCli
131
131
  File.write(ctx_path(fname), content)
132
132
  end
133
133
 
134
+ # will change directories and update the root, the filepath is relative to the command root unless absolute
135
+ #
136
+ # #### Parameters
137
+ # * `path` - the file path to a directory, relative to the context root to remove from the FS
138
+ #
139
+ def chdir(path)
140
+ Dir.chdir(ctx_path(path))
141
+ self.root = ctx_path(path)
142
+ end
143
+
144
+ # checks if a directory exists, the filepath is relative to the command root unless absolute
145
+ #
146
+ # #### Parameters
147
+ # * `path` - the file path to a directory, relative to the context root to remove from the FS
148
+ #
149
+ def dir_exist?(path)
150
+ Dir.exist?(ctx_path(path))
151
+ end
152
+
153
+ # checks if a file exists, the filepath is relative to the command root unless absolute
154
+ #
155
+ # #### Parameters
156
+ # * `path` - the file path to a file, relative to the context root to remove from the FS
157
+ #
158
+ def file_exist?(path)
159
+ File.exist?(ctx_path(path))
160
+ end
161
+
162
+ # will recursively copy a directory from the FS, the filepath is relative to the command
163
+ # root unless absolute
164
+ #
165
+ # #### Parameters
166
+ # * `from` - the path of the original file
167
+ # * `to` - the destination path
168
+ #
169
+ def cp_r(from, to)
170
+ FileUtils.cp_r(ctx_path(from), ctx_path(to))
171
+ end
172
+
173
+ # will copy a directory from the FS, the filepath is relative to the command
174
+ # root unless absolute
175
+ #
176
+ # #### Parameters
177
+ # * `from` - the path of the original file
178
+ # * `to` - the destination path
179
+ #
180
+ def cp(from, to)
181
+ FileUtils.cp(ctx_path(from), ctx_path(to))
182
+ end
183
+
134
184
  # will rename a file from one place to another, relative to the command root
135
185
  # unless the path is absolute.
136
186
  #
@@ -162,6 +212,16 @@ module ShopifyCli
162
212
  FileUtils.rm_r(ctx_path(fname))
163
213
  end
164
214
 
215
+ # will force remove a directory from the FS, the filepath is relative to the command
216
+ # root unless absolute
217
+ #
218
+ # #### Parameters
219
+ # * `fname` - the file path to a directory, relative to the context root to remove from the FS
220
+ #
221
+ def rm_rf(fname)
222
+ FileUtils.rm_rf(ctx_path(fname))
223
+ end
224
+
165
225
  # will create a directory, recursively if it does not exist. So if you create
166
226
  # a directory `foo/bar/dun`, this will also create the directories `foo` and
167
227
  # `foo/bar` if they do not exist. The path will be made relative to the command
@@ -11,6 +11,12 @@ module ShopifyCli
11
11
  IO.open(9) { is_shell_shim = true }
12
12
  rescue Errno::EBADF
13
13
  # This is expected if the descriptor doesn't exist
14
+ rescue ArgumentError => e
15
+ # This can happen on RVM, because it can use fd 9 itself and block access to it. That only happens if the fd
16
+ # did not exist beforehand, so that means there was no fd 9 before Ruby started.
17
+ unless e.message == 'The given fd is not accessible because RubyVM reserves it'
18
+ raise e
19
+ end
14
20
  end
15
21
 
16
22
  if !ctx.testing? && is_shell_shim
@@ -0,0 +1,13 @@
1
+ module ShopifyCli
2
+ module Core
3
+ # This class is just a dummy to make sure that we don't trigger warnings on the first time the updated code runs.
4
+ # The old code would try to call the Finalizer after it is done updating, which would then trigger an autoload of
5
+ # this class and fail.
6
+ module Finalize
7
+ class << self
8
+ def deliver!
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -46,10 +46,10 @@ module ShopifyCli
46
46
  if Dir.exist?(dest)
47
47
  ctx.abort(ctx.message('core.git.error.directory_exists'))
48
48
  else
49
- CLI::UI::Frame.open(ctx.message('core.git.cloning', dest)) do
49
+ success_message = ctx.message('core.git.cloned', dest)
50
+ CLI::UI::Frame.open(ctx.message('core.git.cloning', repository, dest), success_text: success_message) do
50
51
  clone_progress('clone', '--single-branch', repository, dest, ctx: ctx)
51
52
  end
52
- ctx.done(ctx.message('core.git.cloned', dest))
53
53
  end
54
54
  end
55
55
 
@@ -121,19 +121,23 @@ module ShopifyCli
121
121
  def clone_progress(*git_command, ctx:)
122
122
  CLI::UI::Progress.progress do |bar|
123
123
  msg = []
124
- success = ctx.system('git', *git_command, '--progress') do |_out, err|
125
- if err.strip.start_with?('Receiving objects:')
126
- percent = (err.match(/Receiving objects:\s+(\d+)/)[1].to_f / 100).round(2)
124
+ require 'open3'
125
+
126
+ success = Open3.popen3('git', *git_command, '--progress') do |_stdin, _stdout, stderr, thread|
127
+ while (line = stderr.gets)
128
+ next unless line.strip.start_with?('Receiving objects:')
129
+ percent = (line.match(/Receiving objects:\s+(\d+)/)[1].to_f / 100).round(2)
127
130
  bar.tick(set_percent: percent)
128
131
  next
129
132
  end
130
- msg << err
133
+
134
+ msg << stderr
135
+ thread.value
131
136
  end.success?
132
- unless success
133
- ctx.abort(msg.join("\n"))
134
- end
137
+
138
+ ctx.abort(msg.join("\n")) unless success
135
139
  bar.tick(set_percent: 1.0)
136
- true
140
+ success
137
141
  end
138
142
  end
139
143
  end
@@ -60,8 +60,8 @@ module ShopifyCli
60
60
  no_commits_made: "No git commits have been made. Please make at least one commit.",
61
61
  },
62
62
 
63
- cloning: "Cloning into %s...",
64
- cloned: "Cloned into %s",
63
+ cloning: "Cloning %s into %s...",
64
+ cloned: "{{v}} Cloned into %s",
65
65
  },
66
66
 
67
67
  help: {
@@ -154,6 +154,12 @@ module ShopifyCli
154
154
  },
155
155
  },
156
156
 
157
+ api: {
158
+ error: {
159
+ internal_server_error: '{{red:{{x}} An unexpected error occurred on Shopify.}}',
160
+ },
161
+ },
162
+
157
163
  populate: {
158
164
  options: {
159
165
  header: "{{bold:{{cyan:%s}} options:}}",
@@ -245,6 +251,20 @@ module ShopifyCli
245
251
  "{{x}} error: For authentication issues, run {{command:%s logout}} to clear invalid credentials",
246
252
  update_prompt: "Do you want to update your application url?",
247
253
  },
254
+ select_org_and_shop: {
255
+ authentication_issue: "For authentication issues, run {{command:%s logout}} to clear invalid credentials",
256
+ create_store: "Visit {{underline:https://partners.shopify.com/%s/stores}} to create one",
257
+ development_store: "Using development store {{green:%s}}",
258
+ development_store_select: "Select a development store",
259
+ error: {
260
+ no_development_stores: "{{x}} No Development Stores available.",
261
+ no_organizations: "No partner organizations available.",
262
+ organization_not_found: "Cannot find a partner organization with that ID",
263
+ partners_notice: "Please visit https://partners.shopify.com/ to create a partners account",
264
+ },
265
+ organization: "Partner organization {{green:%s (%s)}}",
266
+ organization_select: "Select partner organization",
267
+ },
248
268
  },
249
269
 
250
270
  tunnel: {
@@ -27,6 +27,7 @@ module ShopifyCli
27
27
  register :EnsureEnv, :ensure_env, 'shopify-cli/tasks/ensure_env'
28
28
  register :EnsureLoopbackURL, :ensure_loopback_url, 'shopify-cli/tasks/ensure_loopback_url'
29
29
  register :EnsureDevStore, :ensure_dev_store, 'shopify-cli/tasks/ensure_dev_store'
30
+ register :SelectOrgAndShop, :select_org_and_shop, 'shopify-cli/tasks/select_org_and_shop'
30
31
  register :UpdateDashboardURLS, :update_dashboard_urls, 'shopify-cli/tasks/update_dashboard_urls'
31
32
  end
32
33
  end
@@ -0,0 +1,77 @@
1
+ require 'shopify_cli'
2
+
3
+ module ShopifyCli
4
+ module Tasks
5
+ class SelectOrgAndShop < ShopifyCli::Task
6
+ attr_reader :ctx
7
+
8
+ def call(ctx, organization_id: nil, shop_domain: nil)
9
+ @ctx = ctx
10
+ return response(organization_id.to_i, shop_domain) unless organization_id.nil? || shop_domain.nil?
11
+ org = get_organization(organization_id)
12
+ shop_domain ||= get_shop_domain(org)
13
+ response(org["id"].to_i, shop_domain)
14
+ end
15
+
16
+ private
17
+
18
+ def response(organization_id, shop_domain)
19
+ {
20
+ organization_id: organization_id,
21
+ shop_domain: shop_domain,
22
+ }
23
+ end
24
+
25
+ def organizations
26
+ @organizations ||= ShopifyCli::PartnersAPI::Organizations.fetch_all(ctx)
27
+ end
28
+
29
+ def get_organization(organization_id)
30
+ @organization ||= if !organization_id.nil?
31
+ org = ShopifyCli::PartnersAPI::Organizations.fetch(ctx, id: organization_id)
32
+ if org.nil?
33
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.error.authentication_issue', ShopifyCli::TOOL_NAME))
34
+ ctx.abort(ctx.message('core.tasks.select_org_and_shop.error.organization_not_found'))
35
+ end
36
+ org
37
+ elsif organizations.count == 0
38
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.error.partners_notice'))
39
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.authentication_issue', ShopifyCli::TOOL_NAME))
40
+ ctx.abort(ctx.message('core.tasks.select_org_and_shop.error.no_organizations'))
41
+ elsif organizations.count == 1
42
+ org = organizations.first
43
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.organization', org['businessName'], org['id']))
44
+ org
45
+ else
46
+ org_id = CLI::UI::Prompt.ask(ctx.message('core.tasks.select_org_and_shop.organization_select')) do |handler|
47
+ organizations.each do |o|
48
+ handler.option(ctx.message('core.partners_api.org_name_and_id', o['businessName'], o['id'])) { o['id'] }
49
+ end
50
+ end
51
+ organizations.find { |o| o['id'] == org_id }
52
+ end
53
+ end
54
+
55
+ def get_shop_domain(organization)
56
+ valid_stores = organization['stores'].select do |store|
57
+ store['transferDisabled'] == true || store['convertableToPartnerTest'] == true
58
+ end
59
+
60
+ if valid_stores.count == 0
61
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.error.no_development_stores'))
62
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.create_store', organization['id']))
63
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.authentication_issue', ShopifyCli::TOOL_NAME))
64
+ elsif valid_stores.count == 1
65
+ domain = valid_stores.first['shopDomain']
66
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.development_store', domain))
67
+ domain
68
+ else
69
+ CLI::UI::Prompt.ask(
70
+ ctx.message('core.tasks.select_org_and_shop.development_store_select'),
71
+ options: valid_stores.map { |s| s['shopDomain'] }
72
+ )
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end