shopify-cli 2.7.4 → 2.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/Gemfile.lock +1 -1
- data/RELEASING.md +4 -3
- data/ext/javy/javy.rb +1 -1
- data/lib/project_types/extension/commands/push.rb +2 -2
- data/lib/project_types/extension/messages/messages.rb +1 -1
- data/lib/project_types/extension/models/development_server.rb +2 -4
- data/lib/project_types/rails/gem.rb +1 -2
- data/lib/project_types/script/cli.rb +5 -0
- data/lib/project_types/script/commands/connect.rb +1 -1
- data/lib/project_types/script/commands/create.rb +8 -2
- data/lib/project_types/script/commands/push.rb +35 -12
- data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
- data/lib/project_types/script/layers/application/build_script.rb +0 -1
- data/lib/project_types/script/layers/application/connect_app.rb +11 -5
- data/lib/project_types/script/layers/application/extension_points.rb +50 -26
- data/lib/project_types/script/layers/application/push_script.rb +6 -3
- data/lib/project_types/script/layers/domain/errors.rb +3 -2
- data/lib/project_types/script/layers/domain/extension_point.rb +14 -0
- 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 +38 -23
- 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 +6 -7
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +45 -54
- data/lib/project_types/script/layers/infrastructure/script_service.rb +25 -6
- data/lib/project_types/script/loaders/project.rb +44 -0
- data/lib/project_types/script/loaders/specification_handler.rb +22 -0
- data/lib/project_types/script/messages/messages.rb +28 -16
- data/lib/project_types/script/ui/error_handler.rb +46 -29
- data/lib/project_types/theme/commands/pull.rb +45 -17
- data/lib/project_types/theme/commands/push.rb +62 -27
- data/lib/project_types/theme/commands/serve.rb +5 -0
- data/lib/project_types/theme/messages/messages.rb +33 -18
- data/lib/shopify_cli/commands/login.rb +1 -1
- data/lib/shopify_cli/commands/switch.rb +1 -1
- data/lib/shopify_cli/constants.rb +7 -2
- data/lib/shopify_cli/context.rb +66 -12
- data/lib/shopify_cli/core/executor.rb +4 -4
- data/lib/shopify_cli/environment.rb +50 -20
- data/lib/shopify_cli/identity_auth.rb +4 -3
- data/lib/shopify_cli/messages/messages.rb +2 -0
- data/lib/shopify_cli/method_object.rb +21 -9
- data/lib/shopify_cli/resources/env_file.rb +5 -1
- data/lib/shopify_cli/result.rb +61 -59
- data/lib/shopify_cli/task.rb +5 -3
- data/lib/shopify_cli/theme/dev_server/hot-reload.js +19 -1
- data/lib/shopify_cli/theme/dev_server/hot_reload.rb +18 -2
- data/lib/shopify_cli/theme/dev_server/proxy.rb +1 -0
- data/lib/shopify_cli/theme/dev_server/reload_mode.rb +34 -0
- data/lib/shopify_cli/theme/dev_server.rb +6 -21
- 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 +43 -0
- data/lib/shopify_cli/theme/syncer.rb +17 -2
- data/lib/shopify_cli/theme/theme.rb +26 -4
- data/lib/shopify_cli/version.rb +1 -1
- data/lib/shopify_cli.rb +6 -1
- 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
- metadata +13 -2
@@ -5,63 +5,78 @@ module Script
|
|
5
5
|
module Infrastructure
|
6
6
|
module Errors
|
7
7
|
class BuildError < ScriptProjectError; end
|
8
|
-
|
8
|
+
|
9
|
+
class ScriptConfigurationDefinitionError < ScriptProjectError
|
10
|
+
attr_reader :filename
|
11
|
+
def initialize(message:, filename:)
|
12
|
+
@filename = filename
|
13
|
+
super(message)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class ScriptConfigSyntaxError < ScriptProjectError
|
18
|
+
attr_reader :filename
|
19
|
+
def initialize(filename)
|
20
|
+
@filename = filename
|
21
|
+
super()
|
22
|
+
end
|
23
|
+
end
|
9
24
|
|
10
25
|
class ScriptConfigMissingKeysError < ScriptProjectError
|
11
|
-
attr_reader :missing_keys
|
12
|
-
def initialize(missing_keys)
|
26
|
+
attr_reader :missing_keys, :filename
|
27
|
+
def initialize(missing_keys:, filename:)
|
13
28
|
super()
|
14
29
|
@missing_keys = missing_keys
|
30
|
+
@filename = filename
|
15
31
|
end
|
16
32
|
end
|
17
33
|
|
18
34
|
class ScriptConfigInvalidValueError < ScriptProjectError
|
19
|
-
attr_reader :valid_input_modes
|
20
|
-
def initialize(valid_input_modes)
|
35
|
+
attr_reader :valid_input_modes, :filename
|
36
|
+
def initialize(valid_input_modes:, filename:)
|
21
37
|
super()
|
22
38
|
@valid_input_modes = valid_input_modes
|
39
|
+
@filename = filename
|
23
40
|
end
|
24
41
|
end
|
25
42
|
|
26
43
|
class ScriptConfigFieldsMissingKeysError < ScriptProjectError
|
27
|
-
attr_reader :missing_keys
|
28
|
-
def initialize(missing_keys)
|
44
|
+
attr_reader :missing_keys, :filename
|
45
|
+
def initialize(missing_keys:, filename:)
|
29
46
|
super()
|
30
47
|
@missing_keys = missing_keys
|
48
|
+
@filename = filename
|
31
49
|
end
|
32
50
|
end
|
33
51
|
|
34
52
|
class ScriptConfigFieldsInvalidValueError < ScriptProjectError
|
35
|
-
attr_reader :valid_types
|
36
|
-
def initialize(valid_types)
|
53
|
+
attr_reader :valid_types, :filename
|
54
|
+
def initialize(valid_types:, filename:)
|
37
55
|
super()
|
38
56
|
@valid_types = valid_types
|
57
|
+
@filename = filename
|
39
58
|
end
|
40
59
|
end
|
41
60
|
|
42
|
-
class
|
61
|
+
class ScriptEnvAppNotConnectedError < ScriptProjectError; end
|
43
62
|
|
44
|
-
class
|
45
|
-
|
46
|
-
|
47
|
-
attr_reader :field
|
48
|
-
def initialize(field)
|
63
|
+
class ScriptConfigParseError < ScriptProjectError
|
64
|
+
attr_reader :filename, :serialization_format
|
65
|
+
def initialize(filename:, serialization_format:)
|
49
66
|
super()
|
50
|
-
@
|
67
|
+
@filename = filename
|
68
|
+
@serialization_format = serialization_format
|
51
69
|
end
|
52
70
|
end
|
53
71
|
|
54
|
-
class
|
55
|
-
attr_reader :
|
56
|
-
def initialize(
|
72
|
+
class NoScriptConfigFileError < ScriptProjectError
|
73
|
+
attr_reader :filename
|
74
|
+
def initialize(filename)
|
57
75
|
super()
|
58
|
-
@
|
76
|
+
@filename = filename
|
59
77
|
end
|
60
78
|
end
|
61
79
|
|
62
|
-
class NoScriptConfigYmlFileError < ScriptProjectError; end
|
63
|
-
class NoScriptConfigFileError < ScriptProjectError; end
|
64
|
-
|
65
80
|
class APILibraryNotFoundError < ScriptProjectError
|
66
81
|
attr_reader :library_name
|
67
82
|
def initialize(library_name)
|
@@ -7,8 +7,8 @@ module Script
|
|
7
7
|
include SmartProperties
|
8
8
|
property! :ctx, accepts: ShopifyCLI::Context
|
9
9
|
|
10
|
-
def create_push_package(script_project:, script_content:,
|
11
|
-
build_file_path = file_path(script_project.id
|
10
|
+
def create_push_package(script_project:, script_content:, metadata:, library:)
|
11
|
+
build_file_path = file_path(script_project.id)
|
12
12
|
write_to_path(build_file_path, script_content)
|
13
13
|
|
14
14
|
Domain::PushPackage.new(
|
@@ -16,15 +16,14 @@ module Script
|
|
16
16
|
uuid: script_project.uuid,
|
17
17
|
extension_point_type: script_project.extension_point_type,
|
18
18
|
script_content: script_content,
|
19
|
-
compiled_type: compiled_type,
|
20
19
|
metadata: metadata,
|
21
20
|
script_config: script_project.script_config,
|
22
21
|
library: library
|
23
22
|
)
|
24
23
|
end
|
25
24
|
|
26
|
-
def get_push_package(script_project:,
|
27
|
-
build_file_path = file_path(script_project.id
|
25
|
+
def get_push_package(script_project:, metadata:, library:)
|
26
|
+
build_file_path = file_path(script_project.id)
|
28
27
|
raise Domain::PushPackageNotFoundError unless ctx.file_exist?(build_file_path)
|
29
28
|
|
30
29
|
script_content = ctx.binread(build_file_path)
|
@@ -46,8 +45,8 @@ module Script
|
|
46
45
|
ctx.binwrite(path, content)
|
47
46
|
end
|
48
47
|
|
49
|
-
def file_path(path_to_script
|
50
|
-
"#{path_to_script}/build/script
|
48
|
+
def file_path(path_to_script)
|
49
|
+
"#{path_to_script}/build/script.wasm"
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -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 = {
|
@@ -38,6 +39,7 @@ module Script
|
|
38
39
|
language: library[:language],
|
39
40
|
version: library[:version],
|
40
41
|
},
|
42
|
+
inputQuery: input_query,
|
41
43
|
}
|
42
44
|
resp_hash = make_request(query_name: query_name, variables: variables)
|
43
45
|
user_errors = resp_hash["data"]["appScriptSet"]["userErrors"]
|
@@ -46,20 +48,37 @@ module Script
|
|
46
48
|
|
47
49
|
if user_errors.any? { |e| e["tag"] == "already_exists_error" }
|
48
50
|
raise Errors::ScriptRepushError, uuid
|
51
|
+
elsif (e = user_errors.find { |err| err["tag"] == "configuration_definition_error" })
|
52
|
+
raise Errors::ScriptConfigurationDefinitionError.new(
|
53
|
+
message: e["message"],
|
54
|
+
filename: script_config.filename,
|
55
|
+
)
|
49
56
|
elsif (e = user_errors.any? { |err| err["tag"] == "configuration_definition_syntax_error" })
|
50
|
-
raise Errors::ScriptConfigSyntaxError
|
57
|
+
raise Errors::ScriptConfigSyntaxError, script_config.filename
|
51
58
|
elsif (e = user_errors.find { |err| err["tag"] == "configuration_definition_missing_keys_error" })
|
52
|
-
raise Errors::ScriptConfigMissingKeysError
|
59
|
+
raise Errors::ScriptConfigMissingKeysError.new(
|
60
|
+
missing_keys: e["message"],
|
61
|
+
filename: script_config.filename,
|
62
|
+
)
|
53
63
|
elsif (e = user_errors.find { |err| err["tag"] == "configuration_definition_invalid_value_error" })
|
54
|
-
raise Errors::ScriptConfigInvalidValueError
|
64
|
+
raise Errors::ScriptConfigInvalidValueError.new(
|
65
|
+
valid_input_modes: e["message"],
|
66
|
+
filename: script_config.filename,
|
67
|
+
)
|
55
68
|
elsif (e = user_errors.find do |err|
|
56
69
|
err["tag"] == "configuration_definition_schema_field_missing_keys_error"
|
57
70
|
end)
|
58
|
-
raise Errors::ScriptConfigFieldsMissingKeysError
|
71
|
+
raise Errors::ScriptConfigFieldsMissingKeysError.new(
|
72
|
+
missing_keys: e["message"],
|
73
|
+
filename: script_config.filename,
|
74
|
+
)
|
59
75
|
elsif (e = user_errors.find do |err|
|
60
76
|
err["tag"] == "configuration_definition_schema_field_invalid_value_error"
|
61
77
|
end)
|
62
|
-
raise Errors::ScriptConfigFieldsInvalidValueError
|
78
|
+
raise Errors::ScriptConfigFieldsInvalidValueError.new(
|
79
|
+
valid_types: e["message"],
|
80
|
+
filename: script_config.filename,
|
81
|
+
)
|
63
82
|
elsif user_errors.find { |err| %w(not_use_msgpack_error schema_version_argument_error).include?(err["tag"]) }
|
64
83
|
raise Domain::Errors::MetadataValidationError
|
65
84
|
else
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Script
|
4
|
+
module Loaders
|
5
|
+
module Project
|
6
|
+
def self.load(directory:, api_key:, uuid:, api_secret:, context: ShopifyCLI::Context.new)
|
7
|
+
env_overrides = {
|
8
|
+
"SHOPIFY_API_KEY" => api_key,
|
9
|
+
"SHOPIFY_API_SECRET" => api_secret,
|
10
|
+
"UUID" => uuid,
|
11
|
+
}.compact
|
12
|
+
env_file_present = env_file_exists?(directory)
|
13
|
+
env = if env_file_present
|
14
|
+
ShopifyCLI::Resources::EnvFile.read(directory, overrides: env_overrides)
|
15
|
+
else
|
16
|
+
ShopifyCLI::Resources::EnvFile.from_hash(env_overrides)
|
17
|
+
end
|
18
|
+
|
19
|
+
project = ShopifyCLI::Project.at(directory)
|
20
|
+
project.env = env
|
21
|
+
project
|
22
|
+
rescue SmartProperties::InitializationError, SmartProperties::InvalidValueError => error
|
23
|
+
handle_error(error, context: context, env_file_present: env_file_present)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.handle_error(error, context:, env_file_present:)
|
27
|
+
if env_file_present
|
28
|
+
properties_hash = { api_key: "SHOPIFY_API_KEY", secret: "SHOPIFY_API_SECRET" }
|
29
|
+
missing_env_variables = error.properties.map { |p| properties_hash[p.name] }.compact.join(", ")
|
30
|
+
raise ShopifyCLI::Abort,
|
31
|
+
context.message("script.error.missing_env_file_variables", missing_env_variables, ShopifyCLI::TOOL_NAME)
|
32
|
+
else
|
33
|
+
properties_hash = { api_key: "--api-key", secret: "--api-secret" }
|
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)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.env_file_exists?(directory)
|
40
|
+
File.exist?(ShopifyCLI::Resources::EnvFile.path(directory))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Script
|
4
|
+
module Loaders
|
5
|
+
module SpecificationHandler
|
6
|
+
def self.load(project:, context:)
|
7
|
+
identifier = project.specification_identifier
|
8
|
+
Models::LazySpecificationHandler.new(identifier) do
|
9
|
+
specifications = Models::Specifications.new(
|
10
|
+
fetch_specifications: Tasks::FetchSpecifications.new(api_key: project.app.api_key, context: context)
|
11
|
+
)
|
12
|
+
|
13
|
+
unless specifications.valid?(identifier)
|
14
|
+
context.abort(context.message("errors.unknown_type", project.specification_identifier))
|
15
|
+
end
|
16
|
+
|
17
|
+
specifications[identifier]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -47,38 +47,39 @@ module Script
|
|
47
47
|
invalid_language_cause: "Invalid language %s.",
|
48
48
|
invalid_language_help: "Allowed values: %s.",
|
49
49
|
|
50
|
-
|
51
|
-
|
50
|
+
missing_script_config_field_cause: "The %{filename} file is missing the required %{field} field.",
|
51
|
+
missing_script_config_field_help: "Add the field and try again.",
|
52
52
|
|
53
|
-
|
54
|
-
|
53
|
+
script_config_parse_error_cause: "The %{filename} file contains invalid %{serialization_format}.",
|
54
|
+
script_config_parse_error_help: "Fix the errors and try again.",
|
55
55
|
|
56
|
-
|
57
|
-
|
56
|
+
no_script_config_file_cause: "The %{filename} file is missing.",
|
57
|
+
no_script_config_file_help: "Create this file and try again.",
|
58
58
|
|
59
|
-
|
60
|
-
|
59
|
+
app_not_connected_cause: "Script is not connected to an app.",
|
60
|
+
app_not_connected_help: "Run shopify connect or enter fields for api-key and api-secret.",
|
61
61
|
|
62
|
-
|
63
|
-
|
62
|
+
configuration_definition_error_cause: "In the %{filename} file, there was a problem with the "\
|
63
|
+
"configuration. %{message}",
|
64
|
+
configuration_definition_error_help: "Fix the error and try again.",
|
64
65
|
|
65
|
-
configuration_syntax_error_cause: "The
|
66
|
+
configuration_syntax_error_cause: "The %{filename} is not formatted properly.",
|
66
67
|
configuration_syntax_error_help: "Fix the errors and try again.",
|
67
68
|
|
68
|
-
configuration_missing_keys_error_cause: "The
|
69
|
+
configuration_missing_keys_error_cause: "The %{filename} file is missing required keys: "\
|
69
70
|
"%{missing_keys}.",
|
70
71
|
configuration_missing_keys_error_help: "Add the keys and try again.",
|
71
72
|
|
72
|
-
configuration_invalid_value_error_cause: "The
|
73
|
+
configuration_invalid_value_error_cause: "The %{filename} configuration only accepts "\
|
73
74
|
"one of the following types(s): %{valid_input_modes}.",
|
74
75
|
configuration_invalid_value_error_help: "Change the type and try again.",
|
75
76
|
|
76
|
-
configuration_schema_field_missing_keys_error_cause: "A configuration entry in the
|
77
|
+
configuration_schema_field_missing_keys_error_cause: "A configuration entry in the %{filename} file "\
|
77
78
|
"is missing required keys: %{missing_keys}.",
|
78
79
|
configuration_definition_schema_field_missing_keys_error_help: "Add the keys and try again.",
|
79
80
|
|
80
81
|
configuration_schema_field_invalid_value_error_cause: "The configuration entries in the "\
|
81
|
-
"
|
82
|
+
"%{filename} file only accept one of the following "\
|
82
83
|
"type(s): %{valid_types}.",
|
83
84
|
configuration_schema_field_invalid_value_error_help: "Change the types and try again.",
|
84
85
|
|
@@ -145,6 +146,11 @@ module Script
|
|
145
146
|
language_library_for_api_not_found_cause: "Script can’t be pushed because the %{language} library for API %{api} is missing.",
|
146
147
|
language_library_for_api_not_found_help: "Make sure extension_point.yml contains the correct API library.",
|
147
148
|
no_scripts_found_in_app: "The selected apps have no scripts. Please, create them first on the partners' dashboard.",
|
149
|
+
missing_env_file_variables: "The following variables are missing in the .env file: %s."\
|
150
|
+
" It might happen when the script hasn't been previously connected to an app."\
|
151
|
+
" To connect the script to an app, run {{command:%s script connect}}",
|
152
|
+
missing_push_options: "The following options are required: %s."\
|
153
|
+
" You can obtain them from the .env file generated after connecting the script to an app.",
|
148
154
|
},
|
149
155
|
|
150
156
|
create: {
|
@@ -154,6 +160,7 @@ module Script
|
|
154
160
|
Options:
|
155
161
|
{{command:--name=NAME}} Script project name. Use any string.
|
156
162
|
{{command:--api=TYPE}} Script API name. Allowed values: %2$s.
|
163
|
+
{{command:--language=LANGUAGE}} Programming language. Allowed values: %3$s.
|
157
164
|
HELP
|
158
165
|
|
159
166
|
error: {
|
@@ -171,9 +178,13 @@ module Script
|
|
171
178
|
Usage: {{command:%s script push}}
|
172
179
|
Options:
|
173
180
|
{{command:[--force]}} Replaces the existing script on the app with this version.
|
181
|
+
{{command:[--api-key=API_KEY]}} The API key used to register an app with the script. This can be found on the app page on Partners Dashboard. Overrides the value in the .env file, if present.
|
182
|
+
{{command:[--api-secret=API_SECRET]}} The API secret of the app the script is registered with. Overrides the value in the .env file, if present.
|
183
|
+
{{command:[--uuid=UUID]}} The uuid of the script. Overrides the value in the .env file, if present.
|
174
184
|
HELP
|
175
185
|
|
176
186
|
error: {
|
187
|
+
operation_failed_no_uuid: "UUID is required to push in a CI environment.",
|
177
188
|
operation_failed_with_api_key: "Couldn't push script to app (API key: %{api_key}).",
|
178
189
|
operation_failed_no_api_key: "Couldn't push script to app.",
|
179
190
|
},
|
@@ -182,13 +193,14 @@ module Script
|
|
182
193
|
},
|
183
194
|
connect: {
|
184
195
|
connected: "Connected! Your project is now connected to {{green:%s}}",
|
185
|
-
missing_script: "No script has been selected.",
|
186
196
|
help: <<~HELP,
|
187
197
|
{{command:%s script connect}}: Connects an existing script to an app.
|
188
198
|
Usage: {{command:%s script connect}}
|
189
199
|
HELP
|
190
200
|
error: {
|
191
201
|
operation_failed: "Couldn't connect script to app.",
|
202
|
+
missing_env_file_variables: "The following variables are missing in the .env file: %s."\
|
203
|
+
" To connect the script to an app, either enter the value into the .env file or delete the .env file, then run {{command:%s script connect}}",
|
192
204
|
},
|
193
205
|
},
|
194
206
|
javy: {
|