shopify-cli 2.7.1 → 2.8.0

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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +2 -2
  3. data/.github/workflows/shopify.yml +1 -1
  4. data/.gitignore +1 -0
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +43 -0
  7. data/Codespace.dockerfile +2 -2
  8. data/Gemfile.lock +4 -4
  9. data/Tests.dockerfile +2 -2
  10. data/dev.yml +3 -3
  11. data/ext/javy/hashes/javy-arm-macos-v0.1.0.gz.sha256 +1 -0
  12. data/ext/javy/hashes/javy-x86_64-linux-v0.1.0.gz.sha256 +1 -0
  13. data/ext/javy/hashes/javy-x86_64-macos-v0.1.0.gz.sha256 +1 -0
  14. data/ext/javy/hashes/javy-x86_64-windows-v0.1.0.gz.sha256 +1 -0
  15. data/ext/javy/javy.rb +30 -12
  16. data/lib/graphql/get_extension_registrations.graphql +27 -0
  17. data/lib/project_types/extension/cli.rb +27 -2
  18. data/lib/project_types/extension/commands/build.rb +10 -15
  19. data/lib/project_types/extension/commands/create.rb +3 -6
  20. data/lib/project_types/extension/commands/push.rb +36 -8
  21. data/lib/project_types/extension/extension_project.rb +1 -1
  22. data/lib/project_types/extension/features/argo_serve.rb +6 -5
  23. data/lib/project_types/extension/forms/questions/ask_registration.rb +6 -2
  24. data/lib/project_types/extension/loaders/project.rb +29 -0
  25. data/lib/project_types/extension/loaders/specification_handler.rb +22 -0
  26. data/lib/project_types/extension/messages/messages.rb +4 -2
  27. data/lib/project_types/extension/models/app.rb +1 -1
  28. data/lib/project_types/extension/models/development_server.rb +2 -2
  29. data/lib/project_types/extension/models/specification_handlers/default.rb +4 -0
  30. data/lib/project_types/extension/tasks/convert_server_config.rb +3 -1
  31. data/lib/project_types/extension/tasks/execute_commands/base.rb +13 -0
  32. data/lib/project_types/extension/tasks/execute_commands/build.rb +29 -0
  33. data/lib/project_types/extension/tasks/execute_commands/create.rb +33 -0
  34. data/lib/project_types/extension/tasks/execute_commands/serve.rb +35 -0
  35. data/lib/project_types/extension/tasks/merge_server_config.rb +33 -22
  36. data/lib/project_types/rails/commands/create.rb +2 -4
  37. data/lib/project_types/script/cli.rb +8 -1
  38. data/lib/project_types/script/commands/connect.rb +19 -0
  39. data/lib/project_types/script/commands/create.rb +1 -3
  40. data/lib/project_types/script/commands/javy.rb +0 -2
  41. data/lib/project_types/script/commands/push.rb +2 -1
  42. data/lib/project_types/script/config/extension_points.yml +10 -28
  43. data/lib/project_types/script/forms/ask_app.rb +32 -0
  44. data/lib/project_types/script/forms/ask_org.rb +30 -0
  45. data/lib/project_types/script/forms/ask_script_uuid.rb +22 -0
  46. data/lib/project_types/script/forms/run_against_shopify_org.rb +14 -0
  47. data/lib/project_types/script/graphql/app_script_set.graphql +2 -2
  48. data/lib/project_types/script/layers/application/build_script.rb +0 -1
  49. data/lib/project_types/script/layers/application/connect_app.rb +79 -0
  50. data/lib/project_types/script/layers/application/create_script.rb +17 -17
  51. data/lib/project_types/script/layers/application/push_script.rb +1 -1
  52. data/lib/project_types/script/layers/domain/errors.rb +1 -4
  53. data/lib/project_types/script/layers/domain/push_package.rb +3 -3
  54. data/lib/project_types/script/layers/domain/{script_json.rb → script_config.rb} +2 -2
  55. data/lib/project_types/script/layers/domain/script_project.rb +5 -1
  56. data/lib/project_types/script/layers/infrastructure/errors.rb +28 -6
  57. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +0 -4
  58. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +0 -4
  59. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +2 -2
  60. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +125 -27
  61. data/lib/project_types/script/layers/infrastructure/script_service.rb +11 -11
  62. data/lib/project_types/script/messages/messages.rb +20 -5
  63. data/lib/project_types/script/ui/error_handler.rb +30 -20
  64. data/lib/project_types/theme/commands/pull.rb +3 -0
  65. data/lib/project_types/theme/commands/push.rb +7 -1
  66. data/lib/project_types/theme/commands/serve.rb +1 -1
  67. data/lib/project_types/theme/messages/messages.rb +10 -0
  68. data/lib/project_types/theme/ui/sync_progress_bar.rb +2 -2
  69. data/lib/shopify_cli/command/project_command.rb +20 -7
  70. data/lib/shopify_cli/command.rb +6 -0
  71. data/lib/shopify_cli/commands/app/create/node.rb +1 -3
  72. data/lib/shopify_cli/commands/app/create/rails.rb +1 -3
  73. data/lib/shopify_cli/commands/login.rb +1 -1
  74. data/lib/shopify_cli/commands/switch.rb +1 -1
  75. data/lib/shopify_cli/constants.rb +7 -0
  76. data/lib/shopify_cli/context.rb +11 -1
  77. data/lib/shopify_cli/environment.rb +4 -0
  78. data/lib/shopify_cli/form.rb +2 -0
  79. data/lib/shopify_cli/git.rb +2 -0
  80. data/lib/shopify_cli/identity_auth.rb +18 -0
  81. data/lib/shopify_cli/messages/messages.rb +8 -1
  82. data/lib/shopify_cli/partners_api/app_extensions/job.rb +36 -0
  83. data/lib/shopify_cli/partners_api/app_extensions.rb +46 -0
  84. data/lib/shopify_cli/partners_api/organizations.rb +2 -5
  85. data/lib/shopify_cli/partners_api.rb +2 -8
  86. data/lib/shopify_cli/project.rb +8 -7
  87. data/lib/shopify_cli/resources/env_file.rb +13 -5
  88. data/lib/shopify_cli/services/app/create/rails_service.rb +1 -1
  89. data/lib/shopify_cli/services/app/serve/node_service.rb +1 -1
  90. data/lib/shopify_cli/services/app/serve/rails_service.rb +1 -1
  91. data/lib/shopify_cli/tasks/ensure_authenticated.rb +9 -3
  92. data/lib/shopify_cli/theme/dev_server/cdn_fonts.rb +73 -0
  93. data/lib/shopify_cli/theme/dev_server/hot-reload.js +38 -9
  94. data/lib/shopify_cli/theme/dev_server/proxy/template_param_builder.rb +84 -0
  95. data/lib/shopify_cli/theme/dev_server/proxy.rb +9 -15
  96. data/lib/shopify_cli/theme/dev_server.rb +6 -4
  97. data/lib/shopify_cli/theme/syncer/error_reporter.rb +45 -0
  98. data/lib/shopify_cli/theme/syncer/operation.rb +56 -0
  99. data/lib/shopify_cli/theme/syncer/standard_reporter.rb +32 -0
  100. data/lib/shopify_cli/theme/syncer.rb +40 -39
  101. data/lib/shopify_cli/theme/theme.rb +31 -19
  102. data/lib/shopify_cli/thread_pool/job.rb +27 -0
  103. data/lib/shopify_cli/thread_pool.rb +37 -0
  104. data/lib/shopify_cli/tunnel.rb +9 -10
  105. data/lib/shopify_cli/version.rb +1 -1
  106. data/shopify-cli.gemspec +1 -1
  107. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +3 -1
  108. metadata +31 -8
  109. data/lib/graphql/all_orgs_with_extensions.graphql +0 -37
  110. data/lib/project_types/extension/tasks/run_extension_command.rb +0 -82
  111. data/lib/project_types/script/tasks/ensure_env.rb +0 -106
@@ -6,7 +6,7 @@ module Extension
6
6
  include SmartProperties
7
7
 
8
8
  property! :api_key, accepts: String
9
- property! :secret, accepts: String
9
+ property :secret, accepts: String
10
10
  property :title, accepts: String
11
11
  property :business_name, accepts: String
12
12
  end
@@ -33,8 +33,8 @@ module Extension
33
33
  end
34
34
 
35
35
  def build(server_config)
36
- _, error, status = CLI::Kit::System.capture3(executable, "build", "-", stdin_data: server_config.to_yaml)
37
- return if status.success?
36
+ output, error, status = CLI::Kit::System.capture3(executable, "build", "-", stdin_data: server_config.to_yaml)
37
+ return output if status.success?
38
38
  raise DevelopmentServerError, error
39
39
  end
40
40
 
@@ -103,6 +103,10 @@ module Extension
103
103
  raise NotImplementedError
104
104
  end
105
105
 
106
+ def server_config_path(base_dir = Dir.pwd)
107
+ File.join(base_dir, server_config_file)
108
+ end
109
+
106
110
  def server_config_file
107
111
  "shopifile.yml"
108
112
  end
@@ -9,11 +9,12 @@ module Extension
9
9
  property! :api_key, accepts: String
10
10
  property! :context, accepts: ShopifyCLI::Context
11
11
  property! :hash, accepts: Hash
12
+ property :port, accepts: Integer, default: ShopifyCLI::Constants::Extension::DEFAULT_PORT
12
13
  property! :registration_uuid, accepts: String
13
14
  property :resource_url, accepts: String
14
15
  property! :store, accepts: String
15
16
  property! :title, accepts: String
16
- property :tunnel_url, accepts: String
17
+ property :tunnel_url, accepts: String
17
18
  property! :type, accepts: String
18
19
 
19
20
  def self.call(*args)
@@ -46,6 +47,7 @@ module Extension
46
47
  end
47
48
  server_config = Models::ServerConfig::Root.new(
48
49
  extensions: [extension],
50
+ port: port,
49
51
  public_url: tunnel_url,
50
52
  store: store
51
53
  )
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Tasks
6
+ module ExecuteCommands
7
+ class Base
8
+ include SmartProperties
9
+ property! :type, accepts: Models::DevelopmentServerRequirements::SUPPORTED_EXTENSION_TYPES
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Tasks
6
+ module ExecuteCommands
7
+ class Build < Base
8
+ property! :context, accepts: ShopifyCLI::Context
9
+ property! :config_file_path, accepts: String
10
+
11
+ def call
12
+ ShopifyCLI::Result
13
+ .call(&method(:merge_server_config))
14
+ .then { |server_config| Models::DevelopmentServer.new.build(server_config) }
15
+ end
16
+
17
+ private
18
+
19
+ def merge_server_config
20
+ Tasks::MergeServerConfig.call(
21
+ context: context,
22
+ file_path: config_file_path,
23
+ type: type
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Tasks
6
+ module ExecuteCommands
7
+ class Create < Base
8
+ property! :template, accepts: Models::ServerConfig::Development::VALID_TEMPLATES
9
+ property! :root_dir, accepts: String
10
+
11
+ def call
12
+ ShopifyCLI::Result.success(generate_config)
13
+ .then { |server_config| Models::DevelopmentServer.new.create(server_config) }
14
+ .unwrap do |error|
15
+ raise error unless error.nil?
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def generate_config
22
+ extension = Models::ServerConfig::Extension.build(
23
+ template: template,
24
+ type: type,
25
+ root_dir: root_dir,
26
+ )
27
+
28
+ Models::ServerConfig::Root.new(extensions: [extension])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Tasks
6
+ module ExecuteCommands
7
+ class Serve < Base
8
+ property! :context, accepts: ShopifyCLI::Context
9
+ property! :config_file_path, accepts: String
10
+ property :port, accepts: Integer, default: ShopifyCLI::Constants::Extension::DEFAULT_PORT
11
+ property :resource_url, accepts: String
12
+ property! :tunnel_url, accepts: String
13
+
14
+ def call
15
+ ShopifyCLI::Result
16
+ .call(&method(:merge_server_config))
17
+ .then { |server_config| Models::DevelopmentServer.new.serve(context, server_config) }
18
+ end
19
+
20
+ private
21
+
22
+ def merge_server_config
23
+ Tasks::MergeServerConfig.call(
24
+ context: context,
25
+ file_path: config_file_path,
26
+ port: port,
27
+ resource_url: resource_url,
28
+ tunnel_url: tunnel_url,
29
+ type: type
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -4,28 +4,39 @@ require "yaml"
4
4
 
5
5
  module Extension
6
6
  module Tasks
7
- class MergeServerConfig < ShopifyCLI::Task
8
- class << self
9
- def call(context:, file_name:, resource_url:, tunnel_url:, type:)
10
- config = YAML.load_file(file_name)
11
- project = ExtensionProject.current
12
- Tasks::ConvertServerConfig.call(
13
- api_key: project.env.api_key,
14
- context: context,
15
- hash: config,
16
- registration_uuid: project.registration_uuid,
17
- resource_url: resource_url || project.resource_url,
18
- store: project.env.shop || "",
19
- title: project.title,
20
- tunnel_url: tunnel_url,
21
- type: type
22
- )
23
- rescue Psych::SyntaxError => e
24
- raise(
25
- ShopifyCLI::Abort,
26
- ShopifyCLI::Context.message("core.yaml.error.invalid", file_name, e.message)
27
- )
28
- end
7
+ class MergeServerConfig
8
+ include SmartProperties
9
+
10
+ property! :context, accepts: ShopifyCLI::Context
11
+ property! :file_path, accepts: ->(path) { Pathname(path).yield_self { |pn| pn.absolute? && pn.file? } }
12
+ property :port, accepts: Integer, default: ShopifyCLI::Constants::Extension::DEFAULT_PORT
13
+ property :resource_url, accepts: String
14
+ property :tunnel_url, accepts: String
15
+ property! :type, accepts: Models::DevelopmentServerRequirements::SUPPORTED_EXTENSION_TYPES
16
+
17
+ def self.call(*args)
18
+ new(*args).call
19
+ end
20
+
21
+ def call
22
+ config = YAML.load_file(file_path)
23
+ project = ExtensionProject.current
24
+ Tasks::ConvertServerConfig.call(
25
+ api_key: project.env.api_key,
26
+ context: context,
27
+ hash: config,
28
+ registration_uuid: project.registration_uuid,
29
+ resource_url: resource_url || project.resource_url,
30
+ store: project.env.shop || "",
31
+ title: project.title,
32
+ tunnel_url: tunnel_url,
33
+ type: type
34
+ )
35
+ rescue Psych::SyntaxError => e
36
+ raise(
37
+ ShopifyCLI::Abort,
38
+ ShopifyCLI::Context.message("core.yaml.error.invalid", file_name, e.message)
39
+ )
29
40
  end
30
41
  end
31
42
  end
@@ -2,9 +2,7 @@
2
2
  module Rails
3
3
  class Command
4
4
  class Create < ShopifyCLI::Command::AppSubCommand
5
- unless ShopifyCLI::Environment.acceptance_test?
6
- prerequisite_task :ensure_authenticated
7
- end
5
+ prerequisite_task :ensure_authenticated
8
6
 
9
7
  USER_AGENT_CODE = <<~USERAGENT
10
8
  module ShopifyAPI
@@ -158,10 +156,10 @@ module Rails
158
156
 
159
157
  CLI::UI::Frame.open(@ctx.message("rails.create.generating_app", name)) do
160
158
  new_command = %w(rails new)
159
+ new_command << name
161
160
  new_command += DEFAULT_RAILS_FLAGS
162
161
  new_command << "--database=#{db}"
163
162
  new_command += options.flags[:rails_opts].split unless options.flags[:rails_opts].nil?
164
- new_command << name
165
163
 
166
164
  syscall(new_command)
167
165
  end
@@ -13,13 +13,19 @@ module Script
13
13
  hidden_feature(feature_set: :script_project)
14
14
  subcommand :Create, "create", Project.project_filepath("commands/create")
15
15
  subcommand :Push, "push", Project.project_filepath("commands/push")
16
+ subcommand :Connect, "connect", Project.project_filepath("commands/connect")
16
17
  subcommand :Javy, "javy", Project.project_filepath("commands/javy")
17
18
  end
18
19
  ShopifyCLI::Commands.register("Script::Command", "script")
19
20
 
20
21
  # define/autoload project specific Forms
21
22
  module Forms
23
+ autoload :AskOrg, Project.project_filepath("forms/ask_org")
24
+ autoload :AskApp, Project.project_filepath("forms/ask_app")
25
+ autoload :AskScriptUuid, Project.project_filepath("forms/ask_script_uuid")
26
+ autoload :RunAgainstShopifyOrg, Project.project_filepath("forms/run_against_shopify_org")
22
27
  autoload :Create, Project.project_filepath("forms/create")
28
+ autoload :Connect, Project.project_filepath("forms/connect")
23
29
  autoload :ScriptForm, Project.project_filepath("forms/script_form")
24
30
  end
25
31
 
@@ -30,6 +36,7 @@ module Script
30
36
  module Layers
31
37
  module Application
32
38
  autoload :BuildScript, Project.project_filepath("layers/application/build_script")
39
+ autoload :ConnectApp, Project.project_filepath("layers/application/connect_app")
33
40
  autoload :CreateScript, Project.project_filepath("layers/application/create_script")
34
41
  autoload :PushScript, Project.project_filepath("layers/application/push_script")
35
42
  autoload :ExtensionPoints, Project.project_filepath("layers/application/extension_points")
@@ -41,7 +48,7 @@ module Script
41
48
  autoload :PushPackage, Project.project_filepath("layers/domain/push_package")
42
49
  autoload :Metadata, Project.project_filepath("layers/domain/metadata")
43
50
  autoload :ExtensionPoint, Project.project_filepath("layers/domain/extension_point")
44
- autoload :ScriptJson, Project.project_filepath("layers/domain/script_json")
51
+ autoload :ScriptConfig, Project.project_filepath("layers/domain/script_config")
45
52
  autoload :ScriptProject, Project.project_filepath("layers/domain/script_project")
46
53
  end
47
54
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ module Script
3
+ class Command
4
+ class Connect < ShopifyCLI::Command::SubCommand
5
+ prerequisite_task :ensure_authenticated
6
+ prerequisite_task ensure_project_type: :script
7
+
8
+ def call(_args, _)
9
+ Layers::Application::ConnectApp.call(ctx: @ctx, force: true, strict: true)
10
+ rescue StandardError => e
11
+ UI::ErrorHandler.pretty_print_and_raise(e, failed_op: @ctx.message("script.connect.error.operation_failed"))
12
+ end
13
+
14
+ def self.help
15
+ ShopifyCLI::Context.new.message("connect.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,9 +3,7 @@
3
3
  module Script
4
4
  class Command
5
5
  class Create < ShopifyCLI::Command::SubCommand
6
- unless ShopifyCLI::Environment.acceptance_test?
7
- prerequisite_task :ensure_authenticated
8
- end
6
+ prerequisite_task :ensure_authenticated
9
7
 
10
8
  options do |parser, flags|
11
9
  parser.on("--name=NAME") { |name| flags[:name] = name }
@@ -7,8 +7,6 @@ module Script
7
7
  class Javy < ShopifyCLI::Command::SubCommand
8
8
  hidden_feature
9
9
 
10
- prerequisite_task ensure_project_type: :script
11
-
12
10
  options do |parser, flags|
13
11
  parser.on("--in=IN") { |in_file| flags[:in_file] = in_file }
14
12
  parser.on("--out=OUT") { |out_file| flags[:out_file] = out_file }
@@ -10,7 +10,8 @@ module Script
10
10
  end
11
11
 
12
12
  def call(_args, _name)
13
- fresh_env = Tasks::EnsureEnv.call(@ctx)
13
+ fresh_env = Layers::Application::ConnectApp.call(ctx: @ctx)
14
+
14
15
  force = options.flags.key?(:force) || !!fresh_env
15
16
 
16
17
  api_key = Layers::Infrastructure::ScriptProjectRepository.new(ctx: @ctx).get.api_key
@@ -1,29 +1,3 @@
1
- discount:
2
- deprecated: true
3
- libraries:
4
- assemblyscript:
5
- package: "@shopify/extension-point-as-discount"
6
- unit_limit_per_order:
7
- beta: true
8
- libraries:
9
- assemblyscript:
10
- package: "@shopify/extension-point-as-unit-limit-per-order"
11
- payment_filter:
12
- deprecated: true
13
- libraries:
14
- assemblyscript:
15
- package: "@shopify/extension-point-as-payment-filter"
16
- shipping_filter:
17
- deprecated: true
18
- libraries:
19
- assemblyscript:
20
- package: "@shopify/extension-point-as-shipping-filter"
21
- tax_filter:
22
- beta: true
23
- libraries:
24
- assemblyscript:
25
- repo: "https://github.com/Shopify/extension-points.git"
26
- package: "@shopify/extension-point-as-tax-filter"
27
1
  payment_methods:
28
2
  domain: 'checkout'
29
3
  libraries:
@@ -44,11 +18,19 @@ shipping_methods:
44
18
  beta: true
45
19
  package: "@shopify/scripts-checkout-apis"
46
20
  repo: "https://github.com/Shopify/scripts-apis-examples"
47
- discount_types:
21
+ merchandise_discount_types:
22
+ beta: true
23
+ domain: 'discounts'
24
+ libraries:
25
+ typescript:
26
+ beta: true
27
+ package: "@shopify/scripts-discounts-apis"
28
+ repo: "https://github.com/Shopify/scripts-apis-examples"
29
+ delivery_discount_types:
48
30
  beta: true
49
31
  domain: 'discounts'
50
32
  libraries:
51
33
  typescript:
52
34
  beta: true
53
- package: "@shopify/scripts-discount-apis"
35
+ package: "@shopify/scripts-discounts-apis"
54
36
  repo: "https://github.com/Shopify/scripts-apis-examples"
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Forms
5
+ class AskApp < ShopifyCLI::Form
6
+ attr_reader :app
7
+
8
+ def ask
9
+ apps = @xargs.fetch(:apps)
10
+
11
+ unless @xargs[:acting_as_shopify_organization]
12
+ apps = apps.select { |app| app["appType"] == "custom" }
13
+ end
14
+
15
+ raise Errors::NoExistingAppsError if apps.empty?
16
+
17
+ @app =
18
+ if apps.count > 1
19
+ CLI::UI::Prompt.ask(ctx.message("script.application.ensure_env.app_select")) do |handler|
20
+ apps.each do |app|
21
+ handler.option(app["title"]) { app }
22
+ end
23
+ end
24
+ else
25
+ apps.first.tap do |app|
26
+ ctx.puts(ctx.message("script.application.ensure_env.app", app["title"]))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Forms
5
+ class AskOrg < ShopifyCLI::Form
6
+ attr_reader :org
7
+
8
+ BUSINESS_NAME = "businessName"
9
+ ID = "id"
10
+
11
+ def ask
12
+ orgs = @xargs
13
+ @org =
14
+ if orgs.count == 1
15
+ orgs.first.tap do |org|
16
+ ctx.puts(ctx.message("script.application.ensure_env.organization", org[BUSINESS_NAME], org[ID]))
17
+ end
18
+ elsif orgs.count > 0
19
+ CLI::UI::Prompt.ask(ctx.message("script.application.ensure_env.organization_select")) do |handler|
20
+ orgs.each do |org|
21
+ handler.option("#{org[BUSINESS_NAME]} (#{org[ID]})") { org }
22
+ end
23
+ end
24
+ else
25
+ raise Errors::NoExistingOrganizationsError
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Forms
5
+ class AskScriptUuid < ShopifyCLI::Form
6
+ attr_reader :uuid
7
+ def ask
8
+ scripts = @xargs
9
+
10
+ return if scripts.empty? ||
11
+ !CLI::UI::Prompt.confirm(ctx.message("script.application.ensure_env.ask_connect_to_existing_script"))
12
+
13
+ @uuid =
14
+ CLI::UI::Prompt.ask(ctx.message("script.application.ensure_env.ask_which_script_to_connect_to")) do |handler|
15
+ scripts.each do |script|
16
+ handler.option("#{script["title"]} (#{script["uuid"]})") { script["uuid"] }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Forms
5
+ class RunAgainstShopifyOrg < ShopifyCLI::Form
6
+ attr_reader :response
7
+ def ask
8
+ @ctx.puts(@ctx.message("core.tasks.select_org_and_shop.identified_as_shopify"))
9
+ message = @ctx.message("core.tasks.select_org_and_shop.first_party")
10
+ @response = CLI::UI::Prompt.confirm(message, default: false)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -6,7 +6,7 @@ mutation AppScriptSet(
6
6
  $force: Boolean,
7
7
  $schemaMajorVersion: String,
8
8
  $schemaMinorVersion: String,
9
- $scriptJsonVersion: String!,
9
+ $scriptConfigVersion: String!,
10
10
  $configurationUi: Boolean!,
11
11
  $configurationDefinition: String!,
12
12
  $moduleUploadUrl: String!,
@@ -20,7 +20,7 @@ mutation AppScriptSet(
20
20
  force: $force
21
21
  schemaMajorVersion: $schemaMajorVersion
22
22
  schemaMinorVersion: $schemaMinorVersion,
23
- scriptJsonVersion: $scriptJsonVersion,
23
+ scriptConfigVersion: $scriptConfigVersion,
24
24
  configurationUi: $configurationUi,
25
25
  configurationDefinition: $configurationDefinition,
26
26
  moduleUploadUrl: $moduleUploadUrl,
@@ -23,7 +23,6 @@ module Script
23
23
  ctx.puts("\n{{red:#{e.message}}}")
24
24
  end
25
25
  errors = [
26
- Infrastructure::Errors::InvalidBuildScriptError,
27
26
  Infrastructure::Errors::BuildScriptNotFoundError,
28
27
  Infrastructure::Errors::WebAssemblyBinaryNotFoundError,
29
28
  ]
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shopify_cli"
4
+
5
+ module Script
6
+ module Layers
7
+ module Application
8
+ class ConnectApp
9
+ class << self
10
+ def call(ctx:, force: false, strict: false)
11
+ script_project_repo = Layers::Infrastructure::ScriptProjectRepository.new(ctx: ctx)
12
+ script_project = script_project_repo.get
13
+
14
+ return false if script_project.env_valid? && !force
15
+
16
+ if ShopifyCLI::Shopifolk.check && Forms::RunAgainstShopifyOrg.ask(ctx, nil, nil).response
17
+ ShopifyCLI::Shopifolk.act_as_shopify_organization
18
+ end
19
+
20
+ org =
21
+ if partner_proxy_bypass
22
+ stubbed_org
23
+ else
24
+ orgs = ShopifyCLI::PartnersAPI::Organizations.fetch_with_app(ctx)
25
+ Forms::AskOrg.ask(ctx, orgs, nil).org
26
+ end
27
+
28
+ app = Forms::AskApp.ask(
29
+ ctx,
30
+ {
31
+ apps: org["apps"],
32
+ acting_as_shopify_organization: ShopifyCLI::Shopifolk.acting_as_shopify_organization?,
33
+ },
34
+ nil
35
+ ).app
36
+
37
+ script_service = Layers::Infrastructure::ServiceLocator.script_service(ctx: ctx, api_key: app["apiKey"])
38
+ extension_point_type = script_project.extension_point_type
39
+ scripts = script_service.get_app_scripts(extension_point_type: extension_point_type)
40
+
41
+ uuid = Forms::AskScriptUuid.ask(ctx, scripts, nil)&.uuid
42
+
43
+ if strict && uuid.nil?
44
+ ctx.abort(ctx.message("script.connect.missing_script"))
45
+ end
46
+
47
+ script_project_repo.create_env(
48
+ api_key: app["apiKey"],
49
+ secret: app["apiSecretKeys"].first["secret"],
50
+ uuid: uuid
51
+ )
52
+ ctx.done(ctx.message("script.connect.connected", app["title"]))
53
+
54
+ true
55
+ end
56
+
57
+ private
58
+
59
+ def partner_proxy_bypass
60
+ !ENV["BYPASS_PARTNERS_PROXY"].nil?
61
+ end
62
+
63
+ def stubbed_org
64
+ {
65
+ "apps" => [
66
+ {
67
+ "appType" => "custom",
68
+ "apiKey" => "stubbed-api-key",
69
+ "apiSecretKeys" => [{ "secret" => "stubbed-api-secret" }],
70
+ "title" => "Fake App (Not connected to Partners)",
71
+ },
72
+ ],
73
+ }
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -8,11 +8,14 @@ module Script
8
8
  class CreateScript
9
9
  class << self
10
10
  def call(ctx:, language:, sparse_checkout_branch:, script_name:, extension_point_type:)
11
- raise Infrastructure::Errors::ScriptProjectAlreadyExistsError, script_name if ctx.dir_exist?(script_name)
11
+ script_project_repo = Infrastructure::ScriptProjectRepository.new(
12
+ ctx: ctx,
13
+ directory: script_name,
14
+ initial_directory: ctx.root
15
+ )
12
16
 
13
- in_new_directory_context(ctx, script_name) do
17
+ in_new_directory_context(script_project_repo) do
14
18
  extension_point = ExtensionPoints.get(type: extension_point_type)
15
- script_project_repo = Infrastructure::ScriptProjectRepository.new(ctx: ctx)
16
19
  project = script_project_repo.create(
17
20
  script_name: script_name,
18
21
  extension_point_type: extension_point_type,
@@ -36,7 +39,7 @@ module Script
36
39
  )
37
40
 
38
41
  install_dependencies(ctx, language, script_name, project_creator)
39
- script_project_repo.update_or_create_script_json(title: script_name)
42
+ script_project_repo.update_script_config(title: script_name)
40
43
  project
41
44
  end
42
45
  end
@@ -62,19 +65,16 @@ module Script
62
65
  ProjectDependencies.install(ctx: ctx, task_runner: task_runner)
63
66
  end
64
67
 
65
- def in_new_directory_context(ctx, directory)
66
- initial_directory = ctx.root
67
- begin
68
- ctx.mkdir_p(directory)
69
- ctx.chdir(directory)
70
- yield
71
- rescue
72
- ctx.chdir(initial_directory)
73
- ctx.rm_r(directory)
74
- raise
75
- ensure
76
- ctx.chdir(initial_directory)
77
- end
68
+ def in_new_directory_context(script_project_repo)
69
+ script_project_repo.create_project_directory
70
+ yield
71
+ rescue Infrastructure::Errors::ScriptProjectAlreadyExistsError
72
+ raise
73
+ rescue
74
+ script_project_repo.delete_project_directory
75
+ raise
76
+ ensure
77
+ script_project_repo.change_to_initial_directory
78
78
  end
79
79
  end
80
80
  end