shopify-cli 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.github/PULL_REQUEST_TEMPLATE.md +1 -0
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +9 -0
  5. data/README.md +39 -7
  6. data/Rakefile +2 -0
  7. data/dev.yml +2 -2
  8. data/docs/_config.yml +1 -18
  9. data/docs/app/node/commands/index.md +2 -80
  10. data/docs/app/node/index.md +2 -33
  11. data/docs/app/rails/commands/index.md +2 -78
  12. data/docs/app/rails/index.md +2 -34
  13. data/docs/core/index.md +2 -84
  14. data/docs/getting-started/index.md +2 -25
  15. data/docs/getting-started/install/index.md +1 -118
  16. data/docs/getting-started/migrate/index.md +2 -94
  17. data/docs/getting-started/uninstall/index.md +2 -35
  18. data/docs/getting-started/upgrade/index.md +2 -39
  19. data/docs/help/start-app/index.md +2 -4
  20. data/docs/index.md +2 -24
  21. data/install.sh +1 -1
  22. data/lib/project_types/extension/cli.rb +19 -10
  23. data/lib/project_types/extension/commands/extension_command.rb +2 -2
  24. data/lib/project_types/extension/features/argo.rb +117 -0
  25. data/lib/project_types/extension/forms/create.rb +2 -2
  26. data/lib/project_types/extension/models/specification.rb +35 -0
  27. data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +19 -0
  28. data/lib/project_types/extension/models/specification_handlers/default.rb +67 -0
  29. data/lib/project_types/extension/models/specifications.rb +77 -0
  30. data/lib/project_types/extension/tasks/configure_features.rb +52 -0
  31. data/lib/project_types/extension/tasks/fetch_specifications.rb +38 -0
  32. data/lib/project_types/node/commands/create.rb +3 -1
  33. data/lib/project_types/node/commands/generate.rb +2 -11
  34. data/lib/project_types/node/messages/messages.rb +9 -44
  35. data/lib/project_types/rails/commands/create.rb +8 -9
  36. data/lib/project_types/rails/forms/create.rb +1 -1
  37. data/lib/project_types/rails/gem.rb +1 -1
  38. data/lib/project_types/rails/messages/messages.rb +1 -1
  39. data/lib/project_types/script/cli.rb +7 -4
  40. data/lib/project_types/script/commands/create.rb +6 -4
  41. data/lib/project_types/script/commands/push.rb +5 -13
  42. data/lib/project_types/script/config/extension_points.yml +9 -5
  43. data/lib/project_types/script/errors.rb +17 -0
  44. data/lib/project_types/script/forms/create.rb +26 -2
  45. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +10 -1
  46. data/lib/project_types/script/layers/application/build_script.rb +9 -4
  47. data/lib/project_types/script/layers/application/create_script.rb +12 -10
  48. data/lib/project_types/script/layers/application/extension_points.rb +24 -0
  49. data/lib/project_types/script/layers/application/push_script.rb +18 -16
  50. data/lib/project_types/script/layers/domain/errors.rb +4 -0
  51. data/lib/project_types/script/layers/domain/extension_point.rb +62 -6
  52. data/lib/project_types/script/layers/domain/metadata.rb +55 -0
  53. data/lib/project_types/script/layers/domain/push_package.rb +25 -6
  54. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +6 -6
  55. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +16 -6
  56. data/lib/project_types/script/layers/infrastructure/extension_point_repository.rb +10 -4
  57. data/lib/project_types/script/layers/infrastructure/project_creator.rb +2 -1
  58. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +25 -13
  59. data/lib/project_types/script/layers/infrastructure/rust_project_creator.rb +72 -0
  60. data/lib/project_types/script/layers/infrastructure/rust_task_runner.rb +59 -0
  61. data/lib/project_types/script/layers/infrastructure/script_service.rb +7 -1
  62. data/lib/project_types/script/layers/infrastructure/task_runner.rb +4 -3
  63. data/lib/project_types/script/messages/messages.rb +39 -8
  64. data/lib/project_types/script/script_project.rb +25 -16
  65. data/lib/project_types/script/ui/error_handler.rb +34 -1
  66. data/lib/project_types/theme/cli.rb +40 -0
  67. data/lib/project_types/theme/commands/connect.rb +54 -0
  68. data/lib/project_types/theme/commands/create.rb +48 -0
  69. data/lib/project_types/theme/commands/deploy.rb +38 -0
  70. data/lib/project_types/theme/commands/generate.rb +20 -0
  71. data/lib/project_types/theme/commands/generate/env.rb +79 -0
  72. data/lib/project_types/theme/commands/push.rb +55 -0
  73. data/lib/project_types/theme/commands/serve.rb +31 -0
  74. data/lib/project_types/theme/forms/connect.rb +34 -0
  75. data/lib/project_types/theme/forms/create.rb +22 -0
  76. data/lib/project_types/theme/messages/messages.rb +147 -0
  77. data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +78 -0
  78. data/lib/project_types/theme/themekit.rb +113 -0
  79. data/lib/shopify-cli/admin_api.rb +42 -2
  80. data/lib/shopify-cli/api.rb +27 -24
  81. data/lib/shopify-cli/commands/system.rb +1 -1
  82. data/lib/shopify-cli/context.rb +23 -2
  83. data/lib/shopify-cli/feature.rb +0 -2
  84. data/lib/shopify-cli/http_request.rb +20 -8
  85. data/lib/shopify-cli/messages/messages.rb +6 -3
  86. data/lib/shopify-cli/method_object.rb +104 -0
  87. data/lib/shopify-cli/partners_api.rb +8 -2
  88. data/lib/shopify-cli/project_type.rb +1 -1
  89. data/lib/shopify-cli/resolve_constant.rb +25 -0
  90. data/lib/shopify-cli/result.rb +432 -0
  91. data/lib/shopify-cli/shopifolk.rb +3 -2
  92. data/lib/shopify-cli/tasks/select_org_and_shop.rb +6 -5
  93. data/lib/shopify-cli/tunnel.rb +7 -1
  94. data/lib/shopify-cli/version.rb +1 -1
  95. data/lib/shopify_cli.rb +4 -1
  96. data/shopify.fish +1 -1
  97. data/shopify.sh +1 -1
  98. data/vendor/deps/cli-kit/REVISION +1 -1
  99. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +2 -2
  100. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +3 -3
  101. data/vendor/deps/cli-ui/REVISION +1 -1
  102. data/vendor/deps/cli-ui/lib/cli/ui.rb +26 -22
  103. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +4 -6
  104. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -3
  105. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_stack.rb +8 -9
  106. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -1
  107. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +1 -0
  108. data/vendor/deps/cli-ui/lib/cli/ui/printer.rb +15 -3
  109. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +4 -11
  110. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -5
  111. data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +10 -10
  112. data/vendor/deps/cli-ui/lib/cli/ui/version.rb +1 -1
  113. data/vendor/deps/cli-ui/lib/cli/ui/wrap.rb +56 -0
  114. data/vendor/deps/webrick/.gitignore +9 -0
  115. data/vendor/deps/webrick/Gemfile +3 -0
  116. data/vendor/deps/webrick/LICENSE.txt +22 -0
  117. data/vendor/deps/webrick/README.md +61 -0
  118. data/vendor/deps/webrick/Rakefile +10 -0
  119. data/vendor/deps/webrick/lib/webrick.rb +232 -0
  120. data/vendor/deps/webrick/lib/webrick/accesslog.rb +157 -0
  121. data/vendor/deps/webrick/lib/webrick/cgi.rb +313 -0
  122. data/vendor/deps/webrick/lib/webrick/compat.rb +36 -0
  123. data/vendor/deps/webrick/lib/webrick/config.rb +158 -0
  124. data/vendor/deps/webrick/lib/webrick/cookie.rb +172 -0
  125. data/vendor/deps/webrick/lib/webrick/htmlutils.rb +30 -0
  126. data/vendor/deps/webrick/lib/webrick/httpauth.rb +96 -0
  127. data/vendor/deps/webrick/lib/webrick/httpauth/authenticator.rb +117 -0
  128. data/vendor/deps/webrick/lib/webrick/httpauth/basicauth.rb +116 -0
  129. data/vendor/deps/webrick/lib/webrick/httpauth/digestauth.rb +395 -0
  130. data/vendor/deps/webrick/lib/webrick/httpauth/htdigest.rb +132 -0
  131. data/vendor/deps/webrick/lib/webrick/httpauth/htgroup.rb +97 -0
  132. data/vendor/deps/webrick/lib/webrick/httpauth/htpasswd.rb +158 -0
  133. data/vendor/deps/webrick/lib/webrick/httpauth/userdb.rb +53 -0
  134. data/vendor/deps/webrick/lib/webrick/httpproxy.rb +354 -0
  135. data/vendor/deps/webrick/lib/webrick/httprequest.rb +636 -0
  136. data/vendor/deps/webrick/lib/webrick/httpresponse.rb +564 -0
  137. data/vendor/deps/webrick/lib/webrick/https.rb +152 -0
  138. data/vendor/deps/webrick/lib/webrick/httpserver.rb +294 -0
  139. data/vendor/deps/webrick/lib/webrick/httpservlet.rb +23 -0
  140. data/vendor/deps/webrick/lib/webrick/httpservlet/abstract.rb +152 -0
  141. data/vendor/deps/webrick/lib/webrick/httpservlet/cgi_runner.rb +47 -0
  142. data/vendor/deps/webrick/lib/webrick/httpservlet/cgihandler.rb +126 -0
  143. data/vendor/deps/webrick/lib/webrick/httpservlet/erbhandler.rb +88 -0
  144. data/vendor/deps/webrick/lib/webrick/httpservlet/filehandler.rb +552 -0
  145. data/vendor/deps/webrick/lib/webrick/httpservlet/prochandler.rb +47 -0
  146. data/vendor/deps/webrick/lib/webrick/httpstatus.rb +194 -0
  147. data/vendor/deps/webrick/lib/webrick/httputils.rb +512 -0
  148. data/vendor/deps/webrick/lib/webrick/httpversion.rb +76 -0
  149. data/vendor/deps/webrick/lib/webrick/log.rb +156 -0
  150. data/vendor/deps/webrick/lib/webrick/server.rb +381 -0
  151. data/vendor/deps/webrick/lib/webrick/ssl.rb +215 -0
  152. data/vendor/deps/webrick/lib/webrick/utils.rb +265 -0
  153. data/vendor/deps/webrick/lib/webrick/version.rb +18 -0
  154. data/vendor/deps/webrick/webrick.gemspec +74 -0
  155. metadata +70 -26
  156. data/docs/Gemfile +0 -5
  157. data/docs/Gemfile.lock +0 -258
  158. data/docs/_data/nav.yml +0 -35
  159. data/docs/_includes/footer.html +0 -15
  160. data/docs/_includes/head.html +0 -19
  161. data/docs/_includes/sidebar_nav.html +0 -22
  162. data/docs/_includes/toc.html +0 -112
  163. data/docs/_layouts/default.html +0 -79
  164. data/docs/css/docs.css +0 -157
  165. data/docs/images/header.png +0 -0
  166. data/docs/installing-ruby.md +0 -28
  167. data/lib/project_types/extension/features/argo/admin.rb +0 -20
  168. data/lib/project_types/extension/features/argo/base.rb +0 -129
  169. data/lib/project_types/extension/features/argo/checkout.rb +0 -20
  170. data/lib/project_types/extension/models/type.rb +0 -81
  171. data/lib/project_types/extension/models/types/checkout_post_purchase.rb +0 -23
  172. data/lib/project_types/extension/models/types/product_subscription.rb +0 -24
  173. data/lib/project_types/node/commands/generate/billing.rb +0 -39
  174. data/lib/project_types/node/commands/generate/page.rb +0 -59
  175. data/lib/project_types/node/commands/generate/webhook.rb +0 -37
  176. data/lib/project_types/script/layers/domain/script.rb +0 -18
  177. data/lib/project_types/script/layers/infrastructure/script_repository.rb +0 -47
  178. data/lib/project_types/script/templates/ts/as-pect.config.js +0 -27
  179. data/lib/project_types/script/templates/ts/as-pect.d.ts +0 -1
@@ -0,0 +1,78 @@
1
+ module Theme
2
+ module Tasks
3
+ class EnsureThemekitInstalled < ShopifyCli::Task
4
+ URL = 'https://shopify-themekit.s3.amazonaws.com/releases/latest.json'
5
+ OSMAP = {
6
+ mac: 'darwin-amd64',
7
+ linux: 'linux-amd64',
8
+ windows: 'windows-amd64',
9
+ }
10
+ VERSION_CHECK_INTERVAL = 604800
11
+ VERSION_CHECK_SECTION = 'themekit_version_check'
12
+ LAST_CHECKED_AT_FIELD = 'last_checked_at'
13
+
14
+ def call(ctx)
15
+ _out, stat = ctx.capture2e(Themekit::THEMEKIT)
16
+ unless stat.success?
17
+ CLI::UI::Frame.open(ctx.message('theme.tasks.ensure_themekit_installed.installing_themekit')) do
18
+ install_themekit(ctx)
19
+ end
20
+ end
21
+
22
+ now = Time.now.to_i
23
+ if ShopifyCli::Feature.enabled?(:themekit_auto_update) && (time_of_last_check + VERSION_CHECK_INTERVAL) < now
24
+ CLI::UI::Frame.open(ctx.message('theme.tasks.ensure_themekit_installed.updating_themekit')) do
25
+ unless Themekit.update(ctx)
26
+ ctx.abort(ctx.message('theme.tasks.ensure_themekit_installed.errors.update_fail'))
27
+ end
28
+ update_time_of_last_check(now)
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def install_themekit(ctx)
36
+ require 'json'
37
+ require 'fileutils'
38
+ require 'digest'
39
+ require 'open-uri'
40
+
41
+ begin
42
+ begin
43
+ releases = JSON.parse(Net::HTTP.get(URI(URL)))
44
+ release = releases["platforms"].find { |r| r["name"] == OSMAP[ctx.os] }
45
+ rescue
46
+ ctx.abort(ctx.message('theme.tasks.ensure_themekit_installed.errors.releases_fail'))
47
+ end
48
+
49
+ ctx.puts(ctx.message('theme.tasks.ensure_themekit_installed.downloading', releases['version']))
50
+ _out, stat = ctx.capture2e('curl', '-o', Themekit::THEMEKIT, release["url"])
51
+ ctx.abort(ctx.message('theme.tasks.ensure_themekit_installed.errors.write_fail')) unless stat.success?
52
+
53
+ ctx.puts(ctx.message('theme.tasks.ensure_themekit_installed.verifying'))
54
+ if Digest::MD5.file(Themekit::THEMEKIT) == release['digest']
55
+ FileUtils.chmod("+x", Themekit::THEMEKIT)
56
+ ctx.puts(ctx.message('theme.tasks.ensure_themekit_installed.successful'))
57
+
58
+ auto = CLI::UI.confirm(ctx.message('theme.tasks.ensure_themekit_installed.auto_update'))
59
+ ShopifyCli::Feature.set(:themekit_auto_update, auto)
60
+ else
61
+ ctx.abort(ctx.message('theme.tasks.ensure_themekit_installed.errors.digest_fail'))
62
+ end
63
+ rescue StandardError, ShopifyCli::Abort => e
64
+ FileUtils.rm(Themekit::THEMEKIT) if File.exist?(Themekit::THEMEKIT)
65
+ raise e
66
+ end
67
+ end
68
+
69
+ def time_of_last_check
70
+ (val = ShopifyCli::Config.get(VERSION_CHECK_SECTION, LAST_CHECKED_AT_FIELD)) ? val.to_i : 0
71
+ end
72
+
73
+ def update_time_of_last_check(time)
74
+ ShopifyCli::Config.set(VERSION_CHECK_SECTION, LAST_CHECKED_AT_FIELD, time)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,113 @@
1
+ module Theme
2
+ class Themekit
3
+ THEMEKIT = File.join(ShopifyCli.cache_dir, "themekit")
4
+
5
+ class << self
6
+ def add_flags(flags)
7
+ flags.map do |key, value|
8
+ flag = "--#{key}"
9
+ flag += "=#{value}" if value.is_a?(String)
10
+ flag
11
+ end
12
+ end
13
+
14
+ def connect(ctx, store:, password:, themeid:, env:)
15
+ command = build_command('get', env)
16
+ command << "--password=#{password}"
17
+ command << "--store=#{store}"
18
+ command << "--themeid=#{themeid}"
19
+
20
+ stat = ctx.system(*command)
21
+ stat.success?
22
+ end
23
+
24
+ def create(ctx, password:, store:, name:, env:)
25
+ command = build_command('new', env)
26
+ command << "--password=#{password}"
27
+ command << "--store=#{store}"
28
+ command << "--name=#{name}"
29
+
30
+ stat = ctx.system(*command)
31
+ stat.success?
32
+ end
33
+
34
+ def deploy(ctx, flags: nil, env:)
35
+ unless push(ctx, flags: flags, env: env)
36
+ ctx.abort(ctx.message('theme.deploy.push_fail'))
37
+ end
38
+ ctx.done(ctx.message('theme.deploy.info.pushed'))
39
+
40
+ command = build_command('publish', env)
41
+ (command << flags).compact!
42
+ command.flatten!
43
+
44
+ stat = ctx.system(*command)
45
+ stat.success?
46
+ end
47
+
48
+ def generate_env(ctx, store:, password:, themeid:, env:)
49
+ command = build_command('configure', env)
50
+ command << "--password=#{password}"
51
+ command << "--store=#{store}"
52
+ command << "--themeid=#{themeid}"
53
+
54
+ stat = ctx.system(*command)
55
+ stat.success?
56
+ end
57
+
58
+ def push(ctx, files: nil, flags: nil, remove: false, env:)
59
+ action = remove ? 'remove' : 'deploy'
60
+ command = build_command(action, env)
61
+
62
+ (command << files << flags).compact!
63
+ command.flatten!
64
+
65
+ stat = ctx.system(*command)
66
+ stat.success?
67
+ end
68
+
69
+ def query_themes(ctx, store:, password:)
70
+ begin
71
+ resp = ::ShopifyCli::AdminAPI.rest_request(
72
+ ctx,
73
+ shop: store,
74
+ token: password,
75
+ path: "themes.json",
76
+ )
77
+ rescue ShopifyCli::API::APIRequestUnauthorizedError
78
+ ctx.abort(ctx.message('theme.themekit.query_themes.bad_password'))
79
+ rescue StandardError
80
+ ctx.abort(ctx.message('theme.themekit.query_themes.not_connect'))
81
+ end
82
+
83
+ resp[1]['themes'].map { |theme| [theme['name'], theme['id']] }.to_h
84
+ end
85
+
86
+ def serve(ctx, flags: nil, env:)
87
+ command = build_command('open', env)
88
+ out, stat = ctx.capture2e(*command)
89
+ ctx.puts(out)
90
+ ctx.abort(ctx.message('theme.serve.open_fail')) unless stat.success?
91
+
92
+ command = build_command('watch', env)
93
+ (command << flags).compact!
94
+ command.flatten!
95
+ ctx.system(*command)
96
+ end
97
+
98
+ def update(ctx)
99
+ command = build_command('update')
100
+ ctx.system(*command)
101
+ end
102
+
103
+ private
104
+
105
+ def build_command(action, env = nil)
106
+ command = [THEMEKIT, action]
107
+ command << '--no-update-notifier'
108
+ command << "--env=#{env}" if env
109
+ command
110
+ end
111
+ end
112
+ end
113
+ end
@@ -43,6 +43,46 @@ module ShopifyCli
43
43
  end
44
44
  end
45
45
 
46
+ ##
47
+ #
48
+ #
49
+ #
50
+ # #### Parameters
51
+ # - `ctx`: running context from your command
52
+ # - `shop`: shop domain string for shop whose admin you are calling
53
+ # - `path`: path string (excluding prefixes and API version) for specific JSON that you are requesting
54
+ # ex. "data.json" instead of "/admin/api/unstable/data.json"
55
+ # - `body`: data string for corresponding REST request types
56
+ # - `method`: REST request string for the type of request; if nil, will perform GET request
57
+ # - `api_version`: API version string to specify version; if nil, latest will be used
58
+ # - `token`: shop password string for authentication to shop
59
+ #
60
+ # #### Raises
61
+ #
62
+ # * http 404 will raise a ShopifyCli::API::APIRequestNotFoundError
63
+ # * http 400..499 will raise a ShopifyCli::API::APIRequestClientError
64
+ # * http 500..599 will raise a ShopifyCli::API::APIRequestServerError
65
+ # * All other codes will raise ShopifyCli::API::APIRequestUnexpectedError
66
+ #
67
+ # #### Returns
68
+ #
69
+ # * `resp` - JSON response array
70
+ #
71
+ # #### Example
72
+ #
73
+ # ShopifyCli::AdminAPI.rest_request(@ctx,
74
+ # shop: 'shop.myshopify.com',
75
+ # path: 'data.json',
76
+ # token: 'password')
77
+ #
78
+ def rest_request(ctx, shop:, path:, body: nil, method: "GET", api_version: nil, token: nil)
79
+ ShopifyCli::DB.set(admin_access_token: token) unless token.nil?
80
+ url = URI::HTTPS.build(host: shop, path: "/admin/api/#{fetch_api_version(ctx, api_version, shop)}/#{path}")
81
+ resp = api_client(ctx, api_version, shop, path: path).request(url: url.to_s, body: body, method: method)
82
+ ShopifyCli::DB.set(admin_access_token: nil) unless token.nil?
83
+ resp
84
+ end
85
+
46
86
  private
47
87
 
48
88
  def authenticated_req(ctx, shop)
@@ -65,12 +105,12 @@ module ShopifyCli
65
105
  ).authenticate("https://#{shop}/admin/oauth")
66
106
  end
67
107
 
68
- def api_client(ctx, api_version, shop)
108
+ def api_client(ctx, api_version, shop, path: 'graphql.json')
69
109
  new(
70
110
  ctx: ctx,
71
111
  auth_header: 'X-Shopify-Access-Token',
72
112
  token: admin_access_token(ctx, shop),
73
- url: "https://#{shop}/admin/api/#{fetch_api_version(ctx, api_version, shop)}/graphql.json",
113
+ url: "https://#{shop}/admin/api/#{fetch_api_version(ctx, api_version, shop)}/#{path}",
74
114
  )
75
115
  end
76
116
 
@@ -24,10 +24,8 @@ module ShopifyCli
24
24
 
25
25
  def query(query_name, variables: {})
26
26
  _, resp = request(
27
- load_query(query_name),
28
- variables: variables,
29
- headers: default_headers,
30
- graphql_url: url,
27
+ body: JSON.dump(query: load_query(query_name).tr("\n", ""), variables: variables),
28
+ url: url,
31
29
  )
32
30
  ctx.debug(resp)
33
31
  resp
@@ -36,32 +34,21 @@ module ShopifyCli
36
34
  ctx.debug(ctx.message('core.api.error.internal_server_error_debug', e.message))
37
35
  end
38
36
 
39
- protected
40
-
41
- def load_query(name)
42
- project_type = ShopifyCli::Project.current_project_type
43
- project_file_path = File.join(
44
- ShopifyCli::ROOT, 'lib', 'project_types', project_type.to_s, 'graphql', "#{name}.graphql"
45
- )
46
- if !project_type.nil? && File.exist?(project_file_path)
47
- File.read(project_file_path)
48
- else
49
- File.read(File.join(ShopifyCli::ROOT, 'lib', 'graphql', "#{name}.graphql"))
50
- end
51
- end
52
-
53
- private
54
-
55
- def request(body, graphql_url:, variables: {}, headers: {})
37
+ def request(url:, body: nil, headers: {}, method: "POST")
56
38
  CLI::Kit::Util.begin do
57
- uri = URI.parse(graphql_url)
39
+ uri = URI.parse(url)
58
40
  unless uri.is_a?(URI::HTTP)
59
- ctx.abort("Invalid URL: #{graphql_url}")
41
+ ctx.abort(ctx.message('core.api.error.invalid_url', url))
60
42
  end
61
43
 
62
44
  # we delay this require so as to avoid a performance hit on starting the CLI
63
45
  require 'shopify-cli/http_request'
64
- response = HttpRequest.call(uri, body, variables, headers)
46
+ headers = default_headers.merge(headers)
47
+ response = if method == "POST"
48
+ HttpRequest.post(uri, body, headers)
49
+ elsif method == "GET"
50
+ HttpRequest.get(uri, body, headers)
51
+ end
65
52
 
66
53
  case response.code.to_i
67
54
  when 200..399
@@ -84,6 +71,22 @@ module ShopifyCli
84
71
  end
85
72
  end
86
73
 
74
+ protected
75
+
76
+ def load_query(name)
77
+ project_type = ShopifyCli::Project.current_project_type
78
+ project_file_path = File.join(
79
+ ShopifyCli::ROOT, 'lib', 'project_types', project_type.to_s, 'graphql', "#{name}.graphql"
80
+ )
81
+ if !project_type.nil? && File.exist?(project_file_path)
82
+ File.read(project_file_path)
83
+ else
84
+ File.read(File.join(ShopifyCli::ROOT, 'lib', 'graphql', "#{name}.graphql"))
85
+ end
86
+ end
87
+
88
+ private
89
+
87
90
  def current_sha
88
91
  @current_sha ||= Git.sha(dir: ShopifyCli::ROOT)
89
92
  end
@@ -84,7 +84,7 @@ module ShopifyCli
84
84
  end
85
85
 
86
86
  def display_ngrok
87
- ngrok_location = File.join(ShopifyCli.cache_dir, @ctx.windows? ? 'ngrok.exe' : 'ngrok')
87
+ ngrok_location = File.join(ShopifyCli.cache_dir, "ngrok#{@ctx.executable_file_extension}")
88
88
  if File.exist?(ngrok_location)
89
89
  @ctx.puts(" " + @ctx.message('core.system.ngrok_available', ngrok_location))
90
90
  else
@@ -329,14 +329,18 @@ module ShopifyCli
329
329
  # - `**kwargs`: additional keyword arguments to pass to Process.spawn
330
330
  #
331
331
  # #### Returns
332
- # - `status`: boolean success status of the command execution
332
+ # - `status`: The `Process::Status` result of the command execution.
333
333
  #
334
334
  # #### Usage
335
335
  #
336
336
  # stat = @ctx.system('ls', 'a_folder')
337
337
  #
338
338
  def system(*args, **kwargs)
339
- CLI::Kit::System.system(*args, env: @env, **kwargs)
339
+ process_status = CLI::Kit::System.system(*args, env: @env, **kwargs)
340
+ unless process_status.success?
341
+ abort("System call failed: #{args.join(' ')}")
342
+ end
343
+ process_status
340
344
  end
341
345
 
342
346
  # Execute a command in the user's environment
@@ -470,6 +474,23 @@ module ShopifyCli
470
474
  end
471
475
  end
472
476
 
477
+ # Returns file extension depending on OS
478
+ # since windows has multiple extensions, the default is .exe unless otherwise specified
479
+ #
480
+ # #### Parameters
481
+ # - ext: optional extension for windows file
482
+ #
483
+ # #### Returns
484
+ # - ext: string for file extension on windows
485
+ # : empty string otherwise
486
+ def executable_file_extension(ext = '.exe')
487
+ if windows?
488
+ ext
489
+ else
490
+ ''
491
+ end
492
+ end
493
+
473
494
  private
474
495
 
475
496
  def ctx_path(fname)
@@ -87,8 +87,6 @@ module ShopifyCli
87
87
  ShopifyCli::Config.get_bool(SECTION, feature.to_s)
88
88
  end
89
89
 
90
- private
91
-
92
90
  def set(feature, value)
93
91
  ShopifyCli::Config.set(SECTION, feature.to_s, value)
94
92
  end
@@ -2,14 +2,26 @@ require 'net/http'
2
2
 
3
3
  module ShopifyCli
4
4
  class HttpRequest
5
- def self.call(uri, body, variables, headers)
6
- http = ::Net::HTTP.new(uri.host, uri.port)
7
- http.use_ssl = true
8
- req = ::Net::HTTP::Post.new(uri.request_uri)
9
- req.body = JSON.dump(query: body.tr("\n", ""), variables: variables)
10
- req['Content-Type'] = 'application/json'
11
- headers.each { |header, value| req[header] = value }
12
- http.request(req)
5
+ class << self
6
+ def post(uri, body, headers)
7
+ req = ::Net::HTTP::Post.new(uri.request_uri)
8
+ request(uri, body, headers, req)
9
+ end
10
+
11
+ def get(uri, body, headers)
12
+ req = ::Net::HTTP::Get.new(uri.request_uri)
13
+ request(uri, body, headers, req)
14
+ end
15
+
16
+ def request(uri, body, headers, req)
17
+ http = ::Net::HTTP.new(uri.host, uri.port)
18
+ http.use_ssl = true
19
+
20
+ req.body = body unless body.nil?
21
+ req['Content-Type'] = 'application/json'
22
+ headers.each { |header, value| req[header] = value }
23
+ http.request(req)
24
+ end
13
25
  end
14
26
  end
15
27
  end
@@ -194,6 +194,7 @@ module ShopifyCli
194
194
  error: {
195
195
  internal_server_error: '{{red:{{x}} An unexpected error occurred on Shopify.}}',
196
196
  internal_server_error_debug: "\n{{red:Response details:}}\n%s\n\n",
197
+ invalid_url: 'Invalid URL: %s',
197
198
  },
198
199
  },
199
200
 
@@ -329,6 +330,8 @@ module ShopifyCli
329
330
  url_fetch_failure: "Unable to fetch external url",
330
331
  prereq_command_required: "%1$s is required for installing ngrok. Please install %1$s using the appropriate"\
331
332
  " package manager for your system.",
333
+ ngrok: "Something went wrong with ngrok installation,"\
334
+ "please make sure %s exists within %s before trying again",
332
335
  },
333
336
 
334
337
  not_running: "{{green:x}} ngrok tunnel not running",
@@ -363,15 +366,15 @@ module ShopifyCli
363
366
  {{x}} This version of Shopify App CLI is no longer supported. You’ll need to migrate to the new CLI version to continue.
364
367
 
365
368
  Please visit this page for complete instructions:
366
- {{underline:https://shopify.github.io/shopify-app-cli/migrate/}}
369
+ {{underline:https://shopify.dev/tools/cli/troubleshooting#migrate-from-a-legacy-version}}
367
370
 
368
371
  MESSAGE
369
372
 
370
373
  new_version: <<~MESSAGE,
371
- {{*}} {{yellow:A new version of the Shopify App CLI is available! You have version %s and the latest version is %s.
374
+ {{*}} {{yellow:A new version of Shopify App CLI is available! You have version %s and the latest version is %s.
372
375
 
373
376
  To upgrade, follow the instructions for the package manager you’re using:
374
- {{underline:https://shopify.github.io/shopify-app-cli/getting-started/upgrade/}}}}
377
+ {{underline:https://shopify.dev/tools/cli/troubleshooting#upgrade-shopify-app-cli}}}}
375
378
 
376
379
  MESSAGE
377
380
  },