shopify-cli 1.13.0 → 2.0.2
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 +57 -24
- data/Gemfile +4 -0
- data/Gemfile.lock +32 -0
- data/LICENSE +4 -1
- data/README.md +94 -26
- data/RELEASING.md +31 -7
- data/Rakefile +2 -2
- data/SECURITY.md +1 -1
- data/THEMEKIT_MIGRATION.md +18 -0
- 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/api_versions.graphql +1 -1
- 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 +17 -1
- data/lib/project_types/extension/extension_project_keys.rb +1 -0
- data/lib/project_types/extension/features/argo.rb +6 -6
- data/lib/project_types/extension/features/argo_runtime.rb +22 -56
- 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 +80 -16
- 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 +89 -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 +47 -90
- 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 +72 -119
- data/lib/project_types/script/cli.rb +6 -8
- data/lib/project_types/script/commands/create.rb +3 -1
- data/lib/project_types/script/commands/push.rb +12 -5
- data/lib/project_types/script/graphql/app_script_update_or_create.graphql +9 -3
- data/lib/project_types/script/layers/application/create_script.rb +4 -3
- data/lib/project_types/script/layers/domain/errors.rb +6 -11
- data/lib/project_types/script/layers/domain/push_package.rb +4 -8
- data/lib/project_types/script/layers/domain/script_json.rb +32 -0
- data/lib/project_types/script/layers/domain/script_project.rb +1 -1
- data/lib/project_types/script/layers/infrastructure/errors.rb +13 -17
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +29 -21
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +2 -4
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +45 -34
- data/lib/project_types/script/layers/infrastructure/script_service.rb +37 -16
- data/lib/project_types/script/messages/messages.rb +66 -55
- data/lib/project_types/script/tasks/ensure_env.rb +22 -1
- data/lib/project_types/script/ui/error_handler.rb +32 -32
- data/lib/project_types/theme/cli.rb +16 -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/init.rb +42 -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 +8 -16
- 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 +118 -103
- data/lib/project_types/theme/ui/sync_progress_bar.rb +20 -0
- data/lib/shopify-cli/admin_api.rb +57 -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 +65 -4
- data/lib/shopify-cli/core/entry_point.rb +3 -22
- data/lib/shopify-cli/core/monorail.rb +6 -2
- data/lib/shopify-cli/db.rb +4 -4
- data/lib/shopify-cli/http_request.rb +16 -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 +140 -46
- data/lib/shopify-cli/packager.rb +5 -5
- 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 +332 -0
- data/lib/shopify-cli/theme/theme.rb +204 -0
- data/lib/shopify-cli/tunnel.rb +1 -1
- 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 +91 -35
- data/.github/workflows/release.yml +0 -59
- data/lib/project_types/extension/features/argo_serve_options.rb +0 -41
- 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/script/layers/domain/config_ui.rb +0 -16
- 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
|
@@ -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 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.to_s,
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require "shopify_cli"
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module ShopifyCli
|
|
4
4
|
module Commands
|
|
5
5
|
class Populate
|
|
6
6
|
class Customer < ShopifyCli::AdminAPI::PopulateResourceCommand
|
|
@@ -17,13 +17,7 @@ module Node
|
|
|
17
17
|
def message(data)
|
|
18
18
|
ret = data["customerCreate"]["customer"]
|
|
19
19
|
id = ShopifyCli::API.gid_to_id(ret["id"])
|
|
20
|
-
@ctx.message(
|
|
21
|
-
"node.populate.customer.added",
|
|
22
|
-
ret["displayName"],
|
|
23
|
-
ShopifyCli::Project.current.env.shop,
|
|
24
|
-
admin_url,
|
|
25
|
-
id
|
|
26
|
-
)
|
|
20
|
+
@ctx.message("core.populate.customer.added", ret["displayName"], @shop, admin_url, id)
|
|
27
21
|
end
|
|
28
22
|
end
|
|
29
23
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require "shopify_cli"
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module ShopifyCli
|
|
4
4
|
module Commands
|
|
5
5
|
class Populate
|
|
6
6
|
class DraftOrder < ShopifyCli::AdminAPI::PopulateResourceCommand
|
|
@@ -20,7 +20,7 @@ module Node
|
|
|
20
20
|
def message(data)
|
|
21
21
|
ret = data["draftOrderCreate"]["draftOrder"]
|
|
22
22
|
id = ShopifyCli::API.gid_to_id(ret["id"])
|
|
23
|
-
@ctx.message("
|
|
23
|
+
@ctx.message("core.populate.draft_order.added", @shop, admin_url, id)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require "shopify_cli"
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module ShopifyCli
|
|
4
4
|
module Commands
|
|
5
5
|
class Populate
|
|
6
6
|
class Product < ShopifyCli::AdminAPI::PopulateResourceCommand
|
|
@@ -16,13 +16,7 @@ module Node
|
|
|
16
16
|
def message(data)
|
|
17
17
|
ret = data["productCreate"]["product"]
|
|
18
18
|
id = ShopifyCli::API.gid_to_id(ret["id"])
|
|
19
|
-
@ctx.message(
|
|
20
|
-
"node.populate.product.added",
|
|
21
|
-
ret["title"],
|
|
22
|
-
ShopifyCli::Project.current.env.shop,
|
|
23
|
-
admin_url,
|
|
24
|
-
id
|
|
25
|
-
)
|
|
19
|
+
@ctx.message("core.populate.product.added", ret["title"], @shop, admin_url, id)
|
|
26
20
|
end
|
|
27
21
|
end
|
|
28
22
|
end
|