shopify-cli 2.15.0 → 2.15.3
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/stale.yml +7 -2
- data/.vscode/settings.json +1 -2
- data/CHANGELOG.md +70 -19
- data/Gemfile +1 -0
- data/Gemfile.lock +39 -7
- data/Rakefile +48 -0
- data/ext/javy/hashes/javy-arm-macos-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-linux-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-macos-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-windows-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/version +1 -1
- data/ext/shopify-extensions/version +1 -1
- data/lib/project_types/extension/commands/check.rb +6 -1
- data/lib/project_types/extension/forms/questions/ask_template.rb +5 -8
- data/lib/project_types/extension/messages/messages.rb +11 -3
- data/lib/project_types/extension/models/development_server_requirements.rb +14 -7
- data/lib/project_types/extension/models/server_config/root.rb +2 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension.rb +57 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension_utils/script_config.rb +33 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension_utils/script_config_repository.rb +75 -0
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +16 -1
- data/lib/project_types/extension/tasks/configure_options.rb +2 -1
- data/lib/project_types/extension/tasks/convert_server_config.rb +13 -2
- data/lib/project_types/extension/tasks/merge_server_config.rb +5 -2
- data/lib/project_types/script/cli.rb +1 -0
- data/lib/project_types/script/config/extension_points.yml +18 -0
- data/lib/project_types/script/layers/application/create_script.rb +14 -6
- data/lib/project_types/script/layers/infrastructure/errors.rb +17 -0
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +6 -21
- data/lib/project_types/script/layers/infrastructure/script_service.rb +2 -0
- data/lib/project_types/script/layers/infrastructure/sparse_checkout_details.rb +35 -0
- data/lib/project_types/script/messages/messages.rb +3 -0
- data/lib/project_types/script/ui/error_handler.rb +11 -0
- data/lib/project_types/theme/cli.rb +1 -0
- data/lib/project_types/theme/commands/check.rb +4 -1
- data/lib/project_types/theme/commands/open.rb +2 -2
- data/lib/project_types/theme/commands/push.rb +1 -3
- data/lib/project_types/theme/commands/serve.rb +1 -0
- data/lib/project_types/theme/commands/share.rb +56 -0
- data/lib/project_types/theme/messages/messages.rb +71 -11
- data/lib/shopify_cli/changelog.rb +148 -0
- data/lib/shopify_cli/command.rb +7 -0
- data/lib/shopify_cli/command_options/command_serve_options.rb +10 -0
- data/lib/shopify_cli/commands/app/serve.rb +7 -7
- data/lib/shopify_cli/commands/login.rb +5 -2
- data/lib/shopify_cli/context.rb +13 -0
- data/lib/shopify_cli/git.rb +36 -0
- data/lib/shopify_cli/identity_auth.rb +24 -4
- data/lib/shopify_cli/messages/messages.rb +26 -5
- data/lib/shopify_cli/release.rb +194 -0
- data/lib/shopify_cli/sed.rb +19 -0
- data/lib/shopify_cli/services/app/create/rails_service.rb +10 -2
- data/lib/shopify_cli/services/app/serve/node_service.rb +2 -25
- data/lib/shopify_cli/services/app/serve/php_service.rb +2 -25
- data/lib/shopify_cli/services/app/serve/rails_service.rb +8 -28
- data/lib/shopify_cli/services/app/serve/serve_service.rb +57 -0
- data/lib/shopify_cli/services.rb +1 -0
- data/lib/shopify_cli/tasks/update_dashboard_urls.rb +7 -9
- data/lib/shopify_cli/theme/dev_server/hot-reload.js +40 -13
- data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_reloader.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/hot_reload/sections_index.rb +51 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload.rb +6 -1
- data/lib/shopify_cli/theme/dev_server/local_assets.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/remote_watcher/json_files_update_job.rb +35 -0
- data/lib/shopify_cli/theme/dev_server/remote_watcher.rb +44 -0
- data/lib/shopify_cli/theme/dev_server/watcher.rb +2 -8
- data/lib/shopify_cli/theme/dev_server.rb +18 -5
- data/lib/shopify_cli/theme/file.rb +15 -4
- data/lib/shopify_cli/theme/syncer/checksums.rb +60 -0
- data/lib/shopify_cli/theme/syncer/forms/apply_to_all.rb +39 -0
- data/lib/shopify_cli/theme/syncer/forms/apply_to_all_form.rb +35 -0
- data/lib/shopify_cli/theme/syncer/forms/base_strategy_form.rb +62 -0
- data/lib/shopify_cli/theme/syncer/forms/select_delete_strategy.rb +27 -0
- data/lib/shopify_cli/theme/syncer/forms/select_update_strategy.rb +28 -0
- data/lib/shopify_cli/theme/syncer/ignore_helper.rb +33 -0
- data/lib/shopify_cli/theme/syncer/json_delete_handler.rb +51 -0
- data/lib/shopify_cli/theme/syncer/json_update_handler.rb +82 -0
- data/lib/shopify_cli/theme/syncer/merger.rb +53 -0
- data/lib/shopify_cli/theme/syncer/operation.rb +1 -1
- data/lib/shopify_cli/theme/syncer.rb +79 -63
- data/lib/shopify_cli/theme/theme.rb +26 -4
- data/lib/shopify_cli/theme/theme_admin_api.rb +23 -8
- data/lib/shopify_cli/thread_pool/job.rb +10 -2
- data/lib/shopify_cli/thread_pool.rb +15 -3
- data/lib/shopify_cli/tunnel.rb +9 -0
- data/lib/shopify_cli/version.rb +1 -1
- data/shopify-cli.gemspec +3 -1
- data/vendor/deps/cli-ui/lib/cli/ui/os.rb +8 -0
- metadata +30 -3
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require_relative "script_config"
|
|
2
|
+
module Extension
|
|
3
|
+
module Models
|
|
4
|
+
module SpecificationHandlers
|
|
5
|
+
module BeaconExtensionUtils
|
|
6
|
+
class ScriptConfigRepository
|
|
7
|
+
include SmartProperties
|
|
8
|
+
property! :ctx, accepts: ShopifyCLI::Context
|
|
9
|
+
|
|
10
|
+
def active?
|
|
11
|
+
ctx.file_exist?(filename)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get!
|
|
15
|
+
raise RuntimeError.new("NoScriptConfigFile"), filename unless active?
|
|
16
|
+
|
|
17
|
+
content = ctx.read(filename)
|
|
18
|
+
hash = file_content_to_hash(content)
|
|
19
|
+
|
|
20
|
+
from_h(hash)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def filename
|
|
24
|
+
raise NotImplementedError
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def from_h(hash)
|
|
30
|
+
Extension::Models::SpecificationHandlers::BeaconExtensionUtils::ScriptConfig.new(content: hash,
|
|
31
|
+
filename: filename)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def file_content_to_hash(file_content)
|
|
35
|
+
raise NotImplementedError
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def hash_to_file_content(hash)
|
|
39
|
+
raise NotImplementedError
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class ScriptConfigYmlRepository < ScriptConfigRepository
|
|
44
|
+
def self.filename
|
|
45
|
+
"extension.config.yml"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def filename
|
|
49
|
+
ScriptConfigYmlRepository.filename
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def file_content_to_hash(file_content)
|
|
55
|
+
begin
|
|
56
|
+
hash = YAML.load(file_content)
|
|
57
|
+
rescue Psych::SyntaxError
|
|
58
|
+
raise parse_error
|
|
59
|
+
end
|
|
60
|
+
raise parse_error unless hash.is_a?(Hash)
|
|
61
|
+
hash
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def hash_to_file_content(hash)
|
|
65
|
+
YAML.dump(hash)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def parse_error
|
|
69
|
+
RuntimeError.new("ScriptConfigParseError #{filename}, serialization_format: \"YAML\" ")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -49,7 +49,7 @@ module Extension
|
|
|
49
49
|
|
|
50
50
|
locale_filenames.map do |filename|
|
|
51
51
|
locale = basename_for_locale_filename(filename)
|
|
52
|
-
[locale.to_sym,
|
|
52
|
+
[locale.to_sym, read_locale_file(filename)]
|
|
53
53
|
end
|
|
54
54
|
.yield_self do |encoded_files_by_locale|
|
|
55
55
|
{
|
|
@@ -62,6 +62,14 @@ module Extension
|
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
def read_locale_file(filename)
|
|
66
|
+
content = File.read(filename, mode: "rt", encoding: "bom|utf-8").strip
|
|
67
|
+
raise_invalid_encoding_error(filename) unless content.valid_encoding?
|
|
68
|
+
Base64.strict_encode64(content)
|
|
69
|
+
rescue ArgumentError
|
|
70
|
+
raise_invalid_encoding_error(filename)
|
|
71
|
+
end
|
|
72
|
+
|
|
65
73
|
def validate_no_duplicate_locale(locale_filenames)
|
|
66
74
|
duplicate_locale = locale_filenames
|
|
67
75
|
.map { |filename| basename_for_locale_filename(filename.downcase) }
|
|
@@ -149,6 +157,13 @@ module Extension
|
|
|
149
157
|
def basename_for_locale_filename(filename)
|
|
150
158
|
File.basename(File.basename(filename, ".json"), ".default")
|
|
151
159
|
end
|
|
160
|
+
|
|
161
|
+
def raise_invalid_encoding_error(filename)
|
|
162
|
+
raise(
|
|
163
|
+
ShopifyCLI::Abort,
|
|
164
|
+
ShopifyCLI::Context.message("#{L10N_ERROR_PREFIX}.invalid_file_encoding", filename)
|
|
165
|
+
)
|
|
166
|
+
end
|
|
152
167
|
end
|
|
153
168
|
end
|
|
154
169
|
end
|
|
@@ -13,7 +13,8 @@ module Extension
|
|
|
13
13
|
private
|
|
14
14
|
|
|
15
15
|
def configure_skip_build(attributes)
|
|
16
|
-
attributes[:options].merge!(skip_build: attributes[:identifier] == "theme_app_extension"
|
|
16
|
+
attributes[:options].merge!(skip_build: attributes[:identifier] == "theme_app_extension" ||
|
|
17
|
+
attributes[:identifier] == "beacon_extension")
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
end
|
|
@@ -18,7 +18,6 @@ module Extension
|
|
|
18
18
|
property! :type, accepts: String
|
|
19
19
|
|
|
20
20
|
DEFAULT_BUILD_DIR = "build"
|
|
21
|
-
DEFAULT_MAIN = Dir["src/*"].lazy.grep(/index.[jt]sx?/).first
|
|
22
21
|
|
|
23
22
|
def self.call(*args)
|
|
24
23
|
new(*args).call
|
|
@@ -37,7 +36,7 @@ module Extension
|
|
|
37
36
|
build_dir: hash.dig("development", "build_dir") || DEFAULT_BUILD_DIR,
|
|
38
37
|
renderer: renderer,
|
|
39
38
|
entries: Models::ServerConfig::DevelopmentEntries.new(
|
|
40
|
-
main: hash.dig("development", "entries", "main") ||
|
|
39
|
+
main: hash.dig("development", "entries", "main") || determine_default_entry_main(project_directory),
|
|
41
40
|
)
|
|
42
41
|
),
|
|
43
42
|
extension_points: hash.dig("extension_points"),
|
|
@@ -65,6 +64,18 @@ module Extension
|
|
|
65
64
|
def version(renderer, context)
|
|
66
65
|
Tasks::FindPackageFromJson.call(renderer, context: context).version
|
|
67
66
|
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def determine_default_entry_main(project_directory)
|
|
71
|
+
Dir.chdir(project_directory) do
|
|
72
|
+
Dir["src/*"].lazy.grep(/index.[jt]sx?/).first
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def project_directory
|
|
77
|
+
ExtensionProject.current.directory
|
|
78
|
+
end
|
|
68
79
|
end
|
|
69
80
|
end
|
|
70
81
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require "shopify_cli"
|
|
3
3
|
require "yaml"
|
|
4
|
+
require "pathname"
|
|
4
5
|
|
|
5
6
|
module Extension
|
|
6
7
|
module Tasks
|
|
@@ -8,7 +9,7 @@ module Extension
|
|
|
8
9
|
include SmartProperties
|
|
9
10
|
|
|
10
11
|
property! :context, accepts: ShopifyCLI::Context
|
|
11
|
-
property! :file_path, accepts: ->(path) { Pathname(path).yield_self
|
|
12
|
+
property! :file_path, accepts: ->(path) { Pathname(path).yield_self(&:absolute?) }
|
|
12
13
|
property :port, accepts: Integer, default: ShopifyCLI::Constants::Extension::DEFAULT_PORT
|
|
13
14
|
property :resource_url, accepts: String
|
|
14
15
|
property :tunnel_url, accepts: String
|
|
@@ -19,7 +20,9 @@ module Extension
|
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def call
|
|
22
|
-
config = YAML.load_file(file_path)
|
|
23
|
+
config = YAML.load_file(file_path) if File.file?(file_path)
|
|
24
|
+
config ||= {}
|
|
25
|
+
|
|
23
26
|
project = ExtensionProject.current
|
|
24
27
|
Tasks::ConvertServerConfig.call(
|
|
25
28
|
api_key: project.env.api_key,
|
|
@@ -62,6 +62,7 @@ module Script
|
|
|
62
62
|
autoload :ScriptService, Project.project_filepath("layers/infrastructure/script_service")
|
|
63
63
|
autoload :ScriptUploader, Project.project_filepath("layers/infrastructure/script_uploader")
|
|
64
64
|
autoload :ServiceLocator, Project.project_filepath("layers/infrastructure/service_locator")
|
|
65
|
+
autoload :SparseCheckoutDetails, Project.project_filepath("layers/infrastructure/sparse_checkout_details")
|
|
65
66
|
|
|
66
67
|
module Languages
|
|
67
68
|
autoload :ProjectCreator, Project.project_filepath("layers/infrastructure/languages/project_creator")
|
|
@@ -36,3 +36,21 @@ delivery_discount_types:
|
|
|
36
36
|
repo: "https://github.com/Shopify/scripts-apis-examples"
|
|
37
37
|
wasm:
|
|
38
38
|
repo: "https://github.com/Shopify/scripts-apis-examples"
|
|
39
|
+
product_discount_type:
|
|
40
|
+
beta: true
|
|
41
|
+
domain: 'discounts'
|
|
42
|
+
libraries:
|
|
43
|
+
wasm:
|
|
44
|
+
repo: "https://github.com/Shopify/scripts-apis-examples"
|
|
45
|
+
order_discount_type:
|
|
46
|
+
beta: true
|
|
47
|
+
domain: 'discounts'
|
|
48
|
+
libraries:
|
|
49
|
+
wasm:
|
|
50
|
+
repo: "https://github.com/Shopify/scripts-apis-examples"
|
|
51
|
+
shipping_discount_type:
|
|
52
|
+
beta: true
|
|
53
|
+
domain: 'discounts'
|
|
54
|
+
libraries:
|
|
55
|
+
wasm:
|
|
56
|
+
repo: "https://github.com/Shopify/scripts-apis-examples"
|
|
@@ -23,19 +23,23 @@ module Script
|
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
# remove the need to pass the whole extension-point object to the infra layer
|
|
26
|
-
sparse_checkout_repo = extension_point.libraries.for(language).repo
|
|
27
26
|
type = extension_point.dasherize_type
|
|
28
27
|
domain = extension_point.domain
|
|
29
28
|
|
|
29
|
+
sparse_checkout_details = Infrastructure::SparseCheckoutDetails.new(
|
|
30
|
+
repo: extension_point.libraries.for(language).repo,
|
|
31
|
+
branch: sparse_checkout_branch,
|
|
32
|
+
path: "#{domain}/#{language}/#{type}/default",
|
|
33
|
+
input_queries_enabled: input_queries_enabled?,
|
|
34
|
+
)
|
|
35
|
+
|
|
30
36
|
project_creator = Infrastructure::Languages::ProjectCreator.for(
|
|
31
37
|
ctx: ctx,
|
|
32
38
|
language: language,
|
|
33
39
|
type: type,
|
|
34
40
|
project_name: title,
|
|
35
41
|
path_to_project: project.id,
|
|
36
|
-
|
|
37
|
-
sparse_checkout_branch: sparse_checkout_branch,
|
|
38
|
-
sparse_checkout_set_path: "#{domain}/#{language}/#{type}/default"
|
|
42
|
+
sparse_checkout_details: sparse_checkout_details,
|
|
39
43
|
)
|
|
40
44
|
|
|
41
45
|
install_dependencies(ctx, language, title, project_creator)
|
|
@@ -49,12 +53,12 @@ module Script
|
|
|
49
53
|
task_runner = Infrastructure::Languages::TaskRunner.for(ctx, language)
|
|
50
54
|
CLI::UI::Frame.open(ctx.message(
|
|
51
55
|
"core.git.pulling_from_to",
|
|
52
|
-
project_creator.
|
|
56
|
+
project_creator.sparse_checkout_details.repo,
|
|
53
57
|
title,
|
|
54
58
|
)) do
|
|
55
59
|
UI::StrictSpinner.spin(ctx.message(
|
|
56
60
|
"core.git.pulling",
|
|
57
|
-
project_creator.
|
|
61
|
+
project_creator.sparse_checkout_details.repo,
|
|
58
62
|
title,
|
|
59
63
|
)) do |spinner|
|
|
60
64
|
project_creator.setup_dependencies
|
|
@@ -75,6 +79,10 @@ module Script
|
|
|
75
79
|
ensure
|
|
76
80
|
script_project_repo.change_to_initial_directory
|
|
77
81
|
end
|
|
82
|
+
|
|
83
|
+
def input_queries_enabled?
|
|
84
|
+
ShopifyCLI::Feature.enabled?(:scripts_beta_input_queries)
|
|
85
|
+
end
|
|
78
86
|
end
|
|
79
87
|
end
|
|
80
88
|
end
|
|
@@ -180,6 +180,23 @@ module Script
|
|
|
180
180
|
@max_size = max_size
|
|
181
181
|
end
|
|
182
182
|
end
|
|
183
|
+
|
|
184
|
+
class InvalidInputQueryErrors < ScriptProjectError
|
|
185
|
+
attr_reader :messages
|
|
186
|
+
|
|
187
|
+
def initialize(messages)
|
|
188
|
+
@messages = messages
|
|
189
|
+
super()
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def input_query_path
|
|
193
|
+
ScriptProjectRepository::INPUT_QUERY_PATH
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def message
|
|
197
|
+
messages.join("\n")
|
|
198
|
+
end
|
|
199
|
+
end
|
|
183
200
|
end
|
|
184
201
|
end
|
|
185
202
|
end
|
|
@@ -10,9 +10,7 @@ module Script
|
|
|
10
10
|
property! :type, accepts: String
|
|
11
11
|
property! :project_name, accepts: String
|
|
12
12
|
property! :path_to_project, accepts: String
|
|
13
|
-
property! :
|
|
14
|
-
property! :sparse_checkout_branch, accepts: String
|
|
15
|
-
property! :sparse_checkout_set_path, accepts: String
|
|
13
|
+
property! :sparse_checkout_details, accepts: SparseCheckoutDetails
|
|
16
14
|
|
|
17
15
|
def self.for(
|
|
18
16
|
ctx:,
|
|
@@ -20,9 +18,7 @@ module Script
|
|
|
20
18
|
type:,
|
|
21
19
|
project_name:,
|
|
22
20
|
path_to_project:,
|
|
23
|
-
|
|
24
|
-
sparse_checkout_branch:,
|
|
25
|
-
sparse_checkout_set_path:
|
|
21
|
+
sparse_checkout_details:
|
|
26
22
|
)
|
|
27
23
|
|
|
28
24
|
project_creators = {
|
|
@@ -36,33 +32,22 @@ module Script
|
|
|
36
32
|
type: type,
|
|
37
33
|
project_name: project_name,
|
|
38
34
|
path_to_project: path_to_project,
|
|
39
|
-
|
|
40
|
-
sparse_checkout_branch: sparse_checkout_branch,
|
|
41
|
-
sparse_checkout_set_path: sparse_checkout_set_path
|
|
35
|
+
sparse_checkout_details: sparse_checkout_details,
|
|
42
36
|
)
|
|
43
37
|
end
|
|
44
38
|
|
|
45
39
|
# the sparse checkout process is common to all script types
|
|
46
40
|
def setup_dependencies
|
|
47
|
-
|
|
41
|
+
sparse_checkout_details.setup(ctx)
|
|
48
42
|
clean
|
|
49
43
|
end
|
|
50
44
|
|
|
51
45
|
private
|
|
52
46
|
|
|
53
|
-
def setup_sparse_checkout
|
|
54
|
-
ShopifyCLI::Git.sparse_checkout(
|
|
55
|
-
sparse_checkout_repo,
|
|
56
|
-
sparse_checkout_set_path,
|
|
57
|
-
sparse_checkout_branch,
|
|
58
|
-
ctx
|
|
59
|
-
)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
47
|
def clean
|
|
63
|
-
source = File.join(path_to_project,
|
|
48
|
+
source = File.join(path_to_project, sparse_checkout_details.path, ".")
|
|
64
49
|
FileUtils.cp_r(source, path_to_project)
|
|
65
|
-
ctx.rm_rf(
|
|
50
|
+
ctx.rm_rf(sparse_checkout_details.path.split("/")[0])
|
|
66
51
|
ctx.rm_rf(".git")
|
|
67
52
|
end
|
|
68
53
|
|
|
@@ -83,6 +83,8 @@ module Script
|
|
|
83
83
|
valid_types: e["message"],
|
|
84
84
|
filename: script_config.filename,
|
|
85
85
|
)
|
|
86
|
+
elsif (errors = user_errors.filter { |err| err["tag"] == "input_query_validation_error" }).any?
|
|
87
|
+
raise Errors::InvalidInputQueryErrors, errors.map { |err| err["message"] }
|
|
86
88
|
elsif user_errors.find { |err| %w(not_use_msgpack_error schema_version_argument_error).include?(err["tag"]) }
|
|
87
89
|
raise Domain::Errors::MetadataValidationError
|
|
88
90
|
else
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Script
|
|
4
|
+
module Layers
|
|
5
|
+
module Infrastructure
|
|
6
|
+
class SparseCheckoutDetails
|
|
7
|
+
include SmartProperties
|
|
8
|
+
property! :repo, accepts: String
|
|
9
|
+
property! :branch, accepts: String
|
|
10
|
+
property! :path, accepts: String
|
|
11
|
+
property! :input_queries_enabled, accepts: [true, false]
|
|
12
|
+
|
|
13
|
+
def ==(other)
|
|
14
|
+
self.class == other.class &&
|
|
15
|
+
self.class.properties.all? { |name, _| self[name] == other[name] }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def setup(ctx)
|
|
19
|
+
ShopifyCLI::Git.sparse_checkout(repo, patterns_to_checkout, branch, ctx)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def patterns_to_checkout
|
|
25
|
+
paths = [path]
|
|
26
|
+
unless input_queries_enabled
|
|
27
|
+
paths << "!#{path}/#{ScriptProjectRepository::INPUT_QUERY_PATH}"
|
|
28
|
+
paths << "!#{path}/schema.graphql"
|
|
29
|
+
end
|
|
30
|
+
paths.join(" ")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -86,6 +86,9 @@ module Script
|
|
|
86
86
|
"type(s): %{valid_types}.",
|
|
87
87
|
configuration_schema_field_invalid_value_error_help: "Change the value of the type.",
|
|
88
88
|
|
|
89
|
+
input_query_error_cause: "Input query is invalid:\n%{messages}\n\n",
|
|
90
|
+
input_query_error_help: "Fix the query in the `%{input_query_path}` file.",
|
|
91
|
+
|
|
89
92
|
script_not_found_cause: "Can't find script %s for Script API %s",
|
|
90
93
|
|
|
91
94
|
system_call_failure_cause: "Something went wrong while running: {{command:%{cmd}}}.",
|
|
@@ -216,6 +216,17 @@ module Script
|
|
|
216
216
|
"script.error.configuration_schema_field_invalid_value_error_help"
|
|
217
217
|
),
|
|
218
218
|
}
|
|
219
|
+
when Layers::Infrastructure::Errors::InvalidInputQueryErrors
|
|
220
|
+
{
|
|
221
|
+
cause_of_error: ShopifyCLI::Context.message(
|
|
222
|
+
"script.error.input_query_error_cause",
|
|
223
|
+
messages: e.messages.map { |message| " {{x}} #{message}." }.join("\n"),
|
|
224
|
+
),
|
|
225
|
+
help_suggestion: ShopifyCLI::Context.message(
|
|
226
|
+
"script.error.input_query_error_help",
|
|
227
|
+
input_query_path: e.input_query_path,
|
|
228
|
+
),
|
|
229
|
+
}
|
|
219
230
|
when Layers::Infrastructure::Errors::DependencyInstallError
|
|
220
231
|
{
|
|
221
232
|
cause_of_error: ShopifyCLI::Context.message("script.error.dependency_install_cause"),
|
|
@@ -16,6 +16,7 @@ module Theme
|
|
|
16
16
|
subcommand :Package, "package", Project.project_filepath("commands/package")
|
|
17
17
|
subcommand :Open, "open", Project.project_filepath("commands/open")
|
|
18
18
|
subcommand :List, "list", Project.project_filepath("commands/list")
|
|
19
|
+
subcommand :Share, "share", Project.project_filepath("commands/share")
|
|
19
20
|
subcommand :LanguageServer, "language-server", Project.project_filepath("commands/language_server")
|
|
20
21
|
end
|
|
21
22
|
ShopifyCLI::Commands.register("Theme::Command", "theme")
|
|
@@ -24,7 +24,10 @@ module Theme
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def call(*)
|
|
27
|
-
@theme_check.run
|
|
27
|
+
@theme_check.run!
|
|
28
|
+
rescue ThemeCheck::Cli::Abort, ThemeCheck::ThemeCheckError => e
|
|
29
|
+
raise ShopifyCLI::Abort,
|
|
30
|
+
ShopifyCLI::Context.message("theme.check.error", e.full_message)
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
def self.help
|
|
@@ -17,8 +17,8 @@ module Theme
|
|
|
17
17
|
def call(_args, _name)
|
|
18
18
|
theme = find_theme(**options.flags)
|
|
19
19
|
|
|
20
|
-
@ctx.puts(@ctx.message("theme.open.details", theme.name, theme.editor_url))
|
|
21
|
-
@ctx.
|
|
20
|
+
@ctx.puts(@ctx.message("theme.open.details", theme.name, theme.preview_url, theme.editor_url))
|
|
21
|
+
@ctx.open_browser_url!(theme.preview_url)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def self.help
|
|
@@ -104,9 +104,7 @@ module Theme
|
|
|
104
104
|
|
|
105
105
|
if unpublished
|
|
106
106
|
name = theme || ask_theme_name
|
|
107
|
-
|
|
108
|
-
new_theme.create
|
|
109
|
-
return new_theme
|
|
107
|
+
return ShopifyCLI::Theme::Theme.create_unpublished(@ctx, root: root, name: name)
|
|
110
108
|
end
|
|
111
109
|
|
|
112
110
|
if theme
|
|
@@ -16,6 +16,7 @@ module Theme
|
|
|
16
16
|
parser.on("--port=PORT") { |port| flags[:port] = port.to_i }
|
|
17
17
|
parser.on("--poll") { flags[:poll] = true }
|
|
18
18
|
parser.on("--live-reload=MODE") { |mode| flags[:mode] = as_reload_mode(mode) }
|
|
19
|
+
parser.on("--theme-editor-sync") { flags[:editor_sync] = true }
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def call(_args, name)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "shopify_cli/theme/theme"
|
|
4
|
+
require "shopify_cli/theme/syncer"
|
|
5
|
+
require "project_types/theme/commands/common/root_helper"
|
|
6
|
+
|
|
7
|
+
module Theme
|
|
8
|
+
class Command
|
|
9
|
+
class Share < ShopifyCLI::Command::SubCommand
|
|
10
|
+
include Common::RootHelper
|
|
11
|
+
|
|
12
|
+
recommend_default_ruby_range
|
|
13
|
+
|
|
14
|
+
def call(_args, name)
|
|
15
|
+
root = root_value(options, name)
|
|
16
|
+
theme = create_theme(root)
|
|
17
|
+
|
|
18
|
+
upload(theme)
|
|
19
|
+
|
|
20
|
+
@ctx.done(done_message(theme))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.help
|
|
24
|
+
tool = ShopifyCLI::TOOL_NAME
|
|
25
|
+
@ctx.message("theme.share.help", tool, tool)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def create_theme(root)
|
|
31
|
+
ShopifyCLI::Theme::Theme.create_unpublished(@ctx, root: root)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def upload(theme)
|
|
35
|
+
syncer = ShopifyCLI::Theme::Syncer.new(@ctx, theme: theme)
|
|
36
|
+
syncer.start_threads
|
|
37
|
+
|
|
38
|
+
CLI::UI::Frame.open(upload_message(theme)) do
|
|
39
|
+
UI::SyncProgressBar.new(syncer).progress(:upload_theme!)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
raise ShopifyCLI::AbortSilent if syncer.has_any_error?
|
|
43
|
+
ensure
|
|
44
|
+
syncer.shutdown
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def upload_message(theme)
|
|
48
|
+
@ctx.message("theme.share.upload", theme.name, theme.id, theme.shop)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def done_message(theme)
|
|
52
|
+
@ctx.message("theme.share.done", theme.name, theme.preview_url, theme.editor_url)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|