shopify-cli 2.7.0 → 2.7.4
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/CODEOWNERS +2 -2
- data/.github/workflows/shopify.yml +1 -1
- data/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +46 -0
- data/Codespace.dockerfile +2 -2
- data/Gemfile.lock +4 -4
- data/Rakefile +27 -0
- data/Tests.dockerfile +2 -2
- data/dev.yml +3 -3
- data/ext/javy/hashes/javy-arm-macos-v0.1.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-linux-v0.1.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-macos-v0.1.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-windows-v0.1.0.gz.sha256 +1 -0
- data/ext/javy/javy.rb +204 -0
- data/ext/javy/version +1 -0
- data/lib/graphql/get_extension_registrations.graphql +27 -0
- data/lib/project_types/extension/cli.rb +27 -2
- data/lib/project_types/extension/commands/build.rb +10 -14
- data/lib/project_types/extension/commands/create.rb +3 -6
- data/lib/project_types/extension/commands/push.rb +36 -8
- data/lib/project_types/extension/extension_project.rb +1 -1
- data/lib/project_types/extension/features/argo_serve.rb +6 -5
- data/lib/project_types/extension/forms/questions/ask_registration.rb +6 -2
- data/lib/project_types/extension/loaders/project.rb +29 -0
- data/lib/project_types/extension/loaders/specification_handler.rb +22 -0
- data/lib/project_types/extension/messages/messages.rb +4 -2
- data/lib/project_types/extension/models/app.rb +1 -1
- data/lib/project_types/extension/models/development_server.rb +2 -2
- data/lib/project_types/extension/models/specification_handlers/default.rb +4 -0
- data/lib/project_types/extension/tasks/convert_server_config.rb +3 -1
- data/lib/project_types/extension/tasks/execute_commands/base.rb +13 -0
- data/lib/project_types/extension/tasks/execute_commands/build.rb +29 -0
- data/lib/project_types/extension/tasks/execute_commands/create.rb +33 -0
- data/lib/project_types/extension/tasks/execute_commands/serve.rb +35 -0
- data/lib/project_types/extension/tasks/merge_server_config.rb +33 -22
- data/lib/project_types/rails/commands/create.rb +2 -4
- data/lib/project_types/script/cli.rb +9 -1
- data/lib/project_types/script/commands/connect.rb +19 -0
- data/lib/project_types/script/commands/create.rb +1 -3
- data/lib/project_types/script/commands/javy.rb +29 -0
- data/lib/project_types/script/commands/push.rb +2 -1
- data/lib/project_types/script/config/extension_points.yml +12 -30
- data/lib/project_types/script/forms/ask_app.rb +32 -0
- data/lib/project_types/script/forms/ask_org.rb +30 -0
- data/lib/project_types/script/forms/ask_script_uuid.rb +22 -0
- data/lib/project_types/script/forms/run_against_shopify_org.rb +14 -0
- data/lib/project_types/script/graphql/app_script_set.graphql +2 -2
- data/lib/project_types/script/layers/application/build_script.rb +0 -1
- data/lib/project_types/script/layers/application/connect_app.rb +79 -0
- data/lib/project_types/script/layers/application/create_script.rb +17 -17
- data/lib/project_types/script/layers/application/push_script.rb +1 -1
- data/lib/project_types/script/layers/domain/errors.rb +1 -4
- data/lib/project_types/script/layers/domain/push_package.rb +3 -3
- data/lib/project_types/script/layers/domain/{script_json.rb → script_config.rb} +2 -2
- data/lib/project_types/script/layers/domain/script_project.rb +5 -1
- data/lib/project_types/script/layers/infrastructure/errors.rb +36 -7
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +0 -4
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +0 -4
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +2 -2
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +125 -27
- data/lib/project_types/script/layers/infrastructure/script_service.rb +11 -11
- data/lib/project_types/script/messages/messages.rb +32 -4
- data/lib/project_types/script/ui/error_handler.rb +31 -21
- data/lib/project_types/theme/commands/pull.rb +3 -0
- data/lib/project_types/theme/commands/push.rb +7 -1
- data/lib/project_types/theme/commands/serve.rb +1 -1
- data/lib/project_types/theme/messages/messages.rb +35 -1
- data/lib/project_types/theme/ui/sync_progress_bar.rb +2 -2
- data/lib/shopify_cli/command/project_command.rb +20 -7
- data/lib/shopify_cli/command.rb +6 -0
- data/lib/shopify_cli/commands/app/create/node.rb +1 -3
- data/lib/shopify_cli/commands/app/create/rails.rb +1 -3
- data/lib/shopify_cli/constants.rb +7 -0
- data/lib/shopify_cli/context.rb +11 -1
- data/lib/shopify_cli/environment.rb +4 -0
- data/lib/shopify_cli/form.rb +2 -0
- data/lib/shopify_cli/git.rb +2 -0
- data/lib/shopify_cli/identity_auth.rb +18 -0
- data/lib/shopify_cli/messages/messages.rb +9 -2
- data/lib/shopify_cli/partners_api/app_extensions/job.rb +36 -0
- data/lib/shopify_cli/partners_api/app_extensions.rb +46 -0
- data/lib/shopify_cli/partners_api/organizations.rb +2 -5
- data/lib/shopify_cli/partners_api.rb +2 -8
- data/lib/shopify_cli/project.rb +8 -7
- data/lib/shopify_cli/resources/env_file.rb +13 -5
- data/lib/shopify_cli/services/app/create/node_service.rb +2 -0
- data/lib/shopify_cli/services/app/create/php_service.rb +1 -1
- data/lib/shopify_cli/services/app/create/rails_service.rb +3 -1
- data/lib/shopify_cli/services/app/serve/node_service.rb +1 -1
- data/lib/shopify_cli/services/app/serve/rails_service.rb +1 -1
- data/lib/shopify_cli/tasks/ensure_authenticated.rb +9 -3
- data/lib/shopify_cli/theme/dev_server/cdn_fonts.rb +73 -0
- data/lib/shopify_cli/theme/dev_server/hot-reload.js +38 -9
- data/lib/shopify_cli/theme/dev_server/proxy/template_param_builder.rb +84 -0
- data/lib/shopify_cli/theme/dev_server/proxy.rb +9 -15
- data/lib/shopify_cli/theme/dev_server.rb +32 -19
- data/lib/shopify_cli/theme/syncer/error_reporter.rb +45 -0
- data/lib/shopify_cli/theme/syncer/operation.rb +56 -0
- data/lib/shopify_cli/theme/syncer/standard_reporter.rb +32 -0
- data/lib/shopify_cli/theme/syncer.rb +40 -39
- data/lib/shopify_cli/theme/theme.rb +31 -19
- data/lib/shopify_cli/thread_pool/job.rb +27 -0
- data/lib/shopify_cli/thread_pool.rb +37 -0
- data/lib/shopify_cli/tunnel.rb +26 -22
- data/lib/shopify_cli/version.rb +1 -1
- data/shopify-cli.gemspec +1 -1
- data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +3 -1
- data/vendor/deps/cli-kit/lib/cli/kit/system.rb +1 -1
- metadata +34 -8
- data/lib/graphql/all_orgs_with_extensions.graphql +0 -37
- data/lib/project_types/extension/tasks/run_extension_command.rb +0 -82
- data/lib/project_types/script/tasks/ensure_env.rb +0 -106
|
@@ -47,14 +47,20 @@ module Script
|
|
|
47
47
|
invalid_language_cause: "Invalid language %s.",
|
|
48
48
|
invalid_language_help: "Allowed values: %s.",
|
|
49
49
|
|
|
50
|
+
missing_script_config_yml_field_cause: "The script.config.yml file is missing the required %s field.",
|
|
51
|
+
missing_script_config_yml_field_help: "Add the field and try again.",
|
|
52
|
+
|
|
50
53
|
missing_script_json_field_cause: "The script.json file is missing the required %s field.",
|
|
51
54
|
missing_script_json_field_help: "Add the field and try again.",
|
|
52
55
|
|
|
53
56
|
invalid_script_json_definition_cause: "The script.json file contains invalid JSON.",
|
|
54
57
|
invalid_script_json_definition_help: "Fix the errors and try again.",
|
|
55
58
|
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
invalid_script_config_yml_definition_cause: "The script.config.yml file contains invalid YAML.",
|
|
60
|
+
invalid_script_config_yml_definition_help: "Fix the errors and try again.",
|
|
61
|
+
|
|
62
|
+
no_script_config_yml_file_cause: "The script.config.yml file is missing.",
|
|
63
|
+
no_script_config_yml_file_help: "Create this file and try again.",
|
|
58
64
|
|
|
59
65
|
configuration_syntax_error_cause: "The script.json is not formatted properly.",
|
|
60
66
|
configuration_syntax_error_help: "Fix the errors and try again.",
|
|
@@ -115,8 +121,6 @@ module Script
|
|
|
115
121
|
script_repush_cause: "A version of this script already exists on the app.",
|
|
116
122
|
script_repush_help: "Use {{cyan:--force}} to replace the existing script.",
|
|
117
123
|
|
|
118
|
-
invalid_build_script: "The root package.json contains an invalid build command that " \
|
|
119
|
-
"is needed to compile your script to WebAssembly.",
|
|
120
124
|
build_script_not_found: "The root package.json is missing the build command that " \
|
|
121
125
|
"is needed to compile your script to WebAssembly.",
|
|
122
126
|
# rubocop:disable Layout/LineLength
|
|
@@ -140,6 +144,7 @@ module Script
|
|
|
140
144
|
|
|
141
145
|
language_library_for_api_not_found_cause: "Script can’t be pushed because the %{language} library for API %{api} is missing.",
|
|
142
146
|
language_library_for_api_not_found_help: "Make sure extension_point.yml contains the correct API library.",
|
|
147
|
+
no_scripts_found_in_app: "The selected apps have no scripts. Please, create them first on the partners' dashboard.",
|
|
143
148
|
},
|
|
144
149
|
|
|
145
150
|
create: {
|
|
@@ -175,6 +180,29 @@ module Script
|
|
|
175
180
|
|
|
176
181
|
script_pushed: "{{v}} Script pushed to app (API key: %{api_key}).",
|
|
177
182
|
},
|
|
183
|
+
connect: {
|
|
184
|
+
connected: "Connected! Your project is now connected to {{green:%s}}",
|
|
185
|
+
missing_script: "No script has been selected.",
|
|
186
|
+
help: <<~HELP,
|
|
187
|
+
{{command:%s script connect}}: Connects an existing script to an app.
|
|
188
|
+
Usage: {{command:%s script connect}}
|
|
189
|
+
HELP
|
|
190
|
+
error: {
|
|
191
|
+
operation_failed: "Couldn't connect script to app.",
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
javy: {
|
|
195
|
+
help: <<~HELP,
|
|
196
|
+
Compile the JavaScript code into WebAssembly.
|
|
197
|
+
Usage: {{command:%s script javy}}
|
|
198
|
+
Options:
|
|
199
|
+
{{command:--in}} The name of the JavaScript file that will be compiled.
|
|
200
|
+
{{command:--out}} The name of the file that the WebAssembly should be written to.
|
|
201
|
+
HELP
|
|
202
|
+
errors: {
|
|
203
|
+
invalid_arguments: "Javy was run with invalid arguments. Run {{command: %s script javy --help}} for more information.",
|
|
204
|
+
},
|
|
205
|
+
},
|
|
178
206
|
|
|
179
207
|
project_deps: {
|
|
180
208
|
none_required: "{{v}} None required",
|
|
@@ -74,7 +74,7 @@ module Script
|
|
|
74
74
|
}
|
|
75
75
|
when Layers::Infrastructure::Errors::DeprecatedEPError
|
|
76
76
|
{
|
|
77
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.deprecated_ep", e.
|
|
77
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.deprecated_ep", e.extension_point),
|
|
78
78
|
help_suggestion: ShopifyCLI::Context.message("script.error.deprecated_ep_cause"),
|
|
79
79
|
}
|
|
80
80
|
when Layers::Domain::Errors::InvalidExtensionPointError
|
|
@@ -103,32 +103,47 @@ module Script
|
|
|
103
103
|
cause_of_error: ShopifyCLI::Context.message("script.error.metadata_not_found_cause"),
|
|
104
104
|
help_suggestion: ShopifyCLI::Context.message("script.error.metadata_not_found_help"),
|
|
105
105
|
}
|
|
106
|
-
when Layers::
|
|
106
|
+
when Layers::Infrastructure::Errors::BuildError
|
|
107
107
|
{
|
|
108
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.
|
|
109
|
-
help_suggestion: ShopifyCLI::Context.message("script.error.
|
|
108
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.build_error_cause"),
|
|
109
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.build_error_help"),
|
|
110
110
|
}
|
|
111
|
-
when Layers::
|
|
111
|
+
when Layers::Infrastructure::Errors::InvalidScriptConfigYmlDefinitionError
|
|
112
|
+
{
|
|
113
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.invalid_script_config_yml_definition_cause"),
|
|
114
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.invalid_script_config_yml_definition_help"),
|
|
115
|
+
}
|
|
116
|
+
when Layers::Infrastructure::Errors::InvalidScriptJsonDefinitionError
|
|
112
117
|
{
|
|
113
118
|
cause_of_error: ShopifyCLI::Context.message("script.error.invalid_script_json_definition_cause"),
|
|
114
119
|
help_suggestion: ShopifyCLI::Context.message("script.error.invalid_script_json_definition_help"),
|
|
115
120
|
}
|
|
116
|
-
when Layers::
|
|
121
|
+
when Layers::Infrastructure::Errors::MissingScriptConfigYmlFieldError
|
|
117
122
|
{
|
|
118
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.
|
|
119
|
-
help_suggestion: ShopifyCLI::Context.message("script.error.
|
|
123
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.missing_script_config_yml_field_cause", e.field),
|
|
124
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.missing_script_config_yml_field_help"),
|
|
120
125
|
}
|
|
121
|
-
when Layers::Infrastructure::Errors::
|
|
126
|
+
when Layers::Infrastructure::Errors::MissingScriptConfigYmlFieldError
|
|
122
127
|
{
|
|
123
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.
|
|
124
|
-
help_suggestion: ShopifyCLI::Context.message("script.error.
|
|
128
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.missing_script_config_yml_field_cause", e.field),
|
|
129
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.missing_script_config_yml_field_help"),
|
|
125
130
|
}
|
|
126
|
-
when Layers::Infrastructure::Errors::
|
|
131
|
+
when Layers::Infrastructure::Errors::MissingScriptJsonFieldError
|
|
132
|
+
{
|
|
133
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.missing_script_json_field_cause", e.field),
|
|
134
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.missing_script_json_field_help"),
|
|
135
|
+
}
|
|
136
|
+
when Layers::Infrastructure::Errors::NoScriptConfigYmlFileError
|
|
137
|
+
{
|
|
138
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.no_script_config_yml_file_cause"),
|
|
139
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.no_script_config_yml_file_help"),
|
|
140
|
+
}
|
|
141
|
+
when Layers::Infrastructure::Errors::ScriptConfigSyntaxError
|
|
127
142
|
{
|
|
128
143
|
cause_of_error: ShopifyCLI::Context.message("script.error.configuration_syntax_error_cause"),
|
|
129
144
|
help_suggestion: ShopifyCLI::Context.message("script.error.configuration_syntax_error_help"),
|
|
130
145
|
}
|
|
131
|
-
when Layers::Infrastructure::Errors::
|
|
146
|
+
when Layers::Infrastructure::Errors::ScriptConfigMissingKeysError
|
|
132
147
|
{
|
|
133
148
|
cause_of_error: ShopifyCLI::Context.message(
|
|
134
149
|
"script.error.configuration_missing_keys_error_cause",
|
|
@@ -136,7 +151,7 @@ module Script
|
|
|
136
151
|
),
|
|
137
152
|
help_suggestion: ShopifyCLI::Context.message("script.error.configuration_missing_keys_error_help"),
|
|
138
153
|
}
|
|
139
|
-
when Layers::Infrastructure::Errors::
|
|
154
|
+
when Layers::Infrastructure::Errors::ScriptConfigInvalidValueError
|
|
140
155
|
{
|
|
141
156
|
cause_of_error: ShopifyCLI::Context.message(
|
|
142
157
|
"script.error.configuration_invalid_value_error_cause",
|
|
@@ -144,7 +159,7 @@ module Script
|
|
|
144
159
|
),
|
|
145
160
|
help_suggestion: ShopifyCLI::Context.message("script.error.configuration_invalid_value_error_help"),
|
|
146
161
|
}
|
|
147
|
-
when Layers::Infrastructure::Errors::
|
|
162
|
+
when Layers::Infrastructure::Errors::ScriptConfigFieldsMissingKeysError
|
|
148
163
|
{
|
|
149
164
|
cause_of_error: ShopifyCLI::Context.message(
|
|
150
165
|
"script.error.configuration_schema_field_missing_keys_error_cause",
|
|
@@ -154,7 +169,7 @@ module Script
|
|
|
154
169
|
"script.error.configuration_definition_schema_field_missing_keys_error_help"
|
|
155
170
|
),
|
|
156
171
|
}
|
|
157
|
-
when Layers::Infrastructure::Errors::
|
|
172
|
+
when Layers::Infrastructure::Errors::ScriptConfigFieldsInvalidValueError
|
|
158
173
|
{
|
|
159
174
|
cause_of_error: ShopifyCLI::Context.message(
|
|
160
175
|
"script.error.configuration_schema_field_invalid_value_error_cause",
|
|
@@ -201,11 +216,6 @@ module Script
|
|
|
201
216
|
cause_of_error: ShopifyCLI::Context.message("script.error.build_script_not_found"),
|
|
202
217
|
help_suggestion: ShopifyCLI::Context.message("script.error.build_script_suggestion"),
|
|
203
218
|
}
|
|
204
|
-
when Layers::Infrastructure::Errors::InvalidBuildScriptError
|
|
205
|
-
{
|
|
206
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.invalid_build_script"),
|
|
207
|
-
help_suggestion: ShopifyCLI::Context.message("script.error.build_script_suggestion"),
|
|
208
|
-
}
|
|
209
219
|
when Layers::Infrastructure::Errors::WebAssemblyBinaryNotFoundError
|
|
210
220
|
{
|
|
211
221
|
cause_of_error: ShopifyCLI::Context.message("script.error.web_assembly_binary_not_found"),
|
|
@@ -9,6 +9,7 @@ module Theme
|
|
|
9
9
|
options do |parser, flags|
|
|
10
10
|
parser.on("-n", "--nodelete") { flags[:nodelete] = true }
|
|
11
11
|
parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
|
|
12
|
+
parser.on("-l", "--live") { flags[:live] = true }
|
|
12
13
|
parser.on("-x", "--ignore=PATTERN") do |pattern|
|
|
13
14
|
flags[:ignores] ||= []
|
|
14
15
|
flags[:ignores] << pattern
|
|
@@ -21,6 +22,8 @@ module Theme
|
|
|
21
22
|
|
|
22
23
|
theme = if (theme_id = options.flags[:theme_id])
|
|
23
24
|
ShopifyCLI::Theme::Theme.new(@ctx, root: root, id: theme_id)
|
|
25
|
+
elsif options.flags[:live]
|
|
26
|
+
ShopifyCLI::Theme::Theme.live(@ctx, root: root)
|
|
24
27
|
else
|
|
25
28
|
form = Forms::Select.ask(
|
|
26
29
|
@ctx,
|
|
@@ -10,6 +10,7 @@ module Theme
|
|
|
10
10
|
options do |parser, flags|
|
|
11
11
|
parser.on("-n", "--nodelete") { flags[:nodelete] = true }
|
|
12
12
|
parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
|
|
13
|
+
parser.on("-l", "--live") { flags[:live] = true }
|
|
13
14
|
parser.on("-d", "--development") { flags[:development] = true }
|
|
14
15
|
parser.on("-u", "--unpublished") { flags[:unpublished] = true }
|
|
15
16
|
parser.on("-j", "--json") { flags[:json] = true }
|
|
@@ -27,6 +28,8 @@ module Theme
|
|
|
27
28
|
|
|
28
29
|
theme = if (theme_id = options.flags[:theme_id])
|
|
29
30
|
ShopifyCLI::Theme::Theme.new(@ctx, root: root, id: theme_id)
|
|
31
|
+
elsif options.flags[:live]
|
|
32
|
+
ShopifyCLI::Theme::Theme.live(@ctx, root: root)
|
|
30
33
|
elsif options.flags[:development]
|
|
31
34
|
theme = ShopifyCLI::Theme::DevelopmentTheme.new(@ctx, root: root)
|
|
32
35
|
theme.ensure_exists!
|
|
@@ -48,7 +51,9 @@ module Theme
|
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
if theme.live? && !options.flags[:allow_live]
|
|
51
|
-
|
|
54
|
+
question = @ctx.message("theme.push.live")
|
|
55
|
+
question += @ctx.message("theme.push.theme", theme.name, theme.id) if options.flags[:live]
|
|
56
|
+
return unless CLI::UI::Prompt.confirm(question)
|
|
52
57
|
end
|
|
53
58
|
|
|
54
59
|
ignore_filter = ShopifyCLI::Theme::IgnoreFilter.from_path(root)
|
|
@@ -72,6 +77,7 @@ module Theme
|
|
|
72
77
|
@ctx.done(@ctx.message("theme.push.done", theme.preview_url, theme.editor_url))
|
|
73
78
|
end
|
|
74
79
|
end
|
|
80
|
+
raise ShopifyCLI::AbortSilent if syncer.has_any_error?
|
|
75
81
|
rescue ShopifyCLI::API::APIRequestNotFoundError
|
|
76
82
|
@ctx.abort(@ctx.message("theme.push.theme_not_found", theme.id))
|
|
77
83
|
ensure
|
|
@@ -15,7 +15,7 @@ module Theme
|
|
|
15
15
|
def call(*)
|
|
16
16
|
flags = options.flags.dup
|
|
17
17
|
host = flags[:host] || DEFAULT_HTTP_HOST
|
|
18
|
-
ShopifyCLI::Theme::DevServer.start(@ctx, ".",
|
|
18
|
+
ShopifyCLI::Theme::DevServer.start(@ctx, ".", host: host, **flags) do |syncer|
|
|
19
19
|
UI::SyncProgressBar.new(syncer).progress(:upload_theme!, delay_low_priority_files: true)
|
|
20
20
|
end
|
|
21
21
|
rescue ShopifyCLI::Theme::DevServer::AddressBindingError
|
|
@@ -58,6 +58,7 @@ module Theme
|
|
|
58
58
|
|
|
59
59
|
Options:
|
|
60
60
|
{{command:-i, --themeid=THEMEID}} Theme ID. Must be an existing theme on your store.
|
|
61
|
+
{{command:-l, --live}} Push to your remote live theme, and update your live store.
|
|
61
62
|
{{command:-d, --development}} Push to your remote development theme, and create it if needed.
|
|
62
63
|
{{command:-u, --unpublished}} Create a new unpublished theme and push to it.
|
|
63
64
|
{{command:-n, --nodelete}} Runs the push command without deleting remote files from Shopify.
|
|
@@ -73,6 +74,7 @@ module Theme
|
|
|
73
74
|
push: "Pushing theme files to Shopify",
|
|
74
75
|
select: "Select theme to push to",
|
|
75
76
|
live: "Are you sure you want to push to your live theme?",
|
|
77
|
+
theme: "\n Theme: {{blue:%s #%s}} {{green:[live]}}",
|
|
76
78
|
theme_not_found: "Theme #%s doesn't exist",
|
|
77
79
|
done: <<~DONE,
|
|
78
80
|
{{green:Your theme was pushed successfully}}
|
|
@@ -96,12 +98,43 @@ module Theme
|
|
|
96
98
|
{{command:--poll}} Force polling to detect file changes
|
|
97
99
|
{{command:--host=HOST}} Set which network interface the web server listens on. The default value is 127.0.0.1.
|
|
98
100
|
HELP
|
|
99
|
-
|
|
101
|
+
viewing_theme: "Viewing theme…",
|
|
102
|
+
syncing_theme: "Syncing theme #%s on %s",
|
|
100
103
|
open_fail: "Couldn't open the theme",
|
|
104
|
+
operation: {
|
|
105
|
+
status: {
|
|
106
|
+
error: "ERROR",
|
|
107
|
+
synced: "Synced",
|
|
108
|
+
fixed: "Fixed",
|
|
109
|
+
},
|
|
110
|
+
},
|
|
101
111
|
error: {
|
|
102
112
|
address_binding_error: "Couldn't bind to localhost."\
|
|
103
113
|
" To serve your theme, set a different address with {{command:%s theme serve --host=<address>}}",
|
|
104
114
|
},
|
|
115
|
+
serving: <<~SERVING,
|
|
116
|
+
|
|
117
|
+
Serving %s
|
|
118
|
+
|
|
119
|
+
SERVING
|
|
120
|
+
customize_or_preview: <<~CUSTOMIZE_OR_PREVIEW,
|
|
121
|
+
|
|
122
|
+
Customize this theme in the Online Store Editor:
|
|
123
|
+
{{green:%s}}
|
|
124
|
+
|
|
125
|
+
Share this theme preview:
|
|
126
|
+
{{green:%s}}
|
|
127
|
+
|
|
128
|
+
(Use Ctrl-C to stop)
|
|
129
|
+
CUSTOMIZE_OR_PREVIEW
|
|
130
|
+
ensure_user: <<~ENSURE_USER,
|
|
131
|
+
You are not authorized to edit themes on %s.
|
|
132
|
+
Make sure you are a user of that store, and allowed to edit themes.
|
|
133
|
+
ENSURE_USER
|
|
134
|
+
already_in_use_error: "Error",
|
|
135
|
+
address_already_in_use: "The address \"%s\" is already in use.",
|
|
136
|
+
try_this: "Try this",
|
|
137
|
+
try_port_option: "Use the --port=PORT option to serve the theme in a different port.",
|
|
105
138
|
},
|
|
106
139
|
check: {
|
|
107
140
|
help: <<~HELP,
|
|
@@ -157,6 +190,7 @@ module Theme
|
|
|
157
190
|
|
|
158
191
|
Options:
|
|
159
192
|
{{command:-i, --themeid=THEMEID}} The Theme ID. Must be an existing theme on your store.
|
|
193
|
+
{{command:-l, --live}} Pull theme files from your remote live theme.
|
|
160
194
|
{{command:-n, --nodelete}} Runs the pull command without deleting local files.
|
|
161
195
|
|
|
162
196
|
Run without options to select theme from a list.
|
|
@@ -6,14 +6,14 @@ module Theme
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def progress(method, **args)
|
|
9
|
-
@syncer.
|
|
9
|
+
@syncer.lock_io!
|
|
10
10
|
CLI::UI::Progress.progress do |bar|
|
|
11
11
|
@syncer.public_send(method, **args) do |left, total|
|
|
12
12
|
bar.tick(set_percent: 1 - left.to_f / total)
|
|
13
13
|
end
|
|
14
14
|
bar.tick(set_percent: 1)
|
|
15
15
|
end
|
|
16
|
-
@syncer.
|
|
16
|
+
@syncer.unlock_io!
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -5,13 +5,26 @@ module ShopifyCLI
|
|
|
5
5
|
@ctx.puts(self.class.help)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
class << self
|
|
9
|
+
def help
|
|
10
|
+
project_type = name.split("::")[0].downcase
|
|
11
|
+
ShopifyCLI::Context.message(
|
|
12
|
+
"#{project_type}.help",
|
|
13
|
+
ShopifyCLI::TOOL_NAME,
|
|
14
|
+
available_subcommands
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def available_subcommands
|
|
21
|
+
subcommand_registry
|
|
22
|
+
.resolved_commands
|
|
23
|
+
.reject { |_name, command| command.hidden? }
|
|
24
|
+
.keys
|
|
25
|
+
.sort
|
|
26
|
+
.join(" | ")
|
|
27
|
+
end
|
|
15
28
|
end
|
|
16
29
|
end
|
|
17
30
|
end
|
data/lib/shopify_cli/command.rb
CHANGED
|
@@ -29,6 +29,12 @@ module ShopifyCLI
|
|
|
29
29
|
run_prerequisites
|
|
30
30
|
cmd.call(args, command_name)
|
|
31
31
|
end
|
|
32
|
+
rescue OptionParser::InvalidOption => error
|
|
33
|
+
arg = error.args.first
|
|
34
|
+
raise ShopifyCLI::Abort, @ctx.message("core.errors.option_parser.invalid_option", arg)
|
|
35
|
+
rescue OptionParser::MissingArgument => error
|
|
36
|
+
arg = error.args.first
|
|
37
|
+
raise ShopifyCLI::Abort, @ctx.message("core.errors.option_parser.missing_argument", arg)
|
|
32
38
|
end
|
|
33
39
|
|
|
34
40
|
def options(&block)
|
|
@@ -3,9 +3,7 @@ module ShopifyCLI
|
|
|
3
3
|
class App
|
|
4
4
|
class Create
|
|
5
5
|
class Node < ShopifyCLI::Command::AppSubCommand
|
|
6
|
-
|
|
7
|
-
prerequisite_task :ensure_authenticated
|
|
8
|
-
end
|
|
6
|
+
prerequisite_task :ensure_authenticated
|
|
9
7
|
|
|
10
8
|
options do |parser, flags|
|
|
11
9
|
parser.on("--name=NAME") { |t| flags[:name] = t }
|
|
@@ -3,9 +3,7 @@ module ShopifyCLI
|
|
|
3
3
|
class App
|
|
4
4
|
class Create
|
|
5
5
|
class Rails < ShopifyCLI::Command::AppSubCommand
|
|
6
|
-
|
|
7
|
-
prerequisite_task :ensure_authenticated
|
|
8
|
-
end
|
|
6
|
+
prerequisite_task :ensure_authenticated
|
|
9
7
|
|
|
10
8
|
options do |parser, flags|
|
|
11
9
|
parser.on("--name=NAME") { |t| flags[:name] = t }
|
|
@@ -46,6 +46,9 @@ module ShopifyCLI
|
|
|
46
46
|
ACCEPTANCE_TEST = "SHOPIFY_CLI_ACCEPTANCE_TEST"
|
|
47
47
|
DEVELOPMENT = "SHOPIFY_CLI_DEVELOPMENT"
|
|
48
48
|
|
|
49
|
+
# Authentication
|
|
50
|
+
AUTH_TOKEN = "SHOPIFY_CLI_AUTH_TOKEN"
|
|
51
|
+
|
|
49
52
|
# Monorail
|
|
50
53
|
MONORAIL_REAL_EVENTS = "MONORAIL_REAL_EVENTS"
|
|
51
54
|
end
|
|
@@ -58,5 +61,9 @@ module ShopifyCLI
|
|
|
58
61
|
module Links
|
|
59
62
|
NEW_ISSUE = "https://github.com/Shopify/shopify-cli/issues/new"
|
|
60
63
|
end
|
|
64
|
+
|
|
65
|
+
module Extension
|
|
66
|
+
DEFAULT_PORT = 39351
|
|
67
|
+
end
|
|
61
68
|
end
|
|
62
69
|
end
|
data/lib/shopify_cli/context.rb
CHANGED
|
@@ -61,6 +61,7 @@ module ShopifyCLI
|
|
|
61
61
|
# will return which operating system that the cli is running on [:mac, :linux]
|
|
62
62
|
def os
|
|
63
63
|
host = uname
|
|
64
|
+
return :mac_m1 if /arm64-apple-darwin/i.match(host)
|
|
64
65
|
return :mac if /darwin/i.match(host)
|
|
65
66
|
return :windows if /mswin|mingw|cygwin/i.match(host)
|
|
66
67
|
return :linux if /linux|bsd/i.match(host)
|
|
@@ -89,7 +90,7 @@ module ShopifyCLI
|
|
|
89
90
|
|
|
90
91
|
# will return true if being launched from a tty
|
|
91
92
|
def tty?
|
|
92
|
-
$stdin.tty?
|
|
93
|
+
!testing? && $stdin.tty?
|
|
93
94
|
end
|
|
94
95
|
|
|
95
96
|
# will return true if the cli is being run from an installation, and not a
|
|
@@ -357,6 +358,15 @@ module ShopifyCLI
|
|
|
357
358
|
Kernel.puts(CLI::UI.fmt(*args))
|
|
358
359
|
end
|
|
359
360
|
|
|
361
|
+
# a wrapper around $stderr.puts to allow for easy formatting
|
|
362
|
+
#
|
|
363
|
+
# #### Parameters
|
|
364
|
+
# * `text` - a string message to output
|
|
365
|
+
#
|
|
366
|
+
def error(text)
|
|
367
|
+
$stderr.puts(CLI::UI.fmt(text))
|
|
368
|
+
end
|
|
369
|
+
|
|
360
370
|
# a wrapper around Kernel.warn to allow for easy formatting
|
|
361
371
|
#
|
|
362
372
|
# #### Parameters
|
|
@@ -86,6 +86,10 @@ module ShopifyCLI
|
|
|
86
86
|
)
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
+
def self.auth_token(env_variables: ENV)
|
|
90
|
+
env_variables[Constants::EnvironmentVariables::AUTH_TOKEN]
|
|
91
|
+
end
|
|
92
|
+
|
|
89
93
|
def self.env_variable_truthy?(variable_name, env_variables: ENV)
|
|
90
94
|
TRUTHY_ENV_VARIABLE_VALUES.include?(env_variables[variable_name.to_s])
|
|
91
95
|
end
|
data/lib/shopify_cli/form.rb
CHANGED
data/lib/shopify_cli/git.rb
CHANGED
|
@@ -68,6 +68,24 @@ module ShopifyCLI
|
|
|
68
68
|
request_exchange_tokens
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
def self.fetch_or_auth_partners_token(ctx:)
|
|
72
|
+
env_var_auth_token = Environment.auth_token
|
|
73
|
+
return env_var_auth_token if env_var_auth_token
|
|
74
|
+
|
|
75
|
+
ShopifyCLI::DB.get(:partners_exchange_token) do
|
|
76
|
+
IdentityAuth.new(ctx: ctx).authenticate
|
|
77
|
+
ShopifyCLI::DB.get(:partners_exchange_token)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.environment_auth_token?
|
|
82
|
+
!!Environment.auth_token
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def self.authenticated?
|
|
86
|
+
environment_auth_token? || IDENTITY_ACCESS_TOKENS.all? { |key| ShopifyCLI::DB.exists?(key) }
|
|
87
|
+
end
|
|
88
|
+
|
|
71
89
|
def reauthenticate
|
|
72
90
|
return if refresh_exchange_tokens || refresh_access_tokens
|
|
73
91
|
ctx.abort(ctx.message("core.identity_auth.error.reauthenticate", ShopifyCLI::TOOL_NAME))
|
|
@@ -14,6 +14,12 @@ module ShopifyCLI
|
|
|
14
14
|
},
|
|
15
15
|
},
|
|
16
16
|
core: {
|
|
17
|
+
errors: {
|
|
18
|
+
option_parser: {
|
|
19
|
+
invalid_option: "The option {{command:%s}} is not supported.",
|
|
20
|
+
missing_argument: "The required argument {{command:%s}} is missing.",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
17
23
|
app: {
|
|
18
24
|
help: <<~HELP,
|
|
19
25
|
Suite of commands for developing apps. See {{command:%1$s app <command> --help}} for usage of each command.
|
|
@@ -457,6 +463,7 @@ module ShopifyCLI
|
|
|
457
463
|
not_authenticated: "Failed to authenticate",
|
|
458
464
|
},
|
|
459
465
|
login_prompt: "Please ensure you've logged in with {{command:%s login}} and try again",
|
|
466
|
+
token_authentication: "%s environment variable. We'll authenticate using its value as a token.",
|
|
460
467
|
},
|
|
461
468
|
|
|
462
469
|
options: {
|
|
@@ -718,7 +725,7 @@ module ShopifyCLI
|
|
|
718
725
|
signup_suggestion: <<~MESSAGE,
|
|
719
726
|
{{*}} To avoid tunnels that timeout, it is recommended to signup for a free ngrok
|
|
720
727
|
account at {{underline:https://ngrok.com/signup}}. After you signup, install your
|
|
721
|
-
personalized authorization token using {{command:%s
|
|
728
|
+
personalized authorization token using {{command:%s app tunnel auth <token>}}.
|
|
722
729
|
MESSAGE
|
|
723
730
|
start: "{{v}} ngrok tunnel running at {{underline:%s}}",
|
|
724
731
|
start_with_account: "{{v}} ngrok tunnel running at {{underline:%s}}, with account %s",
|
|
@@ -764,7 +771,7 @@ module ShopifyCLI
|
|
|
764
771
|
Anonymized reports will be sent to Shopify.
|
|
765
772
|
MESSAGE
|
|
766
773
|
turned_off_message: <<~MESSAGE,
|
|
767
|
-
Turn on automatic reporting later
|
|
774
|
+
Turn on automatic reporting later with {{command:%s reporting on}}.
|
|
768
775
|
MESSAGE
|
|
769
776
|
},
|
|
770
777
|
whoami: {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "shopify_cli/thread_pool/job"
|
|
4
|
+
|
|
5
|
+
module ShopifyCLI
|
|
6
|
+
class PartnersAPI
|
|
7
|
+
class AppExtensions
|
|
8
|
+
class Job < ShopifyCLI::ThreadPool::Job
|
|
9
|
+
attr_reader :result
|
|
10
|
+
|
|
11
|
+
def initialize(ctx, app, type)
|
|
12
|
+
super()
|
|
13
|
+
@ctx = ctx
|
|
14
|
+
@app = app
|
|
15
|
+
@api_key = @app["apiKey"]
|
|
16
|
+
@type = type
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def perform!
|
|
20
|
+
resp = PartnersAPI.query(@ctx, "get_extension_registrations", **params)
|
|
21
|
+
@result = resp&.dig("data", "app") || {}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def patch_app_with_extensions!
|
|
25
|
+
@app.merge!(result)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def params
|
|
31
|
+
{ api_key: @api_key, type: @type }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "shopify_cli/thread_pool"
|
|
4
|
+
|
|
5
|
+
require_relative "app_extensions/job"
|
|
6
|
+
|
|
7
|
+
module ShopifyCLI
|
|
8
|
+
class PartnersAPI
|
|
9
|
+
class AppExtensions
|
|
10
|
+
class << self
|
|
11
|
+
def fetch_apps_extensions(ctx, orgs, type)
|
|
12
|
+
jobs = apps(orgs).map { |app| AppExtensions::Job.new(ctx, app, type) }
|
|
13
|
+
|
|
14
|
+
consume_jobs!(jobs)
|
|
15
|
+
patch_apps_with_extensions!(jobs)
|
|
16
|
+
|
|
17
|
+
orgs
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def apps(orgs)
|
|
23
|
+
orgs.flat_map { |org| org["apps"] }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def consume_jobs!(jobs)
|
|
27
|
+
thread_pool = ShopifyCLI::ThreadPool.new
|
|
28
|
+
jobs.each do |job|
|
|
29
|
+
thread_pool.schedule(job)
|
|
30
|
+
end
|
|
31
|
+
thread_pool.shutdown
|
|
32
|
+
|
|
33
|
+
raise_if_any_error(jobs)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def patch_apps_with_extensions!(jobs)
|
|
37
|
+
jobs.each(&:patch_app_with_extensions!)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def raise_if_any_error(jobs)
|
|
41
|
+
jobs.find(&:error?).tap { |job| raise job.error if job }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -28,11 +28,8 @@ module ShopifyCLI
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def fetch_with_extensions(ctx, type)
|
|
31
|
-
|
|
32
|
-
(
|
|
33
|
-
org["apps"] = (org.dig("apps", "nodes") || [])
|
|
34
|
-
org
|
|
35
|
-
end
|
|
31
|
+
orgs = fetch_with_app(ctx)
|
|
32
|
+
AppExtensions.fetch_apps_extensions(ctx, orgs, type)
|
|
36
33
|
end
|
|
37
34
|
end
|
|
38
35
|
end
|