shopify-cli 2.0.2 → 2.2.2
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/CHANGELOG.md +22 -0
- data/Gemfile.lock +4 -4
- data/lib/graphql/get_variant_id.graphql +16 -0
- data/lib/project_types/extension/cli.rb +10 -1
- data/lib/project_types/extension/commands/check.rb +44 -0
- data/lib/project_types/extension/commands/push.rb +0 -1
- data/lib/project_types/extension/commands/serve.rb +8 -2
- data/lib/project_types/extension/extension_project.rb +28 -1
- data/lib/project_types/extension/features/argo.rb +1 -11
- data/lib/project_types/extension/features/argo_runtime.rb +6 -38
- data/lib/project_types/extension/features/argo_serve.rb +30 -1
- data/lib/project_types/extension/features/runtimes/admin.rb +29 -0
- data/lib/project_types/extension/features/runtimes/base.rb +19 -0
- data/lib/project_types/extension/features/runtimes/checkout_post_purchase.rb +23 -0
- data/lib/project_types/extension/features/runtimes/checkout_ui_extension.rb +29 -0
- data/lib/project_types/extension/messages/messages.rb +13 -0
- data/lib/project_types/extension/models/product.rb +12 -0
- data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +10 -0
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +10 -2
- data/lib/project_types/extension/models/specification_handlers/default.rb +13 -4
- data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +12 -0
- data/lib/project_types/extension/tasks/configure_features.rb +1 -0
- data/lib/project_types/extension/tasks/converters/product_converter.rb +21 -0
- data/lib/project_types/extension/tasks/get_product.rb +22 -0
- data/lib/project_types/script/commands/create.rb +1 -1
- data/lib/project_types/script/graphql/app_script_set.graphql +40 -0
- data/lib/project_types/script/graphql/app_script_update_or_create.graphql +0 -44
- data/lib/project_types/script/graphql/module_upload_url_generate.graphql +9 -0
- data/lib/project_types/script/layers/domain/push_package.rb +1 -2
- data/lib/project_types/script/layers/infrastructure/errors.rb +2 -0
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +0 -1
- data/lib/project_types/script/layers/infrastructure/script_service.rb +95 -45
- data/lib/project_types/script/messages/messages.rb +3 -0
- data/lib/project_types/script/ui/error_handler.rb +5 -0
- data/lib/project_types/theme/forms/select.rb +1 -1
- data/lib/shopify-cli/core/monorail.rb +2 -1
- data/lib/shopify-cli/version.rb +1 -1
- data/shopify-cli.gemspec +1 -1
- metadata +15 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c6192e829e79c4cfe8a1e6fe1214d17f57da63bcf3802de71a7171a0037a2c1a
|
|
4
|
+
data.tar.gz: 11f3a7167a24c5b011f930de1a9554176c6371c1a63350ea3a94d9965f521336
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e35ac5b91dea19c5c443616063d1993eefe787b702a9813c4598361f264967baf09d6f4f34a54456b67c6c226cc96b032d3a2bb742ea5425c49fcd3ab843b1fe
|
|
7
|
+
data.tar.gz: c27174aeaf83c67b292a0374b591833f87be66df912e85389148d008e7df0d3c83252b81034d14e1388be2e9a34112f6e9bf925e26359fb11fbfe84cdd8bb875
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
Unreleased
|
|
2
2
|
------
|
|
3
3
|
|
|
4
|
+
Version 2.2.2
|
|
5
|
+
------
|
|
6
|
+
* [1382](https://github.com/Shopify/shopify-cli/pull/1382): Client side module upload for Scripts
|
|
7
|
+
|
|
8
|
+
Version 2.2.1
|
|
9
|
+
------
|
|
10
|
+
|
|
11
|
+
* [1432](https://github.com/Shopify/shopify-cli/pull/1432) New method for determining renderer package name
|
|
12
|
+
|
|
13
|
+
Version 2.2.0
|
|
14
|
+
------
|
|
15
|
+
* [#1424](https://github.com/Shopify/shopify-cli/pull/1424/): Add `--resourceUrl` flag to extension serve command
|
|
16
|
+
* [#1419](https://github.com/Shopify/shopify-cli/pull/1419): Remove analytics prompt when used in CI
|
|
17
|
+
* [#1418](https://github.com/Shopify/shopify-cli/pull/1418): Auto configure resource URL for Checkout Extensions
|
|
18
|
+
* [#1399](https://github.com/Shopify/shopify-cli/pull/1399): Fix error when running `shopify extension serve` in a theme app extension project
|
|
19
|
+
|
|
20
|
+
Version 2.1.0
|
|
21
|
+
-------------
|
|
22
|
+
* [#1357](https://github.com/Shopify/shopify-cli/pull/1357): Update Theme-Check to 1.1
|
|
23
|
+
* [#1352](https://github.com/Shopify/shopify-cli/pull/1352): Add `shopify extension check` for checking theme app extensions
|
|
24
|
+
* [#1304](https://github.com/Shopify/shopify-cli/pull/1304): Prompt user to run `shopify extension connect` if .env file is missing
|
|
25
|
+
|
|
4
26
|
Version 2.0.2
|
|
5
27
|
-------------
|
|
6
28
|
* [#1305](https://github.com/Shopify/shopify-cli/pull/1305): Fix `Uninitialized constant Net::WriteTimeout` error
|
data/Gemfile.lock
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
shopify-cli (2.
|
|
4
|
+
shopify-cli (2.2.2)
|
|
5
5
|
listen (~> 3.5)
|
|
6
|
-
theme-check (~> 1.
|
|
6
|
+
theme-check (~> 1.1)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
@@ -76,7 +76,7 @@ GEM
|
|
|
76
76
|
rubocop-shopify (2.0.1)
|
|
77
77
|
rubocop (~> 1.11)
|
|
78
78
|
ruby-progressbar (1.11.0)
|
|
79
|
-
theme-check (1.
|
|
79
|
+
theme-check (1.1.0)
|
|
80
80
|
liquid (>= 5.0.1)
|
|
81
81
|
nokogumbo
|
|
82
82
|
timecop (0.9.2)
|
|
@@ -108,4 +108,4 @@ DEPENDENCIES
|
|
|
108
108
|
webmock
|
|
109
109
|
|
|
110
110
|
BUNDLED WITH
|
|
111
|
-
2.
|
|
111
|
+
2.2.22
|
|
@@ -24,6 +24,7 @@ module Extension
|
|
|
24
24
|
subcommand :Serve, "serve", Project.project_filepath("commands/serve")
|
|
25
25
|
subcommand :Push, "push", Project.project_filepath("commands/push")
|
|
26
26
|
subcommand :Tunnel, "tunnel", Project.project_filepath("commands/tunnel")
|
|
27
|
+
subcommand :Check, "check", Project.project_filepath("commands/check")
|
|
27
28
|
end
|
|
28
29
|
ShopifyCli::Commands.register("Extension::Command", "extension")
|
|
29
30
|
|
|
@@ -39,12 +40,14 @@ module Extension
|
|
|
39
40
|
autoload :ChooseNextAvailablePort, Project.project_filepath("tasks/choose_next_available_port")
|
|
40
41
|
autoload :FindNpmPackages, Project.project_filepath("tasks/find_npm_packages")
|
|
41
42
|
autoload :GetExtensions, Project.project_filepath("tasks/get_extensions")
|
|
43
|
+
autoload :GetProduct, Project.project_filepath("tasks/get_product")
|
|
42
44
|
|
|
43
45
|
module Converters
|
|
44
46
|
autoload :RegistrationConverter, Project.project_filepath("tasks/converters/registration_converter")
|
|
45
47
|
autoload :VersionConverter, Project.project_filepath("tasks/converters/version_converter")
|
|
46
48
|
autoload :ValidationErrorConverter, Project.project_filepath("tasks/converters/validation_error_converter")
|
|
47
49
|
autoload :AppConverter, Project.project_filepath("tasks/converters/app_converter")
|
|
50
|
+
autoload :ProductConverter, Project.project_filepath("tasks/converters/product_converter")
|
|
48
51
|
end
|
|
49
52
|
end
|
|
50
53
|
|
|
@@ -62,6 +65,12 @@ module Extension
|
|
|
62
65
|
end
|
|
63
66
|
|
|
64
67
|
module Features
|
|
68
|
+
module Runtimes
|
|
69
|
+
autoload :Admin, Project.project_filepath("features/runtimes/admin")
|
|
70
|
+
autoload :Base, Project.project_filepath("features/runtimes/base")
|
|
71
|
+
autoload :CheckoutPostPurchase, Project.project_filepath("features/runtimes/checkout_post_purchase")
|
|
72
|
+
autoload :CheckoutUiExtension, Project.project_filepath("features/runtimes/checkout_ui_extension")
|
|
73
|
+
end
|
|
65
74
|
autoload :ArgoServe, Project.project_filepath("features/argo_serve")
|
|
66
75
|
autoload :ArgoServeOptions, Project.project_filepath("features/argo_serve_options")
|
|
67
76
|
autoload :ArgoSetup, Project.project_filepath("features/argo_setup")
|
|
@@ -76,7 +85,6 @@ module Extension
|
|
|
76
85
|
module Models
|
|
77
86
|
module SpecificationHandlers
|
|
78
87
|
autoload :Default, Project.project_filepath("models/specification_handlers/default")
|
|
79
|
-
autoload :CheckoutArgoExtension, Project.project_filepath("models/specification_handlers/checkout_ui_extension")
|
|
80
88
|
end
|
|
81
89
|
|
|
82
90
|
autoload :App, Project.project_filepath("models/app")
|
|
@@ -87,6 +95,7 @@ module Extension
|
|
|
87
95
|
autoload :Specifications, Project.project_filepath("models/specifications")
|
|
88
96
|
autoload :LazySpecificationHandler, Project.project_filepath("models/lazy_specification_handler")
|
|
89
97
|
autoload :NpmPackage, Project.project_filepath("models/npm_package")
|
|
98
|
+
autoload :Product, Project.project_filepath("models/product")
|
|
90
99
|
end
|
|
91
100
|
|
|
92
101
|
autoload :ExtensionProjectKeys, Project.project_filepath("extension_project_keys")
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "theme_check"
|
|
3
|
+
|
|
4
|
+
module Extension
|
|
5
|
+
class Command
|
|
6
|
+
class Check < ExtensionCommand
|
|
7
|
+
class CheckOptions < ShopifyCli::Options
|
|
8
|
+
def initialize(ctx, theme_check)
|
|
9
|
+
super()
|
|
10
|
+
@theme_check = theme_check
|
|
11
|
+
@ctx = ctx
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def parse(_options_block, args)
|
|
15
|
+
# Check if .theme-check.yml exists, or if another -C has been passed on the command line
|
|
16
|
+
unless args.include?("-C") || @ctx.file_exist?(".theme-check.yml")
|
|
17
|
+
args += ["-C", ":theme_app_extension"]
|
|
18
|
+
end
|
|
19
|
+
@theme_check.parse(args)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(*)
|
|
24
|
+
super
|
|
25
|
+
if project.specification_identifier == "THEME_APP_EXTENSION"
|
|
26
|
+
@theme_check = ThemeCheck::Cli.new
|
|
27
|
+
self.options = CheckOptions.new(@ctx, @theme_check)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def call(*)
|
|
32
|
+
if project.specification_identifier == "THEME_APP_EXTENSION"
|
|
33
|
+
@theme_check.run
|
|
34
|
+
else
|
|
35
|
+
@ctx.abort(@ctx.message("check.unsupported", project.specification_identifier))
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.help
|
|
40
|
+
ShopifyCli::Context.message("check.help", ShopifyCli::TOOL_NAME)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -11,7 +11,6 @@ module Extension
|
|
|
11
11
|
def call(args, name)
|
|
12
12
|
Command::Register.new(@ctx).call(args, name) unless project.registered?
|
|
13
13
|
Command::Build.new(@ctx).call(args, name) unless specification_handler.specification.options[:skip_build]
|
|
14
|
-
|
|
15
14
|
CLI::UI::Frame.open(@ctx.message("push.frame_title")) do
|
|
16
15
|
updated_draft_version = update_draft
|
|
17
16
|
show_message(updated_draft_version)
|
|
@@ -9,19 +9,24 @@ module Extension
|
|
|
9
9
|
|
|
10
10
|
options do |parser, flags|
|
|
11
11
|
parser.on("-t", "--[no-]tunnel", "Establish an ngrok tunnel") { |tunnel| flags[:tunnel] = tunnel }
|
|
12
|
+
parser.on("--resourceUrl=RESOURCE_URL", "Provide a resource URL") do |resource_url|
|
|
13
|
+
flags[:resource_url] = resource_url
|
|
14
|
+
end
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
class RuntimeConfiguration
|
|
15
18
|
include SmartProperties
|
|
16
19
|
|
|
17
20
|
property :tunnel_url, accepts: String, default: nil
|
|
21
|
+
property :resource_url, accepts: String, default: nil
|
|
18
22
|
property! :tunnel_requested, accepts: [true, false], reader: :tunnel_requested?, default: true
|
|
19
23
|
property! :port, accepts: (1...(2**16)), default: DEFAULT_PORT
|
|
20
24
|
end
|
|
21
25
|
|
|
22
26
|
def call(_args, _command_name)
|
|
23
27
|
config = RuntimeConfiguration.new(
|
|
24
|
-
tunnel_requested: tunnel_requested
|
|
28
|
+
tunnel_requested: tunnel_requested?,
|
|
29
|
+
resource_url: options.flags[:resource_url]
|
|
25
30
|
)
|
|
26
31
|
|
|
27
32
|
ShopifyCli::Result
|
|
@@ -74,7 +79,8 @@ module Extension
|
|
|
74
79
|
specification_handler.serve(
|
|
75
80
|
context: @ctx,
|
|
76
81
|
tunnel_url: runtime_configuration.tunnel_url,
|
|
77
|
-
port: runtime_configuration.port
|
|
82
|
+
port: runtime_configuration.port,
|
|
83
|
+
resource_url: runtime_configuration.resource_url
|
|
78
84
|
)
|
|
79
85
|
runtime_configuration
|
|
80
86
|
end
|
|
@@ -14,6 +14,24 @@ module Extension
|
|
|
14
14
|
)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
def update_env_file(context:, **updates)
|
|
18
|
+
current_config = {
|
|
19
|
+
title: current.title,
|
|
20
|
+
shop: current.env.shop,
|
|
21
|
+
api_key: current.app.api_key,
|
|
22
|
+
api_secret: current.app.secret,
|
|
23
|
+
registration_id: current.registration_id,
|
|
24
|
+
registration_uuid: current.registration_uuid,
|
|
25
|
+
resource_url: current.resource_url,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
write_env_file(
|
|
29
|
+
context: context,
|
|
30
|
+
**current_config,
|
|
31
|
+
**updates
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
17
35
|
def write_env_file(
|
|
18
36
|
context:,
|
|
19
37
|
title:,
|
|
@@ -21,11 +39,13 @@ module Extension
|
|
|
21
39
|
api_secret: "",
|
|
22
40
|
registration_id: nil,
|
|
23
41
|
registration_uuid: nil,
|
|
24
|
-
resource_url: nil
|
|
42
|
+
resource_url: nil,
|
|
43
|
+
shop: nil
|
|
25
44
|
)
|
|
26
45
|
ShopifyCli::Resources::EnvFile.new(
|
|
27
46
|
api_key: api_key,
|
|
28
47
|
secret: api_secret,
|
|
48
|
+
shop: shop,
|
|
29
49
|
extra: {
|
|
30
50
|
ExtensionProjectKeys::TITLE_KEY => title,
|
|
31
51
|
ExtensionProjectKeys::REGISTRATION_ID_KEY => registration_id,
|
|
@@ -49,6 +69,7 @@ module Extension
|
|
|
49
69
|
end
|
|
50
70
|
|
|
51
71
|
def app
|
|
72
|
+
validate_env_present
|
|
52
73
|
Models::App.new(api_key: env["api_key"], secret: env["secret"])
|
|
53
74
|
end
|
|
54
75
|
|
|
@@ -107,9 +128,15 @@ module Extension
|
|
|
107
128
|
end
|
|
108
129
|
|
|
109
130
|
def property_present?(key)
|
|
131
|
+
validate_env_present
|
|
110
132
|
!env[key].nil? && !env[key].strip.empty?
|
|
111
133
|
end
|
|
112
134
|
|
|
135
|
+
def validate_env_present
|
|
136
|
+
return if env
|
|
137
|
+
raise ShopifyCli::Abort, "Missing .env file. Run `shopify extension connect` to generate an .env file."
|
|
138
|
+
end
|
|
139
|
+
|
|
113
140
|
def integer?(value)
|
|
114
141
|
value.to_i.to_s == value.to_s
|
|
115
142
|
end
|
|
@@ -19,16 +19,6 @@ module Extension
|
|
|
19
19
|
YARN_RUN_SCRIPT_NAME = %w(build).freeze
|
|
20
20
|
private_constant :YARN_INSTALL_COMMAND, :YARN_INSTALL_PARAMETERS, :YARN_RUN_COMMAND, :YARN_RUN_SCRIPT_NAME
|
|
21
21
|
|
|
22
|
-
UI_EXTENSIONS_CHECKOUT = "@shopify/checkout-ui-extensions"
|
|
23
|
-
UI_EXTENSIONS_ADMIN = "@shopify/admin-ui-extensions"
|
|
24
|
-
UI_EXTENSIONS_POST_PURCHASE = "@shopify/post-purchase-ui-extensions"
|
|
25
|
-
|
|
26
|
-
PACKAGE_NAMES = [
|
|
27
|
-
UI_EXTENSIONS_CHECKOUT,
|
|
28
|
-
UI_EXTENSIONS_ADMIN,
|
|
29
|
-
UI_EXTENSIONS_POST_PURCHASE,
|
|
30
|
-
].freeze
|
|
31
|
-
|
|
32
22
|
def create(directory_name, identifier, context)
|
|
33
23
|
Features::ArgoSetup.new(git_template: git_template).call(directory_name, identifier, context)
|
|
34
24
|
end
|
|
@@ -54,7 +44,7 @@ module Extension
|
|
|
54
44
|
def renderer_package(context)
|
|
55
45
|
js_system = ShopifyCli::JsSystem.new(ctx: context)
|
|
56
46
|
Tasks::FindNpmPackages
|
|
57
|
-
.exactly_one_of(
|
|
47
|
+
.exactly_one_of(renderer_package_name, js_system: js_system)
|
|
58
48
|
.unwrap { |err| raise err }
|
|
59
49
|
rescue Extension::PackageResolutionFailed
|
|
60
50
|
context.abort(
|
|
@@ -1,46 +1,14 @@
|
|
|
1
1
|
module Extension
|
|
2
2
|
module Features
|
|
3
3
|
class ArgoRuntime
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ADMIN_RUN_FLAGS = [
|
|
10
|
-
:api_key,
|
|
11
|
-
:name,
|
|
12
|
-
:port,
|
|
13
|
-
:public_url,
|
|
14
|
-
:renderer_version,
|
|
15
|
-
:shop,
|
|
16
|
-
:uuid,
|
|
4
|
+
RUNTIMES = [
|
|
5
|
+
Runtimes::Admin.new,
|
|
6
|
+
Runtimes::CheckoutPostPurchase.new,
|
|
7
|
+
Runtimes::CheckoutUiExtension.new,
|
|
17
8
|
]
|
|
18
9
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
:public_url,
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
property! :renderer, accepts: Models::NpmPackage
|
|
25
|
-
property! :cli, accepts: Models::NpmPackage
|
|
26
|
-
|
|
27
|
-
def supports?(flag)
|
|
28
|
-
case cli
|
|
29
|
-
when admin?
|
|
30
|
-
ADMIN_RUN_FLAGS.include?(flag.to_sym)
|
|
31
|
-
when checkout?
|
|
32
|
-
CHECKOUT_RUN_FLAGS.include?(flag.to_sym)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
def admin?
|
|
39
|
-
->(cli) { cli.name == UI_EXTENSIONS_ADMIN_RUN }
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def checkout?
|
|
43
|
-
->(cli) { cli.name == UI_EXTENSIONS_CHECKOUT_RUN }
|
|
10
|
+
def self.find(cli_package:, identifier:)
|
|
11
|
+
RUNTIMES.find { |runtime| runtime.active_runtime?(cli_package, identifier) }
|
|
44
12
|
end
|
|
45
13
|
end
|
|
46
14
|
end
|
|
@@ -7,11 +7,12 @@ module Extension
|
|
|
7
7
|
NPM_SERVE_COMMAND = %w(run-script server)
|
|
8
8
|
|
|
9
9
|
property! :specification_handler, accepts: Extension::Models::SpecificationHandlers::Default
|
|
10
|
-
property! :argo_runtime, accepts: Features::
|
|
10
|
+
property! :argo_runtime, accepts: -> (runtime) { runtime.class < Features::Runtimes::Base }
|
|
11
11
|
property! :context, accepts: ShopifyCli::Context
|
|
12
12
|
property! :port, accepts: Integer, default: 39351
|
|
13
13
|
property :tunnel_url, accepts: String, default: nil
|
|
14
14
|
property! :js_system, accepts: ->(jss) { jss.respond_to?(:call) }, default: ShopifyCli::JsSystem
|
|
15
|
+
property :resource_url, accepts: String, default: nil
|
|
15
16
|
|
|
16
17
|
def call
|
|
17
18
|
validate_env!
|
|
@@ -22,6 +23,10 @@ module Extension
|
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
26
|
+
def resource_url
|
|
27
|
+
super || ExtensionProject.current(force_reload: true).resource_url
|
|
28
|
+
end
|
|
29
|
+
|
|
25
30
|
private
|
|
26
31
|
|
|
27
32
|
def start_server
|
|
@@ -57,6 +62,7 @@ module Extension
|
|
|
57
62
|
ShopifyCli::Tasks::EnsureDevStore.call(context) if required_fields.include?(:shop)
|
|
58
63
|
|
|
59
64
|
project = ExtensionProject.current
|
|
65
|
+
ensure_resource_resource_url! if specification_handler.supplies_resource_url?
|
|
60
66
|
|
|
61
67
|
return if required_fields.all? do |field|
|
|
62
68
|
value = project.env.public_send(field)
|
|
@@ -77,8 +83,31 @@ module Extension
|
|
|
77
83
|
options << "--uuid=#{project.registration_uuid}" if argo_runtime.supports?(:uuid)
|
|
78
84
|
options << "--publicUrl=#{tunnel_url}" if !tunnel_url.nil? && argo_runtime.supports?(:public_url)
|
|
79
85
|
options << "--name=#{project.title}" if argo_runtime.supports?(:name)
|
|
86
|
+
options << "--resourceUrl=#{resource_url}" if !resource_url.nil? && argo_runtime.supports?(:resource_url)
|
|
80
87
|
end
|
|
81
88
|
end
|
|
89
|
+
|
|
90
|
+
def ensure_resource_resource_url!
|
|
91
|
+
project = ExtensionProject.current(force_reload: true)
|
|
92
|
+
|
|
93
|
+
ShopifyCli::Result
|
|
94
|
+
.wrap(project.resource_url)
|
|
95
|
+
.rescue { specification_handler.build_resource_url(shop: project.env.shop, context: context) }
|
|
96
|
+
.then(&method(:persist_resource_url))
|
|
97
|
+
.unwrap do |nil_or_exception|
|
|
98
|
+
case nil_or_exception
|
|
99
|
+
when nil
|
|
100
|
+
context.warn(context.message("warnings.resource_url_auto_generation_failed", project.env.shop))
|
|
101
|
+
else
|
|
102
|
+
context.abort(nil_or_exception)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def persist_resource_url(resource_url)
|
|
108
|
+
ExtensionProject.update_env_file(context: context, resource_url: resource_url)
|
|
109
|
+
resource_url
|
|
110
|
+
end
|
|
82
111
|
end
|
|
83
112
|
end
|
|
84
113
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Extension
|
|
2
|
+
module Features
|
|
3
|
+
module Runtimes
|
|
4
|
+
class Admin < Base
|
|
5
|
+
ADMIN_UI_EXTENSIONS_RUN = "@shopify/admin-ui-extensions-run"
|
|
6
|
+
PRODUCT_SUBSCRIPTION = "PRODUCT_SUBSCRIPTION"
|
|
7
|
+
|
|
8
|
+
AVAILABLE_FLAGS = [
|
|
9
|
+
:api_key,
|
|
10
|
+
:name,
|
|
11
|
+
:port,
|
|
12
|
+
:public_url,
|
|
13
|
+
:renderer_version,
|
|
14
|
+
:resource_url,
|
|
15
|
+
:shop,
|
|
16
|
+
:uuid,
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
def available_flags
|
|
20
|
+
AVAILABLE_FLAGS
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def active_runtime?(cli_package, identifier)
|
|
24
|
+
cli_package.name == ADMIN_UI_EXTENSIONS_RUN && identifier == PRODUCT_SUBSCRIPTION
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Extension
|
|
2
|
+
module Features
|
|
3
|
+
module Runtimes
|
|
4
|
+
class Base
|
|
5
|
+
def available_flags
|
|
6
|
+
[]
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def supports?(flag)
|
|
10
|
+
available_flags.include?(flag)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def active_runtime?(cli_package, identifier)
|
|
14
|
+
raise NotImplementedError
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Extension
|
|
2
|
+
module Features
|
|
3
|
+
module Runtimes
|
|
4
|
+
class CheckoutPostPurchase < Base
|
|
5
|
+
CHECKOUT_UI_EXTENSIONS_RUN = "@shopify/checkout-ui-extensions-run"
|
|
6
|
+
CHECKOUT_POST_PURCHASE = "CHECKOUT_POST_PURCHASE"
|
|
7
|
+
|
|
8
|
+
AVAILABLE_FLAGS = [
|
|
9
|
+
:port,
|
|
10
|
+
:public_url,
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
def available_flags
|
|
14
|
+
AVAILABLE_FLAGS
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def active_runtime?(cli_package, identifier)
|
|
18
|
+
cli_package.name == CHECKOUT_UI_EXTENSIONS_RUN && identifier == CHECKOUT_POST_PURCHASE
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Extension
|
|
2
|
+
module Features
|
|
3
|
+
module Runtimes
|
|
4
|
+
class CheckoutUiExtension < Base
|
|
5
|
+
CHECKOUT_UI_EXTENSIONS_RUN = "@shopify/checkout-ui-extensions-run"
|
|
6
|
+
|
|
7
|
+
IDENTIFIERS = [
|
|
8
|
+
"CHECKOUT_ARGO_EXTENSION",
|
|
9
|
+
"CHECKOUT_UI_EXTENSION",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
AVAILABLE_FLAGS = [
|
|
13
|
+
:port,
|
|
14
|
+
:public_url,
|
|
15
|
+
:resource_url,
|
|
16
|
+
:shop,
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
def available_flags
|
|
20
|
+
AVAILABLE_FLAGS
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def active_runtime?(cli_package, identifier)
|
|
24
|
+
cli_package.name == CHECKOUT_UI_EXTENSIONS_RUN && IDENTIFIERS.include?(identifier)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -139,6 +139,10 @@ module Extension
|
|
|
139
139
|
Usage: {{command:%1$s extension tunnel status}}
|
|
140
140
|
HELP
|
|
141
141
|
},
|
|
142
|
+
check: {
|
|
143
|
+
help: "Check your extension for errors, suggestions, and best practices.",
|
|
144
|
+
unsupported: "{{red:%s projects are not supported for `extension check`}}",
|
|
145
|
+
},
|
|
142
146
|
features: {
|
|
143
147
|
argo: {
|
|
144
148
|
missing_file_error: "Could not find built extension file.",
|
|
@@ -162,12 +166,18 @@ module Extension
|
|
|
162
166
|
tasks: {
|
|
163
167
|
errors: {
|
|
164
168
|
parse_error: "Unable to parse response from Partners Dashboard.",
|
|
169
|
+
store_error: "There was an error getting store data. Try again later.",
|
|
165
170
|
},
|
|
166
171
|
},
|
|
167
172
|
errors: {
|
|
168
173
|
unknown_type: "Unknown extension type %s",
|
|
169
174
|
package_not_found: "`%s` package not found.",
|
|
170
175
|
},
|
|
176
|
+
warnings: {
|
|
177
|
+
resource_url_auto_generation_failed: "{{*}} {{yellow:Warning:}} Unable to auto generate " \
|
|
178
|
+
"the extension resource URL because %s does not have any products. " \
|
|
179
|
+
"Please run {{bold:shopify populate products}} to generate sample products.",
|
|
180
|
+
},
|
|
171
181
|
}
|
|
172
182
|
|
|
173
183
|
TYPES = {
|
|
@@ -196,6 +206,9 @@ module Extension
|
|
|
196
206
|
{{*}} You’re ready to start building {{green:%s}}!
|
|
197
207
|
MESSAGE
|
|
198
208
|
},
|
|
209
|
+
serve: {
|
|
210
|
+
unsupported: "shopify extension serve is not supported for theme app extensions",
|
|
211
|
+
},
|
|
199
212
|
},
|
|
200
213
|
},
|
|
201
214
|
}
|
|
@@ -6,6 +6,7 @@ module Extension
|
|
|
6
6
|
module SpecificationHandlers
|
|
7
7
|
class CheckoutPostPurchase < Default
|
|
8
8
|
PERMITTED_CONFIG_KEYS = [:metafields]
|
|
9
|
+
RENDERER_PACKAGE_NAME = "@shopify/post-purchase-ui-extensions"
|
|
9
10
|
|
|
10
11
|
def config(context)
|
|
11
12
|
{
|
|
@@ -13,6 +14,15 @@ module Extension
|
|
|
13
14
|
**argo.config(context),
|
|
14
15
|
}
|
|
15
16
|
end
|
|
17
|
+
|
|
18
|
+
protected
|
|
19
|
+
|
|
20
|
+
def argo
|
|
21
|
+
Features::Argo.new(
|
|
22
|
+
git_template: specification.features.argo.git_template,
|
|
23
|
+
renderer_package_name: RENDERER_PACKAGE_NAME
|
|
24
|
+
)
|
|
25
|
+
end
|
|
16
26
|
end
|
|
17
27
|
end
|
|
18
28
|
end
|
|
@@ -12,9 +12,17 @@ module Extension
|
|
|
12
12
|
**argo.config(context),
|
|
13
13
|
}
|
|
14
14
|
end
|
|
15
|
-
end
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
def supplies_resource_url?
|
|
17
|
+
true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def build_resource_url(context:, shop:)
|
|
21
|
+
product = Tasks::GetProduct.call(context, shop)
|
|
22
|
+
return unless product
|
|
23
|
+
format("/cart/%<variant_id>d:%<quantity>d", variant_id: product.variant_id, quantity: 1)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
18
26
|
end
|
|
19
27
|
end
|
|
20
28
|
end
|
|
@@ -50,13 +50,14 @@ module Extension
|
|
|
50
50
|
argo_runtime(context).supports?(:public_url)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
def serve(context:, port:, tunnel_url:)
|
|
53
|
+
def serve(context:, port:, tunnel_url:, resource_url:)
|
|
54
54
|
Features::ArgoServe.new(
|
|
55
55
|
specification_handler: self,
|
|
56
56
|
argo_runtime: argo_runtime(context),
|
|
57
57
|
context: context,
|
|
58
58
|
port: port,
|
|
59
59
|
tunnel_url: tunnel_url,
|
|
60
|
+
resource_url: resource_url
|
|
60
61
|
).call
|
|
61
62
|
end
|
|
62
63
|
|
|
@@ -65,9 +66,9 @@ module Extension
|
|
|
65
66
|
end
|
|
66
67
|
|
|
67
68
|
def argo_runtime(context)
|
|
68
|
-
@argo_runtime ||= Features::ArgoRuntime.
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
@argo_runtime ||= Features::ArgoRuntime.find(
|
|
70
|
+
cli_package: cli_package(context),
|
|
71
|
+
identifier: identifier
|
|
71
72
|
)
|
|
72
73
|
end
|
|
73
74
|
|
|
@@ -90,6 +91,14 @@ module Extension
|
|
|
90
91
|
end
|
|
91
92
|
end
|
|
92
93
|
|
|
94
|
+
def supplies_resource_url?
|
|
95
|
+
false
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def build_resource_url(shop)
|
|
99
|
+
raise NotImplementedError
|
|
100
|
+
end
|
|
101
|
+
|
|
93
102
|
protected
|
|
94
103
|
|
|
95
104
|
def argo
|
|
@@ -60,6 +60,18 @@ module Extension
|
|
|
60
60
|
"Theme App Extension"
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
def choose_port?(ctx)
|
|
64
|
+
ctx.abort(ctx.message("serve.unsupported"))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def establish_tunnel?(ctx)
|
|
68
|
+
ctx.abort(ctx.message("serve.unsupported"))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def serve(ctx)
|
|
72
|
+
ctx.abort(ctx.message("serve.unsupported"))
|
|
73
|
+
end
|
|
74
|
+
|
|
63
75
|
private
|
|
64
76
|
|
|
65
77
|
def validate(filename)
|
|
@@ -46,6 +46,7 @@ module Extension
|
|
|
46
46
|
checkout: {
|
|
47
47
|
git_template: "https://github.com/Shopify/checkout-ui-extensions-template",
|
|
48
48
|
renderer_package_name: "@shopify/checkout-ui-extensions",
|
|
49
|
+
required_fields: [:shop],
|
|
49
50
|
cli_package_name: "@shopify/checkout-ui-extensions-run",
|
|
50
51
|
},
|
|
51
52
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "shopify_cli"
|
|
3
|
+
|
|
4
|
+
module Extension
|
|
5
|
+
module Tasks
|
|
6
|
+
module Converters
|
|
7
|
+
module ProductConverter
|
|
8
|
+
VARIANT_PATH = ["data", "products", "edges", 0, "node", "variants", "edges", 0, "node", "id"]
|
|
9
|
+
|
|
10
|
+
def self.from_hash(hash)
|
|
11
|
+
return nil if hash.nil?
|
|
12
|
+
variant = hash.dig(*VARIANT_PATH)
|
|
13
|
+
return unless variant
|
|
14
|
+
Models::Product.new(
|
|
15
|
+
variant_id: ShopifyCli::API.gid_to_id(variant)
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "shopify_cli"
|
|
3
|
+
|
|
4
|
+
module Extension
|
|
5
|
+
module Tasks
|
|
6
|
+
class GetProduct < ShopifyCli::Task
|
|
7
|
+
API_VERSION = "2021-07"
|
|
8
|
+
GRAPHQL_FILE = "get_variant_id"
|
|
9
|
+
|
|
10
|
+
def call(context, shop)
|
|
11
|
+
response = ShopifyCli::AdminAPI.query(
|
|
12
|
+
context,
|
|
13
|
+
GRAPHQL_FILE,
|
|
14
|
+
shop: shop,
|
|
15
|
+
api_version: API_VERSION
|
|
16
|
+
)
|
|
17
|
+
context.abort(context.message("tasks.errors.store_error")) if response.nil?
|
|
18
|
+
Converters::ProductConverter.from_hash(response)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -34,7 +34,7 @@ module Script
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def self.help
|
|
37
|
-
allowed_values = Script::Layers::Application::ExtensionPoints.
|
|
37
|
+
allowed_values = Script::Layers::Application::ExtensionPoints.available_types.map { |type| "{{cyan:#{type}}}" }
|
|
38
38
|
ShopifyCli::Context.message("script.create.help", ShopifyCli::TOOL_NAME, allowed_values.join(", "))
|
|
39
39
|
end
|
|
40
40
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
mutation AppScriptSet(
|
|
2
|
+
$uuid: String
|
|
3
|
+
$extensionPointName: ExtensionPointName!,
|
|
4
|
+
$title: String!,
|
|
5
|
+
$description: String,
|
|
6
|
+
$force: Boolean,
|
|
7
|
+
$schemaMajorVersion: String,
|
|
8
|
+
$schemaMinorVersion: String,
|
|
9
|
+
$scriptJsonVersion: String!,
|
|
10
|
+
$configurationUi: Boolean!,
|
|
11
|
+
$configurationDefinition: String!,
|
|
12
|
+
$moduleUploadUrl: String!,
|
|
13
|
+
) {
|
|
14
|
+
appScriptSet(
|
|
15
|
+
uuid: $uuid
|
|
16
|
+
extensionPointName: $extensionPointName
|
|
17
|
+
title: $title
|
|
18
|
+
description: $description
|
|
19
|
+
force: $force
|
|
20
|
+
schemaMajorVersion: $schemaMajorVersion
|
|
21
|
+
schemaMinorVersion: $schemaMinorVersion,
|
|
22
|
+
scriptJsonVersion: $scriptJsonVersion,
|
|
23
|
+
configurationUi: $configurationUi,
|
|
24
|
+
configurationDefinition: $configurationDefinition,
|
|
25
|
+
moduleUploadUrl: $moduleUploadUrl,
|
|
26
|
+
) {
|
|
27
|
+
userErrors {
|
|
28
|
+
field
|
|
29
|
+
message
|
|
30
|
+
tag
|
|
31
|
+
}
|
|
32
|
+
appScript {
|
|
33
|
+
uuid
|
|
34
|
+
appKey
|
|
35
|
+
configSchema
|
|
36
|
+
extensionPointName
|
|
37
|
+
title
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
mutation AppScriptUpdateOrCreate(
|
|
2
|
-
$extensionPointName: ExtensionPointName!,
|
|
3
|
-
$title: String,
|
|
4
|
-
$description: String,
|
|
5
|
-
$sourceCode: String,
|
|
6
|
-
$language: String,
|
|
7
|
-
$force: Boolean,
|
|
8
|
-
$schemaMajorVersion: String,
|
|
9
|
-
$schemaMinorVersion: String,
|
|
10
|
-
$useMsgpack: Boolean,
|
|
11
|
-
$uuid: String,
|
|
12
|
-
$configurationUi: Boolean!,
|
|
13
|
-
$scriptJsonVersion: String!,
|
|
14
|
-
$configurationDefinition: String!,
|
|
15
|
-
) {
|
|
16
|
-
appScriptUpdateOrCreate(
|
|
17
|
-
extensionPointName: $extensionPointName
|
|
18
|
-
title: $title
|
|
19
|
-
description: $description
|
|
20
|
-
sourceCode: $sourceCode
|
|
21
|
-
language: $language
|
|
22
|
-
force: $force
|
|
23
|
-
schemaMajorVersion: $schemaMajorVersion
|
|
24
|
-
schemaMinorVersion: $schemaMinorVersion
|
|
25
|
-
useMsgpack: $useMsgpack,
|
|
26
|
-
uuid: $uuid
|
|
27
|
-
configurationUi: $configurationUi
|
|
28
|
-
scriptJsonVersion: $scriptJsonVersion
|
|
29
|
-
configurationDefinition: $configurationDefinition
|
|
30
|
-
) {
|
|
31
|
-
userErrors {
|
|
32
|
-
field
|
|
33
|
-
message
|
|
34
|
-
tag
|
|
35
|
-
}
|
|
36
|
-
appScript {
|
|
37
|
-
uuid
|
|
38
|
-
appKey
|
|
39
|
-
configSchema
|
|
40
|
-
extensionPointName
|
|
41
|
-
title
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -17,7 +17,7 @@ module Script
|
|
|
17
17
|
uuid:,
|
|
18
18
|
extension_point_type:,
|
|
19
19
|
script_content:,
|
|
20
|
-
compiled_type
|
|
20
|
+
compiled_type: nil,
|
|
21
21
|
metadata:,
|
|
22
22
|
script_json:
|
|
23
23
|
)
|
|
@@ -35,7 +35,6 @@ module Script
|
|
|
35
35
|
uuid: @uuid,
|
|
36
36
|
extension_point_type: @extension_point_type,
|
|
37
37
|
script_content: @script_content,
|
|
38
|
-
compiled_type: @compiled_type,
|
|
39
38
|
api_key: api_key,
|
|
40
39
|
force: force,
|
|
41
40
|
metadata: @metadata,
|
|
@@ -14,32 +14,31 @@ module Script
|
|
|
14
14
|
uuid:,
|
|
15
15
|
extension_point_type:,
|
|
16
16
|
script_content:,
|
|
17
|
-
compiled_type:,
|
|
18
17
|
api_key: nil,
|
|
19
18
|
force: false,
|
|
20
19
|
metadata:,
|
|
21
20
|
script_json:
|
|
22
21
|
)
|
|
23
|
-
|
|
22
|
+
url = UploadScript.new(ctx).call(api_key, script_content)
|
|
23
|
+
|
|
24
|
+
query_name = "app_script_set"
|
|
24
25
|
variables = {
|
|
25
26
|
uuid: uuid,
|
|
26
27
|
extensionPointName: extension_point_type.upcase,
|
|
27
28
|
title: script_json.title,
|
|
28
29
|
description: script_json.description,
|
|
29
|
-
sourceCode: Base64.encode64(script_content),
|
|
30
|
-
language: compiled_type,
|
|
31
30
|
force: force,
|
|
32
31
|
schemaMajorVersion: metadata.schema_major_version.to_s, # API expects string value
|
|
33
32
|
schemaMinorVersion: metadata.schema_minor_version.to_s, # API expects string value
|
|
34
|
-
useMsgpack: metadata.use_msgpack,
|
|
35
33
|
scriptJsonVersion: script_json.version,
|
|
36
34
|
configurationUi: script_json.configuration_ui,
|
|
37
35
|
configurationDefinition: script_json.configuration&.to_json,
|
|
36
|
+
moduleUploadUrl: url,
|
|
38
37
|
}
|
|
39
|
-
resp_hash =
|
|
40
|
-
user_errors = resp_hash["data"]["
|
|
38
|
+
resp_hash = MakeRequest.new(ctx).call(query_name: query_name, api_key: api_key, variables: variables)
|
|
39
|
+
user_errors = resp_hash["data"]["appScriptSet"]["userErrors"]
|
|
41
40
|
|
|
42
|
-
return resp_hash["data"]["
|
|
41
|
+
return resp_hash["data"]["appScriptSet"]["appScript"]["uuid"] if user_errors.empty?
|
|
43
42
|
|
|
44
43
|
if user_errors.any? { |e| e["tag"] == "already_exists_error" }
|
|
45
44
|
raise Errors::ScriptRepushError, uuid
|
|
@@ -67,11 +66,14 @@ module Script
|
|
|
67
66
|
def get_app_scripts(api_key:, extension_point_type:)
|
|
68
67
|
query_name = "get_app_scripts"
|
|
69
68
|
variables = { appKey: api_key, extensionPointName: extension_point_type.upcase }
|
|
70
|
-
|
|
69
|
+
response = MakeRequest.new(ctx).call(
|
|
70
|
+
query_name: query_name,
|
|
71
|
+
api_key: api_key,
|
|
72
|
+
variables: variables
|
|
73
|
+
)
|
|
74
|
+
response["data"]["appScripts"]
|
|
71
75
|
end
|
|
72
76
|
|
|
73
|
-
private
|
|
74
|
-
|
|
75
77
|
class ScriptServiceAPI < ShopifyCli::API
|
|
76
78
|
property(:api_key, accepts: String)
|
|
77
79
|
|
|
@@ -114,47 +116,95 @@ module Script
|
|
|
114
116
|
end
|
|
115
117
|
private_constant(:PartnersProxyAPI)
|
|
116
118
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
class MakeRequest
|
|
120
|
+
attr_reader :ctx
|
|
121
|
+
|
|
122
|
+
def initialize(ctx)
|
|
123
|
+
@ctx = ctx
|
|
122
124
|
end
|
|
123
|
-
raise_if_graphql_failed(resp)
|
|
124
|
-
resp
|
|
125
|
-
end
|
|
126
125
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
def self.bypass_partners_proxy
|
|
127
|
+
!ENV["BYPASS_PARTNERS_PROXY"].nil?
|
|
128
|
+
end
|
|
130
129
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
130
|
+
def call(query_name:, variables: nil, **options)
|
|
131
|
+
resp = if MakeRequest.bypass_partners_proxy
|
|
132
|
+
ScriptServiceAPI.query(ctx, query_name, variables: variables, **options)
|
|
133
|
+
else
|
|
134
|
+
proxy_through_partners(query_name: query_name, variables: variables, **options)
|
|
135
|
+
end
|
|
136
|
+
raise_if_graphql_failed(resp)
|
|
137
|
+
resp
|
|
138
|
+
end
|
|
137
139
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
raise Errors::
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
140
|
+
def proxy_through_partners(query_name:, variables: nil, **options)
|
|
141
|
+
options[:variables] = variables.to_json if variables
|
|
142
|
+
resp = PartnersProxyAPI.query(ctx, query_name, **options)
|
|
143
|
+
raise_if_graphql_failed(resp)
|
|
144
|
+
JSON.parse(resp["data"]["scriptServiceProxy"])
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def raise_if_graphql_failed(response)
|
|
148
|
+
raise Errors::EmptyResponseError if response.nil?
|
|
149
|
+
|
|
150
|
+
return unless response.key?("errors")
|
|
151
|
+
case error_code(response["errors"])
|
|
152
|
+
when "forbidden"
|
|
153
|
+
raise Errors::ForbiddenError
|
|
154
|
+
when "forbidden_on_shop"
|
|
155
|
+
raise Errors::ShopAuthenticationError
|
|
156
|
+
when "app_not_installed_on_shop"
|
|
157
|
+
raise Errors::AppNotInstalledError
|
|
158
|
+
else
|
|
159
|
+
raise Errors::GraphqlError, response["errors"]
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def error_code(errors)
|
|
164
|
+
errors.map do |e|
|
|
165
|
+
code = e.dig("extensions", "code")
|
|
166
|
+
return code if code
|
|
167
|
+
end
|
|
151
168
|
end
|
|
152
169
|
end
|
|
153
170
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
171
|
+
class UploadScript
|
|
172
|
+
attr_reader :ctx
|
|
173
|
+
|
|
174
|
+
def initialize(ctx)
|
|
175
|
+
@ctx = ctx
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def call(api_key, script_content)
|
|
179
|
+
apply_module_upload_url(api_key).tap do |url|
|
|
180
|
+
upload(url, script_content)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
private
|
|
185
|
+
|
|
186
|
+
def apply_module_upload_url(api_key)
|
|
187
|
+
query_name = "module_upload_url_generate"
|
|
188
|
+
variables = {}
|
|
189
|
+
resp_hash = MakeRequest.new(ctx).call(query_name: query_name, api_key: api_key, variables: variables)
|
|
190
|
+
user_errors = resp_hash["data"]["moduleUploadUrlGenerate"]["userErrors"]
|
|
191
|
+
|
|
192
|
+
raise Errors::GraphqlError, user_errors if user_errors.any?
|
|
193
|
+
resp_hash["data"]["moduleUploadUrlGenerate"]["url"]
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def upload(url, script_content)
|
|
197
|
+
url = URI(url)
|
|
198
|
+
|
|
199
|
+
https = Net::HTTP.new(url.host, url.port)
|
|
200
|
+
https.use_ssl = true
|
|
201
|
+
|
|
202
|
+
request = Net::HTTP::Put.new(url)
|
|
203
|
+
request["Content-Type"] = "application/wasm"
|
|
204
|
+
request.body = script_content
|
|
205
|
+
|
|
206
|
+
response = https.request(request)
|
|
207
|
+
raise Errors::ScriptUploadError unless response.code == "200"
|
|
158
208
|
end
|
|
159
209
|
end
|
|
160
210
|
end
|
|
@@ -141,6 +141,9 @@ module Script
|
|
|
141
141
|
web_assembly_binary_not_found_suggestion: "No WebAssembly binary found." \
|
|
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
|
+
|
|
145
|
+
script_upload_cause: "Fail to upload script.",
|
|
146
|
+
script_upload_help: "Try again.",
|
|
144
147
|
},
|
|
145
148
|
|
|
146
149
|
create: {
|
|
@@ -237,6 +237,11 @@ 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::ScriptUploadError
|
|
241
|
+
{
|
|
242
|
+
cause_of_error: ShopifyCli::Context.message("script.error.script_upload_cause"),
|
|
243
|
+
help_suggestion: ShopifyCli::Context.message("script.error.script_upload_help"),
|
|
244
|
+
}
|
|
240
245
|
end
|
|
241
246
|
end
|
|
242
247
|
end
|
|
@@ -46,7 +46,7 @@ module ShopifyCli
|
|
|
46
46
|
|
|
47
47
|
# we only want to send Monorail events in production or when explicitly developing
|
|
48
48
|
def enabled?
|
|
49
|
-
Context.new.system? || ENV["MONORAIL_REAL_EVENTS"] == "1"
|
|
49
|
+
(Context.new.system? || ENV["MONORAIL_REAL_EVENTS"] == "1") && !Context.new.ci?
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def consented?
|
|
@@ -54,6 +54,7 @@ module ShopifyCli
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def prompt_for_consent
|
|
57
|
+
return if Context.new.ci?
|
|
57
58
|
return unless enabled?
|
|
58
59
|
return if ShopifyCli::Config.get_section("analytics").key?("enabled")
|
|
59
60
|
msg = Context.message("core.monorail.consent_prompt")
|
data/lib/shopify-cli/version.rb
CHANGED
data/shopify-cli.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shopify-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-08-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -78,14 +78,14 @@ dependencies:
|
|
|
78
78
|
requirements:
|
|
79
79
|
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '1.
|
|
81
|
+
version: '1.1'
|
|
82
82
|
type: :runtime
|
|
83
83
|
prerelease: false
|
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements:
|
|
86
86
|
- - "~>"
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '1.
|
|
88
|
+
version: '1.1'
|
|
89
89
|
description: |
|
|
90
90
|
Shopify CLI helps you build Shopify apps faster. It quickly scaffolds Node.js
|
|
91
91
|
and Ruby on Rails embedded apps. It also automates many common tasks in the
|
|
@@ -159,9 +159,11 @@ files:
|
|
|
159
159
|
- lib/graphql/find_organization.graphql
|
|
160
160
|
- lib/graphql/get_app_by_api_key.graphql
|
|
161
161
|
- lib/graphql/get_app_urls.graphql
|
|
162
|
+
- lib/graphql/get_variant_id.graphql
|
|
162
163
|
- lib/graphql/update_dashboard_urls.graphql
|
|
163
164
|
- lib/project_types/extension/cli.rb
|
|
164
165
|
- lib/project_types/extension/commands/build.rb
|
|
166
|
+
- lib/project_types/extension/commands/check.rb
|
|
165
167
|
- lib/project_types/extension/commands/connect.rb
|
|
166
168
|
- lib/project_types/extension/commands/create.rb
|
|
167
169
|
- lib/project_types/extension/commands/extension_command.rb
|
|
@@ -181,6 +183,10 @@ files:
|
|
|
181
183
|
- lib/project_types/extension/features/argo_setup.rb
|
|
182
184
|
- lib/project_types/extension/features/argo_setup_step.rb
|
|
183
185
|
- lib/project_types/extension/features/argo_setup_steps.rb
|
|
186
|
+
- lib/project_types/extension/features/runtimes/admin.rb
|
|
187
|
+
- lib/project_types/extension/features/runtimes/base.rb
|
|
188
|
+
- lib/project_types/extension/features/runtimes/checkout_post_purchase.rb
|
|
189
|
+
- lib/project_types/extension/features/runtimes/checkout_ui_extension.rb
|
|
184
190
|
- lib/project_types/extension/forms/connect.rb
|
|
185
191
|
- lib/project_types/extension/forms/create.rb
|
|
186
192
|
- lib/project_types/extension/forms/questions/ask_app.rb
|
|
@@ -192,6 +198,7 @@ files:
|
|
|
192
198
|
- lib/project_types/extension/models/app.rb
|
|
193
199
|
- lib/project_types/extension/models/lazy_specification_handler.rb
|
|
194
200
|
- lib/project_types/extension/models/npm_package.rb
|
|
201
|
+
- lib/project_types/extension/models/product.rb
|
|
195
202
|
- lib/project_types/extension/models/registration.rb
|
|
196
203
|
- lib/project_types/extension/models/specification.rb
|
|
197
204
|
- lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb
|
|
@@ -205,6 +212,7 @@ files:
|
|
|
205
212
|
- lib/project_types/extension/tasks/configure_features.rb
|
|
206
213
|
- lib/project_types/extension/tasks/configure_options.rb
|
|
207
214
|
- lib/project_types/extension/tasks/converters/app_converter.rb
|
|
215
|
+
- lib/project_types/extension/tasks/converters/product_converter.rb
|
|
208
216
|
- lib/project_types/extension/tasks/converters/registration_converter.rb
|
|
209
217
|
- lib/project_types/extension/tasks/converters/validation_error_converter.rb
|
|
210
218
|
- lib/project_types/extension/tasks/converters/version_converter.rb
|
|
@@ -214,6 +222,7 @@ files:
|
|
|
214
222
|
- lib/project_types/extension/tasks/get_app.rb
|
|
215
223
|
- lib/project_types/extension/tasks/get_apps.rb
|
|
216
224
|
- lib/project_types/extension/tasks/get_extensions.rb
|
|
225
|
+
- lib/project_types/extension/tasks/get_product.rb
|
|
217
226
|
- lib/project_types/extension/tasks/update_draft.rb
|
|
218
227
|
- lib/project_types/extension/tasks/user_errors.rb
|
|
219
228
|
- lib/project_types/node/cli.rb
|
|
@@ -247,8 +256,10 @@ files:
|
|
|
247
256
|
- lib/project_types/script/config/extension_points.yml
|
|
248
257
|
- lib/project_types/script/errors.rb
|
|
249
258
|
- lib/project_types/script/forms/create.rb
|
|
259
|
+
- lib/project_types/script/graphql/app_script_set.graphql
|
|
250
260
|
- lib/project_types/script/graphql/app_script_update_or_create.graphql
|
|
251
261
|
- lib/project_types/script/graphql/get_app_scripts.graphql
|
|
262
|
+
- lib/project_types/script/graphql/module_upload_url_generate.graphql
|
|
252
263
|
- lib/project_types/script/graphql/script_service_proxy.graphql
|
|
253
264
|
- lib/project_types/script/layers/application/build_script.rb
|
|
254
265
|
- lib/project_types/script/layers/application/create_script.rb
|