shopify-cli 2.27.0 → 2.29.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07ad4ab4b77c8edc5d1ff4bbbc980abcd625e00081c00aa986de0aef8251db43
4
- data.tar.gz: 774eecdb92623ac595ce3cdcf44b6cf1247b882004833a545756eb7b7dd070db
3
+ metadata.gz: 5f07c45a6fc9d6b93d9f2826a7ad9eb139842d8b7f35717ca5fb17291285c330
4
+ data.tar.gz: 774e222e76f9a8d30b68e8b0756ed4cecbc8281d302d94c131d072c123b19f8c
5
5
  SHA512:
6
- metadata.gz: 32548f2bf7b53d4e3d74a7b100f7f3b89f79438141932fdb876aba9f37a9eeeeb4fd66ed05fef2dbb80abcd05044ca398a30107cbf2277558cd5104f7123ff3a
7
- data.tar.gz: 9075eca951bae25caaaac87774aee024ccaff98391c23d16d9e525f419461ce9cb978a60b640e49c34dd8d30e41b6d33e18050d3c9fbdba586adb70e7b66dcf2
6
+ metadata.gz: eab29689be4de3a23b0b9dd14401a130d6f37cc1064c02f16bbce0656d378d487666bd964dfa673b8fcc48344b01acf8d10899e4fb3755c7f5f46c5dd8c46385
7
+ data.tar.gz: 01d9830606768a70de1de312527875d997dce26f1913c44fd6ffd82407afc7962931fe38dd7568e49c899438e33bf3f1b465b6b5d73bb0585d25643c0d26d5a2
data/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@ From version 2.6.0, the sections in this file adhere to the [keep a changelog](h
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## Version 2.29.0 - 2022-10-19
6
+
7
+ ### Added
8
+ * [#2664](https://github.com/Shopify/shopify-cli/pull/2664): Enable Theme Kit Access passwords
9
+
10
+ ## Version 2.28.0 - 2022-10-17
11
+
12
+ ### Fixed
13
+ * [#2646](https://github.com/Shopify/shopify-cli/pull/2646): Demo themes shouldn't appear in the `shopify theme pull/push/list/open` commands
14
+
15
+ ### Changed
16
+ * [#2648](https://github.com/Shopify/shopify-cli/pull/2648): Do not warn users when the CLI 2.x is running as a subprocess
17
+
5
18
  ## Version 2.27.0 - 2022-10-10
6
19
 
7
20
  ### Fixed
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify-cli (2.27.0)
4
+ shopify-cli (2.29.0)
5
5
  bugsnag (~> 6.22)
6
6
  listen (~> 3.7.0)
7
7
  theme-check (~> 1.11.0)
@@ -8,7 +8,7 @@ module Extension
8
8
  return Messages::MESSAGES if type_specific_messages.nil?
9
9
 
10
10
  if type_specific_messages.key?(:overrides)
11
- deep_merge(Messages::MESSAGES, type_specific_messages[:overrides])
11
+ ShopifyCLI::Utilities.deep_merge(Messages::MESSAGES, type_specific_messages[:overrides])
12
12
  else
13
13
  Messages::MESSAGES
14
14
  end
@@ -29,11 +29,6 @@ module Extension
29
29
 
30
30
  TYPES[type_identifier_symbol]
31
31
  end
32
-
33
- def self.deep_merge(first, second)
34
- merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
35
- first.merge(second, &merger)
36
- end
37
32
  end
38
33
  end
39
34
  end
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Theme
3
4
  class Project < ShopifyCLI::ProjectType
4
5
  require Project.project_filepath("messages/messages")
5
- register_messages(Theme::Messages::MESSAGES)
6
+ register_messages(Theme::Messages.all)
6
7
  end
7
8
 
8
9
  class Command < ShopifyCLI::Command::ProjectCommand
@@ -5,7 +5,7 @@ module Theme
5
5
  module Common
6
6
  module ShopHelper
7
7
  def shop
8
- ShopifyCLI::AdminAPI.get_shop_or_abort(@ctx)
8
+ ShopifyCLI::Theme::ThemeAdminAPI.new(@ctx).get_shop_or_abort
9
9
  end
10
10
  end
11
11
  end
@@ -145,7 +145,7 @@ module Theme
145
145
  It looks like you are using credentials that do not work with {{command:%s theme serve}}.
146
146
  ERROR_MESSAGE
147
147
  help_message: <<~HELP_MESSAGE,
148
- Run {{command:%s logout}} and {{command:%s login --password "" --store STORE}} to force the authentication thought your browser.
148
+ Run {{command:%s logout}} and {{command:%s login --password "" --store STORE}} to authenticate again.
149
149
  HELP_MESSAGE
150
150
  },
151
151
  operation: {
@@ -390,5 +390,31 @@ module Theme
390
390
  },
391
391
  },
392
392
  }.freeze
393
+
394
+ def self.all
395
+ # In order to support theme development inside CLI3, we spawn CLI2 as a
396
+ # subprocess. Whenever an error happens, we want to show the updated
397
+ # version of the commands for the user to try.
398
+ if ShopifyCLI::Environment.run_as_subprocess?
399
+ ShopifyCLI::Utilities.deep_merge(MESSAGES, {
400
+ theme: {
401
+ serve: {
402
+ auth: {
403
+ error_message: <<~ERROR_MESSAGE,
404
+ It looks like you are using credentials that do not work with {{command:%s theme dev}}.
405
+ ERROR_MESSAGE
406
+ help_message: <<~HELP_MESSAGE,
407
+ Run {{command:%s auth logout}} and {{command:%s theme dev --store STORE}} to authenticate again.
408
+ HELP_MESSAGE
409
+ },
410
+ binding_error: "Couldn't bind to localhost." \
411
+ " To serve your theme, set a different address with {{command:%s theme dev --host=<address>}}",
412
+ },
413
+ },
414
+ })
415
+ else
416
+ MESSAGES
417
+ end
418
+ end
393
419
  end
394
420
  end
@@ -5,7 +5,7 @@ require_relative "theme_presenter"
5
5
  module Theme
6
6
  module Presenters
7
7
  class ThemesPresenter
8
- ORDER_BY_ROLE = %w(live unpublished development)
8
+ SUPPORTED_ROLES = %w(live unpublished development)
9
9
 
10
10
  def initialize(ctx, root)
11
11
  @ctx = ctx
@@ -14,16 +14,13 @@ module Theme
14
14
 
15
15
  def all
16
16
  all_themes
17
- .sort_by { |theme| order_by_role(theme) }
17
+ .select { |theme| SUPPORTED_ROLES.include?(theme.role) }
18
+ .sort_by { |theme| SUPPORTED_ROLES.index(theme.role) }
18
19
  .map { |theme| ThemePresenter.new(theme) }
19
20
  end
20
21
 
21
22
  private
22
23
 
23
- def order_by_role(theme)
24
- ORDER_BY_ROLE.index(theme.role) || ORDER_BY_ROLE.size
25
- end
26
-
27
24
  def all_themes
28
25
  ShopifyCLI::Theme::Theme.all(@ctx, root: @root)
29
26
  end
@@ -117,7 +117,7 @@ module ShopifyCLI
117
117
  end
118
118
 
119
119
  def check_version(version, range:, runtime:, context: Context.new)
120
- return if Environment.test?
120
+ return if Environment.test? || Environment.run_as_subprocess?
121
121
  return if range.nil?
122
122
 
123
123
  version_without_pre_nor_build = Utilities.version_dropping_pre_and_build(version)
@@ -59,7 +59,8 @@ module ShopifyCLI
59
59
 
60
60
  # Monorail
61
61
  MONORAIL_REAL_EVENTS = "MONORAIL_REAL_EVENTS"
62
- STORE = "SHOPIFY_CLI_STORE"
62
+
63
+ STORE = "SHOPIFY_SHOP"
63
64
  end
64
65
 
65
66
  module SupportedVersions
@@ -10,6 +10,8 @@ module ShopifyCLI
10
10
  Constants::EnvironmentVariables::SPIN_NAMESPACE,
11
11
  Constants::EnvironmentVariables::SPIN_HOST,
12
12
  ]
13
+ # https://github.com/Shopify/themekit-access/blob/4c3c917d78443160dcf24376a8b5ac6b9bef0bcd/app/models/password_token.rb#L8
14
+ THEME_ACCESS_PASSWORD_PREFIX = "shptka_"
13
15
 
14
16
  def self.ruby_version(context: Context.new)
15
17
  output, status = context.capture2e("ruby", "--version")
@@ -188,5 +190,9 @@ module ShopifyCLI
188
190
  env_variables: env_variables
189
191
  )
190
192
  end
193
+
194
+ def self.theme_access_password?
195
+ admin_auth_token&.start_with?(THEME_ACCESS_PASSWORD_PREFIX)
196
+ end
191
197
  end
192
198
  end
@@ -498,7 +498,7 @@ module ShopifyCLI
498
498
  "{{i}} Authentication required. Login to the URL below with your %s credentials to continue.",
499
499
 
500
500
  servlet: {
501
- success_response: "You've successfuly logged into the Shopify CLI!",
501
+ success_response: "You've successfully logged into the Shopify CLI!",
502
502
  invalid_request_response: "Invalid request: %s",
503
503
  invalid_state_response: "The anti-forgery state token does not match the initial request.",
504
504
  },
@@ -541,6 +541,9 @@ module ShopifyCLI
541
541
  forbidden: <<~FORBIDDEN,
542
542
  Command not allowed with current login. Please check your login details with {{command:%s whoami}}. You may need to request additional permissions for this action.
543
543
  FORBIDDEN
544
+ theme_access_invalid_password: "Invalid password. Please check that it was generated from Theme Access app"\
545
+ " for the current store.",
546
+ theme_access_no_store: "No store found. Please pass it through the environment variable SHOPIFY_SHOP",
544
547
  internal_server_error: "{{red:{{x}} An unexpected error occurred on Shopify.}}",
545
548
  internal_server_error_debug: "\n{{red:Response details:}}\n%s\n\n",
546
549
  invalid_url: "Invalid URL: %s",
@@ -69,11 +69,15 @@ module ShopifyCLI
69
69
  # Checksums of assets with errors.
70
70
  @error_checksums = []
71
71
 
72
+ # Do not use the throttler when --stable is passed or a Theme Access password is set
73
+ # (Theme Access API is not compatible yet with bulks)
74
+ throttler_enabled = !stable && !Environment.theme_access_password?
75
+
72
76
  # Initialize `api_client` on main thread
73
77
  @api_client = ThemeAdminAPIThrottler.new(
74
78
  @ctx,
75
79
  ThemeAdminAPI.new(@ctx, @theme.shop),
76
- !stable
80
+ throttler_enabled
77
81
  )
78
82
  end
79
83
 
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shopify_cli"
4
+
5
+ module ShopifyCLI
6
+ module Theme
7
+ ##
8
+ # ShopifyCLI::ThemeAccessAPI is a wrapper to use Shopify Theme Access API, which allows using passwords
9
+ # generated from Shopify Theme Access app to access the Shopify Admin API (for theme operations)
10
+ #
11
+ class ThemeAccessAPI < API
12
+ BASE_URL = "theme-kit-access.shopifyapps.com"
13
+
14
+ class << self
15
+ ##
16
+ # #### Parameters
17
+ # - `ctx`: running context from your command
18
+ # - `shop`: shop domain string for shop whose admin you are calling
19
+ # - `path`: path string (excluding prefixes and API version) for specific JSON that you are requesting
20
+ # ex. "data.json" instead of "/admin/api/unstable/data.json"
21
+ # - `body`: data string for corresponding REST request types
22
+ # - `method`: REST request string for the type of request; if nil, will perform GET request
23
+ # - `api_version`: an api version string to specify version. Default value: unstable
24
+ #
25
+ # #### Raises
26
+ #
27
+ # * http 404 will raise a ShopifyCLI::API::APIRequestNotFoundError
28
+ # * http 400..499 will raise a ShopifyCLI::API::APIRequestClientError
29
+ # * http 500..599 will raise a ShopifyCLI::API::APIRequestServerError
30
+ # * All other codes will raise ShopifyCLI::API::APIRequestUnexpectedError
31
+ #
32
+ # #### Returns
33
+ #
34
+ # * `resp` - JSON response array
35
+ #
36
+ # #### Example
37
+ #
38
+ # ThemeAccessAPI.rest_request(@ctx, shop: 'shop.myshopify.com', path: 'data.json')
39
+ #
40
+ def rest_request(ctx, shop:, path:, query: nil, body: nil, method: "GET", api_version: "unstable")
41
+ client = api_client(ctx, api_version, shop, path: path)
42
+ url = build_url(api_version, path, query)
43
+ client.request(url: url, body: body, headers: headers(shop), method: method)
44
+ rescue ShopifyCLI::API::APIRequestForbiddenError,
45
+ ShopifyCLI::API::APIRequestUnauthorizedError
46
+ ctx.abort(ctx.message("core.api.error.theme_access_invalid_password"))
47
+ end
48
+
49
+ def get_shop_or_abort(ctx)
50
+ env_store = Environment.store
51
+ return env_store unless env_store.nil?
52
+ ctx.abort(
53
+ ctx.message("core.api.error.theme_access_no_store")
54
+ )
55
+ end
56
+
57
+ private
58
+
59
+ def build_url(api_version, path, query = nil)
60
+ URI::HTTPS.build(
61
+ host: BASE_URL,
62
+ path: "/cli/admin/api/#{api_version}/#{path}",
63
+ query: query
64
+ ).to_s
65
+ end
66
+
67
+ def api_client(ctx, api_version, _shop, path: "graphql.json")
68
+ new(
69
+ ctx: ctx,
70
+ token: Environment.admin_auth_token,
71
+ url: build_url(api_version, path),
72
+ )
73
+ end
74
+
75
+ def headers(shop)
76
+ {
77
+ "X-Shopify-Shop" => shop,
78
+ }
79
+ end
80
+ end
81
+
82
+ def auth_headers(token)
83
+ {
84
+ "X-Shopify-Access-Token" => token,
85
+ }
86
+ end
87
+ end
88
+ end
89
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "theme_access_api"
4
+
3
5
  module ShopifyCLI
4
6
  module Theme
5
7
  class ThemeAdminAPI
@@ -29,11 +31,11 @@ module ShopifyCLI
29
31
  end
30
32
 
31
33
  def get_shop_or_abort # rubocop:disable Naming/AccessorMethodName
32
- ShopifyCLI::AdminAPI.get_shop_or_abort(@ctx)
34
+ api_client.get_shop_or_abort(@ctx)
33
35
  end
34
36
 
35
37
  def rest_request(**args)
36
- status, body, response = ShopifyCLI::AdminAPI.rest_request(
38
+ status, body, response = api_client.rest_request(
37
39
  @ctx,
38
40
  shop: @shop,
39
41
  api_version: API_VERSION,
@@ -67,6 +69,10 @@ module ShopifyCLI
67
69
 
68
70
  private
69
71
 
72
+ def api_client
73
+ @api_client ||= Environment.theme_access_password? ? ThemeAccessAPI : ShopifyCLI::AdminAPI
74
+ end
75
+
70
76
  def permission_error
71
77
  ensure_user_error = @ctx.message("theme.ensure_user_error", shop)
72
78
  ensure_user_try_this = @ctx.message("theme.ensure_user_try_this")
@@ -12,5 +12,10 @@ module ShopifyCLI
12
12
  curr = File.dirname(curr)
13
13
  end
14
14
  end
15
+
16
+ def self.deep_merge(first, second)
17
+ merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
18
+ first.merge(second, &merger)
19
+ end
15
20
  end
16
21
  end
@@ -1,3 +1,3 @@
1
1
  module ShopifyCLI
2
- VERSION = "2.27.0"
2
+ VERSION = "2.29.0"
3
3
  end
data/lib/shopify_cli.rb CHANGED
@@ -97,18 +97,18 @@ module ShopifyCLI
97
97
  )
98
98
  end
99
99
 
100
- autoload :AppTypeDetector, "shopify_cli/app_type_detector"
101
- autoload :Constants, "shopify_cli/constants"
102
- autoload :Environment, "shopify_cli/environment"
103
100
  autoload :AdminAPI, "shopify_cli/admin_api"
104
101
  autoload :API, "shopify_cli/api"
102
+ autoload :AppTypeDetector, "shopify_cli/app_type_detector"
105
103
  autoload :Command, "shopify_cli/command"
106
104
  autoload :CommandOptions, "shopify_cli/command_options"
107
105
  autoload :Commands, "shopify_cli/commands"
108
106
  autoload :Connect, "shopify_cli/connect"
107
+ autoload :Constants, "shopify_cli/constants"
109
108
  autoload :Context, "shopify_cli/context"
110
109
  autoload :Core, "shopify_cli/core"
111
110
  autoload :DB, "shopify_cli/db"
111
+ autoload :Environment, "shopify_cli/environment"
112
112
  autoload :Feature, "shopify_cli/feature"
113
113
  autoload :Form, "shopify_cli/form"
114
114
  autoload :Git, "shopify_cli/git"
@@ -118,11 +118,11 @@ module ShopifyCLI
118
118
  autoload :IdentityAuth, "shopify_cli/identity_auth"
119
119
  autoload :JsDeps, "shopify_cli/js_deps"
120
120
  autoload :JsSystem, "shopify_cli/js_system"
121
- autoload :PHPDeps, "shopify_cli/php_deps"
122
121
  autoload :LazyDelegator, "shopify_cli/lazy_delegator"
123
122
  autoload :MethodObject, "shopify_cli/method_object"
124
123
  autoload :Options, "shopify_cli/options"
125
124
  autoload :PartnersAPI, "shopify_cli/partners_api"
125
+ autoload :PHPDeps, "shopify_cli/php_deps"
126
126
  autoload :ProcessSupervision, "shopify_cli/process_supervision"
127
127
  autoload :Project, "shopify_cli/project"
128
128
  autoload :ProjectType, "shopify_cli/project_type"
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.27.0
4
+ version: 2.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-10 00:00:00.000000000 Z
11
+ date: 2022-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -517,6 +517,7 @@ files:
517
517
  - lib/shopify_cli/theme/syncer/standard_reporter.rb
518
518
  - lib/shopify_cli/theme/syncer/unsupported_script_warning.rb
519
519
  - lib/shopify_cli/theme/theme.rb
520
+ - lib/shopify_cli/theme/theme_access_api.rb
520
521
  - lib/shopify_cli/theme/theme_admin_api.rb
521
522
  - lib/shopify_cli/theme/theme_admin_api_throttler.rb
522
523
  - lib/shopify_cli/theme/theme_admin_api_throttler/bulk.rb