shopify-cli 2.7.1 → 2.7.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -1
  3. data/Gemfile.lock +1 -1
  4. data/lib/project_types/extension/commands/build.rb +3 -8
  5. data/lib/project_types/extension/commands/create.rb +1 -3
  6. data/lib/project_types/extension/messages/messages.rb +0 -2
  7. data/lib/project_types/extension/models/development_server.rb +2 -2
  8. data/lib/project_types/rails/commands/create.rb +1 -3
  9. data/lib/project_types/script/cli.rb +5 -0
  10. data/lib/project_types/script/commands/create.rb +1 -3
  11. data/lib/project_types/script/commands/javy.rb +0 -2
  12. data/lib/project_types/script/commands/push.rb +2 -1
  13. data/lib/project_types/script/config/extension_points.yml +0 -26
  14. data/lib/project_types/script/forms/ask_app.rb +32 -0
  15. data/lib/project_types/script/forms/ask_org.rb +30 -0
  16. data/lib/project_types/script/forms/ask_script_uuid.rb +22 -0
  17. data/lib/project_types/script/forms/run_against_shopify_org.rb +14 -0
  18. data/lib/project_types/script/layers/application/build_script.rb +0 -1
  19. data/lib/project_types/script/layers/application/connect_app.rb +73 -0
  20. data/lib/project_types/script/layers/domain/script_project.rb +4 -0
  21. data/lib/project_types/script/layers/infrastructure/errors.rb +0 -1
  22. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +0 -4
  23. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +0 -4
  24. data/lib/project_types/script/messages/messages.rb +0 -2
  25. data/lib/project_types/script/ui/error_handler.rb +0 -5
  26. data/lib/project_types/theme/commands/pull.rb +3 -0
  27. data/lib/project_types/theme/commands/push.rb +6 -1
  28. data/lib/project_types/theme/commands/serve.rb +1 -1
  29. data/lib/project_types/theme/messages/messages.rb +9 -0
  30. data/lib/project_types/theme/ui/sync_progress_bar.rb +2 -2
  31. data/lib/shopify_cli/command/project_command.rb +20 -7
  32. data/lib/shopify_cli/commands/app/create/node.rb +1 -3
  33. data/lib/shopify_cli/commands/app/create/rails.rb +1 -3
  34. data/lib/shopify_cli/constants.rb +3 -0
  35. data/lib/shopify_cli/context.rb +9 -0
  36. data/lib/shopify_cli/environment.rb +4 -0
  37. data/lib/shopify_cli/identity_auth.rb +18 -0
  38. data/lib/shopify_cli/messages/messages.rb +1 -0
  39. data/lib/shopify_cli/partners_api.rb +1 -8
  40. data/lib/shopify_cli/services/app/serve/node_service.rb +1 -1
  41. data/lib/shopify_cli/services/app/serve/rails_service.rb +1 -1
  42. data/lib/shopify_cli/tasks/ensure_authenticated.rb +9 -3
  43. data/lib/shopify_cli/theme/dev_server.rb +4 -4
  44. data/lib/shopify_cli/theme/syncer/error_reporter.rb +45 -0
  45. data/lib/shopify_cli/theme/syncer/operation.rb +56 -0
  46. data/lib/shopify_cli/theme/syncer/standard_reporter.rb +32 -0
  47. data/lib/shopify_cli/theme/syncer.rb +40 -39
  48. data/lib/shopify_cli/theme/theme.rb +31 -19
  49. data/lib/shopify_cli/tunnel.rb +8 -10
  50. data/lib/shopify_cli/version.rb +1 -1
  51. metadata +10 -3
  52. data/lib/project_types/script/tasks/ensure_env.rb +0 -106
@@ -86,6 +86,10 @@ module ShopifyCLI
86
86
  )
87
87
  end
88
88
 
89
+ def self.auth_token(env_variables: ENV)
90
+ env_variables[Constants::EnvironmentVariables::AUTH_TOKEN]
91
+ end
92
+
89
93
  def self.env_variable_truthy?(variable_name, env_variables: ENV)
90
94
  TRUTHY_ENV_VARIABLE_VALUES.include?(env_variables[variable_name.to_s])
91
95
  end
@@ -68,6 +68,24 @@ module ShopifyCLI
68
68
  request_exchange_tokens
69
69
  end
70
70
 
71
+ def self.fetch_or_auth_partners_token(ctx:)
72
+ env_var_auth_token = Environment.auth_token
73
+ return env_var_auth_token if env_var_auth_token
74
+
75
+ ShopifyCLI::DB.get(:partners_exchange_token) do
76
+ IdentityAuth.new(ctx: ctx).authenticate
77
+ ShopifyCLI::DB.get(:partners_exchange_token)
78
+ end
79
+ end
80
+
81
+ def self.environment_auth_token?
82
+ !!Environment.auth_token
83
+ end
84
+
85
+ def self.authenticated?
86
+ environment_auth_token? || IDENTITY_ACCESS_TOKENS.all? { |key| ShopifyCLI::DB.exists?(key) }
87
+ end
88
+
71
89
  def reauthenticate
72
90
  return if refresh_exchange_tokens || refresh_access_tokens
73
91
  ctx.abort(ctx.message("core.identity_auth.error.reauthenticate", ShopifyCLI::TOOL_NAME))
@@ -457,6 +457,7 @@ module ShopifyCLI
457
457
  not_authenticated: "Failed to authenticate",
458
458
  },
459
459
  login_prompt: "Please ensure you've logged in with {{command:%s login}} and try again",
460
+ token_authentication: "%s environment variable. We'll authenticate using its value as a token.",
460
461
  },
461
462
 
462
463
  options: {
@@ -61,18 +61,11 @@ module ShopifyCLI
61
61
  def api_client(ctx)
62
62
  new(
63
63
  ctx: ctx,
64
- token: access_token(ctx),
64
+ token: IdentityAuth.fetch_or_auth_partners_token(ctx: ctx),
65
65
  url: "https://#{Environment.partners_domain}/api/cli/graphql",
66
66
  )
67
67
  end
68
68
 
69
- def access_token(ctx)
70
- ShopifyCLI::DB.get(:partners_exchange_token) do
71
- IdentityAuth.new(ctx: ctx).authenticate
72
- ShopifyCLI::DB.get(:partners_exchange_token)
73
- end
74
- end
75
-
76
69
  def auth_failure_info(ctx, error)
77
70
  if error.response
78
71
  headers = %w(www-authenticate x-request-id)
@@ -14,7 +14,7 @@ module ShopifyCLI
14
14
 
15
15
  def call
16
16
  project = ShopifyCLI::Project.current
17
- url = host || ShopifyCLI::Tunnel.start(context)
17
+ url = host || ShopifyCLI::Tunnel.start(context, port: port)
18
18
  raise ShopifyCLI::Abort,
19
19
  context.message("core.app.serve.error.host_must_be_https") if url.match(/^https/i).nil?
20
20
  project.env.update(context, :host, url)
@@ -14,7 +14,7 @@ module ShopifyCLI
14
14
 
15
15
  def call
16
16
  project = ShopifyCLI::Project.current
17
- url = host || ShopifyCLI::Tunnel.start(context)
17
+ url = host || ShopifyCLI::Tunnel.start(context, port: port)
18
18
  raise ShopifyCLI::Abort,
19
19
  context.message("core.app.serve.error.host_must_be_https") if url.match(/^https/i).nil?
20
20
  project.env.update(context, :host, url)
@@ -4,9 +4,15 @@ module ShopifyCLI
4
4
  module Tasks
5
5
  class EnsureAuthenticated < ShopifyCLI::Task
6
6
  def call(ctx)
7
- ctx.abort(
8
- ctx.message("core.identity_auth.login_prompt", ShopifyCLI::TOOL_NAME)
9
- ) unless ShopifyCLI::IdentityAuth::IDENTITY_ACCESS_TOKENS.all? { |key| ShopifyCLI::DB.exists?(key) }
7
+ return if ShopifyCLI::Environment.acceptance_test?
8
+ unless ShopifyCLI::IdentityAuth.authenticated?
9
+ raise ShopifyCLI::Abort,
10
+ ctx.message("core.identity_auth.login_prompt", ShopifyCLI::TOOL_NAME)
11
+ end
12
+ if ShopifyCLI::IdentityAuth.environment_auth_token?
13
+ ctx.puts(ctx.message("core.identity_auth.token_authentication",
14
+ ShopifyCLI::Constants::EnvironmentVariables::AUTH_TOKEN))
15
+ end
10
16
  end
11
17
  end
12
18
  end
@@ -24,7 +24,7 @@ module ShopifyCLI
24
24
  class << self
25
25
  attr_accessor :ctx
26
26
 
27
- def start(ctx, root, http_bind: "127.0.0.1", port: 9292, poll: false)
27
+ def start(ctx, root, host: "127.0.0.1", port: 9292, poll: false)
28
28
  @ctx = ctx
29
29
  theme = DevelopmentTheme.new(ctx, root: root)
30
30
  ignore_filter = IgnoreFilter.from_path(root)
@@ -36,7 +36,7 @@ module ShopifyCLI
36
36
  @app = LocalAssets.new(ctx, @app, theme: theme)
37
37
  @app = HotReload.new(ctx, @app, theme: theme, watcher: watcher, ignore_filter: ignore_filter)
38
38
  stopped = false
39
- address = "http://#{http_bind}:#{port}"
39
+ address = "http://#{host}:#{port}"
40
40
 
41
41
  theme.ensure_exists!
42
42
 
@@ -70,7 +70,7 @@ module ShopifyCLI
70
70
  watcher.start
71
71
  WebServer.run(
72
72
  @app,
73
- BindAddress: http_bind,
73
+ BindAddress: host,
74
74
  Port: port,
75
75
  Logger: logger,
76
76
  AccessLog: [],
@@ -83,7 +83,7 @@ module ShopifyCLI
83
83
  rescue Errno::EADDRINUSE
84
84
  abort_address_already_in_use(address)
85
85
  rescue Errno::EADDRNOTAVAIL
86
- raise AddressBindingError, "Error binding to the address #{http_bind}."
86
+ raise AddressBindingError, "Error binding to the address #{host}."
87
87
  end
88
88
 
89
89
  def stop
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyCLI
4
+ module Theme
5
+ class Syncer
6
+ ##
7
+ # ShopifyCLI::Theme::Syncer::ErrorReporter allows delaying log of errors,
8
+ # mainly to not break the progress bar.
9
+ #
10
+ class ErrorReporter
11
+ attr_reader :ctx, :delayed_errors
12
+
13
+ def initialize(ctx)
14
+ @ctx = ctx
15
+ @has_any_error = false
16
+ @delay_errors = false
17
+ @delayed_errors = []
18
+ end
19
+
20
+ def disable!
21
+ @delay_errors = true
22
+ end
23
+
24
+ def enable!
25
+ @delay_errors = false
26
+ @delayed_errors.each { |error| report(error) }
27
+ @delayed_errors.clear
28
+ end
29
+
30
+ def report(error_message)
31
+ if @delay_errors
32
+ @delayed_errors << error_message
33
+ else
34
+ @has_any_error = true
35
+ @ctx.error(error_message)
36
+ end
37
+ end
38
+
39
+ def has_any_error?
40
+ @has_any_error
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyCLI
4
+ module Theme
5
+ class Syncer
6
+ class Operation
7
+ attr_accessor :method, :file
8
+
9
+ COLOR_BY_STATUS = {
10
+ error: :red,
11
+ synced: :green,
12
+ fixed: :cyan,
13
+ }
14
+
15
+ def initialize(ctx, method, file)
16
+ @ctx = ctx
17
+ @method = method
18
+ @file = file
19
+ end
20
+
21
+ def to_s
22
+ "#{method} #{file_path}"
23
+ end
24
+
25
+ def as_error_message
26
+ as_message_with(status: :error)
27
+ end
28
+
29
+ def as_synced_message
30
+ as_message_with(status: :synced)
31
+ end
32
+
33
+ def as_fix_message
34
+ as_message_with(status: :fixed)
35
+ end
36
+
37
+ def file_path
38
+ file&.relative_path.to_s
39
+ end
40
+
41
+ private
42
+
43
+ def as_message_with(status:)
44
+ status_color = COLOR_BY_STATUS[status]
45
+ status_text = @ctx.message("theme.serve.operation.status.#{status}").ljust(6)
46
+
47
+ "#{timestamp} {{#{status_color}:#{status_text}}} {{>}} {{blue:#{self}}}"
48
+ end
49
+
50
+ def timestamp
51
+ Time.now.strftime("%T")
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyCLI
4
+ module Theme
5
+ class Syncer
6
+ ##
7
+ # ShopifyCLI::Theme::Syncer::StdReporter allows disabling/enabling
8
+ # messages reported in the standard output (ShopifyCLI::Context#puts).
9
+ #
10
+ class StandardReporter
11
+ attr_reader :ctx
12
+
13
+ def initialize(ctx)
14
+ @enabled = true
15
+ @ctx = ctx
16
+ end
17
+
18
+ def disable!
19
+ @enabled = false
20
+ end
21
+
22
+ def enable!
23
+ @enabled = true
24
+ end
25
+
26
+ def report(message)
27
+ ctx.puts(message) if @enabled
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -2,24 +2,31 @@
2
2
  require "thread"
3
3
  require "json"
4
4
  require "base64"
5
+ require "forwardable"
6
+
7
+ require_relative "syncer/error_reporter"
8
+ require_relative "syncer/standard_reporter"
9
+ require_relative "syncer/operation"
5
10
 
6
11
  module ShopifyCLI
7
12
  module Theme
8
13
  class Syncer
9
- class Operation < Struct.new(:method, :file)
10
- def to_s
11
- "#{method} #{file&.relative_path}"
12
- end
13
- end
14
+ extend Forwardable
15
+
14
16
  API_VERSION = "unstable"
15
17
 
16
18
  attr_reader :checksums
17
19
  attr_accessor :ignore_filter
18
20
 
21
+ def_delegators :@error_reporter, :has_any_error?
22
+
19
23
  def initialize(ctx, theme:, ignore_filter: nil)
20
24
  @ctx = ctx
21
25
  @theme = theme
22
26
  @ignore_filter = ignore_filter
27
+ @error_reporter = ErrorReporter.new(ctx)
28
+ @standard_reporter = StandardReporter.new(ctx)
29
+ @reporters = [@error_reporter, @standard_reporter]
23
30
 
24
31
  # Queue of `Operation`s waiting to be picked up from a thread for processing.
25
32
  @queue = Queue.new
@@ -30,12 +37,19 @@ module ShopifyCLI
30
37
  # Mutex used to pause all threads when backing-off when hitting API rate limits
31
38
  @backoff_mutex = Mutex.new
32
39
 
33
- # Allows delaying log of errors, mainly to not break the progress bar.
34
- @delay_errors = false
35
- @delayed_errors = []
36
-
37
40
  # Latest theme assets checksums. Updated on each upload.
38
41
  @checksums = {}
42
+
43
+ # Checksums of assets with errors.
44
+ @error_checksums = []
45
+ end
46
+
47
+ def lock_io!
48
+ @reporters.each { |reporter| reporter.disable! }
49
+ end
50
+
51
+ def unlock_io!
52
+ @reporters.each { |reporter| reporter.enable! }
39
53
  end
40
54
 
41
55
  def enqueue_updates(files)
@@ -103,25 +117,14 @@ module ShopifyCLI
103
117
  break if operation.nil? # shutdown was called
104
118
  perform(operation)
105
119
  rescue Exception => e
106
- report_error(
107
- "{{red:ERROR}} {{blue:#{operation}}}: #{e}" +
108
- (@ctx.debug? ? "\n\t#{e.backtrace.join("\n\t")}" : "")
109
- )
120
+ error_suffix = ": #{e}"
121
+ error_suffix += + "\n\t#{e.backtrace.join("\n\t")}" if @ctx.debug?
122
+ report_error(operation, error_suffix)
110
123
  end
111
124
  end
112
125
  end
113
126
  end
114
127
 
115
- def delay_errors!
116
- @delay_errors = true
117
- end
118
-
119
- def report_errors!
120
- @delay_errors = false
121
- @delayed_errors.each { |error| report_error(error) }
122
- @delayed_errors.clear
123
- end
124
-
125
128
  def upload_theme!(delay_low_priority_files: false, delete: true, &block)
126
129
  fetch_checksums!
127
130
 
@@ -177,21 +180,27 @@ module ShopifyCLI
177
180
 
178
181
  private
179
182
 
183
+ def report_error(operation, error_suffix = "")
184
+ @error_checksums << @checksums[operation.file_path]
185
+ @error_reporter.report("#{operation.as_error_message}#{error_suffix}")
186
+ end
187
+
180
188
  def enqueue(method, file)
181
189
  raise ArgumentError, "file required" unless file
182
190
 
183
- operation = Operation.new(method, @theme[file])
191
+ operation = Operation.new(@ctx, method, @theme[file])
184
192
 
185
193
  # Already enqueued
186
194
  return if @pending.include?(operation)
187
195
 
188
- if @ignore_filter&.ignore?(operation.file.relative_path)
189
- @ctx.debug("ignore #{operation.file.relative_path}")
196
+ if @ignore_filter&.ignore?(operation.file_path)
197
+ @ctx.debug("ignore #{operation.file_path}")
190
198
  return
191
199
  end
192
200
 
193
201
  if [:update, :get].include?(method) && operation.file.exist? && !file_has_changed?(operation.file)
194
- @ctx.debug("skip #{operation}")
202
+ is_fixed = !!@error_checksums.delete(operation.file.checksum)
203
+ @standard_reporter.report(operation.as_fix_message) if is_fixed
195
204
  return
196
205
  end
197
206
 
@@ -206,16 +215,16 @@ module ShopifyCLI
206
215
 
207
216
  response = send(operation.method, operation.file)
208
217
 
218
+ @standard_reporter.report(operation.as_synced_message)
219
+
209
220
  # Check if the API told us we're near the rate limit
210
221
  if !backingoff? && (limit = response["x-shopify-shop-api-call-limit"])
211
222
  used, total = limit.split("/").map(&:to_i)
212
223
  backoff_if_near_limit!(used, total)
213
224
  end
214
225
  rescue ShopifyCLI::API::APIRequestError => e
215
- report_error(
216
- "{{red:ERROR}} {{blue:#{operation}}}:\n " +
217
- parse_api_errors(e).join("\n ")
218
- )
226
+ error_suffix = ":\n " + parse_api_errors(e).join("\n ")
227
+ report_error(operation, error_suffix)
219
228
  ensure
220
229
  @pending.delete(operation)
221
230
  end
@@ -295,14 +304,6 @@ module ShopifyCLI
295
304
  file.checksum != @checksums[file.relative_path.to_s]
296
305
  end
297
306
 
298
- def report_error(error)
299
- if @delay_errors
300
- @delayed_errors << error
301
- else
302
- @ctx.puts(error)
303
- end
304
- end
305
-
306
307
  def parse_api_errors(exception)
307
308
  parsed_body = JSON.parse(exception&.response&.body)
308
309
  message = parsed_body.dig("errors", "asset") || parsed_body["message"] || exception.message
@@ -162,26 +162,38 @@ module ShopifyCLI
162
162
  }
163
163
  end
164
164
 
165
- def self.all(ctx, root: nil)
166
- _status, body = AdminAPI.rest_request(
167
- ctx,
168
- shop: AdminAPI.get_shop_or_abort(ctx),
169
- path: "themes.json",
170
- api_version: "unstable",
171
- )
165
+ class << self
166
+ def all(ctx, root: nil)
167
+ _status, body = fetch_themes(ctx)
168
+
169
+ body["themes"]
170
+ .sort_by { |theme_attrs| Time.parse(theme_attrs["updated_at"]) }
171
+ .reverse
172
+ .map { |theme_attrs| new(ctx, root: root, **allowed_attrs(theme_attrs)) }
173
+ end
174
+
175
+ def live(ctx, root: nil)
176
+ _status, body = fetch_themes(ctx)
172
177
 
173
- body["themes"]
174
- .sort_by { |attributes| Time.parse(attributes["updated_at"]) }
175
- .reverse
176
- .map do |attributes|
177
- new(
178
- ctx,
179
- root: root,
180
- id: attributes["id"],
181
- name: attributes["name"],
182
- role: attributes["role"],
183
- )
184
- end
178
+ body["themes"]
179
+ .find { |theme_attrs| theme_attrs["role"] == "main" }
180
+ .tap { |theme_attrs| break new(ctx, root: root, **allowed_attrs(theme_attrs)) }
181
+ end
182
+
183
+ private
184
+
185
+ def allowed_attrs(attrs)
186
+ attrs.slice("id", "name", "role").transform_keys(&:to_sym)
187
+ end
188
+
189
+ def fetch_themes(ctx)
190
+ AdminAPI.rest_request(
191
+ ctx,
192
+ shop: AdminAPI.get_shop_or_abort(ctx),
193
+ path: "themes.json",
194
+ api_version: "unstable",
195
+ )
196
+ end
185
197
  end
186
198
 
187
199
  private
@@ -87,7 +87,7 @@ module ShopifyCLI
87
87
  #
88
88
  def auth(ctx, token)
89
89
  install(ctx)
90
- ctx.system(ngrok_path, "authtoken", token)
90
+ ctx.system(ngrok_path(ctx), "authtoken", token)
91
91
  end
92
92
 
93
93
  ##
@@ -150,7 +150,7 @@ module ShopifyCLI
150
150
 
151
151
  def install(ctx)
152
152
  ngrok = "ngrok#{ctx.executable_file_extension}"
153
- return if File.exist?(ngrok_path)
153
+ return if File.exist?(ngrok_path(ctx))
154
154
  check_prereq_command(ctx, "curl")
155
155
  check_prereq_command(ctx, ctx.linux? ? "unzip" : "tar")
156
156
  spinner = CLI::UI::SpinGroup.new
@@ -170,7 +170,7 @@ module ShopifyCLI
170
170
  spinner.wait
171
171
 
172
172
  # final check to see if ngrok is accessible
173
- unless File.exist?(ngrok_path)
173
+ unless File.exist?(ngrok_path(ctx))
174
174
  ctx.abort(ctx.message("core.tunnel.error.ngrok", ngrok, ShopifyCLI.cache_dir))
175
175
  end
176
176
  end
@@ -182,12 +182,9 @@ module ShopifyCLI
182
182
  raise e.class, e.message
183
183
  end
184
184
 
185
- def ngrok_path
186
- File.join(ShopifyCLI.cache_dir, "ngrok")
187
- end
188
-
189
- def ngrok_command(port)
190
- "\"#{ngrok_path}\" http -inspect=false -log=stdout -log-level=debug #{port}"
185
+ def ngrok_path(ctx)
186
+ ngrok = "ngrok#{ctx.executable_file_extension}"
187
+ File.join(ShopifyCLI.cache_dir, ngrok)
191
188
  end
192
189
 
193
190
  def seconds_to_hm(seconds)
@@ -195,7 +192,8 @@ module ShopifyCLI
195
192
  end
196
193
 
197
194
  def start_ngrok(ctx, port)
198
- process = ShopifyCLI::ProcessSupervision.start(:ngrok, ngrok_command(port))
195
+ ngrok_command = "\"#{ngrok_path(ctx)}\" http -inspect=false -log=stdout -log-level=debug #{port}"
196
+ process = ShopifyCLI::ProcessSupervision.start(:ngrok, ngrok_command)
199
197
  log = fetch_url(ctx, process.log_path)
200
198
  [log.url, log.account]
201
199
  end
@@ -1,3 +1,3 @@
1
1
  module ShopifyCLI
2
- VERSION = "2.7.1"
2
+ VERSION = "2.7.2"
3
3
  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.7.1
4
+ version: 2.7.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-17 00:00:00.000000000 Z
11
+ date: 2021-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -275,12 +275,17 @@ files:
275
275
  - lib/project_types/script/commands/push.rb
276
276
  - lib/project_types/script/config/extension_points.yml
277
277
  - lib/project_types/script/errors.rb
278
+ - lib/project_types/script/forms/ask_app.rb
279
+ - lib/project_types/script/forms/ask_org.rb
280
+ - lib/project_types/script/forms/ask_script_uuid.rb
278
281
  - lib/project_types/script/forms/create.rb
282
+ - lib/project_types/script/forms/run_against_shopify_org.rb
279
283
  - lib/project_types/script/graphql/app_script_set.graphql
280
284
  - lib/project_types/script/graphql/get_app_scripts.graphql
281
285
  - lib/project_types/script/graphql/module_upload_url_generate.graphql
282
286
  - lib/project_types/script/graphql/script_service_proxy.graphql
283
287
  - lib/project_types/script/layers/application/build_script.rb
288
+ - lib/project_types/script/layers/application/connect_app.rb
284
289
  - lib/project_types/script/layers/application/create_script.rb
285
290
  - lib/project_types/script/layers/application/extension_points.rb
286
291
  - lib/project_types/script/layers/application/project_dependencies.rb
@@ -308,7 +313,6 @@ files:
308
313
  - lib/project_types/script/layers/infrastructure/script_uploader.rb
309
314
  - lib/project_types/script/layers/infrastructure/service_locator.rb
310
315
  - lib/project_types/script/messages/messages.rb
311
- - lib/project_types/script/tasks/ensure_env.rb
312
316
  - lib/project_types/script/ui/error_handler.rb
313
317
  - lib/project_types/script/ui/printing_spinner.rb
314
318
  - lib/project_types/script/ui/strict_spinner.rb
@@ -454,6 +458,9 @@ files:
454
458
  - lib/shopify_cli/theme/ignore_filter.rb
455
459
  - lib/shopify_cli/theme/mime_type.rb
456
460
  - lib/shopify_cli/theme/syncer.rb
461
+ - lib/shopify_cli/theme/syncer/error_reporter.rb
462
+ - lib/shopify_cli/theme/syncer/operation.rb
463
+ - lib/shopify_cli/theme/syncer/standard_reporter.rb
457
464
  - lib/shopify_cli/theme/theme.rb
458
465
  - lib/shopify_cli/transform_data_structure.rb
459
466
  - lib/shopify_cli/tunnel.rb