shopify-cli 1.0.0 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -2
  3. data/CHANGELOG.md +20 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +13 -13
  6. data/docs/Gemfile.lock +23 -13
  7. data/docs/getting-started/install/index.md +37 -1
  8. data/docs/getting-started/migrate/index.md +34 -1
  9. data/lib/project_types/extension/cli.rb +1 -1
  10. data/lib/project_types/extension/commands/build.rb +1 -1
  11. data/lib/project_types/extension/models/type.rb +1 -0
  12. data/lib/project_types/extension/tasks/create_extension.rb +1 -1
  13. data/lib/project_types/extension/tasks/get_app.rb +1 -1
  14. data/lib/project_types/extension/tasks/update_draft.rb +1 -1
  15. data/lib/project_types/node/forms/create.rb +3 -54
  16. data/lib/project_types/node/messages/messages.rb +3 -14
  17. data/lib/project_types/rails/cli.rb +0 -1
  18. data/lib/project_types/rails/forms/create.rb +3 -52
  19. data/lib/project_types/rails/messages/messages.rb +2 -13
  20. data/lib/project_types/script/cli.rb +2 -3
  21. data/lib/project_types/script/commands/create.rb +5 -9
  22. data/lib/project_types/script/commands/disable.rb +4 -15
  23. data/lib/project_types/script/commands/enable.rb +37 -13
  24. data/lib/project_types/script/commands/push.rb +8 -13
  25. data/lib/project_types/script/config/extension_points.yml +9 -3
  26. data/lib/project_types/script/errors.rb +8 -0
  27. data/lib/project_types/script/forms/script_form.rb +5 -2
  28. data/lib/project_types/script/layers/application/create_script.rb +7 -6
  29. data/lib/project_types/script/layers/application/disable_script.rb +9 -7
  30. data/lib/project_types/script/layers/application/enable_script.rb +11 -9
  31. data/lib/project_types/script/layers/application/push_script.rb +6 -4
  32. data/lib/project_types/script/layers/domain/errors.rb +2 -0
  33. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +2 -2
  34. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +2 -2
  35. data/lib/project_types/script/layers/infrastructure/errors.rb +2 -0
  36. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +1 -1
  37. data/lib/project_types/script/layers/infrastructure/script_repository.rb +1 -1
  38. data/lib/project_types/script/layers/infrastructure/script_service.rb +2 -0
  39. data/lib/project_types/script/messages/messages.rb +25 -31
  40. data/lib/project_types/script/script_project.rb +8 -4
  41. data/lib/project_types/script/templates/ts/as-pect.config.js +6 -0
  42. data/lib/project_types/script/ui/error_handler.rb +8 -0
  43. data/lib/project_types/script/ui/printing_spinner.rb +75 -0
  44. data/lib/shopify-cli/admin_api.rb +1 -2
  45. data/lib/shopify-cli/admin_api/populate_resource_command.rb +10 -1
  46. data/lib/shopify-cli/admin_api/schema.rb +20 -8
  47. data/lib/shopify-cli/command.rb +14 -11
  48. data/lib/shopify-cli/commands.rb +1 -0
  49. data/lib/shopify-cli/commands/config.rb +44 -0
  50. data/lib/shopify-cli/commands/connect.rb +8 -69
  51. data/lib/shopify-cli/commands/create.rb +2 -2
  52. data/lib/shopify-cli/commands/help.rb +1 -1
  53. data/lib/shopify-cli/commands/system.rb +14 -6
  54. data/lib/shopify-cli/context.rb +10 -1
  55. data/lib/shopify-cli/core.rb +0 -1
  56. data/lib/shopify-cli/core/entry_point.rb +7 -1
  57. data/lib/shopify-cli/core/executor.rb +3 -5
  58. data/lib/shopify-cli/core/finalize.rb +13 -0
  59. data/lib/shopify-cli/core/monorail.rb +1 -1
  60. data/lib/shopify-cli/db.rb +1 -1
  61. data/lib/shopify-cli/feature.rb +97 -0
  62. data/lib/shopify-cli/heroku.rb +4 -4
  63. data/lib/shopify-cli/messages/messages.rb +51 -12
  64. data/lib/shopify-cli/partners_api/organizations.rb +7 -7
  65. data/lib/shopify-cli/process_supervision.rb +8 -6
  66. data/lib/shopify-cli/project_type.rb +5 -7
  67. data/lib/shopify-cli/sub_command.rb +1 -0
  68. data/lib/shopify-cli/task.rb +2 -2
  69. data/lib/shopify-cli/tasks.rb +12 -4
  70. data/lib/shopify-cli/tasks/ensure_env.rb +72 -16
  71. data/lib/shopify-cli/tasks/select_org_and_shop.rb +77 -0
  72. data/lib/shopify-cli/tasks/update_dashboard_urls.rb +4 -3
  73. data/lib/shopify-cli/tunnel.rb +38 -14
  74. data/lib/shopify-cli/version.rb +1 -1
  75. data/lib/shopify_cli.rb +32 -9
  76. metadata +7 -4
  77. data/lib/project_types/script/forms/enable.rb +0 -24
  78. data/lib/project_types/script/forms/push.rb +0 -19
@@ -14,7 +14,7 @@ module ShopifyCli
14
14
 
15
15
  attr_reader :db # :nodoc:
16
16
 
17
- def initialize(path: File.join(ShopifyCli::CACHE_DIR, ".db.pstore")) # :nodoc:
17
+ def initialize(path: File.join(ShopifyCli.cache_dir, ".db.pstore")) # :nodoc:
18
18
  @db = PStore.new(path)
19
19
  end
20
20
 
@@ -0,0 +1,97 @@
1
+ module ShopifyCli
2
+ ##
3
+ # ShopifyCli::Feature contains the logic to hide and show features across the CLI
4
+ # These features can be either commands or project types currently.
5
+ #
6
+ # Feature flags will persist between runs so if the flag is enabled or disabled,
7
+ # it will still be in that same state on the next cli invocation.
8
+ class Feature
9
+ SECTION = 'features'
10
+
11
+ ##
12
+ # ShopifyCli::Feature::Set is included on commands and projects to allow you to hide
13
+ # and enable projects and commands based on feature flags.
14
+ module Set
15
+ ##
16
+ # will hide a feature, either a project_type or a command
17
+ #
18
+ # #### Parameters
19
+ #
20
+ # * `feature_set` - either a single, or array of symbols that represent feature sets
21
+ #
22
+ # #### Example
23
+ #
24
+ # module ShopifyCli
25
+ # module Commands
26
+ # class Config < ShopifyCli::Command
27
+ # hidden_feature(feature_set: :basic)
28
+ # ....
29
+ #
30
+ def hidden_feature(feature_set: [])
31
+ @feature_hidden = true
32
+ @hidden_feature_set = Array(feature_set).compact
33
+ end
34
+
35
+ ##
36
+ # will return if the feature has been hidden or not
37
+ #
38
+ # #### Returns
39
+ #
40
+ # * `is_hidden` - returns true if the feature has been hidden and false otherwise
41
+ #
42
+ # #### Example
43
+ #
44
+ # ShopifyCli::Commands::Config.hidden?
45
+ #
46
+ def hidden?
47
+ enabled = (@hidden_feature_set || []).any? do |feature|
48
+ Feature.enabled?(feature)
49
+ end
50
+ @feature_hidden && !enabled
51
+ end
52
+ end
53
+
54
+ class << self
55
+ ##
56
+ # will enable a feature in the CLI.
57
+ #
58
+ # #### Parameters
59
+ #
60
+ # * `feature` - a symbol representing the flag to be enabled
61
+ def enable(feature)
62
+ set(feature, true)
63
+ end
64
+
65
+ ##
66
+ # will disable a feature in the CLI.
67
+ #
68
+ # #### Parameters
69
+ #
70
+ # * `feature` - a symbol representing the flag to be disabled
71
+ def disable(feature)
72
+ set(feature, false)
73
+ end
74
+
75
+ ##
76
+ # will check if the feature has been enabled
77
+ #
78
+ # #### Parameters
79
+ #
80
+ # * `feature` - a symbol representing a flag that the status should be requested
81
+ #
82
+ # #### Returns
83
+ #
84
+ # * `is_enabled` - will be true if the feature has been enabled.
85
+ def enabled?(feature)
86
+ return false if feature.nil?
87
+ ShopifyCli::Config.get_bool(SECTION, feature.to_s)
88
+ end
89
+
90
+ private
91
+
92
+ def set(feature, value)
93
+ ShopifyCli::Config.set(SECTION, feature.to_s, value)
94
+ end
95
+ end
96
+ end
97
+ end
@@ -36,7 +36,7 @@ module ShopifyCli
36
36
  def download
37
37
  return if installed?
38
38
 
39
- result = @ctx.system('curl', '-o', download_path, DOWNLOAD_URLS[@ctx.os], chdir: ShopifyCli::CACHE_DIR)
39
+ result = @ctx.system('curl', '-o', download_path, DOWNLOAD_URLS[@ctx.os], chdir: ShopifyCli.cache_dir)
40
40
  @ctx.abort(@ctx.message('core.heroku.error.download')) unless result.success?
41
41
  @ctx.abort(@ctx.message('core.heroku.error.download')) unless File.exist?(download_path)
42
42
  end
@@ -44,7 +44,7 @@ module ShopifyCli
44
44
  def install
45
45
  return if installed?
46
46
 
47
- result = @ctx.system('tar', '-xf', download_path, chdir: ShopifyCli::CACHE_DIR)
47
+ result = @ctx.system('tar', '-xf', download_path, chdir: ShopifyCli.cache_dir)
48
48
  @ctx.abort(@ctx.message('core.heroku.error.install')) unless result.success?
49
49
 
50
50
  @ctx.rm(download_path)
@@ -70,7 +70,7 @@ module ShopifyCli
70
70
  end
71
71
 
72
72
  def download_path
73
- File.join(ShopifyCli::CACHE_DIR, download_filename)
73
+ File.join(ShopifyCli.cache_dir, download_filename)
74
74
  end
75
75
 
76
76
  def git_remote
@@ -79,7 +79,7 @@ module ShopifyCli
79
79
  end
80
80
 
81
81
  def heroku_command
82
- local_path = File.join(ShopifyCli::CACHE_DIR, 'heroku', 'bin', 'heroku').to_s
82
+ local_path = File.join(ShopifyCli.cache_dir, 'heroku', 'bin', 'heroku').to_s
83
83
  if File.exist?(local_path)
84
84
  local_path
85
85
  else
@@ -16,13 +16,6 @@ module ShopifyCli
16
16
  already_connected_warning: "{{yellow:! This app appears to be already connected}}",
17
17
  connected: "{{v}} Project now connected to {{green:%s}}",
18
18
  project_type_select: "What type of project would you like to connect?",
19
- organization_select: "To which partner organization does this project belong?",
20
- app_select: "To which app does this project belong?",
21
- no_development_stores: <<~MESSAGE,
22
- No development stores available.
23
- Visit {{underline:https://partners.shopify.com/%d/stores}} to create one
24
- MESSAGE
25
- development_store_select: "Which development store would you like to use?",
26
19
  cli_yml_saved: ".shopify-cli.yml saved to project root",
27
20
  },
28
21
 
@@ -52,6 +45,19 @@ module ShopifyCli
52
45
  saved: "%s saved to project root",
53
46
  },
54
47
 
48
+ config: {
49
+ help: <<~HELP,
50
+ Change configuration of how the CLI operates
51
+ Usage: {{command:%s config [ feature ] [ feature_name ] }}
52
+ HELP
53
+ feature: {
54
+ enabled: "{{v}} feature {{green:%s}} was enabled",
55
+ disabled: "{{v}} feature {{green:%s}} was disabled",
56
+ is_enabled: "{{v}} feature {{green:%s}} is enabled",
57
+ is_disabled: "{{v}} feature {{green:%s}} is disabled",
58
+ },
59
+ },
60
+
55
61
  git: {
56
62
  error: {
57
63
  directory_exists: "Project directory already exists. Please create a project with a new name.",
@@ -232,9 +238,21 @@ module ShopifyCli
232
238
 
233
239
  tasks: {
234
240
  ensure_env: {
235
- api_key_question: "What is your Shopify API key?",
236
- api_secret_key_question: "What is your Shopify API secret key?",
237
- development_store_question: "What is your development store URL? (Example: my-dev-store.myshopify.com)",
241
+ organization_select: "To which partner organization does this project belong?",
242
+ no_development_stores: <<~MESSAGE,
243
+ No development stores available.
244
+ Visit {{underline:https://partners.shopify.com/%d/stores}} to create one
245
+ MESSAGE
246
+ development_store_select: "Which development store would you like to use?",
247
+ app_select: "To which app does this project belong?",
248
+ no_apps: 'You have no apps to connect to, creating a new app.',
249
+ app_name: "App name",
250
+ app_type: {
251
+ select: "What type of app are you building?",
252
+ select_public: "Public: An app built for a wide merchant audience.",
253
+ select_custom: "Custom: An app custom built for a single client.",
254
+ selected: "App type {{green:%s}}",
255
+ },
238
256
  },
239
257
  ensure_dev_store: {
240
258
  could_not_verify_store: "Couldn't verify your store %s",
@@ -251,6 +269,20 @@ module ShopifyCli
251
269
  "{{x}} error: For authentication issues, run {{command:%s logout}} to clear invalid credentials",
252
270
  update_prompt: "Do you want to update your application url?",
253
271
  },
272
+ select_org_and_shop: {
273
+ authentication_issue: "For authentication issues, run {{command:%s logout}} to clear invalid credentials",
274
+ create_store: "Visit {{underline:https://partners.shopify.com/%s/stores}} to create one",
275
+ development_store: "Using development store {{green:%s}}",
276
+ development_store_select: "Select a development store",
277
+ error: {
278
+ no_development_stores: "{{x}} No Development Stores available.",
279
+ no_organizations: "No partner organizations available.",
280
+ organization_not_found: "Cannot find a partner organization with that ID",
281
+ partners_notice: "Please visit https://partners.shopify.com/ to create a partners account",
282
+ },
283
+ organization: "Partner organization {{green:%s (%s)}}",
284
+ organization_select: "Select partner organization",
285
+ },
254
286
  },
255
287
 
256
288
  tunnel: {
@@ -259,10 +291,17 @@ module ShopifyCli
259
291
  url_fetch_failure: "Unable to fetch external url",
260
292
  },
261
293
 
262
- stopped: "{{green:x}} ngrok tunnel stopped",
263
294
  not_running: "{{green:x}} ngrok tunnel not running",
264
- start_with_account: "{{v}} ngrok tunnel running at {{underline:%s}}, with account %s",
295
+ signup_suggestion: <<~MESSAGE,
296
+ {{*}} To avoid tunnels that timeout, it is recommended to signup for a free ngrok
297
+ account at {{underline:https://ngrok.com/signup}}. After you signup, install your
298
+ personalized authorization token using {{command:%s tunnel auth <token>}}.
299
+ MESSAGE
265
300
  start: "{{v}} ngrok tunnel running at {{underline:%s}}",
301
+ start_with_account: "{{v}} ngrok tunnel running at {{underline:%s}}, with account %s",
302
+ stopped: "{{green:x}} ngrok tunnel stopped",
303
+ timed_out: "{{x}} ngrok tunnel has timed out, restarting ...",
304
+ will_timeout: "{{*}} This tunnel will timeout in {{red:%s}}",
266
305
  },
267
306
 
268
307
  version: {
@@ -4,25 +4,25 @@ module ShopifyCli
4
4
  class << self
5
5
  def fetch_all(ctx)
6
6
  resp = PartnersAPI.query(ctx, 'all_organizations')
7
- resp['data']['organizations']['nodes'].map do |org|
8
- org['stores'] = org['stores']['nodes']
7
+ (resp.dig('data', 'organizations', 'nodes') || []).map do |org|
8
+ org['stores'] = (org.dig('stores', 'nodes') || [])
9
9
  org
10
10
  end
11
11
  end
12
12
 
13
13
  def fetch(ctx, id:)
14
14
  resp = PartnersAPI.query(ctx, 'find_organization', id: id)
15
- org = resp['data']['organizations']['nodes'].first
15
+ org = resp.dig('data', 'organizations', 'nodes').first
16
16
  return nil if org.nil?
17
- org['stores'] = org['stores']['nodes']
17
+ org['stores'] = (org.dig('stores', 'nodes') || [])
18
18
  org
19
19
  end
20
20
 
21
21
  def fetch_with_app(ctx)
22
22
  resp = PartnersAPI.query(ctx, 'all_orgs_with_apps')
23
- resp['data']['organizations']['nodes'].map do |org|
24
- org['stores'] = org['stores']['nodes']
25
- org['apps'] = org['apps']['nodes']
23
+ (resp.dig('data', 'organizations', 'nodes') || []).map do |org|
24
+ org['stores'] = (org.dig('stores', 'nodes') || [])
25
+ org['apps'] = (org.dig('apps', 'nodes') || [])
26
26
  org
27
27
  end
28
28
  end
@@ -5,9 +5,6 @@ module ShopifyCli
5
5
  # ProcessSupervision wraps a running process spawned by `exec` and keeps track
6
6
  # if its `pid` and keeps a log file for it as well
7
7
  class ProcessSupervision
8
- # is the directory where the pid and logfile are kept
9
- RUN_DIR = File.join(ShopifyCli::CACHE_DIR, 'sv')
10
-
11
8
  # a string or a symbol to identify this process by
12
9
  attr_reader :identifier
13
10
  # process ID for the running process
@@ -20,6 +17,11 @@ module ShopifyCli
20
17
  attr_reader :log_path
21
18
 
22
19
  class << self
20
+ def run_dir
21
+ # is the directory where the pid and logfile are kept
22
+ File.join(ShopifyCli.cache_dir, 'sv')
23
+ end
24
+
23
25
  ##
24
26
  # Will find and create a new instance of ProcessSupervision for a running process
25
27
  # if it is currently running. It will return nil if the process is not running.
@@ -34,7 +36,7 @@ module ShopifyCli
34
36
  # will be nil if the process is not running.
35
37
  #
36
38
  def for_ident(identifier)
37
- pid, time = File.read(File.join(RUN_DIR, "#{identifier}.pid")).split(':')
39
+ pid, time = File.read(File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.pid")).split(':')
38
40
  new(identifier, pid: Integer(pid), time: time)
39
41
  rescue Errno::ENOENT
40
42
  nil
@@ -108,8 +110,8 @@ module ShopifyCli
108
110
  @identifier = identifier
109
111
  @pid = pid
110
112
  @time = time
111
- @pid_path = File.join(RUN_DIR, "#{identifier}.pid")
112
- @log_path = File.join(RUN_DIR, "#{identifier}.log")
113
+ @pid_path = File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.pid")
114
+ @log_path = File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.log")
113
115
  end
114
116
 
115
117
  ##
@@ -1,11 +1,12 @@
1
1
  module ShopifyCli
2
2
  class ProjectType
3
+ extend Feature::Set
4
+
3
5
  class << self
4
6
  attr_accessor :project_type,
5
7
  :project_name,
6
8
  :project_creator_command_class,
7
9
  :project_load_shallow
8
- attr_reader :hidden
9
10
 
10
11
  def repository
11
12
  @repository ||= []
@@ -13,6 +14,7 @@ module ShopifyCli
13
14
  alias_method :all_loaded, :repository
14
15
 
15
16
  def inherited(klass)
17
+ super
16
18
  repository << klass
17
19
  klass.project_type = @current_type
18
20
  klass.project_load_shallow = @shallow_load
@@ -31,7 +33,7 @@ module ShopifyCli
31
33
 
32
34
  def load_all
33
35
  Dir.glob(File.join(ShopifyCli::ROOT, 'lib', 'project_types', '*', 'cli.rb')).map do |filepath|
34
- load_type(filepath.split(File::Separator)[-2], true)
36
+ load_type(filepath.split(File::Separator)[-2].to_sym, true)
35
37
  end
36
38
  end
37
39
 
@@ -53,10 +55,6 @@ module ShopifyCli
53
55
  const_get(@project_creator_command_class)
54
56
  end
55
57
 
56
- def hidden_project_type
57
- @hidden = true
58
- end
59
-
60
58
  def register_command(const, cmd)
61
59
  return if project_load_shallow
62
60
  Context.new.abort(
@@ -67,7 +65,7 @@ module ShopifyCli
67
65
 
68
66
  def register_task(task, name)
69
67
  return if project_load_shallow
70
- Task::Registry.add(const_get(task), name)
68
+ ShopifyCli::Task.register(task, name)
71
69
  end
72
70
 
73
71
  def register_messages(messages)
@@ -8,6 +8,7 @@ module ShopifyCli
8
8
  cmd = new(@ctx)
9
9
  args = cmd.options.parse(@_options, args[1..-1] || [])
10
10
  return call_help(parent_command, command_name) if cmd.options.help
11
+ run_prerequisites
11
12
  cmd.call(args, command_name)
12
13
  end
13
14
  end
@@ -2,9 +2,9 @@ require 'shopify_cli'
2
2
 
3
3
  module ShopifyCli
4
4
  class Task
5
- def self.call(*args)
5
+ def self.call(*args, **kwargs)
6
6
  task = new
7
- task.call(*args)
7
+ task.call(*args, **kwargs)
8
8
  end
9
9
  end
10
10
  end
@@ -12,21 +12,29 @@ module ShopifyCli
12
12
  end
13
13
 
14
14
  def [](name)
15
- @tasks[name]
15
+ class_or_proc = @tasks[name]
16
+ if class_or_proc.is_a?(Class)
17
+ class_or_proc
18
+ elsif class_or_proc.respond_to?(:call)
19
+ class_or_proc.call
20
+ else
21
+ class_or_proc
22
+ end
16
23
  end
17
24
  end
18
25
 
19
26
  Registry = TaskRegistry.new
20
27
 
21
- def self.register(task, name, path)
22
- autoload(task, path)
23
- Registry.add(const_get(task), name)
28
+ def self.register(task, name, path = nil)
29
+ autoload(task, path) if path
30
+ Registry.add(-> () { const_get(task) }, name)
24
31
  end
25
32
 
26
33
  register :CreateApiClient, :create_api_client, 'shopify-cli/tasks/create_api_client'
27
34
  register :EnsureEnv, :ensure_env, 'shopify-cli/tasks/ensure_env'
28
35
  register :EnsureLoopbackURL, :ensure_loopback_url, 'shopify-cli/tasks/ensure_loopback_url'
29
36
  register :EnsureDevStore, :ensure_dev_store, 'shopify-cli/tasks/ensure_dev_store'
37
+ register :SelectOrgAndShop, :select_org_and_shop, 'shopify-cli/tasks/select_org_and_shop'
30
38
  register :UpdateDashboardURLS, :update_dashboard_urls, 'shopify-cli/tasks/update_dashboard_urls'
31
39
  end
32
40
  end
@@ -3,28 +3,84 @@ require 'shopify_cli'
3
3
  module ShopifyCli
4
4
  module Tasks
5
5
  class EnsureEnv < ShopifyCli::Task
6
- def call(ctx)
6
+ def call(ctx, regenerate: false, required: [:api_key, :secret])
7
7
  @ctx = ctx
8
- Resources::EnvFile.read(ctx.root)
9
- rescue Errno::ENOENT
10
- ask
8
+ env_data =
9
+ begin
10
+ Resources::EnvFile.parse_external_env
11
+ rescue Errno::ENOENT
12
+ {}
13
+ end
14
+
15
+ return {} if !regenerate && required.all? { |property| env_data[property] }
16
+
17
+ org = fetch_org
18
+ write_env(env_data, org)
19
+ org
20
+ end
21
+
22
+ private
23
+
24
+ def fetch_org
25
+ orgs = PartnersAPI::Organizations.fetch_with_app(@ctx)
26
+ org_id = if orgs.count == 1
27
+ orgs.first["id"]
28
+ else
29
+ CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.organization_select')) do |handler|
30
+ orgs.each do |org|
31
+ handler.option(
32
+ @ctx.message('core.partners_api.org_name_and_id', org['businessName'], org['id'])
33
+ ) { org["id"] }
34
+ end
35
+ end
36
+ end
37
+ orgs.find { |o| o["id"] == org_id }
38
+ end
39
+
40
+ def get_app(org_id, apps)
41
+ if apps.count == 1
42
+ apps.first
43
+ elsif apps.count == 0
44
+ @ctx.puts(@ctx.message('core.tasks.ensure_env.no_apps'))
45
+ title = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_name'))
46
+ type = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_type.select')) do |handler|
47
+ handler.option(@ctx.message('core.tasks.ensure_env.app_type.select_public')) { 'public' }
48
+ handler.option(@ctx.message('core.tasks.ensure_env.app_type.select_custom')) { 'custom' }
49
+ end
50
+ ShopifyCli::Tasks::CreateApiClient.call(@ctx, org_id: org_id, title: title, type: type)
51
+ else
52
+ CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_select')) do |handler|
53
+ apps.each { |app| handler.option(app["title"]) { app } }
54
+ end
55
+ end
56
+ end
57
+
58
+ def get_shop(shops, id)
59
+ if shops.count == 1
60
+ shop = shops.first["shopDomain"]
61
+ elsif shops.count == 0
62
+ @ctx.puts(@ctx.message('core.tasks.ensure_env.no_development_stores', id))
63
+ else
64
+ shop = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.development_store_select')) do |handler|
65
+ shops.each { |s| handler.option(s["shopName"]) { s["shopDomain"] } }
66
+ end
67
+ end
68
+ shop
11
69
  end
12
70
 
13
- def ask
14
- api_key = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.api_key_question'))
15
- api_secret = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.api_secret_key_question'))
16
- shop = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.development_store_question'))
71
+ def write_env(env_data, org)
72
+ id = org['id']
73
+ app = get_app(id, org['apps'])
17
74
 
18
- shop.gsub!(/https?\:\/\//, '')
75
+ env_data[:shop] = get_shop(org['stores'], id)
76
+ env_data[:api_key] = app["apiKey"]
77
+ env_data[:secret] = app["apiSecretKeys"].first["secret"]
78
+ env_data[:scopes] = 'write_products,write_customers,write_draft_orders' if env_data[:scopes].nil?
79
+ env_data[:extra] = {} if env_data[:extra].nil?
19
80
 
20
- env = Resources::EnvFile.new(
21
- api_key: api_key,
22
- secret: api_secret,
23
- shop: shop,
24
- host: ShopifyCli::Tunnel.start(@ctx),
25
- scopes: 'write_products,write_customers,write_draft_orders',
81
+ Resources::EnvFile.new(
82
+ env_data
26
83
  ).write(@ctx)
27
- env
28
84
  end
29
85
  end
30
86
  end