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.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -1
- data/.github/CONTRIBUTING.md +7 -7
- data/.github/DESIGN.md +3 -3
- data/.github/workflows/build.yml +1 -1
- data/.gitignore +3 -0
- data/.rubocop.yml +3 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +35 -29
- data/Gemfile +4 -0
- data/Gemfile.lock +32 -0
- data/LICENSE +4 -1
- data/README.md +92 -26
- data/RELEASING.md +29 -7
- data/Rakefile +2 -2
- data/SECURITY.md +1 -1
- data/bin/load_shopify.rb +1 -1
- data/bin/shopify +3 -3
- data/dev.yml +1 -1
- data/docs/app/node/index.md +1 -1
- data/docs/app/rails/index.md +1 -1
- data/docs/core/index.md +1 -1
- data/docs/getting-started/index.md +1 -1
- data/docs/getting-started/install/index.md +1 -1
- data/docs/getting-started/migrate/index.md +1 -1
- data/docs/getting-started/uninstall/index.md +1 -1
- data/docs/getting-started/upgrade/index.md +1 -1
- data/docs/help/start-app/index.md +1 -1
- data/docs/index.md +1 -1
- data/ext/shopify-cli/extconf.rb +17 -5
- data/install.sh +1 -1
- data/lib/docgen/index_template.md.erb +2 -2
- data/lib/graphql/all_orgs_with_extensions.graphql +37 -0
- data/lib/graphql/find_organization.graphql +2 -1
- data/lib/project_types/extension/cli.rb +18 -15
- data/lib/project_types/extension/commands/build.rb +4 -5
- data/lib/project_types/extension/commands/connect.rb +35 -0
- data/lib/project_types/extension/commands/create.rb +12 -16
- data/lib/project_types/extension/commands/extension_command.rb +2 -2
- data/lib/project_types/extension/commands/info.rb +86 -0
- data/lib/project_types/extension/commands/push.rb +8 -7
- data/lib/project_types/extension/commands/register.rb +4 -5
- data/lib/project_types/extension/commands/serve.rb +5 -8
- data/lib/project_types/extension/commands/tunnel.rb +3 -1
- data/lib/project_types/extension/errors.rb +9 -0
- data/lib/project_types/extension/extension_project.rb +5 -0
- data/lib/project_types/extension/features/argo.rb +6 -6
- data/lib/project_types/extension/features/argo_runtime.rb +22 -66
- data/lib/project_types/extension/features/argo_serve.rb +25 -18
- data/lib/project_types/extension/forms/connect.rb +42 -0
- data/lib/project_types/extension/forms/questions/ask_name.rb +14 -6
- data/lib/project_types/extension/forms/questions/ask_registration.rb +51 -0
- data/lib/project_types/extension/messages/messages.rb +75 -11
- data/lib/project_types/extension/models/specification.rb +1 -0
- data/lib/project_types/extension/models/specification_handlers/{checkout_argo_extension.rb → checkout_ui_extension.rb} +3 -1
- data/lib/project_types/extension/models/specification_handlers/default.rb +13 -3
- data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +86 -0
- data/lib/project_types/extension/models/specifications.rb +1 -0
- data/lib/project_types/extension/tasks/configure_features.rb +6 -7
- data/lib/project_types/extension/tasks/configure_options.rb +20 -0
- data/lib/project_types/extension/tasks/get_extensions.rb +32 -0
- data/lib/project_types/node/cli.rb +9 -21
- data/lib/project_types/node/commands/connect.rb +8 -2
- data/lib/project_types/node/commands/create.rb +9 -5
- data/lib/project_types/node/commands/deploy.rb +15 -5
- data/lib/project_types/node/commands/deploy/heroku.rb +29 -29
- data/lib/project_types/node/commands/generate.rb +4 -2
- data/lib/project_types/node/commands/open.rb +4 -2
- data/lib/project_types/node/commands/serve.rb +3 -2
- data/lib/project_types/node/commands/tunnel.rb +4 -2
- data/lib/project_types/node/messages/messages.rb +46 -89
- data/lib/project_types/rails/cli.rb +9 -21
- data/lib/project_types/rails/commands/connect.rb +8 -2
- data/lib/project_types/rails/commands/create.rb +10 -6
- data/lib/project_types/rails/commands/deploy.rb +15 -5
- data/lib/project_types/rails/commands/deploy/heroku.rb +84 -82
- data/lib/project_types/rails/commands/generate.rb +15 -5
- data/lib/project_types/rails/commands/generate/webhook.rb +28 -26
- data/lib/project_types/rails/commands/open.rb +4 -2
- data/lib/project_types/rails/commands/serve.rb +3 -2
- data/lib/project_types/rails/commands/tunnel.rb +4 -2
- data/lib/project_types/rails/messages/messages.rb +54 -101
- data/lib/project_types/script/cli.rb +5 -7
- data/lib/project_types/script/commands/create.rb +3 -1
- data/lib/project_types/script/commands/push.rb +4 -2
- data/lib/project_types/script/messages/messages.rb +52 -45
- data/lib/project_types/script/ui/error_handler.rb +2 -2
- data/lib/project_types/theme/cli.rb +15 -27
- data/lib/project_types/theme/commands/check.rb +33 -0
- data/lib/project_types/theme/commands/delete.rb +64 -0
- data/lib/project_types/theme/commands/language_server.rb +16 -0
- data/lib/project_types/theme/commands/package.rb +55 -0
- data/lib/project_types/theme/commands/publish.rb +43 -0
- data/lib/project_types/theme/commands/pull.rb +51 -0
- data/lib/project_types/theme/commands/push.rb +58 -32
- data/lib/project_types/theme/commands/serve.rb +7 -17
- data/lib/project_types/theme/forms/confirm_store.rb +15 -0
- data/lib/project_types/theme/forms/select.rb +59 -0
- data/lib/project_types/theme/messages/messages.rb +110 -106
- data/lib/project_types/theme/ui/sync_progress_bar.rb +20 -0
- data/lib/shopify-cli/admin_api.rb +53 -38
- data/lib/shopify-cli/admin_api/populate_resource_command.rb +6 -14
- data/lib/shopify-cli/admin_api/schema.rb +1 -10
- data/lib/shopify-cli/api.rb +29 -14
- data/lib/shopify-cli/command.rb +15 -3
- data/lib/shopify-cli/commands.rb +7 -2
- data/lib/shopify-cli/commands/help.rb +2 -29
- data/lib/shopify-cli/commands/login.rb +95 -0
- data/lib/shopify-cli/commands/logout.rb +24 -8
- data/lib/shopify-cli/commands/populate.rb +23 -0
- data/lib/{project_types/node → shopify-cli}/commands/populate/customer.rb +2 -8
- data/lib/{project_types/node → shopify-cli}/commands/populate/draft_order.rb +2 -2
- data/lib/{project_types/node → shopify-cli}/commands/populate/product.rb +2 -8
- data/lib/shopify-cli/commands/store.rb +15 -0
- data/lib/shopify-cli/commands/switch.rb +39 -0
- data/lib/shopify-cli/commands/system.rb +12 -0
- data/lib/shopify-cli/commands/whoami.rb +28 -0
- data/lib/shopify-cli/connect.rb +32 -0
- data/lib/shopify-cli/context.rb +52 -4
- data/lib/shopify-cli/core/entry_point.rb +3 -22
- data/lib/shopify-cli/db.rb +4 -4
- data/lib/shopify-cli/http_request.rb +10 -0
- data/lib/shopify-cli/identity_auth.rb +282 -0
- data/lib/shopify-cli/{oauth → identity_auth}/servlet.rb +11 -12
- data/lib/shopify-cli/messages/messages.rb +132 -39
- data/lib/shopify-cli/partners_api.rb +21 -44
- data/lib/shopify-cli/partners_api/organizations.rb +8 -0
- data/lib/shopify-cli/project_commands.rb +16 -0
- data/lib/shopify-cli/project_type.rb +0 -31
- data/lib/shopify-cli/shopifolk.rb +8 -11
- data/lib/shopify-cli/sub_command.rb +1 -0
- data/lib/shopify-cli/tasks.rb +3 -0
- data/lib/shopify-cli/tasks/confirm_store.rb +18 -0
- data/lib/shopify-cli/tasks/create_api_client.rb +2 -2
- data/lib/shopify-cli/tasks/ensure_authenticated.rb +13 -0
- data/lib/shopify-cli/tasks/ensure_loopback_url.rb +1 -1
- data/lib/shopify-cli/tasks/ensure_project_type.rb +12 -0
- data/lib/shopify-cli/tasks/select_org_and_shop.rb +0 -3
- data/lib/shopify-cli/theme/dev_server.rb +98 -0
- data/lib/shopify-cli/theme/dev_server/certificate_manager.rb +79 -0
- data/lib/shopify-cli/theme/dev_server/header_hash.rb +94 -0
- data/lib/shopify-cli/theme/dev_server/hot-reload.js +93 -0
- data/lib/shopify-cli/theme/dev_server/hot_reload.rb +76 -0
- data/lib/shopify-cli/theme/dev_server/local_assets.rb +87 -0
- data/lib/shopify-cli/theme/dev_server/proxy.rb +205 -0
- data/lib/shopify-cli/theme/dev_server/sse.rb +75 -0
- data/lib/shopify-cli/theme/dev_server/watcher.rb +59 -0
- data/lib/shopify-cli/theme/dev_server/web_server.rb +140 -0
- data/lib/shopify-cli/theme/development_theme.rb +69 -0
- data/lib/shopify-cli/theme/file.rb +112 -0
- data/lib/shopify-cli/theme/ignore_filter.rb +109 -0
- data/lib/shopify-cli/theme/mime_type.rb +34 -0
- data/lib/shopify-cli/theme/syncer.rb +328 -0
- data/lib/shopify-cli/theme/theme.rb +204 -0
- data/lib/shopify-cli/version.rb +1 -1
- data/lib/shopify_cli.rb +18 -11
- data/shopify-cli.gemspec +12 -5
- data/shopify.fish +1 -1
- data/shopify.sh +1 -1
- metadata +88 -34
- data/.github/workflows/release.yml +0 -59
- data/lib/project_types/extension/features/argo_serve_options.rb +0 -42
- data/lib/project_types/node/commands/populate.rb +0 -23
- data/lib/project_types/rails/commands/populate.rb +0 -23
- data/lib/project_types/rails/commands/populate/customer.rb +0 -31
- data/lib/project_types/rails/commands/populate/draft_order.rb +0 -28
- data/lib/project_types/rails/commands/populate/product.rb +0 -30
- data/lib/project_types/theme/commands/connect.rb +0 -54
- data/lib/project_types/theme/commands/create.rb +0 -48
- data/lib/project_types/theme/commands/deploy.rb +0 -38
- data/lib/project_types/theme/commands/generate.rb +0 -20
- data/lib/project_types/theme/commands/generate/env.rb +0 -79
- data/lib/project_types/theme/forms/connect.rb +0 -34
- data/lib/project_types/theme/forms/create.rb +0 -22
- data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +0 -78
- data/lib/project_types/theme/themekit.rb +0 -113
- data/lib/shopify-cli/commands/connect.rb +0 -64
- data/lib/shopify-cli/commands/create.rb +0 -50
- data/lib/shopify-cli/oauth.rb +0 -198
@@ -25,12 +25,11 @@ module ShopifyCli
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def call(args, _)
|
28
|
-
return unless Project.current
|
29
|
-
Tasks::EnsureEnv.call(@ctx)
|
30
28
|
@args = args
|
31
29
|
@input = Hash.new
|
32
30
|
@count = DEFAULT_COUNT
|
33
31
|
@help = false
|
32
|
+
@skip_shop_confirmation = false
|
34
33
|
input_options
|
35
34
|
resource_options.parse(@args)
|
36
35
|
|
@@ -41,8 +40,8 @@ module ShopifyCli
|
|
41
40
|
return @ctx.puts(output)
|
42
41
|
end
|
43
42
|
|
44
|
-
|
45
|
-
|
43
|
+
ShopifyCli::Tasks::ConfirmStore.call(@ctx) unless @skip_shop_confirmation
|
44
|
+
@shop = AdminAPI.get_shop_or_abort(@ctx)
|
46
45
|
if @silent
|
47
46
|
spin_group = CLI::UI::SpinGroup.new
|
48
47
|
spin_group.add(@ctx.message("core.populate.populating", @count, camel_case_resource_type)) do |spinner|
|
@@ -89,7 +88,7 @@ module ShopifyCli
|
|
89
88
|
|
90
89
|
opts.on("--silent") { |v| @silent = v }
|
91
90
|
|
92
|
-
opts.on("--shop
|
91
|
+
opts.on("--skip-shop-confirmation") { |v| @skip_shop_confirmation = v }
|
93
92
|
end
|
94
93
|
end
|
95
94
|
|
@@ -130,7 +129,7 @@ module ShopifyCli
|
|
130
129
|
"core.populate.completion_message",
|
131
130
|
@count,
|
132
131
|
"#{camel_case_resource_type}#{plural}",
|
133
|
-
|
132
|
+
@shop,
|
134
133
|
camel_case_resource_type,
|
135
134
|
admin_url,
|
136
135
|
snake_case_resource_type
|
@@ -138,7 +137,7 @@ module ShopifyCli
|
|
138
137
|
end
|
139
138
|
|
140
139
|
def admin_url
|
141
|
-
"https://#{
|
140
|
+
"https://#{@shop}/admin/"
|
142
141
|
end
|
143
142
|
|
144
143
|
def price
|
@@ -147,13 +146,6 @@ module ShopifyCli
|
|
147
146
|
|
148
147
|
private
|
149
148
|
|
150
|
-
def get_shop(ctx)
|
151
|
-
res = ShopifyCli::Tasks::SelectOrgAndShop.call(ctx)
|
152
|
-
domain = res[:shop_domain]
|
153
|
-
Project.current.env.update(ctx, :shop, domain)
|
154
|
-
domain
|
155
|
-
end
|
156
|
-
|
157
149
|
def camel_case_resource_type
|
158
150
|
@camel_case_resource_type ||= self.class.to_s.split("::").last
|
159
151
|
end
|
@@ -6,7 +6,7 @@ module ShopifyCli
|
|
6
6
|
class << self
|
7
7
|
def get(ctx)
|
8
8
|
unless ShopifyCli::DB.exists?(:shopify_admin_schema)
|
9
|
-
shop =
|
9
|
+
shop = AdminAPI.get_shop_or_abort(ctx)
|
10
10
|
schema = AdminAPI.query(ctx, "admin_introspection", shop: shop)
|
11
11
|
ShopifyCli::DB.set(shopify_admin_schema: JSON.dump(schema))
|
12
12
|
end
|
@@ -15,15 +15,6 @@ module ShopifyCli
|
|
15
15
|
# available
|
16
16
|
self[JSON.parse(ShopifyCli::DB.get(:shopify_admin_schema))]
|
17
17
|
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def get_shop(ctx)
|
22
|
-
res = ShopifyCli::Tasks::SelectOrgAndShop.call(ctx)
|
23
|
-
domain = res[:shop_domain]
|
24
|
-
Project.current.env.update(ctx, :shop, domain)
|
25
|
-
domain
|
26
|
-
end
|
27
18
|
end
|
28
19
|
|
29
20
|
def type(name)
|
data/lib/shopify-cli/api.rb
CHANGED
@@ -9,12 +9,22 @@ module ShopifyCli
|
|
9
9
|
property :auth_header, accepts: String
|
10
10
|
property! :url, accepts: String
|
11
11
|
|
12
|
-
class APIRequestError < StandardError
|
12
|
+
class APIRequestError < StandardError
|
13
|
+
attr_reader :response
|
14
|
+
|
15
|
+
def initialize(message = nil, response: nil)
|
16
|
+
super(message)
|
17
|
+
@response = response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
class APIRequestNotFoundError < APIRequestError; end
|
14
22
|
class APIRequestClientError < APIRequestError; end
|
15
23
|
class APIRequestUnauthorizedError < APIRequestClientError; end
|
24
|
+
class APIRequestForbiddenError < APIRequestClientError; end
|
16
25
|
class APIRequestUnexpectedError < APIRequestError; end
|
17
26
|
class APIRequestRetriableError < APIRequestError; end
|
27
|
+
class APIRequestTimeoutError < APIRequestRetriableError; end
|
18
28
|
class APIRequestServerError < APIRequestRetriableError; end
|
19
29
|
class APIRequestThrottledError < APIRequestRetriableError; end
|
20
30
|
|
@@ -46,26 +56,33 @@ module ShopifyCli
|
|
46
56
|
headers = default_headers.merge(headers)
|
47
57
|
response = if method == "POST"
|
48
58
|
HttpRequest.post(uri, body, headers)
|
59
|
+
elsif method == "PUT"
|
60
|
+
HttpRequest.put(uri, body, headers)
|
49
61
|
elsif method == "GET"
|
50
62
|
HttpRequest.get(uri, body, headers)
|
63
|
+
elsif method == "DELETE"
|
64
|
+
HttpRequest.delete(uri, body, headers)
|
51
65
|
end
|
52
|
-
|
53
66
|
case response.code.to_i
|
54
67
|
when 200..399
|
55
|
-
[response.code.to_i, JSON.parse(response.body)]
|
68
|
+
[response.code.to_i, JSON.parse(response.body), response]
|
56
69
|
when 401
|
57
|
-
raise APIRequestUnauthorizedError
|
70
|
+
raise APIRequestUnauthorizedError.new("#{response.code}\n#{response.body}", response: response)
|
71
|
+
when 403
|
72
|
+
raise APIRequestForbiddenError.new("#{response.code}\n#{response.body}", response: response)
|
58
73
|
when 404
|
59
|
-
raise APIRequestNotFoundError
|
74
|
+
raise APIRequestNotFoundError.new("#{response.code}\n#{response.body}", response: response)
|
60
75
|
when 429
|
61
|
-
raise APIRequestThrottledError
|
76
|
+
raise APIRequestThrottledError.new("#{response.code}\n#{response.body}", response: response)
|
62
77
|
when 400..499
|
63
|
-
raise APIRequestClientError
|
78
|
+
raise APIRequestClientError.new("#{response.code}\n#{response.body}", response: response)
|
64
79
|
when 500..599
|
65
|
-
raise APIRequestServerError
|
80
|
+
raise APIRequestServerError.new("#{response.code}\n#{response.body}", response: response)
|
66
81
|
else
|
67
|
-
raise APIRequestUnexpectedError
|
82
|
+
raise APIRequestUnexpectedError.new("#{response.code}\n#{response.body}", response: response)
|
68
83
|
end
|
84
|
+
rescue Net::OpenTimeout, Net::ReadTimeout, Net::WriteTimeout, Errno::ETIMEDOUT, Timeout::Error
|
85
|
+
raise APIRequestTimeoutError.new("Timeout")
|
69
86
|
end.retry_after(APIRequestRetriableError, retries: 3) do |e|
|
70
87
|
sleep(1) if e.is_a?(APIRequestThrottledError)
|
71
88
|
end
|
@@ -87,13 +104,11 @@ module ShopifyCli
|
|
87
104
|
|
88
105
|
private
|
89
106
|
|
90
|
-
def current_sha
|
91
|
-
@current_sha ||= Git.sha(dir: ShopifyCli::ROOT)
|
92
|
-
end
|
93
|
-
|
94
107
|
def default_headers
|
95
108
|
{
|
96
|
-
"User-Agent" => "Shopify
|
109
|
+
"User-Agent" => "Shopify CLI; v=#{ShopifyCli::VERSION}",
|
110
|
+
"Sec-CH-UA" => "Shopify CLI; v=#{ShopifyCli::VERSION} sha=#{ShopifyCli.sha}",
|
111
|
+
"Sec-CH-UA-PLATFORM" => ctx.os,
|
97
112
|
}.tap do |headers|
|
98
113
|
headers["X-Shopify-Cli-Employee"] = "1" if Shopifolk.acting_as_shopify_organization?
|
99
114
|
end.merge(auth_headers(token))
|
data/lib/shopify-cli/command.rb
CHANGED
@@ -42,13 +42,16 @@ module ShopifyCli
|
|
42
42
|
)
|
43
43
|
end
|
44
44
|
|
45
|
-
def prerequisite_task(*
|
45
|
+
def prerequisite_task(*tasks_without_args, **tasks_with_args)
|
46
46
|
@prerequisite_tasks ||= []
|
47
|
-
@prerequisite_tasks +=
|
47
|
+
@prerequisite_tasks += tasks_without_args.map { |t| PrerequisiteTask.new(t) }
|
48
|
+
@prerequisite_tasks += tasks_with_args.map { |t, args| PrerequisiteTask.new(t, args) }
|
48
49
|
end
|
49
50
|
|
50
51
|
def run_prerequisites
|
51
|
-
(@prerequisite_tasks || []).each
|
52
|
+
(@prerequisite_tasks || []).each do |task|
|
53
|
+
task_registry[task.name]&.call(@ctx, *task.args)
|
54
|
+
end
|
52
55
|
end
|
53
56
|
|
54
57
|
def task_registry
|
@@ -59,6 +62,15 @@ module ShopifyCli
|
|
59
62
|
help = Commands::Help.new(@ctx)
|
60
63
|
help.call(cmds, nil)
|
61
64
|
end
|
65
|
+
|
66
|
+
class PrerequisiteTask
|
67
|
+
attr_reader :name, :args
|
68
|
+
|
69
|
+
def initialize(name, args = [])
|
70
|
+
@name = name
|
71
|
+
@args = args
|
72
|
+
end
|
73
|
+
end
|
62
74
|
end
|
63
75
|
|
64
76
|
def initialize(ctx = nil)
|
data/lib/shopify-cli/commands.rb
CHANGED
@@ -19,11 +19,16 @@ module ShopifyCli
|
|
19
19
|
end
|
20
20
|
|
21
21
|
register :Config, "config", "shopify-cli/commands/config", true
|
22
|
-
register :Connect, "connect", "shopify-cli/commands/connect", true
|
23
|
-
register :Create, "create", "shopify-cli/commands/create", true
|
24
22
|
register :Help, "help", "shopify-cli/commands/help", true
|
23
|
+
register :Login, "login", "shopify-cli/commands/login", true
|
25
24
|
register :Logout, "logout", "shopify-cli/commands/logout", true
|
25
|
+
register :Populate, "populate", "shopify-cli/commands/populate", true
|
26
|
+
register :Store, "store", "shopify-cli/commands/store", true
|
27
|
+
register :Switch, "switch", "shopify-cli/commands/switch", true
|
26
28
|
register :System, "system", "shopify-cli/commands/system", true
|
27
29
|
register :Version, "version", "shopify-cli/commands/version", true
|
30
|
+
register :Whoami, "whoami", "shopify-cli/commands/whoami", true
|
31
|
+
|
32
|
+
autoload :Connect, "shopify-cli/commands/connect"
|
28
33
|
end
|
29
34
|
end
|
@@ -23,17 +23,9 @@ module ShopifyCli
|
|
23
23
|
preamble = @ctx.message("core.help.preamble", ShopifyCli::TOOL_NAME)
|
24
24
|
@ctx.puts(preamble)
|
25
25
|
|
26
|
-
|
27
|
-
next if name == "help"
|
28
|
-
@ctx.puts("{{command:#{name}}}: #{klass.help}\n")
|
29
|
-
end
|
30
|
-
|
31
|
-
return unless inside_supported_project?
|
26
|
+
available_commands = resolved_commands.select { |_name, c| !c.hidden? }
|
32
27
|
|
33
|
-
|
34
|
-
@ctx.puts("{{bold:Available commands for #{project_type_name} projects:}}\n\n")
|
35
|
-
|
36
|
-
local_commands.each do |name, klass|
|
28
|
+
available_commands.each do |name, klass|
|
37
29
|
next if name == "help"
|
38
30
|
@ctx.puts("{{command:#{name}}}: #{klass.help}\n")
|
39
31
|
end
|
@@ -41,21 +33,6 @@ module ShopifyCli
|
|
41
33
|
|
42
34
|
private
|
43
35
|
|
44
|
-
def project_type_name
|
45
|
-
ProjectType.load_type(Project.current_project_type).project_name
|
46
|
-
end
|
47
|
-
|
48
|
-
def core_commands
|
49
|
-
resolved_commands
|
50
|
-
.select { |_name, c| !c.hidden? }
|
51
|
-
.select { |name, _c| Commands.core_command?(name) }
|
52
|
-
end
|
53
|
-
|
54
|
-
def local_commands
|
55
|
-
resolved_commands
|
56
|
-
.reject { |name, _c| Commands.core_command?(name) }
|
57
|
-
end
|
58
|
-
|
59
36
|
def display_help(klass)
|
60
37
|
output = klass.help
|
61
38
|
if klass.respond_to?(:extended_help)
|
@@ -70,10 +47,6 @@ module ShopifyCli
|
|
70
47
|
.resolved_commands
|
71
48
|
.sort
|
72
49
|
end
|
73
|
-
|
74
|
-
def inside_supported_project?
|
75
|
-
Project.current_project_type && ProjectType.load_type(Project.current_project_type)
|
76
|
-
end
|
77
50
|
end
|
78
51
|
end
|
79
52
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "shopify_cli"
|
2
|
+
|
3
|
+
module ShopifyCli
|
4
|
+
module Commands
|
5
|
+
class Login < ShopifyCli::Command
|
6
|
+
PROTOCOL_REGEX = /^https?\:\/\//
|
7
|
+
PERMANENT_DOMAIN_SUFFIX = /\.myshopify\.(com|io)$/
|
8
|
+
|
9
|
+
options do |parser, flags|
|
10
|
+
parser.on("--store=STORE") { |url| flags[:shop] = url }
|
11
|
+
# backwards compatibility allow 'shop' for now
|
12
|
+
parser.on("--shop=SHOP") { |url| flags[:shop] = url }
|
13
|
+
parser.on("--password=PASSWORD") { |password| flags[:password] = password }
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(*)
|
17
|
+
shop = (options.flags[:shop] || @ctx.getenv("SHOPIFY_SHOP" || nil))
|
18
|
+
ShopifyCli::DB.set(shop: self.class.validate_shop(shop)) unless shop.nil?
|
19
|
+
|
20
|
+
if shop.nil? && Shopifolk.check
|
21
|
+
Shopifolk.reset
|
22
|
+
@ctx.puts(@ctx.message("core.tasks.select_org_and_shop.identified_as_shopify"))
|
23
|
+
message = @ctx.message("core.tasks.select_org_and_shop.first_party")
|
24
|
+
if CLI::UI::Prompt.confirm(message, default: false)
|
25
|
+
Shopifolk.act_as_shopify_organization
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# As password auth will soon be deprecated, we enable only in CI
|
30
|
+
if @ctx.ci? && (password = options.flags[:password] || @ctx.getenv("SHOPIFY_PASSWORD"))
|
31
|
+
ShopifyCli::DB.set(shopify_exchange_token: password)
|
32
|
+
else
|
33
|
+
IdentityAuth.new(ctx: @ctx).authenticate
|
34
|
+
org = select_organization
|
35
|
+
ShopifyCli::DB.set(organization_id: org["id"].to_i) unless org.nil?
|
36
|
+
Whoami.call([], "whoami")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.help
|
41
|
+
ShopifyCli::Context.message("core.login.help", ShopifyCli::TOOL_NAME)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.validate_shop(shop)
|
45
|
+
permanent_domain = shop_to_permanent_domain(shop)
|
46
|
+
@ctx.abort(@ctx.message("core.login.invalid_shop", shop)) unless permanent_domain
|
47
|
+
permanent_domain
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.shop_to_permanent_domain(shop)
|
51
|
+
url = if PROTOCOL_REGEX =~ shop
|
52
|
+
shop
|
53
|
+
elsif shop.include?(".")
|
54
|
+
"https://#{shop}"
|
55
|
+
else
|
56
|
+
"https://#{shop}.myshopify.com"
|
57
|
+
end
|
58
|
+
|
59
|
+
# Make a request to see if it exists or if we get redirected to the permanent domain one
|
60
|
+
uri = URI.parse(url)
|
61
|
+
Net::HTTP.start(uri.host, use_ssl: true) do |http|
|
62
|
+
response = http.request_head("/admin")
|
63
|
+
case response
|
64
|
+
when Net::HTTPSuccess, Net::HTTPSeeOther
|
65
|
+
uri.host
|
66
|
+
when Net::HTTPFound
|
67
|
+
domain = URI.parse(response["location"]).host
|
68
|
+
if PERMANENT_DOMAIN_SUFFIX =~ domain
|
69
|
+
domain
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def select_organization
|
78
|
+
organizations = ShopifyCli::PartnersAPI::Organizations.fetch_all(@ctx)
|
79
|
+
|
80
|
+
if organizations.count == 0
|
81
|
+
nil
|
82
|
+
elsif organizations.count == 1
|
83
|
+
organizations.first
|
84
|
+
else
|
85
|
+
org_id = CLI::UI::Prompt.ask(@ctx.message("core.tasks.select_org_and_shop.organization_select")) do |handler|
|
86
|
+
organizations.each do |o|
|
87
|
+
handler.option(@ctx.message("core.partners_api.org_name_and_id", o["businessName"], o["id"])) { o["id"] }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
organizations.find { |o| o["id"] == org_id }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -1,23 +1,39 @@
|
|
1
1
|
require "shopify_cli"
|
2
|
+
require "shopify-cli/theme/development_theme"
|
2
3
|
|
3
4
|
module ShopifyCli
|
4
5
|
module Commands
|
5
6
|
class Logout < ShopifyCli::Command
|
6
|
-
LOGIN_TOKENS = [
|
7
|
-
:identity_access_token, :identity_refresh_token, :identity_exchange_token,
|
8
|
-
:admin_access_token, :admin_refresh_token, :admin_exchange_token
|
9
|
-
]
|
10
|
-
|
11
7
|
def call(*)
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
try_delete_development_theme
|
9
|
+
ShopifyCli::IdentityAuth.delete_tokens_and_keys
|
10
|
+
ShopifyCli::DB.del(:shop) if has_shop?
|
11
|
+
ShopifyCli::DB.del(:organization_id) if has_organization_id?
|
12
|
+
ShopifyCli::Shopifolk.reset
|
15
13
|
@ctx.puts(@ctx.message("core.logout.success"))
|
16
14
|
end
|
17
15
|
|
18
16
|
def self.help
|
19
17
|
ShopifyCli::Context.message("core.logout.help", ShopifyCli::TOOL_NAME)
|
20
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def has_shop?
|
23
|
+
ShopifyCli::DB.exists?(:shop)
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_organization_id?
|
27
|
+
ShopifyCli::DB.exists?(:organization_id)
|
28
|
+
end
|
29
|
+
|
30
|
+
def try_delete_development_theme
|
31
|
+
return unless has_shop?
|
32
|
+
|
33
|
+
ShopifyCli::Theme::DevelopmentTheme.delete(@ctx)
|
34
|
+
rescue ShopifyCli::API::APIRequestError
|
35
|
+
# Ignore since we can't delete it
|
36
|
+
end
|
21
37
|
end
|
22
38
|
end
|
23
39
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "shopify_cli"
|
2
|
+
|
3
|
+
module ShopifyCli
|
4
|
+
module Commands
|
5
|
+
class Populate < ShopifyCli::Command
|
6
|
+
subcommand :Customer, "customers", "shopify-cli/commands/populate/customer"
|
7
|
+
subcommand :DraftOrder, "draftorders", "shopify-cli/commands/populate/draft_order"
|
8
|
+
subcommand :Product, "products", "shopify-cli/commands/populate/product"
|
9
|
+
|
10
|
+
def call(_args, _name)
|
11
|
+
@ctx.puts(self.class.help)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.help
|
15
|
+
ShopifyCli::Context.message("core.populate.help", ShopifyCli::TOOL_NAME)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.extended_help
|
19
|
+
ShopifyCli::Context.message("core.populate.extended_help", ShopifyCli::TOOL_NAME)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|