shopify-cli 1.4.1 → 1.8.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 (303) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +2 -2
  3. data/.github/CONTRIBUTING.md +9 -1
  4. data/.github/PULL_REQUEST_TEMPLATE.md +3 -2
  5. data/.github/workflows/release.yml +0 -1
  6. data/.github/workflows/triage.yml +22 -0
  7. data/.rubocop.yml +21 -7
  8. data/.rubocop_todo.yml +2 -15
  9. data/.travis.yml +1 -1
  10. data/CHANGELOG.md +28 -0
  11. data/Gemfile +12 -11
  12. data/Gemfile.lock +17 -14
  13. data/README.md +39 -7
  14. data/RELEASING.md +5 -13
  15. data/Rakefile +32 -28
  16. data/bin/load_shopify.rb +6 -6
  17. data/bin/shopify +2 -2
  18. data/dev.yml +2 -2
  19. data/docs/_config.yml +1 -18
  20. data/docs/app/node/commands/index.md +2 -80
  21. data/docs/app/node/index.md +2 -33
  22. data/docs/app/rails/commands/index.md +2 -78
  23. data/docs/app/rails/index.md +2 -34
  24. data/docs/core/index.md +2 -84
  25. data/docs/getting-started/index.md +2 -25
  26. data/docs/getting-started/install/index.md +1 -118
  27. data/docs/getting-started/migrate/index.md +2 -94
  28. data/docs/getting-started/uninstall/index.md +2 -35
  29. data/docs/getting-started/upgrade/index.md +2 -39
  30. data/docs/help/start-app/index.md +2 -4
  31. data/docs/index.md +2 -24
  32. data/ext/shopify-cli/extconf.rb +7 -7
  33. data/install.sh +1 -1
  34. data/lib/docgen/markdown.rb +12 -12
  35. data/lib/graphql/fetch_specifications.graphql +14 -0
  36. data/lib/{project_types/extension/graphql → graphql}/get_app_by_api_key.graphql +0 -0
  37. data/lib/project_types/extension/cli.rb +54 -47
  38. data/lib/project_types/extension/commands/build.rb +3 -3
  39. data/lib/project_types/extension/commands/create.rb +17 -10
  40. data/lib/project_types/extension/commands/extension_command.rb +12 -5
  41. data/lib/project_types/extension/commands/push.rb +8 -8
  42. data/lib/project_types/extension/commands/register.rb +19 -30
  43. data/lib/project_types/extension/commands/serve.rb +31 -3
  44. data/lib/project_types/extension/commands/tunnel.rb +12 -12
  45. data/lib/project_types/extension/extension_project.rb +8 -4
  46. data/lib/project_types/extension/extension_project_keys.rb +4 -4
  47. data/lib/project_types/extension/features/argo.rb +117 -0
  48. data/lib/project_types/extension/features/argo_config.rb +5 -5
  49. data/lib/project_types/extension/features/argo_dependencies.rb +5 -5
  50. data/lib/project_types/extension/features/argo_setup.rb +2 -2
  51. data/lib/project_types/extension/features/argo_setup_steps.rb +4 -4
  52. data/lib/project_types/extension/forms/create.rb +28 -34
  53. data/lib/project_types/extension/forms/questions/ask_app.rb +53 -0
  54. data/lib/project_types/extension/forms/questions/ask_name.rb +40 -0
  55. data/lib/project_types/extension/forms/questions/ask_type.rb +47 -0
  56. data/lib/project_types/extension/messages/messages.rb +55 -52
  57. data/lib/project_types/extension/models/lazy_specification_handler.rb +12 -0
  58. data/lib/project_types/extension/models/specification.rb +37 -0
  59. data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +19 -0
  60. data/lib/project_types/extension/models/specification_handlers/default.rb +67 -0
  61. data/lib/project_types/extension/models/specifications.rb +88 -0
  62. data/lib/project_types/extension/tasks/configure_features.rb +52 -0
  63. data/lib/project_types/extension/tasks/converters/app_converter.rb +6 -6
  64. data/lib/project_types/extension/tasks/converters/registration_converter.rb +6 -6
  65. data/lib/project_types/extension/tasks/converters/validation_error_converter.rb +4 -4
  66. data/lib/project_types/extension/tasks/converters/version_converter.rb +7 -7
  67. data/lib/project_types/extension/tasks/create_extension.rb +4 -4
  68. data/lib/project_types/extension/tasks/fetch_specifications.rb +18 -0
  69. data/lib/project_types/extension/tasks/get_app.rb +4 -4
  70. data/lib/project_types/extension/tasks/get_apps.rb +3 -3
  71. data/lib/project_types/extension/tasks/update_draft.rb +4 -4
  72. data/lib/project_types/extension/tasks/user_errors.rb +4 -4
  73. data/lib/project_types/node/cli.rb +19 -16
  74. data/lib/project_types/node/commands/connect.rb +15 -0
  75. data/lib/project_types/node/commands/create.rb +44 -41
  76. data/lib/project_types/node/commands/deploy.rb +4 -4
  77. data/lib/project_types/node/commands/deploy/heroku.rb +24 -24
  78. data/lib/project_types/node/commands/generate.rb +9 -18
  79. data/lib/project_types/node/commands/open.rb +2 -2
  80. data/lib/project_types/node/commands/populate.rb +6 -6
  81. data/lib/project_types/node/commands/populate/customer.rb +5 -5
  82. data/lib/project_types/node/commands/populate/draft_order.rb +5 -5
  83. data/lib/project_types/node/commands/populate/product.rb +5 -5
  84. data/lib/project_types/node/commands/serve.rb +9 -9
  85. data/lib/project_types/node/commands/tunnel.rb +7 -7
  86. data/lib/project_types/node/forms/create.rb +17 -8
  87. data/lib/project_types/node/messages/messages.rb +20 -53
  88. data/lib/project_types/rails/cli.rb +21 -18
  89. data/lib/project_types/rails/commands/connect.rb +15 -0
  90. data/lib/project_types/rails/commands/create.rb +58 -57
  91. data/lib/project_types/rails/commands/deploy.rb +4 -4
  92. data/lib/project_types/rails/commands/deploy/heroku.rb +30 -30
  93. data/lib/project_types/rails/commands/generate.rb +7 -7
  94. data/lib/project_types/rails/commands/generate/webhook.rb +6 -6
  95. data/lib/project_types/rails/commands/open.rb +2 -2
  96. data/lib/project_types/rails/commands/populate.rb +6 -6
  97. data/lib/project_types/rails/commands/populate/customer.rb +5 -5
  98. data/lib/project_types/rails/commands/populate/draft_order.rb +5 -5
  99. data/lib/project_types/rails/commands/populate/product.rb +5 -5
  100. data/lib/project_types/rails/commands/serve.rb +11 -11
  101. data/lib/project_types/rails/commands/tunnel.rb +7 -7
  102. data/lib/project_types/rails/forms/create.rb +35 -25
  103. data/lib/project_types/rails/gem.rb +24 -24
  104. data/lib/project_types/rails/messages/messages.rb +13 -9
  105. data/lib/project_types/rails/ruby.rb +2 -2
  106. data/lib/project_types/script/cli.rb +44 -38
  107. data/lib/project_types/script/commands/create.rb +15 -10
  108. data/lib/project_types/script/commands/disable.rb +3 -3
  109. data/lib/project_types/script/commands/enable.rb +19 -9
  110. data/lib/project_types/script/commands/push.rb +10 -17
  111. data/lib/project_types/script/config/extension_points.yml +30 -12
  112. data/lib/project_types/script/errors.rb +22 -0
  113. data/lib/project_types/script/forms/create.rb +29 -5
  114. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +12 -1
  115. data/lib/project_types/script/layers/application/build_script.rb +19 -19
  116. data/lib/project_types/script/layers/application/create_script.rb +45 -12
  117. data/lib/project_types/script/layers/application/disable_script.rb +2 -2
  118. data/lib/project_types/script/layers/application/enable_script.rb +2 -2
  119. data/lib/project_types/script/layers/application/extension_points.rb +24 -0
  120. data/lib/project_types/script/layers/application/project_dependencies.rb +4 -4
  121. data/lib/project_types/script/layers/application/push_script.rb +15 -18
  122. data/lib/project_types/script/layers/domain/config_ui.rb +16 -0
  123. data/lib/project_types/script/layers/domain/errors.rb +23 -0
  124. data/lib/project_types/script/layers/domain/extension_point.rb +67 -7
  125. data/lib/project_types/script/layers/domain/metadata.rb +55 -0
  126. data/lib/project_types/script/layers/domain/push_package.rb +29 -6
  127. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +45 -55
  128. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +41 -45
  129. data/lib/project_types/script/layers/infrastructure/config_ui_repository.rb +46 -0
  130. data/lib/project_types/script/layers/infrastructure/errors.rb +32 -5
  131. data/lib/project_types/script/layers/infrastructure/extension_point_repository.rb +12 -6
  132. data/lib/project_types/script/layers/infrastructure/project_creator.rb +2 -1
  133. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +20 -13
  134. data/lib/project_types/script/layers/infrastructure/rust_project_creator.rb +72 -0
  135. data/lib/project_types/script/layers/infrastructure/rust_task_runner.rb +59 -0
  136. data/lib/project_types/script/layers/infrastructure/script_service.rb +39 -17
  137. data/lib/project_types/script/layers/infrastructure/task_runner.rb +4 -3
  138. data/lib/project_types/script/messages/messages.rb +76 -10
  139. data/lib/project_types/script/script_project.rb +26 -16
  140. data/lib/project_types/script/ui/error_handler.rb +135 -50
  141. data/lib/project_types/script/ui/printing_spinner.rb +1 -1
  142. data/lib/project_types/script/ui/strict_spinner.rb +1 -1
  143. data/lib/project_types/theme/cli.rb +40 -0
  144. data/lib/project_types/theme/commands/connect.rb +54 -0
  145. data/lib/project_types/theme/commands/create.rb +48 -0
  146. data/lib/project_types/theme/commands/deploy.rb +38 -0
  147. data/lib/project_types/theme/commands/generate.rb +20 -0
  148. data/lib/project_types/theme/commands/generate/env.rb +79 -0
  149. data/lib/project_types/theme/commands/push.rb +55 -0
  150. data/lib/project_types/theme/commands/serve.rb +31 -0
  151. data/lib/project_types/theme/forms/connect.rb +34 -0
  152. data/lib/project_types/theme/forms/create.rb +22 -0
  153. data/lib/project_types/theme/messages/messages.rb +147 -0
  154. data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +78 -0
  155. data/lib/project_types/theme/themekit.rb +113 -0
  156. data/lib/rubygems_plugin.rb +3 -3
  157. data/lib/shopify-cli/admin_api.rb +52 -12
  158. data/lib/shopify-cli/admin_api/populate_resource_command.rb +17 -17
  159. data/lib/shopify-cli/admin_api/schema.rb +3 -3
  160. data/lib/shopify-cli/api.rb +36 -31
  161. data/lib/shopify-cli/command.rb +1 -1
  162. data/lib/shopify-cli/commands.rb +9 -9
  163. data/lib/shopify-cli/commands/config.rb +28 -28
  164. data/lib/shopify-cli/commands/connect.rb +35 -18
  165. data/lib/shopify-cli/commands/create.rb +5 -5
  166. data/lib/shopify-cli/commands/help.rb +6 -6
  167. data/lib/shopify-cli/commands/logout.rb +3 -3
  168. data/lib/shopify-cli/commands/system.rb +33 -33
  169. data/lib/shopify-cli/commands/version.rb +2 -2
  170. data/lib/shopify-cli/context.rb +43 -22
  171. data/lib/shopify-cli/core.rb +4 -4
  172. data/lib/shopify-cli/core/entry_point.rb +5 -5
  173. data/lib/shopify-cli/core/executor.rb +1 -1
  174. data/lib/shopify-cli/core/help_resolver.rb +2 -2
  175. data/lib/shopify-cli/core/monorail.rb +17 -16
  176. data/lib/shopify-cli/db.rb +2 -2
  177. data/lib/shopify-cli/feature.rb +1 -3
  178. data/lib/shopify-cli/form.rb +1 -1
  179. data/lib/shopify-cli/git.rb +17 -17
  180. data/lib/shopify-cli/helpers.rb +1 -1
  181. data/lib/shopify-cli/helpers/haikunator.rb +1 -1
  182. data/lib/shopify-cli/heroku.rb +28 -28
  183. data/lib/shopify-cli/http_request.rb +21 -9
  184. data/lib/shopify-cli/js_deps.rb +13 -13
  185. data/lib/shopify-cli/js_system.rb +5 -5
  186. data/lib/shopify-cli/lazy_delegator.rb +55 -0
  187. data/lib/shopify-cli/messages/messages.rb +21 -10
  188. data/lib/shopify-cli/method_object.rb +104 -0
  189. data/lib/shopify-cli/oauth.rb +25 -25
  190. data/lib/shopify-cli/oauth/servlet.rb +9 -9
  191. data/lib/shopify-cli/options.rb +3 -3
  192. data/lib/shopify-cli/packager.rb +24 -24
  193. data/lib/shopify-cli/partners_api.rb +38 -16
  194. data/lib/shopify-cli/partners_api/organizations.rb +10 -10
  195. data/lib/shopify-cli/process_supervision.rb +8 -8
  196. data/lib/shopify-cli/project.rb +27 -23
  197. data/lib/shopify-cli/project_type.rb +21 -5
  198. data/lib/shopify-cli/resolve_constant.rb +25 -0
  199. data/lib/shopify-cli/resources.rb +1 -1
  200. data/lib/shopify-cli/resources/env_file.rb +9 -9
  201. data/lib/shopify-cli/result.rb +432 -0
  202. data/lib/shopify-cli/shopifolk.rb +35 -18
  203. data/lib/shopify-cli/sub_command.rb +1 -1
  204. data/lib/shopify-cli/task.rb +9 -1
  205. data/lib/shopify-cli/tasks.rb +7 -7
  206. data/lib/shopify-cli/tasks/create_api_client.rb +13 -4
  207. data/lib/shopify-cli/tasks/ensure_dev_store.rb +12 -12
  208. data/lib/shopify-cli/tasks/ensure_env.rb +18 -15
  209. data/lib/shopify-cli/tasks/ensure_loopback_url.rb +4 -4
  210. data/lib/shopify-cli/tasks/select_org_and_shop.rb +28 -24
  211. data/lib/shopify-cli/tasks/update_dashboard_urls.rb +10 -10
  212. data/lib/shopify-cli/transform_data_structure.rb +86 -0
  213. data/lib/shopify-cli/tunnel.rb +36 -30
  214. data/lib/shopify-cli/version.rb +1 -1
  215. data/lib/shopify_cli.rb +57 -52
  216. data/shopify-cli.gemspec +6 -6
  217. data/shopify.fish +1 -1
  218. data/shopify.sh +1 -1
  219. data/vendor/deps/cli-kit/REVISION +1 -1
  220. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +2 -2
  221. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +3 -3
  222. data/vendor/deps/cli-ui/REVISION +1 -1
  223. data/vendor/deps/cli-ui/lib/cli/ui.rb +26 -22
  224. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +4 -6
  225. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -3
  226. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_stack.rb +8 -9
  227. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -1
  228. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +1 -0
  229. data/vendor/deps/cli-ui/lib/cli/ui/printer.rb +15 -3
  230. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +4 -11
  231. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -5
  232. data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +10 -10
  233. data/vendor/deps/cli-ui/lib/cli/ui/version.rb +1 -1
  234. data/vendor/deps/cli-ui/lib/cli/ui/wrap.rb +56 -0
  235. data/vendor/deps/webrick/.gitignore +9 -0
  236. data/vendor/deps/webrick/Gemfile +3 -0
  237. data/vendor/deps/webrick/LICENSE.txt +22 -0
  238. data/vendor/deps/webrick/README.md +61 -0
  239. data/vendor/deps/webrick/Rakefile +10 -0
  240. data/vendor/deps/webrick/lib/webrick.rb +232 -0
  241. data/vendor/deps/webrick/lib/webrick/accesslog.rb +157 -0
  242. data/vendor/deps/webrick/lib/webrick/cgi.rb +313 -0
  243. data/vendor/deps/webrick/lib/webrick/compat.rb +36 -0
  244. data/vendor/deps/webrick/lib/webrick/config.rb +158 -0
  245. data/vendor/deps/webrick/lib/webrick/cookie.rb +172 -0
  246. data/vendor/deps/webrick/lib/webrick/htmlutils.rb +30 -0
  247. data/vendor/deps/webrick/lib/webrick/httpauth.rb +96 -0
  248. data/vendor/deps/webrick/lib/webrick/httpauth/authenticator.rb +117 -0
  249. data/vendor/deps/webrick/lib/webrick/httpauth/basicauth.rb +116 -0
  250. data/vendor/deps/webrick/lib/webrick/httpauth/digestauth.rb +395 -0
  251. data/vendor/deps/webrick/lib/webrick/httpauth/htdigest.rb +132 -0
  252. data/vendor/deps/webrick/lib/webrick/httpauth/htgroup.rb +97 -0
  253. data/vendor/deps/webrick/lib/webrick/httpauth/htpasswd.rb +158 -0
  254. data/vendor/deps/webrick/lib/webrick/httpauth/userdb.rb +53 -0
  255. data/vendor/deps/webrick/lib/webrick/httpproxy.rb +354 -0
  256. data/vendor/deps/webrick/lib/webrick/httprequest.rb +636 -0
  257. data/vendor/deps/webrick/lib/webrick/httpresponse.rb +564 -0
  258. data/vendor/deps/webrick/lib/webrick/https.rb +152 -0
  259. data/vendor/deps/webrick/lib/webrick/httpserver.rb +294 -0
  260. data/vendor/deps/webrick/lib/webrick/httpservlet.rb +23 -0
  261. data/vendor/deps/webrick/lib/webrick/httpservlet/abstract.rb +152 -0
  262. data/vendor/deps/webrick/lib/webrick/httpservlet/cgi_runner.rb +47 -0
  263. data/vendor/deps/webrick/lib/webrick/httpservlet/cgihandler.rb +126 -0
  264. data/vendor/deps/webrick/lib/webrick/httpservlet/erbhandler.rb +88 -0
  265. data/vendor/deps/webrick/lib/webrick/httpservlet/filehandler.rb +552 -0
  266. data/vendor/deps/webrick/lib/webrick/httpservlet/prochandler.rb +47 -0
  267. data/vendor/deps/webrick/lib/webrick/httpstatus.rb +194 -0
  268. data/vendor/deps/webrick/lib/webrick/httputils.rb +512 -0
  269. data/vendor/deps/webrick/lib/webrick/httpversion.rb +76 -0
  270. data/vendor/deps/webrick/lib/webrick/log.rb +156 -0
  271. data/vendor/deps/webrick/lib/webrick/server.rb +381 -0
  272. data/vendor/deps/webrick/lib/webrick/ssl.rb +215 -0
  273. data/vendor/deps/webrick/lib/webrick/utils.rb +265 -0
  274. data/vendor/deps/webrick/lib/webrick/version.rb +18 -0
  275. data/vendor/deps/webrick/webrick.gemspec +74 -0
  276. data/vendor/gen/template/bin/update-deps +9 -9
  277. metadata +83 -29
  278. data/docs/Gemfile +0 -5
  279. data/docs/Gemfile.lock +0 -258
  280. data/docs/_data/nav.yml +0 -35
  281. data/docs/_includes/footer.html +0 -15
  282. data/docs/_includes/head.html +0 -19
  283. data/docs/_includes/sidebar_nav.html +0 -22
  284. data/docs/_includes/toc.html +0 -112
  285. data/docs/_layouts/default.html +0 -79
  286. data/docs/css/docs.css +0 -157
  287. data/docs/images/header.png +0 -0
  288. data/docs/installing-ruby.md +0 -28
  289. data/lib/project_types/extension/features/argo/admin.rb +0 -20
  290. data/lib/project_types/extension/features/argo/base.rb +0 -129
  291. data/lib/project_types/extension/features/argo/checkout.rb +0 -20
  292. data/lib/project_types/extension/forms/register.rb +0 -47
  293. data/lib/project_types/extension/models/type.rb +0 -81
  294. data/lib/project_types/extension/models/types/checkout_post_purchase.rb +0 -23
  295. data/lib/project_types/extension/models/types/product_subscription.rb +0 -24
  296. data/lib/project_types/node/commands/generate/billing.rb +0 -39
  297. data/lib/project_types/node/commands/generate/page.rb +0 -59
  298. data/lib/project_types/node/commands/generate/webhook.rb +0 -37
  299. data/lib/project_types/script/layers/domain/script.rb +0 -18
  300. data/lib/project_types/script/layers/infrastructure/assemblyscript_tsconfig.rb +0 -38
  301. data/lib/project_types/script/layers/infrastructure/script_repository.rb +0 -59
  302. data/lib/project_types/script/templates/ts/as-pect.config.js +0 -27
  303. data/lib/project_types/script/templates/ts/as-pect.d.ts +0 -1
@@ -0,0 +1,12 @@
1
+ module Extension
2
+ module Models
3
+ class LazySpecificationHandler < ShopifyCli::LazyDelegator
4
+ attr_reader :identifier
5
+
6
+ def initialize(identifier, &specification_handler_initializer)
7
+ super(&specification_handler_initializer)
8
+ @identifier = identifier
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,37 @@
1
+ module Extension
2
+ module Models
3
+ class Specification
4
+ include SmartProperties
5
+
6
+ module Features
7
+ class Argo
8
+ include SmartProperties
9
+
10
+ property! :surface, converts: :to_str
11
+ property! :renderer_package_name, converts: :to_str
12
+ property! :git_template, converts: :to_str
13
+ end
14
+
15
+ def self.build(feature_set_attributes)
16
+ feature_set_attributes.each_with_object(OpenStruct.new) do |(identifier, feature_attributes), feature_set|
17
+ feature_set[identifier] = ShopifyCli::ResolveConstant
18
+ .call(identifier, namespace: Features)
19
+ .rescue { OpenStruct }
20
+ .then { |c| c.new(**feature_attributes) }
21
+ .unwrap { |error| raise(error) }
22
+ end
23
+ end
24
+ end
25
+
26
+ property! :identifier
27
+ property :name, converts: :to_str
28
+ property :graphql_identifier, converts: :to_str
29
+ property! :features, converts: Features.method(:build), default: -> { [] }
30
+ property! :options, converts: ->(options) { OpenStruct.new(options) }, default: -> { OpenStruct.new }
31
+
32
+ def graphql_identifier
33
+ super || identifier
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ require "base64"
3
+
4
+ module Extension
5
+ module Models
6
+ module SpecificationHandlers
7
+ class CheckoutPostPurchase < Default
8
+ PERMITTED_CONFIG_KEYS = [:metafields]
9
+
10
+ def config(context)
11
+ {
12
+ **Features::ArgoConfig.parse_yaml(context, PERMITTED_CONFIG_KEYS),
13
+ **argo.config(context),
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Models
5
+ module SpecificationHandlers
6
+ class Default
7
+ attr_reader :specification
8
+
9
+ def initialize(specification)
10
+ @specification = specification
11
+ end
12
+
13
+ def identifier
14
+ specification.identifier.to_s.upcase
15
+ end
16
+
17
+ def graphql_identifier
18
+ specification.graphql_identifier.to_s.upcase
19
+ end
20
+
21
+ def name
22
+ message("name") || specification.name
23
+ end
24
+
25
+ def tagline
26
+ message("tagline") || ""
27
+ end
28
+
29
+ def config(context)
30
+ argo.config(context)
31
+ end
32
+
33
+ def create(directory_name, context)
34
+ argo.create(directory_name, identifier, context)
35
+ end
36
+
37
+ def extension_context(_context)
38
+ nil
39
+ end
40
+
41
+ def valid_extension_contexts
42
+ []
43
+ end
44
+
45
+ protected
46
+
47
+ def argo
48
+ Features::Argo.new(
49
+ git_template: specification.features.argo.git_template,
50
+ renderer_package_name: specification.features.argo.renderer_package_name,
51
+ )
52
+ end
53
+
54
+ private
55
+
56
+ def message(key, *params)
57
+ return unless messages.key?(key.to_sym)
58
+ messages[key.to_sym] % params
59
+ end
60
+
61
+ def messages
62
+ @messages ||= Messages::TYPES[identifier.downcase.to_sym] || {}
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,88 @@
1
+ module Extension
2
+ module Models
3
+ class Specifications
4
+ include SmartProperties
5
+
6
+ property! :custom_handler_root,
7
+ accepts: ->(d) { File.directory?(d) },
8
+ default: -> { File.expand_path("lib/project_types/extension/models/specification_handlers", ShopifyCli::ROOT) }
9
+
10
+ property! :custom_handler_namespace,
11
+ accepts: ->(m) { m.respond_to?(:const_get) },
12
+ default: -> { ::Extension::Models::SpecificationHandlers }
13
+
14
+ property! :fetch_specifications,
15
+ accepts: ->(p) { p.respond_to?(:to_proc) }
16
+
17
+ def [](identifier)
18
+ handlers[identifier]
19
+ end
20
+
21
+ def valid?(identifier)
22
+ handlers.key?(identifier)
23
+ end
24
+
25
+ def each(&block)
26
+ handlers.values.each(&block)
27
+ end
28
+
29
+ def none?
30
+ each.none?
31
+ end
32
+
33
+ protected
34
+
35
+ def handlers
36
+ @handlers ||= fetch_specifications_and_build_handlers
37
+ end
38
+
39
+ private
40
+
41
+ def fetch_specifications_and_build_handlers
42
+ ShopifyCli::Result
43
+ .call(&fetch_specifications)
44
+ .map(&ShopifyCli::TransformDataStructure.new(symbolize_keys: true, underscore_keys: true))
45
+ .then(&method(:select_cli_extensions))
46
+ .then(&Tasks::ConfigureFeatures)
47
+ .then(&method(:ensure_legacy_compatibility))
48
+ .then(&method(:build_specifications))
49
+ .then(&method(:require_handler_implementations))
50
+ .then(&method(:instantiate_specification_handlers))
51
+ .unwrap { |err| raise err }
52
+ end
53
+
54
+ def require_handler_implementations(specifications)
55
+ specifications.each do |s|
56
+ implementation_file = File.join(custom_handler_root, "#{s.identifier}.rb")
57
+ require(implementation_file) if File.file?(implementation_file)
58
+ end
59
+ end
60
+
61
+ def instantiate_specification_handlers(specifications)
62
+ specifications.each_with_object({}) do |specification, handlers|
63
+ ShopifyCli::ResolveConstant.call(specification.identifier, namespace: custom_handler_namespace)
64
+ .rescue { |error| error.is_a?(NameError) ? SpecificationHandlers::Default : raise(error) }
65
+ .then { |handler_class| handler_class.new(specification) }
66
+ .unwrap { |error| raise error }
67
+ .yield_self { |handler| handlers[handler.identifier] = handler }
68
+ end
69
+ end
70
+
71
+ def ensure_legacy_compatibility(specification_attribute_sets)
72
+ specification_attribute_sets.each do |attributes|
73
+ next unless attributes.fetch(:identifier) == "subscription_management"
74
+ attributes[:identifier] = "product_subscription"
75
+ attributes[:graphql_identifier] = "SUBSCRIPTION_MANAGEMENT"
76
+ end
77
+ end
78
+
79
+ def build_specifications(specification_attribute_sets)
80
+ specification_attribute_sets.map { |attributes| Models::Specification.new(**attributes) }
81
+ end
82
+
83
+ def select_cli_extensions(specification_attribute_sets)
84
+ specification_attribute_sets.select { |attributes| attributes.dig(:options, :management_experience) == "cli" }
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,52 @@
1
+ module Extension
2
+ module Tasks
3
+ class ConfigureFeatures
4
+ include ShopifyCli::MethodObject
5
+
6
+ class Error < RuntimeError; end
7
+ class UnknownSurfaceArea < Error; end
8
+ class UnspecifiedSurfaceArea < Error; end
9
+
10
+ def call(specification_attribute_sets)
11
+ specification_attribute_sets.each do |attributes|
12
+ argo_configuration = extract_argo_configuration(attributes)
13
+ next if argo_configuration.nil?
14
+ surface_area = extract_surface_area(argo_configuration)
15
+ surface_area_configuration = fetch_surface_area_configuration(surface_area)
16
+ argo_configuration.merge!(surface_area_configuration)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def extract_argo_configuration(attributes)
23
+ attributes.dig(:features, :argo)
24
+ end
25
+
26
+ def extract_surface_area(argo_configuration)
27
+ argo_configuration.fetch(:surface) do
28
+ raise UnspecifiedSurfaceArea, "Argo configuration does not specify surface area"
29
+ end
30
+ end
31
+
32
+ def fetch_surface_area_configuration(surface_area)
33
+ surface_area_configurations.fetch(surface_area.to_sym) do
34
+ raise UnknownSurfaceArea, "Unknown surface area: #{surface_area}"
35
+ end
36
+ end
37
+
38
+ def surface_area_configurations
39
+ {
40
+ admin: {
41
+ git_template: "https://github.com/Shopify/argo-admin-template.git",
42
+ renderer_package_name: "@shopify/argo-admin",
43
+ },
44
+ checkout: {
45
+ git_template: "https://github.com/Shopify/argo-checkout-template.git",
46
+ renderer_package_name: "@shopify/argo-checkout",
47
+ },
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
- require 'shopify_cli'
2
+ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  module Tasks
6
6
  module Converters
7
7
  module AppConverter
8
- API_KEY_FIELD = 'apiKey'
9
- API_SECRET_KEYS_FIELD = 'apiSecretKeys'
10
- API_SECRET_FIELD = 'secret'
11
- TITLE_FIELD = 'title'
12
- ORGANIZATION_NAME_FIELD = 'businessName'
8
+ API_KEY_FIELD = "apiKey"
9
+ API_SECRET_KEYS_FIELD = "apiSecretKeys"
10
+ API_SECRET_FIELD = "secret"
11
+ TITLE_FIELD = "title"
12
+ ORGANIZATION_NAME_FIELD = "businessName"
13
13
 
14
14
  def self.from_hash(hash, organization = {})
15
15
  return nil if hash.nil?
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
- require 'shopify_cli'
2
+ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  module Tasks
6
6
  module Converters
7
7
  module RegistrationConverter
8
- ID_FIELD = 'id'
9
- TYPE_FIELD = 'type'
10
- TITLE_FIELD = 'title'
11
- DRAFT_VERSION_FIELD = 'draftVersion'
8
+ ID_FIELD = "id"
9
+ TYPE_FIELD = "type"
10
+ TITLE_FIELD = "title"
11
+ DRAFT_VERSION_FIELD = "draftVersion"
12
12
 
13
13
  def self.from_hash(context, hash)
14
- context.abort(context.message('tasks.errors.parse_error')) if hash.nil?
14
+ context.abort(context.message("tasks.errors.parse_error")) if hash.nil?
15
15
 
16
16
  Models::Registration.new(
17
17
  id: hash[ID_FIELD].to_i,
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
- require 'shopify_cli'
2
+ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  module Tasks
6
6
  module Converters
7
7
  module ValidationErrorConverter
8
- FIELD_FIELD = 'field'
9
- MESSAGE_FIELD = 'message'
8
+ FIELD_FIELD = "field"
9
+ MESSAGE_FIELD = "message"
10
10
 
11
11
  def self.from_array(context, errors)
12
12
  return [] if errors.nil?
13
- context.abort(context.message('tasks.errors.parse_error')) unless errors.is_a?(Array)
13
+ context.abort(context.message("tasks.errors.parse_error")) unless errors.is_a?(Array)
14
14
 
15
15
  errors.map do |error|
16
16
  Models::ValidationError.new(
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
- require 'shopify_cli'
2
+ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  module Tasks
6
6
  module Converters
7
7
  module VersionConverter
8
- REGISTRATION_ID_FIELD = 'registrationId'
9
- CONTEXT_FIELD = 'context'
10
- LAST_USER_INTERACTION_AT_FIELD = 'lastUserInteractionAt'
11
- LOCATION_FIELD = 'location'
12
- VALIDATION_ERRORS_FIELD = 'validationErrors'
8
+ REGISTRATION_ID_FIELD = "registrationId"
9
+ CONTEXT_FIELD = "context"
10
+ LAST_USER_INTERACTION_AT_FIELD = "lastUserInteractionAt"
11
+ LOCATION_FIELD = "location"
12
+ VALIDATION_ERRORS_FIELD = "validationErrors"
13
13
 
14
14
  def self.from_hash(context, hash)
15
- context.abort(context.message('tasks.errors.parse_error')) if hash.nil?
15
+ context.abort(context.message("tasks.errors.parse_error")) if hash.nil?
16
16
 
17
17
  Models::Version.new(
18
18
  registration_id: hash[REGISTRATION_ID_FIELD].to_i,
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
- require 'shopify_cli'
2
+ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  module Tasks
6
6
  class CreateExtension < ShopifyCli::Task
7
7
  include UserErrors
8
8
 
9
- GRAPHQL_FILE = 'extension_create'
9
+ GRAPHQL_FILE = "extension_create"
10
10
 
11
11
  RESPONSE_FIELD = %w(data extensionCreate)
12
- REGISTRATION_FIELD = 'extensionRegistration'
12
+ REGISTRATION_FIELD = "extensionRegistration"
13
13
 
14
14
  def call(context:, api_key:, type:, title:, config:, extension_context: nil)
15
15
  input = {
@@ -21,7 +21,7 @@ module Extension
21
21
  }
22
22
 
23
23
  response = ShopifyCli::PartnersAPI.query(context, GRAPHQL_FILE, **input).dig(*RESPONSE_FIELD)
24
- context.abort(context.message('tasks.errors.parse_error')) if response.nil?
24
+ context.abort(context.message("tasks.errors.parse_error")) if response.nil?
25
25
 
26
26
  abort_if_user_errors(context, response)
27
27
  Converters::RegistrationConverter.from_hash(context, response.dig(REGISTRATION_FIELD))
@@ -0,0 +1,18 @@
1
+ module Extension
2
+ module Tasks
3
+ class FetchSpecifications
4
+ include ShopifyCli::MethodObject
5
+
6
+ property :context
7
+ property :api_key
8
+
9
+ def call
10
+ response = ShopifyCli::PartnersAPI
11
+ .query(context, "fetch_specifications", api_key: api_key)
12
+ .dig("data", "extensionSpecifications")
13
+ context.abort(context.message("tasks.errors.parse_error")) if response.nil?
14
+ response
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
- require 'shopify_cli'
2
+ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  module Tasks
6
6
  class GetApp < ShopifyCli::Task
7
- GRAPHQL_FILE = 'get_app_by_api_key'
7
+ GRAPHQL_FILE = "get_app_by_api_key"
8
8
 
9
9
  RESPONSE_FIELD = %w(data)
10
- APP_FIELD = 'app'
10
+ APP_FIELD = "app"
11
11
 
12
12
  def call(context:, api_key:)
13
13
  input = { api_key: api_key }
14
14
 
15
15
  response = ShopifyCli::PartnersAPI.query(context, GRAPHQL_FILE, **input).dig(*RESPONSE_FIELD)
16
- context.abort(context.message('tasks.errors.parse_error')) if response.nil?
16
+ context.abort(context.message("tasks.errors.parse_error")) if response.nil?
17
17
 
18
18
  Converters::AppConverter.from_hash(response.dig(APP_FIELD))
19
19
  end