shopify-cli 2.0.2 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/Gemfile.lock +4 -4
  4. data/lib/graphql/get_variant_id.graphql +16 -0
  5. data/lib/project_types/extension/cli.rb +10 -1
  6. data/lib/project_types/extension/commands/check.rb +44 -0
  7. data/lib/project_types/extension/commands/push.rb +0 -1
  8. data/lib/project_types/extension/commands/serve.rb +8 -2
  9. data/lib/project_types/extension/extension_project.rb +28 -1
  10. data/lib/project_types/extension/features/argo.rb +1 -11
  11. data/lib/project_types/extension/features/argo_runtime.rb +6 -38
  12. data/lib/project_types/extension/features/argo_serve.rb +30 -1
  13. data/lib/project_types/extension/features/runtimes/admin.rb +29 -0
  14. data/lib/project_types/extension/features/runtimes/base.rb +19 -0
  15. data/lib/project_types/extension/features/runtimes/checkout_post_purchase.rb +23 -0
  16. data/lib/project_types/extension/features/runtimes/checkout_ui_extension.rb +29 -0
  17. data/lib/project_types/extension/messages/messages.rb +13 -0
  18. data/lib/project_types/extension/models/product.rb +12 -0
  19. data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +10 -0
  20. data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +10 -2
  21. data/lib/project_types/extension/models/specification_handlers/default.rb +13 -4
  22. data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +12 -0
  23. data/lib/project_types/extension/tasks/configure_features.rb +1 -0
  24. data/lib/project_types/extension/tasks/converters/product_converter.rb +21 -0
  25. data/lib/project_types/extension/tasks/get_product.rb +22 -0
  26. data/lib/project_types/script/commands/create.rb +1 -1
  27. data/lib/project_types/script/graphql/app_script_set.graphql +40 -0
  28. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +0 -44
  29. data/lib/project_types/script/graphql/module_upload_url_generate.graphql +9 -0
  30. data/lib/project_types/script/layers/domain/push_package.rb +1 -2
  31. data/lib/project_types/script/layers/infrastructure/errors.rb +2 -0
  32. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +0 -1
  33. data/lib/project_types/script/layers/infrastructure/script_service.rb +95 -45
  34. data/lib/project_types/script/messages/messages.rb +3 -0
  35. data/lib/project_types/script/ui/error_handler.rb +5 -0
  36. data/lib/project_types/theme/forms/select.rb +1 -1
  37. data/lib/shopify-cli/core/monorail.rb +2 -1
  38. data/lib/shopify-cli/version.rb +1 -1
  39. data/shopify-cli.gemspec +1 -1
  40. metadata +15 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e891dd1947743de4abbd7ef4e2c7e40a60e313eed78e33e5813c1fbb72369b22
4
- data.tar.gz: 2af5852d53518d1089fabd4420cc6a432bccf99585d935812f8c347d9ad42d45
3
+ metadata.gz: c6192e829e79c4cfe8a1e6fe1214d17f57da63bcf3802de71a7171a0037a2c1a
4
+ data.tar.gz: 11f3a7167a24c5b011f930de1a9554176c6371c1a63350ea3a94d9965f521336
5
5
  SHA512:
6
- metadata.gz: 02fa4e4ed76dc0576474246772e332d7a21d0242807ceb407244a0af8dfe3c21c9e1eced54283a11ed304c0ae74ae81becc040c7f9c0242c9b35e8171f3182a4
7
- data.tar.gz: 5c587408bffbb49a09c087f2810b5b65b754de6fb2c3c8c158996446198817c7e2c0a21143544d7e7bc8ef74e4407fd4389d805ed298432c64656d202745fe86
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.0.2)
4
+ shopify-cli (2.2.2)
5
5
  listen (~> 3.5)
6
- theme-check (~> 1.0)
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.0.0)
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.1.4
111
+ 2.2.22
@@ -0,0 +1,16 @@
1
+ query {
2
+ products(first: 1) {
3
+ edges {
4
+ node {
5
+ id
6
+ variants(first: 1) {
7
+ edges {
8
+ node {
9
+ id
10
+ }
11
+ }
12
+ }
13
+ }
14
+ }
15
+ }
16
+ }
@@ -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(*PACKAGE_NAMES, js_system: js_system)
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
- include SmartProperties
5
-
6
- UI_EXTENSIONS_CHECKOUT_RUN = "@shopify/checkout-ui-extensions-run"
7
- UI_EXTENSIONS_ADMIN_RUN = "@shopify/admin-ui-extensions-run"
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
- CHECKOUT_RUN_FLAGS = [
20
- :port,
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::ArgoRuntime
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
  }
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Models
5
+ class Product
6
+ include SmartProperties
7
+
8
+ property :variant_id, accepts: Integer, converts: :to_i
9
+ property :quantity, accepts: Integer, default: 1
10
+ end
11
+ end
12
+ end
@@ -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
- CheckoutArgoExtension = CheckoutUiExtension
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.new(
69
- renderer: renderer_package(context),
70
- cli: cli_package(context),
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.types.map { |type| "{{cyan:#{type}}}" }
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
- }
@@ -0,0 +1,9 @@
1
+ mutation moduleUploadUrlGenerate {
2
+ moduleUploadUrlGenerate {
3
+ url
4
+ userErrors {
5
+ field
6
+ message
7
+ }
8
+ }
9
+ }
@@ -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,
@@ -93,6 +93,8 @@ module Script
93
93
  super("WebAssembly binary not found")
94
94
  end
95
95
  end
96
+
97
+ class ScriptUploadError < ScriptProjectError; end
96
98
  end
97
99
  end
98
100
  end
@@ -32,7 +32,6 @@ module Script
32
32
  uuid: script_project.uuid,
33
33
  extension_point_type: script_project.extension_point_type,
34
34
  script_content: script_content,
35
- compiled_type: compiled_type,
36
35
  metadata: metadata,
37
36
  script_json: script_project.script_json,
38
37
  )
@@ -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
- query_name = "app_script_update_or_create"
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 = script_service_request(query_name: query_name, api_key: api_key, variables: variables)
40
- user_errors = resp_hash["data"]["appScriptUpdateOrCreate"]["userErrors"]
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"]["appScriptUpdateOrCreate"]["appScript"]["uuid"] if user_errors.empty?
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
- script_service_request(query_name: query_name, api_key: api_key, variables: variables)["data"]["appScripts"]
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
- def script_service_request(query_name:, variables: nil, **options)
118
- resp = if bypass_partners_proxy
119
- ScriptServiceAPI.query(ctx, query_name, variables: variables, **options)
120
- else
121
- proxy_through_partners(query_name: query_name, variables: variables, **options)
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
- def bypass_partners_proxy
128
- !ENV["BYPASS_PARTNERS_PROXY"].nil?
129
- end
126
+ def self.bypass_partners_proxy
127
+ !ENV["BYPASS_PARTNERS_PROXY"].nil?
128
+ end
130
129
 
131
- def proxy_through_partners(query_name:, variables: nil, **options)
132
- options[:variables] = variables.to_json if variables
133
- resp = PartnersProxyAPI.query(ctx, query_name, **options)
134
- raise_if_graphql_failed(resp)
135
- JSON.parse(resp["data"]["scriptServiceProxy"])
136
- end
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
- def raise_if_graphql_failed(response)
139
- raise Errors::EmptyResponseError if response.nil?
140
-
141
- return unless response.key?("errors")
142
- case error_code(response["errors"])
143
- when "forbidden"
144
- raise Errors::ForbiddenError
145
- when "forbidden_on_shop"
146
- raise Errors::ShopAuthenticationError
147
- when "app_not_installed_on_shop"
148
- raise Errors::AppNotInstalledError
149
- else
150
- raise Errors::GraphqlError, response["errors"]
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
- def error_code(errors)
155
- errors.map do |e|
156
- code = e.dig("extensions", "code")
157
- return code if code
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
@@ -43,7 +43,7 @@ module Theme
43
43
  when "development"
44
44
  "blue"
45
45
  else
46
- "grey"
46
+ "italic"
47
47
  end
48
48
 
49
49
  tags = ["{{#{color}:[#{theme.role}]}}"]
@@ -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")
@@ -1,3 +1,3 @@
1
1
  module ShopifyCli
2
- VERSION = "2.0.2"
2
+ VERSION = "2.2.2"
3
3
  end
data/shopify-cli.gemspec CHANGED
@@ -44,5 +44,5 @@ Gem::Specification.new do |spec|
44
44
  spec.add_development_dependency("minitest", "~> 5.0")
45
45
 
46
46
  spec.add_dependency("listen", "~> 3.5")
47
- spec.add_dependency("theme-check", "~> 1.0")
47
+ spec.add_dependency("theme-check", "~> 1.1")
48
48
  end
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.0.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-07-07 00:00:00.000000000 Z
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.0'
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.0'
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