shopify-cli 1.14.0 → 2.0.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 (179) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/CONTRIBUTING.md +7 -7
  4. data/.github/DESIGN.md +3 -3
  5. data/.github/workflows/build.yml +1 -1
  6. data/.gitignore +3 -0
  7. data/.rubocop.yml +3 -1
  8. data/.ruby-version +1 -1
  9. data/CHANGELOG.md +35 -29
  10. data/Gemfile +4 -0
  11. data/Gemfile.lock +32 -0
  12. data/LICENSE +4 -1
  13. data/README.md +92 -26
  14. data/RELEASING.md +29 -7
  15. data/Rakefile +2 -2
  16. data/SECURITY.md +1 -1
  17. data/bin/load_shopify.rb +1 -1
  18. data/bin/shopify +3 -3
  19. data/dev.yml +1 -1
  20. data/docs/app/node/index.md +1 -1
  21. data/docs/app/rails/index.md +1 -1
  22. data/docs/core/index.md +1 -1
  23. data/docs/getting-started/index.md +1 -1
  24. data/docs/getting-started/install/index.md +1 -1
  25. data/docs/getting-started/migrate/index.md +1 -1
  26. data/docs/getting-started/uninstall/index.md +1 -1
  27. data/docs/getting-started/upgrade/index.md +1 -1
  28. data/docs/help/start-app/index.md +1 -1
  29. data/docs/index.md +1 -1
  30. data/ext/shopify-cli/extconf.rb +17 -5
  31. data/install.sh +1 -1
  32. data/lib/docgen/index_template.md.erb +2 -2
  33. data/lib/graphql/all_orgs_with_extensions.graphql +37 -0
  34. data/lib/graphql/find_organization.graphql +2 -1
  35. data/lib/project_types/extension/cli.rb +18 -15
  36. data/lib/project_types/extension/commands/build.rb +4 -5
  37. data/lib/project_types/extension/commands/connect.rb +35 -0
  38. data/lib/project_types/extension/commands/create.rb +12 -16
  39. data/lib/project_types/extension/commands/extension_command.rb +2 -2
  40. data/lib/project_types/extension/commands/info.rb +86 -0
  41. data/lib/project_types/extension/commands/push.rb +8 -7
  42. data/lib/project_types/extension/commands/register.rb +4 -5
  43. data/lib/project_types/extension/commands/serve.rb +5 -8
  44. data/lib/project_types/extension/commands/tunnel.rb +3 -1
  45. data/lib/project_types/extension/errors.rb +9 -0
  46. data/lib/project_types/extension/extension_project.rb +5 -0
  47. data/lib/project_types/extension/features/argo.rb +6 -6
  48. data/lib/project_types/extension/features/argo_runtime.rb +22 -66
  49. data/lib/project_types/extension/features/argo_serve.rb +25 -18
  50. data/lib/project_types/extension/forms/connect.rb +42 -0
  51. data/lib/project_types/extension/forms/questions/ask_name.rb +14 -6
  52. data/lib/project_types/extension/forms/questions/ask_registration.rb +51 -0
  53. data/lib/project_types/extension/messages/messages.rb +75 -11
  54. data/lib/project_types/extension/models/specification.rb +1 -0
  55. data/lib/project_types/extension/models/specification_handlers/{checkout_argo_extension.rb → checkout_ui_extension.rb} +3 -1
  56. data/lib/project_types/extension/models/specification_handlers/default.rb +13 -3
  57. data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +86 -0
  58. data/lib/project_types/extension/models/specifications.rb +1 -0
  59. data/lib/project_types/extension/tasks/configure_features.rb +6 -7
  60. data/lib/project_types/extension/tasks/configure_options.rb +20 -0
  61. data/lib/project_types/extension/tasks/get_extensions.rb +32 -0
  62. data/lib/project_types/node/cli.rb +9 -21
  63. data/lib/project_types/node/commands/connect.rb +8 -2
  64. data/lib/project_types/node/commands/create.rb +9 -5
  65. data/lib/project_types/node/commands/deploy.rb +15 -5
  66. data/lib/project_types/node/commands/deploy/heroku.rb +29 -29
  67. data/lib/project_types/node/commands/generate.rb +4 -2
  68. data/lib/project_types/node/commands/open.rb +4 -2
  69. data/lib/project_types/node/commands/serve.rb +3 -2
  70. data/lib/project_types/node/commands/tunnel.rb +4 -2
  71. data/lib/project_types/node/messages/messages.rb +46 -89
  72. data/lib/project_types/rails/cli.rb +9 -21
  73. data/lib/project_types/rails/commands/connect.rb +8 -2
  74. data/lib/project_types/rails/commands/create.rb +10 -6
  75. data/lib/project_types/rails/commands/deploy.rb +15 -5
  76. data/lib/project_types/rails/commands/deploy/heroku.rb +84 -82
  77. data/lib/project_types/rails/commands/generate.rb +15 -5
  78. data/lib/project_types/rails/commands/generate/webhook.rb +28 -26
  79. data/lib/project_types/rails/commands/open.rb +4 -2
  80. data/lib/project_types/rails/commands/serve.rb +3 -2
  81. data/lib/project_types/rails/commands/tunnel.rb +4 -2
  82. data/lib/project_types/rails/messages/messages.rb +54 -101
  83. data/lib/project_types/script/cli.rb +5 -7
  84. data/lib/project_types/script/commands/create.rb +3 -1
  85. data/lib/project_types/script/commands/push.rb +4 -2
  86. data/lib/project_types/script/messages/messages.rb +52 -45
  87. data/lib/project_types/script/ui/error_handler.rb +2 -2
  88. data/lib/project_types/theme/cli.rb +15 -27
  89. data/lib/project_types/theme/commands/check.rb +33 -0
  90. data/lib/project_types/theme/commands/delete.rb +64 -0
  91. data/lib/project_types/theme/commands/language_server.rb +16 -0
  92. data/lib/project_types/theme/commands/package.rb +55 -0
  93. data/lib/project_types/theme/commands/publish.rb +43 -0
  94. data/lib/project_types/theme/commands/pull.rb +51 -0
  95. data/lib/project_types/theme/commands/push.rb +58 -32
  96. data/lib/project_types/theme/commands/serve.rb +7 -17
  97. data/lib/project_types/theme/forms/confirm_store.rb +15 -0
  98. data/lib/project_types/theme/forms/select.rb +59 -0
  99. data/lib/project_types/theme/messages/messages.rb +110 -106
  100. data/lib/project_types/theme/ui/sync_progress_bar.rb +20 -0
  101. data/lib/shopify-cli/admin_api.rb +53 -38
  102. data/lib/shopify-cli/admin_api/populate_resource_command.rb +6 -14
  103. data/lib/shopify-cli/admin_api/schema.rb +1 -10
  104. data/lib/shopify-cli/api.rb +29 -14
  105. data/lib/shopify-cli/command.rb +15 -3
  106. data/lib/shopify-cli/commands.rb +7 -2
  107. data/lib/shopify-cli/commands/help.rb +2 -29
  108. data/lib/shopify-cli/commands/login.rb +95 -0
  109. data/lib/shopify-cli/commands/logout.rb +24 -8
  110. data/lib/shopify-cli/commands/populate.rb +23 -0
  111. data/lib/{project_types/node → shopify-cli}/commands/populate/customer.rb +2 -8
  112. data/lib/{project_types/node → shopify-cli}/commands/populate/draft_order.rb +2 -2
  113. data/lib/{project_types/node → shopify-cli}/commands/populate/product.rb +2 -8
  114. data/lib/shopify-cli/commands/store.rb +15 -0
  115. data/lib/shopify-cli/commands/switch.rb +39 -0
  116. data/lib/shopify-cli/commands/system.rb +12 -0
  117. data/lib/shopify-cli/commands/whoami.rb +28 -0
  118. data/lib/shopify-cli/connect.rb +32 -0
  119. data/lib/shopify-cli/context.rb +52 -4
  120. data/lib/shopify-cli/core/entry_point.rb +3 -22
  121. data/lib/shopify-cli/db.rb +4 -4
  122. data/lib/shopify-cli/http_request.rb +10 -0
  123. data/lib/shopify-cli/identity_auth.rb +282 -0
  124. data/lib/shopify-cli/{oauth → identity_auth}/servlet.rb +11 -12
  125. data/lib/shopify-cli/messages/messages.rb +132 -39
  126. data/lib/shopify-cli/partners_api.rb +21 -44
  127. data/lib/shopify-cli/partners_api/organizations.rb +8 -0
  128. data/lib/shopify-cli/project_commands.rb +16 -0
  129. data/lib/shopify-cli/project_type.rb +0 -31
  130. data/lib/shopify-cli/shopifolk.rb +8 -11
  131. data/lib/shopify-cli/sub_command.rb +1 -0
  132. data/lib/shopify-cli/tasks.rb +3 -0
  133. data/lib/shopify-cli/tasks/confirm_store.rb +18 -0
  134. data/lib/shopify-cli/tasks/create_api_client.rb +2 -2
  135. data/lib/shopify-cli/tasks/ensure_authenticated.rb +13 -0
  136. data/lib/shopify-cli/tasks/ensure_loopback_url.rb +1 -1
  137. data/lib/shopify-cli/tasks/ensure_project_type.rb +12 -0
  138. data/lib/shopify-cli/tasks/select_org_and_shop.rb +0 -3
  139. data/lib/shopify-cli/theme/dev_server.rb +98 -0
  140. data/lib/shopify-cli/theme/dev_server/certificate_manager.rb +79 -0
  141. data/lib/shopify-cli/theme/dev_server/header_hash.rb +94 -0
  142. data/lib/shopify-cli/theme/dev_server/hot-reload.js +93 -0
  143. data/lib/shopify-cli/theme/dev_server/hot_reload.rb +76 -0
  144. data/lib/shopify-cli/theme/dev_server/local_assets.rb +87 -0
  145. data/lib/shopify-cli/theme/dev_server/proxy.rb +205 -0
  146. data/lib/shopify-cli/theme/dev_server/sse.rb +75 -0
  147. data/lib/shopify-cli/theme/dev_server/watcher.rb +59 -0
  148. data/lib/shopify-cli/theme/dev_server/web_server.rb +140 -0
  149. data/lib/shopify-cli/theme/development_theme.rb +69 -0
  150. data/lib/shopify-cli/theme/file.rb +112 -0
  151. data/lib/shopify-cli/theme/ignore_filter.rb +109 -0
  152. data/lib/shopify-cli/theme/mime_type.rb +34 -0
  153. data/lib/shopify-cli/theme/syncer.rb +328 -0
  154. data/lib/shopify-cli/theme/theme.rb +204 -0
  155. data/lib/shopify-cli/version.rb +1 -1
  156. data/lib/shopify_cli.rb +18 -11
  157. data/shopify-cli.gemspec +12 -5
  158. data/shopify.fish +1 -1
  159. data/shopify.sh +1 -1
  160. metadata +88 -34
  161. data/.github/workflows/release.yml +0 -59
  162. data/lib/project_types/extension/features/argo_serve_options.rb +0 -42
  163. data/lib/project_types/node/commands/populate.rb +0 -23
  164. data/lib/project_types/rails/commands/populate.rb +0 -23
  165. data/lib/project_types/rails/commands/populate/customer.rb +0 -31
  166. data/lib/project_types/rails/commands/populate/draft_order.rb +0 -28
  167. data/lib/project_types/rails/commands/populate/product.rb +0 -30
  168. data/lib/project_types/theme/commands/connect.rb +0 -54
  169. data/lib/project_types/theme/commands/create.rb +0 -48
  170. data/lib/project_types/theme/commands/deploy.rb +0 -38
  171. data/lib/project_types/theme/commands/generate.rb +0 -20
  172. data/lib/project_types/theme/commands/generate/env.rb +0 -79
  173. data/lib/project_types/theme/forms/connect.rb +0 -34
  174. data/lib/project_types/theme/forms/create.rb +0 -22
  175. data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +0 -78
  176. data/lib/project_types/theme/themekit.rb +0 -113
  177. data/lib/shopify-cli/commands/connect.rb +0 -64
  178. data/lib/shopify-cli/commands/create.rb +0 -50
  179. data/lib/shopify-cli/oauth.rb +0 -198
@@ -1,5 +1,5 @@
1
1
  module ShopifyCli
2
- class OAuth
2
+ class IdentityAuth
3
3
  class Servlet < WEBrick::HTTPServlet::AbstractServlet
4
4
  TEMPLATE = %{<!DOCTYPE html>
5
5
  <html>
@@ -13,15 +13,13 @@ module ShopifyCli
13
13
  </html>
14
14
  }
15
15
  AUTOCLOSE_TEMPLATE = %{
16
- <script>
17
- setTimeout(function() { window.close(); }, 3000)
18
- </script>
16
+ <script>window.close();</script>
19
17
  }
20
18
 
21
- def initialize(server, oauth, token)
19
+ def initialize(server, identity_auth, token)
22
20
  super
23
21
  @server = server
24
- @oauth = oauth
22
+ @identity_auth = identity_auth
25
23
  @state_token = token
26
24
  end
27
25
 
@@ -30,16 +28,16 @@ module ShopifyCli
30
28
  respond_with(
31
29
  res,
32
30
  400,
33
- Context.message("core.oauth.servlet.invalid_request_response", req.query["error_description"])
31
+ Context.message("core.identity_auth.servlet.invalid_request_response", req.query["error_description"])
34
32
  )
35
33
  elsif req.query["state"] != @state_token
36
- response_message = Context.message("core.oauth.servlet.invalid_state_response")
34
+ response_message = Context.message("core.identity_auth.servlet.invalid_state_response")
37
35
  req.query.merge!("error" => "invalid_state", "error_description" => response_message)
38
36
  respond_with(res, 403, response_message)
39
37
  else
40
- respond_with(res, 200, Context.message("core.oauth.servlet.success_response"))
38
+ respond_with(res, 200, Context.message("core.identity_auth.servlet.success_response"))
41
39
  end
42
- @oauth.response_query = req.query
40
+ @identity_auth.response_query = req.query
43
41
  @server.shutdown
44
42
  end
45
43
 
@@ -49,8 +47,9 @@ module ShopifyCli
49
47
  status: status,
50
48
  message: message,
51
49
  color: successful ? "black" : "red",
52
- title:
53
- Context.message(successful ? "core.oauth.servlet.authenticated" : "core.oauth.servlet.not_authenticated"),
50
+ title: Context.message(
51
+ successful ? "core.identity_auth.servlet.authenticated" : "core.identity_auth.servlet.not_authenticated"
52
+ ),
54
53
  autoclose: successful ? AUTOCLOSE_TEMPLATE : "",
55
54
  }
56
55
  response.status = status
@@ -7,19 +7,14 @@ module ShopifyCli
7
7
  create: {
8
8
  info: {
9
9
  created: "{{v}} {{green:%s}} was created in the organization's Partner Dashboard {{underline:%s}}",
10
- serve: "{{*}} Change directories to your new project folder {{green:%s}} and run {{command:%s serve}} " \
11
- "to start a local server",
10
+ serve: "{{*}} Change directories to your new project folder {{green:%s}} and run "\
11
+ "{{command:%s %s serve}} to start a local server",
12
12
  install: "{{*}} Then, visit {{underline:%s/test}} to install {{green:%s}} on your Dev Store",
13
13
  },
14
14
  },
15
15
  },
16
16
  core: {
17
17
  connect: {
18
- help: <<~HELP,
19
- Connect (or re-connect) an existing project to a Shopify partner organization and/or a store. Creates or updates the {{green:.env}} file, and creates the {{green:.shopify-cli.yml}} file.
20
- Usage: {{command:%s connect}}
21
- HELP
22
-
23
18
  already_connected_warning: "{{yellow:! This app appears to be already connected}}",
24
19
  project_type_select: "What type of project would you like to connect?",
25
20
  cli_yml_saved: ".shopify-cli.yml saved to project root",
@@ -32,19 +27,6 @@ module ShopifyCli
32
27
  OPEN
33
28
  },
34
29
 
35
- create: {
36
- help: <<~HELP,
37
- Create a new project.
38
- Usage: {{command:%s create [ %s ]}}
39
- HELP
40
-
41
- error: {
42
- invalid_app_type: "{{red:Error}}: invalid app type {{bold:%s}}",
43
- },
44
-
45
- project_type_select: "What type of project would you like to create?",
46
- },
47
-
48
30
  env_file: {
49
31
  saving_header: "writing %s file...",
50
32
  saving: "writing %s file",
@@ -99,8 +81,6 @@ module ShopifyCli
99
81
  preamble: <<~MESSAGE,
100
82
  Use {{command:%s help <command>}} to display detailed information about a specific command.
101
83
 
102
- {{bold:Available core commands:}}
103
-
104
84
  MESSAGE
105
85
  },
106
86
 
@@ -129,13 +109,35 @@ module ShopifyCli
129
109
  npm_installed_deps: "%d npm dependencies installed",
130
110
  },
131
111
 
112
+ login: {
113
+ help: <<~HELP,
114
+ Log in to the Shopify CLI by authenticating with a store or partner organization
115
+ Usage: {{command:%s login [--store=STORE]}}
116
+ HELP
117
+ invalid_shop: <<~MESSAGE,
118
+ Invalid store provided (%s). Please provide the store in the following format: my-store.myshopify.com
119
+ MESSAGE
120
+ shop_prompt: <<~PROMPT,
121
+ What store are you connecting to? (e.g. my-store.myshopify.com; do {{bold:NOT}} include protocol part, e.g., https://)
122
+ PROMPT
123
+ },
124
+
132
125
  logout: {
133
126
  help: <<~HELP,
134
- Log out of a currently authenticated partner organization and store, or clear invalid credentials
127
+ Log out of an authenticated partner organization and store, or clear invalid credentials
135
128
  Usage: {{command:%s logout}}
136
129
  HELP
137
130
 
138
- success: "Logged out of partner organization and store",
131
+ success: "Successfully logged out of your account",
132
+ },
133
+
134
+ switch: {
135
+ help: <<~HELP,
136
+ Switch between development stores in your partner organization
137
+ Usage: {{command:%s switch [--store=STORE]}}
138
+ HELP
139
+ disabled_as_shopify_org: "Can't switch development stores logged in as {{green:Shopify partners org}}",
140
+ success: "Switched development store to {{green:%s}}",
139
141
  },
140
142
 
141
143
  monorail: {
@@ -146,9 +148,12 @@ module ShopifyCli
146
148
  MSG
147
149
  },
148
150
 
149
- oauth: {
151
+ identity_auth: {
150
152
  error: {
151
153
  timeout: "Timed out while waiting for response from Shopify",
154
+ local_identity_not_running: "Identity needs to be running locally in order to proceed.",
155
+ reauthenticate: "Please login again with {{command:shopify login}}",
156
+ invalid_destination: "The store %s doesn't exist. Please log out and try again.",
152
157
  },
153
158
 
154
159
  location: {
@@ -166,6 +171,7 @@ module ShopifyCli
166
171
  authenticated: "Authenticated successfully",
167
172
  not_authenticated: "Failed to authenticate",
168
173
  },
174
+ login_prompt: "Please ensure you've logged in with {{command:%s login}} and try again",
169
175
  },
170
176
 
171
177
  options: {
@@ -185,6 +191,10 @@ module ShopifyCli
185
191
  api: {
186
192
  error: {
187
193
  failed_auth: "Failed to authenticate with Shopify. Please try again later.",
194
+ failed_auth_debugging: "{{red:Please provide this information with your report:}}\n%s\n\n",
195
+ forbidden: <<~FORBIDDEN,
196
+ 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.
197
+ FORBIDDEN
188
198
  internal_server_error: "{{red:{{x}} An unexpected error occurred on Shopify.}}",
189
199
  internal_server_error_debug: "\n{{red:Response details:}}\n%s\n\n",
190
200
  invalid_url: "Invalid URL: %s",
@@ -192,22 +202,78 @@ module ShopifyCli
192
202
  },
193
203
 
194
204
  populate: {
205
+ help: <<~HELP,
206
+ Populate a Shopify store with example customers, orders, or products.
207
+ Usage: {{command:%s populate [ customers | draftorders | products ]}}
208
+ HELP
209
+
210
+ extended_help: <<~HELP,
211
+ {{bold:Subcommands:}}
212
+
213
+ {{cyan:customers [options]}}: Add dummy customers to the specified store.
214
+ Usage: {{command:%1$s populate customers}}
215
+
216
+ {{cyan:draftorders [options]}}: Add dummy orders to the specified store.
217
+ Usage: {{command:%1$s populate draftorders}}
218
+
219
+ {{cyan:products [options]}}: Add dummy products to the specified store.
220
+ Usage: {{command:%1$s populate products}}
221
+
222
+ {{bold:Options:}}
223
+
224
+ {{cyan:--count [integer]}}: The number of dummy items to populate. Defaults to 5.
225
+ {{cyan:--silent}}: Silence the populate output.
226
+ {{cyan:--help}}: Display more options specific to each subcommand.
227
+
228
+ {{bold:Examples:}}
229
+
230
+ {{command:%1$s populate products}}
231
+ Populate your store with 5 additional products.
232
+
233
+ {{command:%1$s populate customers --count 30}}
234
+ Populate your store with 30 additional customers.
235
+
236
+ {{command:%1$s populate draftorders}}
237
+ Populate your store with 5 additional orders.
238
+
239
+ {{command:%1$s populate products --help}}
240
+ Display the list of options available to customize the {{command:%1$s populate products}} command.
241
+ HELP
242
+
243
+ error: {
244
+ no_shop: "No store found. Please run {{command:%s login --store=STORE}} to login to a specific store",
245
+ },
246
+
247
+ customer: {
248
+ added: "%s added to {{green:%s}} at {{underline:%scustomers/%d}}",
249
+ },
250
+
251
+ draft_order: {
252
+ added: "DraftOrder added to {{green:%s}} at {{underline:%sdraft_orders/%d}}",
253
+ },
254
+
195
255
  options: {
196
256
  header: "{{bold:{{cyan:%s}} options:}}",
197
257
  count_help: "Number of resources to generate",
198
258
  },
259
+
199
260
  populating: "Populating %d %ss...",
261
+
200
262
  completion_message: <<~COMPLETION_MESSAGE,
201
263
  Successfully added %d %s to {{green:%s}}
202
264
  {{*}} View all %ss at {{underline:%s%ss}}
203
265
  COMPLETION_MESSAGE
266
+
267
+ product: {
268
+ added: "%s added to {{green:%s}} at {{underline:%sproducts/%d}}",
269
+ },
204
270
  },
205
271
 
206
272
  project: {
207
273
  error: {
208
274
  not_in_project: <<~MESSAGE,
209
275
  {{x}} You are not in a Shopify app project
210
- {{yellow:{{*}}}}{{reset: Run}}{{cyan: shopify create}}{{reset: to create your app}}
276
+ {{yellow:{{*}}}}{{reset: Run}}{{cyan: shopify rails create}}{{reset: or}}{{cyan: shopify node create}}{{reset: to create your app}}
211
277
  MESSAGE
212
278
  },
213
279
  },
@@ -239,7 +305,8 @@ module ShopifyCli
239
305
  unknown_option: "{{x}} {{red:unknown option '%s'}}",
240
306
  },
241
307
 
242
- header: "{{bold:Shopify App CLI}}",
308
+ header: "{{bold:Shopify CLI}}",
309
+ shop_header: "{{bold:Current Shop}}",
243
310
  const: "%17s = %s",
244
311
  ruby_header: <<~RUBY_MESSAGE,
245
312
  {{bold:Ruby (via RbConfig)}}
@@ -266,7 +333,20 @@ module ShopifyCli
266
333
  identity_is_shopifolk: "{{v}} Checked user settings: you’re Shopify staff!",
267
334
  },
268
335
 
336
+ store: {
337
+ help: <<~HELP,
338
+ Display current store.
339
+ Usage: {{command:%s store}}
340
+ HELP
341
+ shop: "You're currently logged into {{green:%s}}",
342
+ },
343
+
269
344
  tasks: {
345
+ confirm_store: {
346
+ prompt: "You are currently logged into {{green:%s}}. Do you want to proceed using this store?",
347
+ confirmation: "Proceeding using {{green:%s}}",
348
+ cancelling: "Cancelling ...",
349
+ },
270
350
  ensure_env: {
271
351
  organization_select: "To which partner organization does this project belong?",
272
352
  no_development_stores: <<~MESSAGE,
@@ -293,6 +373,9 @@ module ShopifyCli
293
373
  MESSAGE
294
374
  transfer_disabled: "{{v}} Transfer has been disabled on %s.",
295
375
  },
376
+ ensure_project_type: {
377
+ wrong_project_type: "This command can only be run within %s projects.",
378
+ },
296
379
  update_dashboard_urls: {
297
380
  updated: "{{v}} Whitelist URLS updated in Partners Dashboard}}",
298
381
  update_error:
@@ -310,10 +393,11 @@ module ShopifyCli
310
393
  organization_not_found: "Cannot find a partner organization with that ID",
311
394
  shopifolk_notice: <<~MESSAGE,
312
395
  {{i}} As a {{green:Shopify}} employee, the authentication should take you to the Shopify Okta login,
313
- NOT the Partner account login. Please run {{command:%s logout}} and try again.
396
+ NOT the partner account login. Please run {{command:%s logout}} and try again.
314
397
  MESSAGE
315
398
  },
316
- first_party: "Are you working on a 1P (1st Party) app?",
399
+ first_party: "Are you working on a {{green:Shopify project}} on behalf of the"\
400
+ " {{green:Shopify partners org}}?",
317
401
  identified_as_shopify: "We've identified you as a {{green:Shopify}} employee.",
318
402
  organization: "Partner organization {{green:%s (%s)}}",
319
403
  organization_select: "Select partner organization",
@@ -334,7 +418,7 @@ module ShopifyCli
334
418
  signup_suggestion: <<~MESSAGE,
335
419
  {{*}} To avoid tunnels that timeout, it is recommended to signup for a free ngrok
336
420
  account at {{underline:https://ngrok.com/signup}}. After you signup, install your
337
- personalized authorization token using {{command:%s tunnel auth <token>}}.
421
+ personalized authorization token using {{command:%s [ node | rails ] tunnel auth <token>}}.
338
422
  MESSAGE
339
423
  start: "{{v}} ngrok tunnel running at {{underline:%s}}",
340
424
  start_with_account: "{{v}} ngrok tunnel running at {{underline:%s}}, with account %s",
@@ -358,21 +442,30 @@ module ShopifyCli
358
442
 
359
443
  DEVELOPMENT
360
444
 
361
- shell_shim: <<~MESSAGE,
362
- {{x}} This version of Shopify App CLI is no longer supported. You’ll need to migrate to the new CLI version to continue.
445
+ new_version: <<~MESSAGE,
446
+ {{*}} {{yellow:A new version of Shopify CLI is available! You have version %s and the latest version is %s.
363
447
 
364
- Please visit this page for complete instructions:
365
- {{underline:https://shopify.dev/tools/cli/troubleshooting#migrate-from-a-legacy-version}}
448
+ To upgrade, follow the instructions for the package manager you’re using:
449
+ {{underline:https://shopify.dev/tools/cli/troubleshooting#upgrade-shopify-cli}}}}
366
450
 
367
451
  MESSAGE
452
+ },
368
453
 
369
- new_version: <<~MESSAGE,
370
- {{*}} {{yellow:A new version of Shopify App CLI is available! You have version %s and the latest version is %s.
371
-
372
- To upgrade, follow the instructions for the package manager you’re using:
373
- {{underline:https://shopify.dev/tools/cli/troubleshooting#upgrade-shopify-app-cli}}}}
454
+ whoami: {
455
+ help: <<~HELP,
456
+ Identifies which partner organization or store you are currently logged into.
457
+ Usage: {{command:%s whoami}}
458
+ HELP
459
+ not_logged_in: <<~MESSAGE,
460
+ It doesn't appear that you're logged in. You must log into a partner organization or a store staff account.
374
461
 
462
+ If trying to log into a store staff account, please use {{command:%s login --store=STORE}} to log in.
463
+ MESSAGE
464
+ logged_in_shop_only: <<~MESSAGE,
465
+ Logged into store {{green:%s}} as staff (no partner organizations available for this login)
375
466
  MESSAGE
467
+ logged_in_partner_only: "Logged into partner organization {{green:%s}}",
468
+ logged_in_partner_and_shop: "Logged into store {{green:%s}} in partner organization {{green:%s}}",
376
469
  },
377
470
  },
378
471
  }.freeze
@@ -45,9 +45,18 @@ module ShopifyCli
45
45
  # ShopifyCli::PartnersAPI.query(@ctx, 'all_organizations')
46
46
  #
47
47
  def query(ctx, query_name, **variables)
48
- authenticated_req(ctx) do
48
+ CLI::Kit::Util.begin do
49
49
  api_client(ctx).query(query_name, variables: variables)
50
+ end.retry_after(API::APIRequestUnauthorizedError, retries: 1) do
51
+ ShopifyCli::IdentityAuth.new(ctx: ctx).reauthenticate
50
52
  end
53
+ rescue API::APIRequestUnauthorizedError => e
54
+ if (request_info = auth_failure_info(ctx, e))
55
+ ctx.puts(ctx.message("core.api.error.failed_auth_debugging", request_info))
56
+ end
57
+ ctx.abort(ctx.message("core.api.error.failed_auth"))
58
+ rescue API::APIRequestNotFoundError
59
+ ctx.puts(ctx.message("core.partners_api.error.account_not_found", ShopifyCli::TOOL_NAME))
51
60
  end
52
61
 
53
62
  def partners_url_for(organization_id, api_client_id, local_debug)
@@ -59,18 +68,6 @@ module ShopifyCli
59
68
 
60
69
  private
61
70
 
62
- def authenticated_req(ctx, &block)
63
- CLI::Kit::Util
64
- .begin(&block)
65
- .retry_after(API::APIRequestUnauthorizedError, retries: 1) do
66
- authenticate(ctx)
67
- end
68
- rescue API::APIRequestUnauthorizedError
69
- ctx.abort(ctx.message("core.api.error.failed_auth"))
70
- rescue API::APIRequestNotFoundError
71
- ctx.puts(ctx.message("core.partners_api.error.account_not_found", ShopifyCli::TOOL_NAME))
72
- end
73
-
74
71
  def api_client(ctx)
75
72
  new(
76
73
  ctx: ctx,
@@ -80,37 +77,12 @@ module ShopifyCli
80
77
  end
81
78
 
82
79
  def access_token(ctx)
83
- ShopifyCli::DB.get(:identity_exchange_token) do
84
- authenticate(ctx)
85
- ShopifyCli::DB.get(:identity_exchange_token)
80
+ ShopifyCli::DB.get(:partners_exchange_token) do
81
+ IdentityAuth.new(ctx: ctx).authenticate
82
+ ShopifyCli::DB.get(:partners_exchange_token)
86
83
  end
87
84
  end
88
85
 
89
- def authenticate(ctx)
90
- OAuth.new(
91
- ctx: ctx,
92
- service: "identity",
93
- client_id: cli_id,
94
- scopes: scopes.join(" "),
95
- request_exchange: partners_id,
96
- ).authenticate("#{auth_endpoint}/oauth")
97
- end
98
-
99
- def partners_id
100
- return "271e16d403dfa18082ffb3d197bd2b5f4479c3fc32736d69296829cbb28d41a6" if ENV[LOCAL_DEBUG].nil?
101
- "df89d73339ac3c6c5f0a98d9ca93260763e384d51d6038da129889c308973978"
102
- end
103
-
104
- def cli_id
105
- return "fbdb2649-e327-4907-8f67-908d24cfd7e3" if ENV[LOCAL_DEBUG].nil?
106
- "e5380e02-312a-7408-5718-e07017e9cf52"
107
- end
108
-
109
- def auth_endpoint
110
- return "https://accounts.shopify.com" if ENV[LOCAL_DEBUG].nil?
111
- "https://identity.myshopify.io"
112
- end
113
-
114
86
  def endpoint
115
87
  return "https://partners.shopify.com" if ENV[LOCAL_DEBUG].nil?
116
88
  "https://partners.myshopify.io/"
@@ -125,10 +97,15 @@ module ShopifyCli
125
97
  "https://#{domain}"
126
98
  end
127
99
 
128
- def scopes
129
- %w[openid https://api.shopify.com/auth/partners.app.cli.access].tap do |result|
130
- result << "employee" if ShopifyCli::Shopifolk.acting_as_shopify_organization?
100
+ def auth_failure_info(ctx, error)
101
+ if error.response
102
+ headers = %w(www-authenticate x-request-id)
103
+ request_info = headers.map { |h| "#{h}: #{error.response[h]}" if error.response.key?(h) }.join("\n")
104
+ ctx.debug("Full headers: #{error.response.each_header.to_h}")
105
+ request_info
131
106
  end
107
+ rescue => e
108
+ ctx.debug("Couldn't fetch auth failure information from #{error}: #{e}")
132
109
  end
133
110
  end
134
111