shopify-cli 1.0.0 → 1.0.5

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 (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