shopify-cli 2.12.0 → 2.13.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/shopify.yml +2 -1
  3. data/.rubocop.yml +1 -1
  4. data/.ruby-version +1 -1
  5. data/CHANGELOG.md +10 -0
  6. data/Gemfile.lock +14 -14
  7. data/bin/shopify +4 -4
  8. data/dev.yml +1 -1
  9. data/ext/javy/hashes/javy-arm-macos-v0.2.0.gz.sha256 +1 -0
  10. data/ext/javy/hashes/javy-x86_64-linux-v0.2.0.gz.sha256 +1 -0
  11. data/ext/javy/hashes/javy-x86_64-macos-v0.2.0.gz.sha256 +1 -0
  12. data/ext/javy/hashes/javy-x86_64-windows-v0.2.0.gz.sha256 +1 -0
  13. data/ext/javy/version +1 -1
  14. data/lib/project_types/extension/features/argo_setup_steps.rb +4 -6
  15. data/lib/project_types/extension/tasks/configure_features.rb +15 -2
  16. data/lib/project_types/extension/tasks/convert_server_config.rb +2 -1
  17. data/lib/project_types/script/commands/create.rb +4 -4
  18. data/lib/project_types/script/errors.rb +1 -1
  19. data/lib/project_types/script/forms/create.rb +7 -7
  20. data/lib/project_types/script/layers/application/build_script.rb +22 -24
  21. data/lib/project_types/script/layers/application/create_script.rb +9 -10
  22. data/lib/project_types/script/layers/application/project_dependencies.rb +12 -14
  23. data/lib/project_types/script/layers/application/push_script.rb +2 -0
  24. data/lib/project_types/script/layers/domain/errors.rb +3 -3
  25. data/lib/project_types/script/layers/domain/push_package.rb +6 -0
  26. data/lib/project_types/script/layers/domain/script_config.rb +2 -4
  27. data/lib/project_types/script/layers/domain/script_project.rb +3 -2
  28. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +19 -4
  29. data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +0 -15
  30. data/lib/project_types/script/layers/infrastructure/languages/typescript_project_creator.rb +19 -4
  31. data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +0 -3
  32. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +4 -0
  33. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +13 -25
  34. data/lib/project_types/script/layers/infrastructure/script_service.rb +4 -2
  35. data/lib/project_types/script/messages/messages.rb +7 -7
  36. data/lib/project_types/script/ui/error_handler.rb +4 -4
  37. data/lib/project_types/script/ui/strict_spinner.rb +4 -6
  38. data/lib/project_types/theme/cli.rb +2 -0
  39. data/lib/project_types/theme/commands/common/root_helper.rb +11 -5
  40. data/lib/project_types/theme/commands/list.rb +34 -0
  41. data/lib/project_types/theme/commands/open.rb +65 -0
  42. data/lib/project_types/theme/commands/pull.rb +2 -2
  43. data/lib/project_types/theme/commands/push.rb +2 -2
  44. data/lib/project_types/theme/forms/select.rb +11 -39
  45. data/lib/project_types/theme/messages/messages.rb +31 -2
  46. data/lib/project_types/theme/presenters/theme_presenter.rb +48 -0
  47. data/lib/project_types/theme/presenters/themes_presenter.rb +32 -0
  48. data/lib/shopify_cli/api.rb +1 -1
  49. data/lib/shopify_cli/constants.rb +2 -2
  50. data/lib/shopify_cli/context.rb +11 -13
  51. data/lib/shopify_cli/services/app/create/rails_service.rb +1 -1
  52. data/lib/shopify_cli/theme/syncer.rb +7 -7
  53. data/lib/shopify_cli/version.rb +1 -1
  54. data/shopify-dev +9 -11
  55. metadata +10 -2
@@ -5,10 +5,6 @@ module Script
5
5
  module Infrastructure
6
6
  module Languages
7
7
  class TypeScriptProjectCreator < ProjectCreator
8
- def self.config_file
9
- "package.json"
10
- end
11
-
12
8
  def setup_dependencies
13
9
  task_runner = Infrastructure::Languages::TypeScriptTaskRunner.new(ctx)
14
10
  task_runner.set_npm_config
@@ -22,6 +18,25 @@ module Script
22
18
  if ctx.file_exist?("package-lock.json")
23
19
  ctx.rm("package-lock.json")
24
20
  end
21
+
22
+ update_package_json_name
23
+ end
24
+
25
+ private
26
+
27
+ def update_package_json_name
28
+ file_content = ctx.read("package.json")
29
+ hash = file_content_to_hash(file_content)
30
+ hash["name"] = project_name
31
+ ctx.write("package.json", hash_to_file_content(hash))
32
+ end
33
+
34
+ def file_content_to_hash(content)
35
+ JSON.parse(content)
36
+ end
37
+
38
+ def hash_to_file_content(hash)
39
+ JSON.pretty_generate(hash)
25
40
  end
26
41
  end
27
42
  end
@@ -5,9 +5,6 @@ module Script
5
5
  module Infrastructure
6
6
  module Languages
7
7
  class WasmProjectCreator < ProjectCreator
8
- def self.config_file
9
- "script.config.yml"
10
- end
11
8
  end
12
9
  end
13
10
  end
@@ -15,6 +15,8 @@ module Script
15
15
  id: build_file_path,
16
16
  uuid: script_project.uuid,
17
17
  extension_point_type: script_project.extension_point_type,
18
+ title: script_project.title,
19
+ description: script_project.description,
18
20
  script_content: script_content,
19
21
  metadata: metadata,
20
22
  script_config: script_project.script_config,
@@ -31,6 +33,8 @@ module Script
31
33
  id: build_file_path,
32
34
  uuid: script_project.uuid,
33
35
  extension_point_type: script_project.extension_point_type,
36
+ title: script_project.title,
37
+ description: script_project.description,
34
38
  script_content: script_content,
35
39
  metadata: metadata,
36
40
  script_config: script_project.script_config,
@@ -27,7 +27,7 @@ module Script
27
27
  change_directory(directory: initial_directory)
28
28
  end
29
29
 
30
- def create(script_name:, extension_point_type:, language:)
30
+ def create(title:, extension_point_type:, language:)
31
31
  validate_metadata!(extension_point_type, language)
32
32
 
33
33
  ShopifyCLI::Project.write(
@@ -35,7 +35,8 @@ module Script
35
35
  project_type: :script,
36
36
  organization_id: nil,
37
37
  extension_point_type: extension_point_type,
38
- script_name: script_name,
38
+ title: title,
39
+ description: nil,
39
40
  language: language
40
41
  )
41
42
 
@@ -48,7 +49,8 @@ module Script
48
49
  Domain::ScriptProject.new(
49
50
  id: project.directory,
50
51
  env: project.env,
51
- script_name: script_name,
52
+ title: title,
53
+ description: description,
52
54
  extension_point_type: extension_point_type,
53
55
  language: language,
54
56
  script_config: script_config_repository.get!,
@@ -79,11 +81,6 @@ module Script
79
81
  build_script_project
80
82
  end
81
83
 
82
- def update_script_config(title:)
83
- script_config = script_config_repository.update!(title: title)
84
- build_script_project(script_config: script_config)
85
- end
86
-
87
84
  private
88
85
 
89
86
  def build_script_project(
@@ -92,7 +89,8 @@ module Script
92
89
  Domain::ScriptProject.new(
93
90
  id: ctx.root,
94
91
  env: project.env,
95
- script_name: script_name,
92
+ title: title,
93
+ description: description,
96
94
  extension_point_type: extension_point_type,
97
95
  language: language,
98
96
  script_config: script_config,
@@ -111,8 +109,12 @@ module Script
111
109
  project_config_value!("extension_point_type")
112
110
  end
113
111
 
114
- def script_name
115
- project_config_value!("script_name")
112
+ def title
113
+ project_config_value!("title")
114
+ end
115
+
116
+ def description
117
+ project_config_value("description")
116
118
  end
117
119
 
118
120
  def language
@@ -181,26 +183,12 @@ module Script
181
183
  from_h(hash)
182
184
  end
183
185
 
184
- def update!(title:)
185
- hash = get!.content
186
- update_hash(hash: hash, title: title)
187
-
188
- ctx.write(filename, hash_to_file_content(hash))
189
-
190
- from_h(hash)
191
- end
192
-
193
186
  def filename
194
187
  raise NotImplementedError
195
188
  end
196
189
 
197
190
  private
198
191
 
199
- def update_hash(hash:, title:)
200
- hash["version"] ||= "2"
201
- hash["title"] = title
202
- end
203
-
204
192
  def from_h(hash)
205
193
  Domain::ScriptConfig.new(content: hash, filename: filename)
206
194
  end
@@ -15,6 +15,8 @@ module Script
15
15
  def set_app_script(
16
16
  uuid:,
17
17
  extension_point_type:,
18
+ title:,
19
+ description:,
18
20
  force: false,
19
21
  metadata:,
20
22
  script_config:,
@@ -26,8 +28,8 @@ module Script
26
28
  variables = {
27
29
  uuid: uuid,
28
30
  extensionPointName: extension_point_type.upcase,
29
- title: script_config.title,
30
- description: script_config.description,
31
+ title: title,
32
+ description: description,
31
33
  force: force,
32
34
  schemaMajorVersion: metadata.schema_major_version.to_s, # API expects string value
33
35
  schemaMinorVersion: metadata.schema_minor_version.to_s, # API expects string value
@@ -24,11 +24,11 @@ module Script
24
24
  oauth_help: "Wait a few minutes and try again.",
25
25
 
26
26
  invalid_context_cause: "Your .shopify-cli.yml is formatted incorrectly. It's missing values for "\
27
- "extension_point_type or script_name.",
27
+ "extension_point_type or title.",
28
28
  invalid_context_help: "Add these values.",
29
29
 
30
- invalid_script_name_cause: "Script name contains unsupported characters.",
31
- invalid_script_name_help: "Use only numbers, letters, hyphens, or underscores.",
30
+ invalid_script_title_cause: "Script title contains unsupported characters.",
31
+ invalid_script_title_help: "Use only numbers, letters, hyphens, or underscores.",
32
32
 
33
33
  no_existing_apps_cause: "Your script can't be pushed to an app because your Partner account "\
34
34
  "doesn't have any apps.",
@@ -37,8 +37,8 @@ module Script
37
37
  no_existing_orgs_cause: "Your account doesn't belong to a Partner Organization.",
38
38
  no_existing_orgs_help: "Visit https://partners.shopify.com/ to create an account.",
39
39
 
40
- project_exists_cause: "A directory with this same name already exists.",
41
- project_exists_help: "Choose a different name for your script.",
40
+ project_exists_cause: "A directory with this same title already exists.",
41
+ project_exists_help: "Choose a different title for your script.",
42
42
 
43
43
  invalid_extension_cause: "The name of the Script API is incorrect: %s.",
44
44
  invalid_extension_help: "Choose a supported API: %s.",
@@ -168,7 +168,7 @@ module Script
168
168
  {{command:%1$s script create}}: Creates a script project.
169
169
  Usage: {{command:%1$s script create}}
170
170
  Options:
171
- {{command:--name=NAME}} Script project name.
171
+ {{command:--title=TITLE}} Script project title.
172
172
  {{command:--api=TYPE}} Script API name. Supported values: %2$s.
173
173
  {{command:--language=LANGUAGE}} Programming language. Defaults to wasm. Supported values: %3$s.
174
174
  HELP
@@ -235,7 +235,7 @@ module Script
235
235
  forms: {
236
236
  create: {
237
237
  select_extension_point: "Which Script API do you want to use?",
238
- script_name: "What do you want to name your script?",
238
+ script_title: "What do you want to title your script?",
239
239
  },
240
240
  },
241
241
 
@@ -59,10 +59,10 @@ module Script
59
59
  Script::Layers::Application::ExtensionPoints.languages(type: e.extension_point_type).join(", ")
60
60
  ),
61
61
  }
62
- when Errors::InvalidScriptNameError
62
+ when Errors::InvalidScriptTitleError
63
63
  {
64
- cause_of_error: ShopifyCLI::Context.message("script.error.invalid_script_name_cause"),
65
- help_suggestion: ShopifyCLI::Context.message("script.error.invalid_script_name_help"),
64
+ cause_of_error: ShopifyCLI::Context.message("script.error.invalid_script_title_cause"),
65
+ help_suggestion: ShopifyCLI::Context.message("script.error.invalid_script_title_help"),
66
66
  }
67
67
  when Errors::NoExistingAppsError
68
68
  {
@@ -96,7 +96,7 @@ module Script
96
96
  {
97
97
  cause_of_error: ShopifyCLI::Context.message(
98
98
  "script.error.script_not_found_cause",
99
- e.script_name,
99
+ e.title,
100
100
  e.extension_point_type
101
101
  ),
102
102
  }
@@ -8,12 +8,10 @@ module Script
8
8
  def self.spin(title, auto_debrief: false)
9
9
  exception = nil
10
10
  CLI::UI::Spinner.spin(title, auto_debrief: auto_debrief) do |*args|
11
- begin
12
- yield(*args)
13
- rescue StandardError => e
14
- exception = e
15
- CLI::UI::Spinner::TASK_FAILED
16
- end
11
+ yield(*args)
12
+ rescue StandardError => e
13
+ exception = e
14
+ CLI::UI::Spinner::TASK_FAILED
17
15
  end
18
16
  raise exception if exception
19
17
  end
@@ -14,6 +14,8 @@ module Theme
14
14
  subcommand :Check, "check", Project.project_filepath("commands/check")
15
15
  subcommand :Publish, "publish", Project.project_filepath("commands/publish")
16
16
  subcommand :Package, "package", Project.project_filepath("commands/package")
17
+ subcommand :Open, "open", Project.project_filepath("commands/open")
18
+ subcommand :List, "list", Project.project_filepath("commands/list")
17
19
  subcommand :LanguageServer, "language-server", Project.project_filepath("commands/language_server")
18
20
  end
19
21
  ShopifyCLI::Commands.register("Theme::Command", "theme")
@@ -15,15 +15,16 @@ module Theme
15
15
 
16
16
  while next_index < argv.size
17
17
  element = argv[next_index]
18
- option = option_by_key[element]
18
+ key, value = key_value_tuple(element)
19
+ option = option_by_key[key]
19
20
 
20
21
  return element if option.nil?
21
22
 
22
23
  # Skip the option argument
23
- next_index += 1 unless option.arg.nil?
24
+ next_index += 1 if !option.arg.nil? && !value
24
25
 
25
26
  # PATTERN arguments take precedence over the `root`
26
- if option.arg =~ /PATTERN/
27
+ if option.arg =~ /PATTERN/ && !value
27
28
  next_index += 1 while option_argument?(argv, next_index, option_by_key)
28
29
  next
29
30
  end
@@ -37,7 +38,7 @@ module Theme
37
38
  private
38
39
 
39
40
  def default_argv(options)
40
- options.parser.default_argv
41
+ options.parser.default_argv.compact
41
42
  end
42
43
 
43
44
  def options_map(options)
@@ -57,7 +58,12 @@ module Theme
57
58
  return false unless next_index < argv.size
58
59
 
59
60
  element = argv[next_index]
60
- option_by_key[element].nil?
61
+ key, _value = key_value_tuple(element)
62
+ option_by_key[key].nil?
63
+ end
64
+
65
+ def key_value_tuple(element)
66
+ element.split("=")
61
67
  end
62
68
  end
63
69
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shopify_cli/theme/theme"
4
+ require "project_types/theme/presenters/themes_presenter"
5
+
6
+ module Theme
7
+ class Command
8
+ class List < ShopifyCLI::Command::SubCommand
9
+ recommend_default_ruby_range
10
+
11
+ def call(_args, _name)
12
+ @ctx.puts(@ctx.message("theme.list.title", shop))
13
+
14
+ themes_presenter.all.each do |theme|
15
+ @ctx.puts(" #{theme}")
16
+ end
17
+ end
18
+
19
+ def self.help
20
+ @ctx.message("theme.list.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
21
+ end
22
+
23
+ private
24
+
25
+ def themes_presenter
26
+ Theme::Presenters::ThemesPresenter.new(@ctx, nil)
27
+ end
28
+
29
+ def shop
30
+ ShopifyCLI::AdminAPI.get_shop_or_abort(@ctx)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shopify_cli/theme/theme"
4
+ require "shopify_cli/theme/development_theme"
5
+
6
+ module Theme
7
+ class Command
8
+ class Open < ShopifyCLI::Command::SubCommand
9
+ recommend_default_ruby_range
10
+
11
+ options do |parser, flags|
12
+ parser.on("-t", "--theme=NAME_OR_ID") { |theme| flags[:theme] = theme }
13
+ parser.on("-l", "--live") { flags[:live] = true }
14
+ parser.on("-d", "--development") { flags[:development] = true }
15
+ end
16
+
17
+ def call(_args, _name)
18
+ theme = find_theme(**options.flags)
19
+
20
+ @ctx.puts(@ctx.message("theme.open.details", theme.name, theme.editor_url))
21
+ @ctx.open_url!(theme.preview_url)
22
+ end
23
+
24
+ def self.help
25
+ ShopifyCLI::Context.message("theme.open.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
26
+ end
27
+
28
+ def find_theme(theme: nil, live: nil, development: nil, **_args)
29
+ return theme_by_identifier(theme) if theme
30
+ return live_theme if live
31
+ return development_theme if development
32
+
33
+ select_theme
34
+ end
35
+
36
+ def theme_by_identifier(identifier)
37
+ theme = ShopifyCLI::Theme::Theme.find_by_identifier(@ctx, identifier: identifier)
38
+ theme || not_found_error(identifier)
39
+ end
40
+
41
+ def development_theme
42
+ theme = ShopifyCLI::Theme::DevelopmentTheme.find(@ctx)
43
+ theme || not_found_error("development")
44
+ end
45
+
46
+ def live_theme
47
+ ShopifyCLI::Theme::Theme.live(@ctx)
48
+ end
49
+
50
+ def not_found_error(identifier)
51
+ @ctx.abort(@ctx.message("theme.open.theme_not_found", identifier))
52
+ end
53
+
54
+ def select_theme
55
+ form = Forms::Select.ask(
56
+ @ctx,
57
+ [],
58
+ title: @ctx.message("theme.open.select"),
59
+ root: nil
60
+ )
61
+ form&.theme
62
+ end
63
+ end
64
+ end
65
+ end
@@ -45,8 +45,8 @@ module Theme
45
45
  ignore_filter.add_patterns(options.flags[:ignores]) if options.flags[:ignores]
46
46
 
47
47
  syncer = ShopifyCLI::Theme::Syncer.new(@ctx, theme: theme,
48
- include_filter: include_filter,
49
- ignore_filter: ignore_filter)
48
+ include_filter: include_filter,
49
+ ignore_filter: ignore_filter)
50
50
  begin
51
51
  syncer.start_threads
52
52
  CLI::UI::Frame.open(@ctx.message("theme.pull.pulling", theme.name, theme.id, theme.shop)) do
@@ -55,8 +55,8 @@ module Theme
55
55
  ignore_filter.add_patterns(options.flags[:ignores]) if options.flags[:ignores]
56
56
 
57
57
  syncer = ShopifyCLI::Theme::Syncer.new(@ctx, theme: theme,
58
- include_filter: include_filter,
59
- ignore_filter: ignore_filter)
58
+ include_filter: include_filter,
59
+ ignore_filter: ignore_filter)
60
60
  begin
61
61
  syncer.start_threads
62
62
  if options.flags[:json]
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "project_types/theme/presenters/themes_presenter"
4
+
1
5
  module Theme
2
6
  module Forms
3
7
  class Select < ShopifyCLI::Form
@@ -6,53 +10,21 @@ module Theme
6
10
 
7
11
  def ask
8
12
  self.theme = CLI::UI::Prompt.ask(title, allow_empty: false) do |handler|
9
- themes.each do |theme|
13
+ theme_presenters.each do |presenter|
14
+ theme = presenter.theme
15
+
10
16
  next if exclude_roles&.include?(theme.role)
11
17
  next if !include_foreign_developments && theme.foreign_development?
12
- handler.option("#{theme.name} #{theme_tags(theme)}") { theme }
18
+
19
+ handler.option(presenter.to_s(:short)) { theme }
13
20
  end
14
21
  end
15
22
  end
16
23
 
17
24
  private
18
25
 
19
- def themes
20
- @themes ||= ShopifyCLI::Theme::Theme.all(@ctx, root: root)
21
- .sort_by { |theme| theme_sort_order(theme) }
22
- end
23
-
24
- def theme_sort_order(theme)
25
- case theme.role
26
- when "live"
27
- 0
28
- when "unpublished"
29
- 1
30
- when "development"
31
- 2
32
- else
33
- 3
34
- end
35
- end
36
-
37
- def theme_tags(theme)
38
- color = case theme.role
39
- when "live"
40
- "green"
41
- when "unpublished"
42
- "yellow"
43
- when "development"
44
- "blue"
45
- else
46
- "italic"
47
- end
48
-
49
- tags = ["{{#{color}:[#{theme.role}]}}"]
50
-
51
- if theme.current_development?
52
- tags << "{{cyan:[yours]}}}}"
53
- end
54
-
55
- tags.join(" ")
26
+ def theme_presenters
27
+ Theme::Presenters::ThemesPresenter.new(ctx, root).all
56
28
  end
57
29
  end
58
30
  end
@@ -87,7 +87,7 @@ module Theme
87
87
  {{info:View your theme:}}
88
88
  {{underline:%s}}
89
89
 
90
- {{info:Customize this theme in the Online Store Editor:}}
90
+ {{info:Customize this theme in the Theme Editor:}}
91
91
  {{underline:%s}}
92
92
  DONE
93
93
  name: "Theme name",
@@ -130,7 +130,7 @@ module Theme
130
130
  SERVING
131
131
  customize_or_preview: <<~CUSTOMIZE_OR_PREVIEW,
132
132
 
133
- Customize this theme in the Online Store Editor:
133
+ Customize this theme in the Theme Editor:
134
134
  {{green:%s}}
135
135
 
136
136
  Share this theme preview:
@@ -215,6 +215,35 @@ module Theme
215
215
  WARN
216
216
  theme_not_found: "Theme \"%s\" doesn't exist",
217
217
  },
218
+ open: {
219
+ select: "Select a theme to open",
220
+ theme_not_found: "Theme \"%s\" doesn't exist",
221
+ details: <<~DETAILS,
222
+ {{*}} {{bold:%s}}
223
+
224
+ Customize your theme in the Theme Editor:
225
+ {{green:%s}}
226
+
227
+ DETAILS
228
+ help: <<~HELP,
229
+ {{command:%s theme open}}: Opens the preview of your remote theme.
230
+
231
+ Usage: {{command:%s theme open}}
232
+
233
+ Options:
234
+ {{command:-t, --theme=NAME_OR_ID}} Theme ID or name of your theme.
235
+ {{command:-l, --live}} Open your live theme.
236
+ {{command:-d, --development}} Open your development theme.
237
+ HELP
238
+ },
239
+ list: {
240
+ title: "{{*}} List of {{bold:%s}} themes:",
241
+ help: <<~HELP,
242
+ {{command:%s theme list}}: Lists your remote themes.
243
+
244
+ Usage: {{command:%s theme list}}
245
+ HELP
246
+ },
218
247
  },
219
248
  }.freeze
220
249
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module Theme
6
+ module Presenters
7
+ class ThemePresenter
8
+ extend Forwardable
9
+
10
+ COLOR_BY_ROLE = {
11
+ "live" => "green",
12
+ "unpublished" => "yellow",
13
+ "development" => "blue",
14
+ }
15
+
16
+ attr_reader :theme
17
+
18
+ def_delegators :theme, :id, :name, :role
19
+
20
+ def initialize(theme)
21
+ @theme = theme
22
+ end
23
+
24
+ def to_s(mode = :long)
25
+ case mode
26
+ when :short
27
+ "{{bold:#{name} #{theme_tags}}}"
28
+ when :long
29
+ "{{green:##{id}}} {{bold:#{name} #{theme_tags}}}"
30
+ else
31
+ inspect
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def theme_tags
38
+ tags = ["{{#{tag_color}:[#{role}]}}"]
39
+ tags << "{{cyan:[yours]}}}}" if theme.current_development?
40
+ tags.join(" ")
41
+ end
42
+
43
+ def tag_color
44
+ COLOR_BY_ROLE[role] || "italic"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "theme_presenter"
4
+
5
+ module Theme
6
+ module Presenters
7
+ class ThemesPresenter
8
+ ORDER_BY_ROLE = %w(live unpublished development)
9
+
10
+ def initialize(ctx, root)
11
+ @ctx = ctx
12
+ @root = root
13
+ end
14
+
15
+ def all
16
+ all_themes
17
+ .sort_by { |theme| order_by_role(theme) }
18
+ .map { |theme| ThemePresenter.new(theme) }
19
+ end
20
+
21
+ private
22
+
23
+ def order_by_role(theme)
24
+ ORDER_BY_ROLE.index(theme.role) || ORDER_BY_ROLE.size
25
+ end
26
+
27
+ def all_themes
28
+ ShopifyCLI::Theme::Theme.all(@ctx, root: @root)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -85,7 +85,7 @@ module ShopifyCLI
85
85
  end
86
86
  rescue Errno::ETIMEDOUT, Timeout::Error
87
87
  ctx.debug("timeout in #{method} #{uri} with X-Request-Id: #{headers["X-Request-Id"]}")
88
- raise APIRequestTimeoutError.new("Timeout")
88
+ raise APIRequestTimeoutError, "Timeout"
89
89
  end.retry_after(APIRequestRetriableError, retries: 3) do |e|
90
90
  sleep(1) if e.is_a?(APIRequestThrottledError)
91
91
  end
@@ -61,12 +61,12 @@ module ShopifyCLI
61
61
  module SupportedVersions
62
62
  module Ruby
63
63
  FROM = "2.6.6"
64
- TO = "3.1.0"
64
+ TO = "3.2.0"
65
65
  end
66
66
 
67
67
  module Node
68
68
  FROM = "14.5.0"
69
- TO = "17.0.0"
69
+ TO = "18.0.0"
70
70
  end
71
71
  end
72
72