shopify-cli 2.9.0 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.yaml +117 -0
- data/.github/ISSUE_TEMPLATE/enhancement.yaml +38 -0
- data/.github/ISSUE_TEMPLATE/feature.yaml +47 -0
- data/.github/ISSUE_TEMPLATE.md +18 -0
- data/CHANGELOG.md +38 -5
- data/Gemfile.lock +1 -1
- data/dev.yml +3 -0
- data/lib/project_types/extension/commands/build.rb +3 -0
- data/lib/project_types/extension/commands/check.rb +3 -0
- data/lib/project_types/extension/commands/create.rb +3 -0
- data/lib/project_types/extension/commands/push.rb +3 -0
- data/lib/project_types/extension/commands/serve.rb +3 -0
- data/lib/project_types/extension/models/specification_handlers/default.rb +1 -1
- data/lib/project_types/extension/tasks/convert_server_config.rb +3 -1
- data/lib/project_types/script/cli.rb +5 -0
- data/lib/project_types/script/commands/connect.rb +3 -1
- data/lib/project_types/script/commands/create.rb +2 -0
- data/lib/project_types/script/commands/push.rb +6 -0
- data/lib/project_types/script/config/extension_points.yml +12 -0
- data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
- data/lib/project_types/script/graphql/module_upload_url_generate.graphql +5 -1
- data/lib/project_types/script/layers/application/build_script.rb +6 -3
- data/lib/project_types/script/layers/application/project_dependencies.rb +1 -1
- data/lib/project_types/script/layers/application/push_script.rb +38 -30
- data/lib/project_types/script/layers/domain/errors.rb +10 -3
- data/lib/project_types/script/layers/domain/extension_point.rb +2 -2
- data/lib/project_types/script/layers/domain/push_package.rb +0 -3
- data/lib/project_types/script/layers/domain/script_config.rb +6 -4
- data/lib/project_types/script/layers/domain/script_project.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/errors.rb +47 -24
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +2 -12
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +2 -12
- data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +15 -0
- data/lib/project_types/script/layers/infrastructure/languages/wasm_task_runner.rb +36 -0
- data/lib/project_types/script/layers/infrastructure/metadata_repository.rb +18 -0
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +7 -8
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +45 -54
- data/lib/project_types/script/layers/infrastructure/script_service.rb +35 -12
- data/lib/project_types/script/layers/infrastructure/script_uploader.rb +22 -9
- data/lib/project_types/script/loaders/project.rb +2 -1
- data/lib/project_types/script/messages/messages.rb +94 -88
- data/lib/project_types/script/ui/error_handler.rb +75 -38
- data/lib/project_types/theme/commands/check.rb +3 -0
- data/lib/project_types/theme/commands/delete.rb +3 -0
- data/lib/project_types/theme/commands/init.rb +3 -0
- data/lib/project_types/theme/commands/language_server.rb +3 -0
- data/lib/project_types/theme/commands/package.rb +3 -0
- data/lib/project_types/theme/commands/publish.rb +3 -0
- data/lib/project_types/theme/commands/pull.rb +12 -1
- data/lib/project_types/theme/commands/push.rb +12 -1
- data/lib/project_types/theme/commands/serve.rb +3 -0
- data/lib/project_types/theme/messages/messages.rb +4 -0
- data/lib/shopify_cli/command/sub_command.rb +2 -0
- data/lib/shopify_cli/command.rb +66 -0
- data/lib/shopify_cli/commands/app/create/node.rb +3 -0
- data/lib/shopify_cli/commands/app/create/rails.rb +3 -0
- data/lib/shopify_cli/commands/app/create.rb +3 -0
- data/lib/shopify_cli/commands/app/deploy.rb +3 -0
- data/lib/shopify_cli/commands/app/serve.rb +3 -0
- data/lib/shopify_cli/commands/login.rb +4 -10
- data/lib/shopify_cli/constants.rb +18 -2
- data/lib/shopify_cli/core/executor.rb +4 -4
- data/lib/shopify_cli/environment.rb +61 -16
- data/lib/shopify_cli/exception_reporter.rb +9 -0
- data/lib/shopify_cli/github/issue_url_generator.rb +19 -8
- data/lib/shopify_cli/identity_auth/env_auth_token.rb +34 -0
- data/lib/shopify_cli/identity_auth.rb +36 -18
- data/lib/shopify_cli/messages/messages.rb +2 -2
- data/lib/shopify_cli/method_object.rb +21 -9
- data/lib/shopify_cli/partners_api.rb +7 -2
- data/lib/shopify_cli/result.rb +61 -59
- data/lib/shopify_cli/services/app/create/rails_service.rb +37 -13
- data/lib/shopify_cli/task.rb +5 -3
- data/lib/shopify_cli/theme/file.rb +2 -2
- data/lib/shopify_cli/theme/filter/path_matcher.rb +38 -0
- data/lib/shopify_cli/theme/ignore_filter.rb +14 -18
- data/lib/shopify_cli/theme/include_filter.rb +65 -0
- data/lib/shopify_cli/theme/syncer.rb +17 -2
- data/lib/shopify_cli/utilities.rb +7 -0
- data/lib/shopify_cli/version.rb +1 -1
- data/lib/shopify_cli.rb +3 -1
- data/vendor/deps/cli-kit/lib/cli/kit/system.rb +11 -6
- data/vendor/deps/cli-kit/lib/cli/kit/util.rb +5 -1
- data/vendor/deps/cli-ui/lib/cli/ui/os.rb +6 -4
- data/vendor/deps/ruby2_keywords/LICENSE +22 -0
- data/vendor/deps/ruby2_keywords/README.md +67 -0
- data/vendor/deps/ruby2_keywords/Rakefile +54 -0
- data/vendor/deps/ruby2_keywords/lib/ruby2_keywords.rb +57 -0
- data/vendor/deps/ruby2_keywords/ruby2_keywords.gemspec +18 -0
- data/vendor/deps/ruby2_keywords/test/test_keyword.rb +41 -0
- data/vendor/lib/semantic/version.rb +0 -1
- metadata +18 -3
- data/lib/project_types/rails/commands/create.rb +0 -210
@@ -10,6 +10,7 @@ module Script
|
|
10
10
|
property :initial_directory, accepts: String
|
11
11
|
|
12
12
|
MUTABLE_ENV_VALUES = %i(uuid)
|
13
|
+
INPUT_QUERY_PATH = "input.graphql"
|
13
14
|
|
14
15
|
def create_project_directory
|
15
16
|
raise Infrastructure::Errors::ScriptProjectAlreadyExistsError, directory if ctx.dir_exist?(directory)
|
@@ -38,13 +39,7 @@ module Script
|
|
38
39
|
language: language
|
39
40
|
)
|
40
41
|
|
41
|
-
|
42
|
-
id: ctx.root,
|
43
|
-
env: project.env,
|
44
|
-
script_name: script_name,
|
45
|
-
extension_point_type: extension_point_type,
|
46
|
-
language: language
|
47
|
-
)
|
42
|
+
build_script_project(script_config: nil)
|
48
43
|
end
|
49
44
|
|
50
45
|
def get
|
@@ -56,7 +51,8 @@ module Script
|
|
56
51
|
script_name: script_name,
|
57
52
|
extension_point_type: extension_point_type,
|
58
53
|
language: language,
|
59
|
-
script_config: script_config_repository.get
|
54
|
+
script_config: script_config_repository.get!,
|
55
|
+
input_query: read_input_query,
|
60
56
|
)
|
61
57
|
end
|
62
58
|
|
@@ -68,14 +64,7 @@ module Script
|
|
68
64
|
end
|
69
65
|
end
|
70
66
|
|
71
|
-
|
72
|
-
id: ctx.root,
|
73
|
-
env: project.env,
|
74
|
-
script_name: script_name,
|
75
|
-
extension_point_type: extension_point_type,
|
76
|
-
language: language,
|
77
|
-
script_config: script_config_repository.get!,
|
78
|
-
)
|
67
|
+
build_script_project
|
79
68
|
end
|
80
69
|
|
81
70
|
def create_env(api_key:, secret:, uuid:)
|
@@ -87,19 +76,19 @@ module Script
|
|
87
76
|
}
|
88
77
|
).write(ctx)
|
89
78
|
|
90
|
-
|
91
|
-
id: ctx.root,
|
92
|
-
env: project.env,
|
93
|
-
script_name: script_name,
|
94
|
-
extension_point_type: extension_point_type,
|
95
|
-
language: language,
|
96
|
-
script_config: script_config_repository.get!,
|
97
|
-
)
|
79
|
+
build_script_project
|
98
80
|
end
|
99
81
|
|
100
82
|
def update_script_config(title:)
|
101
83
|
script_config = script_config_repository.update!(title: title)
|
84
|
+
build_script_project(script_config: script_config)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
102
88
|
|
89
|
+
def build_script_project(
|
90
|
+
script_config: script_config_repository.get!
|
91
|
+
)
|
103
92
|
Domain::ScriptProject.new(
|
104
93
|
id: ctx.root,
|
105
94
|
env: project.env,
|
@@ -110,8 +99,6 @@ module Script
|
|
110
99
|
)
|
111
100
|
end
|
112
101
|
|
113
|
-
private
|
114
|
-
|
115
102
|
def change_directory(directory:)
|
116
103
|
ctx.chdir(directory)
|
117
104
|
end
|
@@ -160,16 +147,23 @@ module Script
|
|
160
147
|
|
161
148
|
def script_config_repository
|
162
149
|
@script_config_repository ||= begin
|
150
|
+
script_config_yml_repo = ScriptConfigYmlRepository.new(ctx: ctx)
|
163
151
|
supported_repos = [
|
164
|
-
|
152
|
+
script_config_yml_repo,
|
165
153
|
ScriptJsonRepository.new(ctx: ctx),
|
166
154
|
]
|
167
155
|
repo = supported_repos.find(&:active?)
|
168
|
-
|
156
|
+
if repo.nil?
|
157
|
+
raise Infrastructure::Errors::NoScriptConfigFileError, script_config_yml_repo.filename
|
158
|
+
end
|
169
159
|
repo
|
170
160
|
end
|
171
161
|
end
|
172
162
|
|
163
|
+
def read_input_query
|
164
|
+
ctx.read(INPUT_QUERY_PATH) if ctx.file_exist?(INPUT_QUERY_PATH)
|
165
|
+
end
|
166
|
+
|
173
167
|
class ScriptConfigRepository
|
174
168
|
include SmartProperties
|
175
169
|
property! :ctx, accepts: ShopifyCLI::Context
|
@@ -179,7 +173,7 @@ module Script
|
|
179
173
|
end
|
180
174
|
|
181
175
|
def get!
|
182
|
-
raise Infrastructure::Errors::NoScriptConfigFileError unless active?
|
176
|
+
raise Infrastructure::Errors::NoScriptConfigFileError, filename unless active?
|
183
177
|
|
184
178
|
content = ctx.read(filename)
|
185
179
|
hash = file_content_to_hash(content)
|
@@ -196,6 +190,10 @@ module Script
|
|
196
190
|
from_h(hash)
|
197
191
|
end
|
198
192
|
|
193
|
+
def filename
|
194
|
+
raise NotImplementedError
|
195
|
+
end
|
196
|
+
|
199
197
|
private
|
200
198
|
|
201
199
|
def update_hash(hash:, title:)
|
@@ -204,14 +202,7 @@ module Script
|
|
204
202
|
end
|
205
203
|
|
206
204
|
def from_h(hash)
|
207
|
-
Domain::ScriptConfig.new(content: hash)
|
208
|
-
rescue Domain::Errors::MissingScriptConfigFieldError => e
|
209
|
-
raise missing_field_error, e.field
|
210
|
-
end
|
211
|
-
|
212
|
-
# to be implemented by subclasses
|
213
|
-
def filename
|
214
|
-
raise NotImplementedError
|
205
|
+
Domain::ScriptConfig.new(content: hash, filename: filename)
|
215
206
|
end
|
216
207
|
|
217
208
|
def file_content_to_hash(file_content)
|
@@ -221,26 +212,22 @@ module Script
|
|
221
212
|
def hash_to_file_content(hash)
|
222
213
|
raise NotImplementedError
|
223
214
|
end
|
224
|
-
|
225
|
-
def missing_field_error
|
226
|
-
raise NotImplementedError
|
227
|
-
end
|
228
215
|
end
|
229
216
|
|
230
217
|
class ScriptConfigYmlRepository < ScriptConfigRepository
|
231
|
-
private
|
232
|
-
|
233
218
|
def filename
|
234
219
|
"script.config.yml"
|
235
220
|
end
|
236
221
|
|
222
|
+
private
|
223
|
+
|
237
224
|
def file_content_to_hash(file_content)
|
238
225
|
begin
|
239
226
|
hash = YAML.load(file_content)
|
240
227
|
rescue Psych::SyntaxError
|
241
|
-
raise
|
228
|
+
raise parse_error
|
242
229
|
end
|
243
|
-
raise
|
230
|
+
raise parse_error unless hash.is_a?(Hash)
|
244
231
|
hash
|
245
232
|
end
|
246
233
|
|
@@ -248,30 +235,34 @@ module Script
|
|
248
235
|
YAML.dump(hash)
|
249
236
|
end
|
250
237
|
|
251
|
-
def
|
252
|
-
Errors::
|
238
|
+
def parse_error
|
239
|
+
Errors::ScriptConfigParseError.new(filename: filename, serialization_format: "YAML")
|
253
240
|
end
|
254
241
|
end
|
255
242
|
|
256
243
|
class ScriptJsonRepository < ScriptConfigRepository
|
257
|
-
private
|
258
|
-
|
259
244
|
def filename
|
260
245
|
"script.json"
|
261
246
|
end
|
262
247
|
|
248
|
+
private
|
249
|
+
|
263
250
|
def file_content_to_hash(file_content)
|
264
|
-
|
265
|
-
|
266
|
-
|
251
|
+
begin
|
252
|
+
hash = JSON.parse(file_content)
|
253
|
+
rescue JSON::ParserError
|
254
|
+
raise parse_error
|
255
|
+
end
|
256
|
+
raise parse_error unless hash.is_a?(Hash)
|
257
|
+
hash
|
267
258
|
end
|
268
259
|
|
269
260
|
def hash_to_file_content(hash)
|
270
261
|
JSON.pretty_generate(hash)
|
271
262
|
end
|
272
263
|
|
273
|
-
def
|
274
|
-
Errors::
|
264
|
+
def parse_error
|
265
|
+
Errors::ScriptConfigParseError.new(filename: filename, serialization_format: "JSON")
|
275
266
|
end
|
276
267
|
end
|
277
268
|
end
|
@@ -19,7 +19,8 @@ module Script
|
|
19
19
|
metadata:,
|
20
20
|
script_config:,
|
21
21
|
module_upload_url:,
|
22
|
-
library
|
22
|
+
library:,
|
23
|
+
input_query: nil
|
23
24
|
)
|
24
25
|
query_name = "app_script_set"
|
25
26
|
variables = {
|
@@ -34,11 +35,14 @@ module Script
|
|
34
35
|
configurationUi: script_config.configuration_ui,
|
35
36
|
configurationDefinition: script_config.configuration&.to_json,
|
36
37
|
moduleUploadUrl: module_upload_url,
|
37
|
-
|
38
|
-
language: library[:language],
|
39
|
-
version: library[:version],
|
40
|
-
},
|
38
|
+
inputQuery: input_query,
|
41
39
|
}
|
40
|
+
|
41
|
+
variables[:library] = {
|
42
|
+
language: library[:language],
|
43
|
+
version: library[:version],
|
44
|
+
} if library
|
45
|
+
|
42
46
|
resp_hash = make_request(query_name: query_name, variables: variables)
|
43
47
|
user_errors = resp_hash["data"]["appScriptSet"]["userErrors"]
|
44
48
|
|
@@ -46,20 +50,37 @@ module Script
|
|
46
50
|
|
47
51
|
if user_errors.any? { |e| e["tag"] == "already_exists_error" }
|
48
52
|
raise Errors::ScriptRepushError, uuid
|
53
|
+
elsif (errors = user_errors.select { |err| err["tag"] == "configuration_definition_error" }).any?
|
54
|
+
raise Errors::ScriptConfigurationDefinitionError.new(
|
55
|
+
messages: errors.map { |e| e["message"] },
|
56
|
+
filename: script_config.filename,
|
57
|
+
)
|
49
58
|
elsif (e = user_errors.any? { |err| err["tag"] == "configuration_definition_syntax_error" })
|
50
|
-
raise Errors::ScriptConfigSyntaxError
|
59
|
+
raise Errors::ScriptConfigSyntaxError, script_config.filename
|
51
60
|
elsif (e = user_errors.find { |err| err["tag"] == "configuration_definition_missing_keys_error" })
|
52
|
-
raise Errors::ScriptConfigMissingKeysError
|
61
|
+
raise Errors::ScriptConfigMissingKeysError.new(
|
62
|
+
missing_keys: e["message"],
|
63
|
+
filename: script_config.filename,
|
64
|
+
)
|
53
65
|
elsif (e = user_errors.find { |err| err["tag"] == "configuration_definition_invalid_value_error" })
|
54
|
-
raise Errors::ScriptConfigInvalidValueError
|
66
|
+
raise Errors::ScriptConfigInvalidValueError.new(
|
67
|
+
valid_input_modes: e["message"],
|
68
|
+
filename: script_config.filename,
|
69
|
+
)
|
55
70
|
elsif (e = user_errors.find do |err|
|
56
71
|
err["tag"] == "configuration_definition_schema_field_missing_keys_error"
|
57
72
|
end)
|
58
|
-
raise Errors::ScriptConfigFieldsMissingKeysError
|
73
|
+
raise Errors::ScriptConfigFieldsMissingKeysError.new(
|
74
|
+
missing_keys: e["message"],
|
75
|
+
filename: script_config.filename,
|
76
|
+
)
|
59
77
|
elsif (e = user_errors.find do |err|
|
60
78
|
err["tag"] == "configuration_definition_schema_field_invalid_value_error"
|
61
79
|
end)
|
62
|
-
raise Errors::ScriptConfigFieldsInvalidValueError
|
80
|
+
raise Errors::ScriptConfigFieldsInvalidValueError.new(
|
81
|
+
valid_types: e["message"],
|
82
|
+
filename: script_config.filename,
|
83
|
+
)
|
63
84
|
elsif user_errors.find { |err| %w(not_use_msgpack_error schema_version_argument_error).include?(err["tag"]) }
|
64
85
|
raise Domain::Errors::MetadataValidationError
|
65
86
|
else
|
@@ -74,14 +95,16 @@ module Script
|
|
74
95
|
response["data"]["appScripts"]
|
75
96
|
end
|
76
97
|
|
77
|
-
def
|
98
|
+
def generate_module_upload_details
|
78
99
|
query_name = "module_upload_url_generate"
|
79
100
|
variables = {}
|
80
101
|
response = make_request(query_name: query_name, variables: variables)
|
81
102
|
user_errors = response["data"]["moduleUploadUrlGenerate"]["userErrors"]
|
82
103
|
|
83
104
|
raise Errors::GraphqlError, user_errors if user_errors.any?
|
84
|
-
|
105
|
+
|
106
|
+
data = response["data"]["moduleUploadUrlGenerate"]["details"]
|
107
|
+
{ url: data["url"], headers: data["headers"], max_size: data["humanizedMaxSize"] }
|
85
108
|
end
|
86
109
|
|
87
110
|
private
|
@@ -7,19 +7,32 @@ module Script
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def upload(script_content)
|
10
|
-
@script_service.
|
11
|
-
|
10
|
+
upload_details = @script_service.generate_module_upload_details
|
11
|
+
url = URI(upload_details[:url])
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
https = Net::HTTP.new(url.host, url.port)
|
14
|
+
https.use_ssl = true
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
request.body = script_content
|
16
|
+
request = Net::HTTP::Put.new(url)
|
17
|
+
request["Content-Type"] = "application/wasm"
|
19
18
|
|
20
|
-
|
21
|
-
|
19
|
+
upload_details[:headers].each do |header, value|
|
20
|
+
request[header] = value
|
22
21
|
end
|
22
|
+
|
23
|
+
request.body = script_content
|
24
|
+
|
25
|
+
response = https.request(request)
|
26
|
+
raise Errors::ScriptTooLargeError, upload_details[:max_size] if script_too_large?(response)
|
27
|
+
raise Errors::ScriptUploadError unless response.code == "200"
|
28
|
+
|
29
|
+
upload_details[:url]
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def script_too_large?(response)
|
35
|
+
response.code == "400" && response.body.include?("EntityTooLarge")
|
23
36
|
end
|
24
37
|
end
|
25
38
|
end
|
@@ -32,7 +32,8 @@ module Script
|
|
32
32
|
else
|
33
33
|
properties_hash = { api_key: "--api-key", secret: "--api-secret" }
|
34
34
|
missing_options = error.properties.map { |p| properties_hash[p.name] }.compact.join(", ")
|
35
|
-
raise ShopifyCLI::Abort, context.message("script.error.missing_push_options", missing_options
|
35
|
+
raise ShopifyCLI::Abort, context.message("script.error.missing_push_options", missing_options,
|
36
|
+
ShopifyCli::TOOL_NAME)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|