shopify-cli 2.27.0 → 2.29.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.
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