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.
- checksums.yaml +4 -4
- data/.github/workflows/shopify.yml +2 -1
- data/.rubocop.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +14 -14
- data/bin/shopify +4 -4
- data/dev.yml +1 -1
- data/ext/javy/hashes/javy-arm-macos-v0.2.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-linux-v0.2.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-macos-v0.2.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-windows-v0.2.0.gz.sha256 +1 -0
- data/ext/javy/version +1 -1
- data/lib/project_types/extension/features/argo_setup_steps.rb +4 -6
- data/lib/project_types/extension/tasks/configure_features.rb +15 -2
- data/lib/project_types/extension/tasks/convert_server_config.rb +2 -1
- data/lib/project_types/script/commands/create.rb +4 -4
- data/lib/project_types/script/errors.rb +1 -1
- data/lib/project_types/script/forms/create.rb +7 -7
- data/lib/project_types/script/layers/application/build_script.rb +22 -24
- data/lib/project_types/script/layers/application/create_script.rb +9 -10
- data/lib/project_types/script/layers/application/project_dependencies.rb +12 -14
- data/lib/project_types/script/layers/application/push_script.rb +2 -0
- data/lib/project_types/script/layers/domain/errors.rb +3 -3
- data/lib/project_types/script/layers/domain/push_package.rb +6 -0
- data/lib/project_types/script/layers/domain/script_config.rb +2 -4
- data/lib/project_types/script/layers/domain/script_project.rb +3 -2
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +19 -4
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +0 -15
- data/lib/project_types/script/layers/infrastructure/languages/typescript_project_creator.rb +19 -4
- data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +0 -3
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +4 -0
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +13 -25
- data/lib/project_types/script/layers/infrastructure/script_service.rb +4 -2
- data/lib/project_types/script/messages/messages.rb +7 -7
- data/lib/project_types/script/ui/error_handler.rb +4 -4
- data/lib/project_types/script/ui/strict_spinner.rb +4 -6
- data/lib/project_types/theme/cli.rb +2 -0
- data/lib/project_types/theme/commands/common/root_helper.rb +11 -5
- data/lib/project_types/theme/commands/list.rb +34 -0
- data/lib/project_types/theme/commands/open.rb +65 -0
- data/lib/project_types/theme/commands/pull.rb +2 -2
- data/lib/project_types/theme/commands/push.rb +2 -2
- data/lib/project_types/theme/forms/select.rb +11 -39
- data/lib/project_types/theme/messages/messages.rb +31 -2
- data/lib/project_types/theme/presenters/theme_presenter.rb +48 -0
- data/lib/project_types/theme/presenters/themes_presenter.rb +32 -0
- data/lib/shopify_cli/api.rb +1 -1
- data/lib/shopify_cli/constants.rb +2 -2
- data/lib/shopify_cli/context.rb +11 -13
- data/lib/shopify_cli/services/app/create/rails_service.rb +1 -1
- data/lib/shopify_cli/theme/syncer.rb +7 -7
- data/lib/shopify_cli/version.rb +1 -1
- data/shopify-dev +9 -11
- 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
|
@@ -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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
115
|
-
project_config_value!("
|
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:
|
30
|
-
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
|
27
|
+
"extension_point_type or title.",
|
28
28
|
invalid_context_help: "Add these values.",
|
29
29
|
|
30
|
-
|
31
|
-
|
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
|
41
|
-
project_exists_help: "Choose a different
|
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:--
|
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
|
-
|
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::
|
62
|
+
when Errors::InvalidScriptTitleError
|
63
63
|
{
|
64
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.
|
65
|
-
help_suggestion: ShopifyCLI::Context.message("script.error.
|
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.
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
49
|
-
|
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
|
-
|
59
|
-
|
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
|
-
|
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
|
-
|
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
|
20
|
-
|
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
|
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
|
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
|
data/lib/shopify_cli/api.rb
CHANGED
@@ -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
|
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
|