shopify-cli 2.7.1 → 2.7.2

Sign up to get free protection for your applications and to get access to all the features.
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