shopify-cli 2.5.0 → 2.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +25 -0
- data/Dockerfile +0 -2
- data/Gemfile.lock +22 -16
- data/README.md +1 -1
- data/Rakefile +7 -16
- data/bin/console +11 -0
- data/bin/shopify +16 -3
- data/dev.yml +3 -0
- data/ext/shopify-cli/extconf.rb +1 -0
- data/lib/project_types/extension/cli.rb +2 -0
- data/lib/project_types/extension/commands/build.rb +2 -1
- data/lib/project_types/extension/features/argo.rb +1 -1
- data/lib/project_types/extension/features/argo_serve.rb +1 -0
- data/lib/project_types/extension/models/development_server.rb +4 -0
- data/lib/project_types/extension/models/development_server_requirements.rb +1 -2
- data/lib/project_types/extension/models/specification_handlers/default.rb +4 -0
- data/lib/project_types/extension/tasks/converters/server_config_converter.rb +31 -0
- data/lib/project_types/extension/tasks/find_npm_packages.rb +2 -2
- data/lib/project_types/extension/tasks/load_server_config.rb +23 -0
- data/lib/project_types/extension/tasks/run_extension_command.rb +26 -10
- data/lib/project_types/node/commands/serve.rb +9 -1
- data/lib/project_types/node/messages/messages.rb +3 -0
- data/lib/project_types/script/cli.rb +4 -3
- data/lib/project_types/script/commands/create.rb +2 -0
- data/lib/project_types/script/config/extension_points.yml +30 -29
- data/lib/project_types/script/layers/application/create_script.rb +32 -12
- data/lib/project_types/script/layers/application/extension_points.rb +3 -3
- data/lib/project_types/script/layers/domain/extension_point.rb +13 -45
- data/lib/project_types/script/layers/infrastructure/api_clients/partners_proxy_api_client.rb +4 -2
- data/lib/project_types/script/layers/infrastructure/api_clients/script_service_api_client.rb +1 -1
- data/lib/project_types/script/layers/infrastructure/errors.rb +5 -0
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +10 -90
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +76 -11
- data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +1 -1
- data/lib/project_types/script/layers/infrastructure/languages/typescript_project_creator.rb +33 -0
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +105 -0
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +1 -1
- data/lib/project_types/script/messages/messages.rb +4 -0
- data/lib/project_types/script/ui/error_handler.rb +8 -0
- data/lib/shopify_cli/api.rb +4 -0
- data/lib/shopify_cli/command/app_sub_command.rb +16 -0
- data/lib/shopify_cli/constants.rb +33 -5
- data/lib/shopify_cli/core/executor.rb +5 -1
- data/lib/shopify_cli/environment.rb +35 -4
- data/lib/shopify_cli/exception_reporter/permission_controller.rb +54 -0
- data/lib/shopify_cli/exception_reporter.rb +55 -0
- data/lib/shopify_cli/git.rb +30 -0
- data/lib/shopify_cli/messages/messages.rb +27 -1
- data/lib/shopify_cli/method_object.rb +11 -4
- data/lib/shopify_cli/migrator/migration.rb +27 -0
- data/lib/shopify_cli/migrator/migrations/1631709766_noop.rb +13 -0
- data/lib/shopify_cli/migrator.rb +48 -0
- data/lib/shopify_cli/version.rb +1 -1
- data/lib/shopify_cli.rb +11 -3
- data/shopify-cli.gemspec +9 -1
- data/utilities/docker.rb +47 -0
- data/utilities/utilities.rb +5 -0
- metadata +31 -6
- data/lib/project_types/script/layers/infrastructure/languages/rust_project_creator.rb +0 -73
- data/lib/project_types/script/layers/infrastructure/languages/rust_task_runner.rb +0 -60
@@ -7,7 +7,7 @@ module Script
|
|
7
7
|
module Application
|
8
8
|
class CreateScript
|
9
9
|
class << self
|
10
|
-
def call(ctx:, language:, script_name:, extension_point_type:, no_config_ui:)
|
10
|
+
def call(ctx:, language:, sparse_checkout_branch:, script_name:, extension_point_type:, no_config_ui:)
|
11
11
|
raise Infrastructure::Errors::ScriptProjectAlreadyExistsError, script_name if ctx.dir_exist?(script_name)
|
12
12
|
|
13
13
|
in_new_directory_context(ctx, script_name) do
|
@@ -18,10 +18,24 @@ module Script
|
|
18
18
|
extension_point_type: extension_point_type,
|
19
19
|
language: language
|
20
20
|
)
|
21
|
-
|
22
|
-
|
21
|
+
|
22
|
+
# remove the need to pass the whole extension-point object to the infra layer
|
23
|
+
sparse_checkout_repo = extension_point.libraries.for(language).repo
|
24
|
+
type = extension_point.dasherize_type
|
25
|
+
domain = extension_point.domain
|
26
|
+
|
27
|
+
project_creator = Infrastructure::Languages::ProjectCreator.for(
|
28
|
+
ctx: ctx,
|
29
|
+
language: language,
|
30
|
+
type: type,
|
31
|
+
project_name: script_name,
|
32
|
+
path_to_project: project.id,
|
33
|
+
sparse_checkout_repo: sparse_checkout_repo,
|
34
|
+
sparse_checkout_branch: sparse_checkout_branch,
|
35
|
+
sparse_checkout_set_path: "#{domain}/#{language}/#{type}/default"
|
36
|
+
)
|
37
|
+
|
23
38
|
install_dependencies(ctx, language, script_name, project_creator)
|
24
|
-
bootstrap(ctx, project_creator)
|
25
39
|
script_project_repo.update_or_create_script_json(title: script_name, configuration_ui: !no_config_ui)
|
26
40
|
project
|
27
41
|
end
|
@@ -31,15 +45,21 @@ module Script
|
|
31
45
|
|
32
46
|
def install_dependencies(ctx, language, script_name, project_creator)
|
33
47
|
task_runner = Infrastructure::Languages::TaskRunner.for(ctx, language, script_name)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
48
|
+
CLI::UI::Frame.open(ctx.message(
|
49
|
+
"core.git.pulling_from_to",
|
50
|
+
project_creator.sparse_checkout_repo,
|
51
|
+
script_name,
|
52
|
+
)) do
|
53
|
+
UI::StrictSpinner.spin(ctx.message(
|
54
|
+
"core.git.pulling",
|
55
|
+
project_creator.sparse_checkout_repo,
|
56
|
+
script_name,
|
57
|
+
)) do |spinner|
|
58
|
+
project_creator.setup_dependencies
|
59
|
+
spinner.update_title(ctx.message("core.git.pulled", script_name))
|
60
|
+
end
|
42
61
|
end
|
62
|
+
ProjectDependencies.install(ctx: ctx, task_runner: task_runner)
|
43
63
|
end
|
44
64
|
|
45
65
|
def in_new_directory_context(ctx, directory)
|
@@ -27,9 +27,9 @@ module Script
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.languages(type:)
|
30
|
-
get(type: type).
|
31
|
-
next nil if
|
32
|
-
|
30
|
+
get(type: type).libraries.all.map do |library|
|
31
|
+
next nil if library.beta? && !ShopifyCLI::Feature.enabled?(:scripts_beta_languages)
|
32
|
+
library.language
|
33
33
|
end.compact
|
34
34
|
end
|
35
35
|
|
@@ -4,14 +4,14 @@ module Script
|
|
4
4
|
module Layers
|
5
5
|
module Domain
|
6
6
|
class ExtensionPoint
|
7
|
-
attr_reader :type, :beta, :deprecated, :
|
7
|
+
attr_reader :type, :beta, :deprecated, :libraries, :domain
|
8
8
|
|
9
9
|
def initialize(type, config)
|
10
10
|
@type = type
|
11
11
|
@beta = config["beta"] || false
|
12
12
|
@deprecated = config["deprecated"] || false
|
13
13
|
@domain = config["domain"] || nil
|
14
|
-
@
|
14
|
+
@libraries = ExtensionPointLibraries.new(config["libraries"])
|
15
15
|
end
|
16
16
|
|
17
17
|
def beta?
|
@@ -26,39 +26,31 @@ module Script
|
|
26
26
|
@type.gsub("_", "-")
|
27
27
|
end
|
28
28
|
|
29
|
-
class
|
29
|
+
class ExtensionPointLibraries
|
30
30
|
def initialize(config)
|
31
31
|
@config = config
|
32
32
|
end
|
33
33
|
|
34
34
|
def all
|
35
|
-
|
35
|
+
@all ||= @config.map do |language, libray_config|
|
36
|
+
ExtensionPointLibrary.new(language, libray_config)
|
37
|
+
end
|
36
38
|
end
|
37
39
|
|
38
|
-
def
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
def rust
|
43
|
-
@rust ||= new_sdk(ExtensionPointRustSDK)
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def new_sdk(klass)
|
49
|
-
config = @config[klass.language]
|
50
|
-
return nil if config.nil?
|
51
|
-
klass.new(config)
|
40
|
+
def for(language)
|
41
|
+
all.find { |ep| ep.language == language }
|
52
42
|
end
|
53
43
|
end
|
54
44
|
|
55
|
-
class
|
56
|
-
attr_reader :version, :beta, :package
|
45
|
+
class ExtensionPointLibrary
|
46
|
+
attr_reader :language, :version, :beta, :package, :repo
|
57
47
|
|
58
|
-
def initialize(config)
|
48
|
+
def initialize(language, config)
|
49
|
+
@language = language
|
59
50
|
@beta = config["beta"] || false
|
60
51
|
@package = config["package"]
|
61
52
|
@version = config["package-version"]
|
53
|
+
@repo = config["repo"]
|
62
54
|
end
|
63
55
|
|
64
56
|
def beta?
|
@@ -68,30 +60,6 @@ module Script
|
|
68
60
|
def versioned?
|
69
61
|
@version
|
70
62
|
end
|
71
|
-
|
72
|
-
def self.language
|
73
|
-
raise NotImplementedError
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
class ExtensionPointAssemblyScriptSDK < ExtensionPointSDK
|
78
|
-
attr_reader :sdk_version, :toolchain_version
|
79
|
-
|
80
|
-
def initialize(config)
|
81
|
-
super
|
82
|
-
@sdk_version = config["sdk-version"]
|
83
|
-
@toolchain_version = config["toolchain-version"]
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.language
|
87
|
-
"assemblyscript"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
class ExtensionPointRustSDK < ExtensionPointSDK
|
92
|
-
def self.language
|
93
|
-
"rust"
|
94
|
-
end
|
95
63
|
end
|
96
64
|
end
|
97
65
|
end
|
data/lib/project_types/script/layers/infrastructure/api_clients/partners_proxy_api_client.rb
CHANGED
@@ -12,8 +12,10 @@ module Script
|
|
12
12
|
proxy_response = ShimAPI.query(@ctx, query_name, api_key: @api_key, variables: variables.to_json)
|
13
13
|
raise_if_graphql_failed(proxy_response)
|
14
14
|
|
15
|
-
response = proxy_response
|
16
|
-
|
15
|
+
response = proxy_response.dig("data", "scriptServiceProxy")
|
16
|
+
raise Errors::InvalidResponseError unless response
|
17
|
+
|
18
|
+
JSON.parse(response)
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
@@ -43,6 +43,7 @@ module Script
|
|
43
43
|
class DependencyInstallError < ScriptProjectError; end
|
44
44
|
class DeprecatedEPError < ScriptProjectError; end
|
45
45
|
class EmptyResponseError < ScriptProjectError; end
|
46
|
+
class InvalidResponseError < ScriptProjectError; end
|
46
47
|
class ForbiddenError < ScriptProjectError; end
|
47
48
|
class InvalidContextError < ScriptProjectError; end
|
48
49
|
|
@@ -94,7 +95,11 @@ module Script
|
|
94
95
|
end
|
95
96
|
end
|
96
97
|
|
98
|
+
class InvalidProjectError < ScriptProjectError; end
|
99
|
+
|
97
100
|
class ScriptUploadError < ScriptProjectError; end
|
101
|
+
class ProjectConfigNotFoundError < ScriptProjectError; end
|
102
|
+
class InvalidProjectConfigError < ScriptProjectError; end
|
98
103
|
end
|
99
104
|
end
|
100
105
|
end
|
data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb
CHANGED
@@ -4,99 +4,19 @@ module Script
|
|
4
4
|
module Layers
|
5
5
|
module Infrastructure
|
6
6
|
module Languages
|
7
|
-
class AssemblyScriptProjectCreator
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
property! :script_name, accepts: String
|
12
|
-
property! :path_to_project, accepts: String
|
7
|
+
class AssemblyScriptProjectCreator < ProjectCreator
|
8
|
+
MIN_NODE_VERSION = "14.5.0" # kept because task_runner uses this
|
9
|
+
NPM_SET_REGISTRY_COMMAND = "npm --userconfig ./.npmrc config set @shopify:registry https://registry.npmjs.com"
|
10
|
+
NPM_SET_ENGINE_STRICT_COMMAND = "npm --userconfig ./.npmrc config set engine-strict true"
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
"--binary build/script.wasm --metadata build/metadata.json"
|
17
|
-
MIN_NODE_VERSION = "14.5.0"
|
18
|
-
ASC_ARGS = "-- --lib node_modules --optimize --use Date="
|
19
|
-
|
20
|
-
def setup_dependencies
|
21
|
-
write_npmrc
|
22
|
-
write_package_json
|
23
|
-
end
|
24
|
-
|
25
|
-
def bootstrap
|
26
|
-
command_runner.call(bootstap_command)
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def command_runner
|
32
|
-
@command_runner ||= CommandRunner.new(ctx: ctx)
|
33
|
-
end
|
34
|
-
|
35
|
-
def write_npmrc
|
36
|
-
command_runner.call("npm --userconfig ./.npmrc config set @shopify:registry https://registry.npmjs.com")
|
37
|
-
command_runner.call("npm --userconfig ./.npmrc config set engine-strict true")
|
38
|
-
end
|
39
|
-
|
40
|
-
def extension_point_version
|
41
|
-
return extension_point.sdks.assemblyscript.version if extension_point.sdks.assemblyscript.versioned?
|
42
|
-
|
43
|
-
out = command_runner.call("npm -s show #{extension_point.sdks.assemblyscript.package} version --json")
|
44
|
-
"^#{JSON.parse(out)}"
|
12
|
+
def self.config_file
|
13
|
+
"package.json"
|
45
14
|
end
|
46
15
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
devDependencies: dev_dependencies,
|
52
|
-
scripts: {
|
53
|
-
test: "asp --summary --verbose",
|
54
|
-
build: build_command,
|
55
|
-
},
|
56
|
-
engines: {
|
57
|
-
node: ">=#{MIN_NODE_VERSION}",
|
58
|
-
},
|
59
|
-
}
|
60
|
-
|
61
|
-
ctx.write("package.json", JSON.pretty_generate(package_json))
|
62
|
-
end
|
63
|
-
|
64
|
-
def bootstap_command
|
65
|
-
type = extension_point.dasherize_type
|
66
|
-
base_command = format(BOOTSTRAP, extension_point: type, base: path_to_project)
|
67
|
-
domain = extension_point.domain
|
68
|
-
|
69
|
-
if domain.nil?
|
70
|
-
base_command
|
71
|
-
else
|
72
|
-
"#{base_command} --domain #{domain}"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def build_command
|
77
|
-
type = extension_point.dasherize_type
|
78
|
-
domain = extension_point.domain
|
79
|
-
|
80
|
-
if domain.nil?
|
81
|
-
"#{BUILD} #{ASC_ARGS}"
|
82
|
-
else
|
83
|
-
"#{BUILD} --domain #{domain} --ep #{type} #{ASC_ARGS}"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def dev_dependencies
|
88
|
-
dependencies = {
|
89
|
-
"@as-pect/cli": "^6.0.0",
|
90
|
-
"assemblyscript": "^0.18.13",
|
91
|
-
"@shopify/scripts-toolchain-as": extension_point.sdks.assemblyscript.toolchain_version,
|
92
|
-
"#{extension_point.sdks.assemblyscript.package}": extension_point_version,
|
93
|
-
}
|
94
|
-
|
95
|
-
if extension_point.sdks.assemblyscript.sdk_version
|
96
|
-
dependencies["@shopify/scripts-sdk-as"] = extension_point.sdks.assemblyscript.sdk_version
|
97
|
-
end
|
98
|
-
|
99
|
-
dependencies
|
16
|
+
def setup_dependencies
|
17
|
+
super
|
18
|
+
command_runner.call(NPM_SET_REGISTRY_COMMAND)
|
19
|
+
command_runner.call(NPM_SET_ENGINE_STRICT_COMMAND)
|
100
20
|
end
|
101
21
|
end
|
102
22
|
end
|
@@ -5,20 +5,85 @@ module Script
|
|
5
5
|
module Infrastructure
|
6
6
|
module Languages
|
7
7
|
class ProjectCreator
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
include SmartProperties
|
9
|
+
property! :ctx, accepts: ShopifyCLI::Context
|
10
|
+
property! :type, accepts: String
|
11
|
+
property! :project_name, accepts: String
|
12
|
+
property! :path_to_project, accepts: String
|
13
|
+
property! :sparse_checkout_repo, accepts: String
|
14
|
+
property! :sparse_checkout_branch, accepts: String
|
15
|
+
property! :sparse_checkout_set_path, accepts: String
|
16
|
+
|
17
|
+
def self.for(
|
18
|
+
ctx:,
|
19
|
+
language:,
|
20
|
+
type:,
|
21
|
+
project_name:,
|
22
|
+
path_to_project:,
|
23
|
+
sparse_checkout_repo:,
|
24
|
+
sparse_checkout_branch:,
|
25
|
+
sparse_checkout_set_path:
|
26
|
+
)
|
27
|
+
|
28
|
+
project_creators = {
|
29
|
+
"assemblyscript" => AssemblyScriptProjectCreator,
|
30
|
+
"typescript" => TypeScriptProjectCreator,
|
31
|
+
}
|
32
|
+
|
33
|
+
raise Errors::ProjectCreatorNotFoundError unless project_creators[language]
|
34
|
+
project_creators[language].new(
|
16
35
|
ctx: ctx,
|
17
|
-
|
18
|
-
|
19
|
-
path_to_project: path_to_project
|
36
|
+
type: type,
|
37
|
+
project_name: project_name,
|
38
|
+
path_to_project: path_to_project,
|
39
|
+
sparse_checkout_repo: sparse_checkout_repo,
|
40
|
+
sparse_checkout_branch: sparse_checkout_branch,
|
41
|
+
sparse_checkout_set_path: sparse_checkout_set_path
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.config_file
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
49
|
+
# the sparse checkout process is common to all script types
|
50
|
+
def setup_dependencies
|
51
|
+
setup_sparse_checkout
|
52
|
+
clean
|
53
|
+
update_project_name(File.join(path_to_project, self.class.config_file))
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def setup_sparse_checkout
|
59
|
+
ShopifyCLI::Git.sparse_checkout(
|
60
|
+
sparse_checkout_repo,
|
61
|
+
sparse_checkout_set_path,
|
62
|
+
sparse_checkout_branch,
|
63
|
+
ctx
|
20
64
|
)
|
21
65
|
end
|
66
|
+
|
67
|
+
def clean
|
68
|
+
source = File.join(path_to_project, sparse_checkout_set_path, ".")
|
69
|
+
FileUtils.cp_r(source, path_to_project)
|
70
|
+
ctx.rm_rf(sparse_checkout_set_path.split("/")[0])
|
71
|
+
ctx.rm_rf(".git")
|
72
|
+
end
|
73
|
+
|
74
|
+
def update_project_name(config_file)
|
75
|
+
raise Errors::ProjectConfigNotFoundError unless File.exist?(config_file)
|
76
|
+
upstream_name = "#{type.gsub("_", "-")}-default"
|
77
|
+
contents = File.read(config_file)
|
78
|
+
|
79
|
+
raise Errors::InvalidProjectConfigError unless contents.include?(upstream_name)
|
80
|
+
new_contents = contents.gsub(upstream_name, project_name)
|
81
|
+
File.write(config_file, new_contents)
|
82
|
+
end
|
83
|
+
|
84
|
+
def command_runner
|
85
|
+
@command_runner ||= CommandRunner.new(ctx: ctx)
|
86
|
+
end
|
22
87
|
end
|
23
88
|
end
|
24
89
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Script
|
4
|
+
module Layers
|
5
|
+
module Infrastructure
|
6
|
+
module Languages
|
7
|
+
class TypeScriptProjectCreator < ProjectCreator
|
8
|
+
MIN_NODE_VERSION = "14.15.0"
|
9
|
+
NPM_SET_REGISTRY_COMMAND = "npm --userconfig ./.npmrc config set @shopify:registry https://registry.npmjs.com"
|
10
|
+
NPM_SET_ENGINE_STRICT_COMMAND = "npm --userconfig ./.npmrc config set engine-strict true"
|
11
|
+
|
12
|
+
def self.config_file
|
13
|
+
"package.json"
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup_dependencies
|
17
|
+
super
|
18
|
+
command_runner.call(NPM_SET_REGISTRY_COMMAND)
|
19
|
+
command_runner.call(NPM_SET_ENGINE_STRICT_COMMAND)
|
20
|
+
|
21
|
+
if ctx.file_exist?("yarn.lock")
|
22
|
+
ctx.rm("yarn.lock")
|
23
|
+
end
|
24
|
+
|
25
|
+
if ctx.file_exist?("package-lock.json")
|
26
|
+
ctx.rm("package-lock.json")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Script
|
4
|
+
module Layers
|
5
|
+
module Infrastructure
|
6
|
+
module Languages
|
7
|
+
class TypeScriptTaskRunner
|
8
|
+
BYTECODE_FILE = "build/%{name}.wasm"
|
9
|
+
METADATA_FILE = "build/metadata.json"
|
10
|
+
SCRIPT_SDK_BUILD = "npm run build"
|
11
|
+
GEN_METADATA = "npm run gen-metadata"
|
12
|
+
|
13
|
+
attr_reader :ctx, :script_name
|
14
|
+
|
15
|
+
def initialize(ctx, script_name)
|
16
|
+
@ctx = ctx
|
17
|
+
@script_name = script_name
|
18
|
+
end
|
19
|
+
|
20
|
+
def build
|
21
|
+
compile
|
22
|
+
bytecode
|
23
|
+
end
|
24
|
+
|
25
|
+
def compiled_type
|
26
|
+
"wasm"
|
27
|
+
end
|
28
|
+
|
29
|
+
def install_dependencies
|
30
|
+
check_node_version!
|
31
|
+
|
32
|
+
output, status = ctx.capture2e("npm install --no-audit --no-optional --legacy-peer-deps --loglevel error")
|
33
|
+
raise Errors::DependencyInstallError, output unless status.success?
|
34
|
+
end
|
35
|
+
|
36
|
+
def dependencies_installed?
|
37
|
+
# Assuming if node_modules folder exist at root of script folder, all deps are installed
|
38
|
+
ctx.dir_exist?("node_modules")
|
39
|
+
end
|
40
|
+
|
41
|
+
def metadata
|
42
|
+
unless @ctx.file_exist?(METADATA_FILE)
|
43
|
+
msg = @ctx.message("script.error.metadata_not_found_cause", METADATA_FILE)
|
44
|
+
raise Domain::Errors::MetadataNotFoundError, msg
|
45
|
+
end
|
46
|
+
|
47
|
+
raw_contents = File.read(METADATA_FILE)
|
48
|
+
Domain::Metadata.create_from_json(@ctx, raw_contents)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def check_node_version!
|
54
|
+
output, status = @ctx.capture2e("node", "--version")
|
55
|
+
raise Errors::DependencyInstallError, output unless status.success?
|
56
|
+
|
57
|
+
require "semantic/semantic"
|
58
|
+
version = ::Semantic::Version.new(output[1..-1])
|
59
|
+
unless version >= ::Semantic::Version.new(TypeScriptProjectCreator::MIN_NODE_VERSION)
|
60
|
+
raise Errors::DependencyInstallError,
|
61
|
+
"Node version must be >= v#{TypeScriptProjectCreator::MIN_NODE_VERSION}. "\
|
62
|
+
"Current version: #{output.strip}."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def compile
|
67
|
+
check_compilation_dependencies!
|
68
|
+
CommandRunner.new(ctx: ctx).call(SCRIPT_SDK_BUILD)
|
69
|
+
CommandRunner.new(ctx: ctx).call(GEN_METADATA)
|
70
|
+
end
|
71
|
+
|
72
|
+
def check_compilation_dependencies!
|
73
|
+
pkg = JSON.parse(File.read("package.json"))
|
74
|
+
build_script = pkg.dig("scripts", "build")
|
75
|
+
|
76
|
+
raise Errors::BuildScriptNotFoundError,
|
77
|
+
"Build script not found" if build_script.nil?
|
78
|
+
|
79
|
+
unless build_script.start_with?("javy")
|
80
|
+
raise Errors::InvalidBuildScriptError, "Invalid build script"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def bytecode
|
85
|
+
legacy_filename = format(BYTECODE_FILE, name: script_name)
|
86
|
+
filename = format(BYTECODE_FILE, name: "index")
|
87
|
+
|
88
|
+
bytecode_file = if ctx.file_exist?(filename)
|
89
|
+
filename
|
90
|
+
elsif ctx.file_exist?(legacy_filename)
|
91
|
+
legacy_filename
|
92
|
+
else
|
93
|
+
raise Errors::WebAssemblyBinaryNotFoundError
|
94
|
+
end
|
95
|
+
|
96
|
+
contents = ctx.binread(bytecode_file)
|
97
|
+
ctx.rm(bytecode_file)
|
98
|
+
|
99
|
+
contents
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -142,6 +142,10 @@ module Script
|
|
142
142
|
"Check that your build npm script outputs the generated binary to the root of the directory." \
|
143
143
|
"Generated binary should match the script name: <script_name>.wasm",
|
144
144
|
|
145
|
+
project_config_not_found: "Internal error - Script can't be created because the project's config file is missing from the repository.",
|
146
|
+
|
147
|
+
invalid_project_config: "Internal error - Script can't be created because the project's config file is invalid in the repository.",
|
148
|
+
|
145
149
|
script_upload_cause: "Fail to upload script.",
|
146
150
|
script_upload_help: "Try again.",
|
147
151
|
},
|
@@ -237,6 +237,14 @@ module Script
|
|
237
237
|
cause_of_error: ShopifyCLI::Context.message("script.error.web_assembly_binary_not_found"),
|
238
238
|
help_suggestion: ShopifyCLI::Context.message("script.error.web_assembly_binary_not_found_suggestion"),
|
239
239
|
}
|
240
|
+
when Layers::Infrastructure::Errors::ProjectConfigNotFoundError
|
241
|
+
{
|
242
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.project_config_not_found"),
|
243
|
+
}
|
244
|
+
when Layers::Infrastructure::Errors::InvalidProjectConfigError
|
245
|
+
{
|
246
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.invalid_project_config"),
|
247
|
+
}
|
240
248
|
when Layers::Infrastructure::Errors::ScriptUploadError
|
241
249
|
{
|
242
250
|
cause_of_error: ShopifyCLI::Context.message("script.error.script_upload_cause"),
|
data/lib/shopify_cli/api.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "shopify_cli"
|
2
|
+
require "securerandom"
|
2
3
|
|
3
4
|
module ShopifyCLI
|
4
5
|
class API
|
@@ -54,6 +55,7 @@ module ShopifyCLI
|
|
54
55
|
# we delay this require so as to avoid a performance hit on starting the CLI
|
55
56
|
require "shopify_cli/http_request"
|
56
57
|
headers = default_headers.merge(headers)
|
58
|
+
ctx.debug("#{method} #{uri} with X-Request-Id: #{headers["X-Request-Id"]}")
|
57
59
|
response = if method == "POST"
|
58
60
|
HttpRequest.post(uri, body, headers)
|
59
61
|
elsif method == "PUT"
|
@@ -82,6 +84,7 @@ module ShopifyCLI
|
|
82
84
|
raise APIRequestUnexpectedError.new("#{response.code}\n#{response.body}", response: response)
|
83
85
|
end
|
84
86
|
rescue Errno::ETIMEDOUT, Timeout::Error
|
87
|
+
ctx.debug("timeout in #{method} #{uri} with X-Request-Id: #{headers["X-Request-Id"]}")
|
85
88
|
raise APIRequestTimeoutError.new("Timeout")
|
86
89
|
end.retry_after(APIRequestRetriableError, retries: 3) do |e|
|
87
90
|
sleep(1) if e.is_a?(APIRequestThrottledError)
|
@@ -109,6 +112,7 @@ module ShopifyCLI
|
|
109
112
|
"User-Agent" => "Shopify CLI; v=#{ShopifyCLI::VERSION}",
|
110
113
|
"Sec-CH-UA" => "Shopify CLI; v=#{ShopifyCLI::VERSION} sha=#{ShopifyCLI.sha}",
|
111
114
|
"Sec-CH-UA-PLATFORM" => ctx.os.to_s,
|
115
|
+
"X-Request-Id" => SecureRandom.uuid,
|
112
116
|
}.tap do |headers|
|
113
117
|
headers["X-Shopify-Cli-Employee"] = "1" if Shopifolk.acting_as_shopify_organization?
|
114
118
|
end.merge(auth_headers(token))
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ShopifyCLI
|
2
|
+
class Command
|
3
|
+
class AppSubCommand < SubCommand
|
4
|
+
class << self
|
5
|
+
def call_help(*)
|
6
|
+
output = help
|
7
|
+
if respond_to?(:extended_help)
|
8
|
+
output += "\n"
|
9
|
+
output += extended_help
|
10
|
+
end
|
11
|
+
@ctx.puts(output)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|