shopify-cli 1.7.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/Gemfile.lock +13 -13
  4. data/lib/docgen/markdown.rb +1 -1
  5. data/lib/graphql/fetch_specifications.graphql +14 -0
  6. data/lib/project_types/extension/cli.rb +0 -10
  7. data/lib/project_types/extension/commands/create.rb +2 -2
  8. data/lib/project_types/extension/commands/extension_command.rb +6 -2
  9. data/lib/project_types/extension/commands/register.rb +2 -2
  10. data/lib/project_types/extension/commands/serve.rb +9 -1
  11. data/lib/project_types/extension/extension_project.rb +4 -0
  12. data/lib/project_types/extension/forms/questions/ask_type.rb +16 -5
  13. data/lib/project_types/extension/messages/messages.rb +4 -2
  14. data/lib/project_types/extension/models/specification.rb +4 -2
  15. data/lib/project_types/extension/models/specification_handlers/default.rb +1 -1
  16. data/lib/project_types/extension/models/specifications.rb +12 -1
  17. data/lib/project_types/extension/tasks/configure_features.rb +1 -1
  18. data/lib/project_types/extension/tasks/fetch_specifications.rb +8 -28
  19. data/lib/project_types/node/forms/create.rb +10 -1
  20. data/lib/project_types/node/messages/messages.rb +1 -0
  21. data/lib/project_types/rails/forms/create.rb +11 -1
  22. data/lib/project_types/rails/messages/messages.rb +1 -0
  23. data/lib/project_types/script/config/extension_points.yml +13 -0
  24. data/lib/project_types/script/layers/application/create_script.rb +10 -6
  25. data/lib/project_types/script/layers/domain/extension_point.rb +6 -1
  26. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +29 -3
  27. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +1 -36
  28. data/lib/project_types/script/layers/infrastructure/errors.rb +0 -9
  29. data/lib/project_types/script/layers/infrastructure/script_service.rb +4 -4
  30. data/lib/project_types/script/messages/messages.rb +0 -3
  31. data/lib/project_types/script/ui/error_handler.rb +0 -11
  32. data/lib/shopify-cli/tasks/ensure_dev_store.rb +1 -1
  33. data/lib/shopify-cli/transform_data_structure.rb +1 -1
  34. data/lib/shopify-cli/version.rb +1 -1
  35. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 810ed674eed1f0938f1e4fdb55703fe8bcbcf10d13293a27f7e59f28cc39d384
4
- data.tar.gz: 0f7572e8d715e589bbe3cc23d6835e6256063a54b99504f3f6975b5008a0ed24
3
+ metadata.gz: 30e766112b0e09d6de0e907ecf7e002377fe8a0ecb6776bf0975ec1677a5858a
4
+ data.tar.gz: 3fbcc004481a0b06c8ccfcd0fb5890d7ab4bf6ee778a6b4dc43c773508376a05
5
5
  SHA512:
6
- metadata.gz: 7681161d8502e8e728bac04b339b06d84334b1ec0edfc8a58c3f8eb5d4a85ba873c79810c63d30e784508cb9b155c3f39d672e88689b53fc0dd5cff32be865ff
7
- data.tar.gz: ac283b1b16d617b27c2f61dc948e77adead2910f218c0649783884ee6debc6c4135c18dccf35bf73931ded907dadab0ba9c70598238874d941107fa471970041
6
+ metadata.gz: d3b9f2da8984619e58cb73a5a066bd67b7b0e3f050a82f794b36079d3f0850d8c57e4e346e7f6ae0c0ea01601d07e26d54359cced3e132d23246ad88bbed314f
7
+ data.tar.gz: 1ec7d262e39e6b112cf25a35b85788faeb77fce56febdeb46e0f8630608ca19ec0eb032b668302515e23fbfa0831ad25492439cc8cb35e5fb376c6e2277e4596
data/CHANGELOG.md CHANGED
@@ -1,12 +1,18 @@
1
1
  Unreleased
2
2
  ------
3
3
 
4
+ Version 1.8.0
5
+ -------------
6
+
7
+ * [1119](https://github.com/Shopify/shopify-app-cli/pull/1119): Enable guest serialization for scripts
8
+
4
9
  Version 1.7.1
5
10
  ------
6
11
  * Updating internal features in development
7
12
 
8
13
  Version 1.7.0
9
14
  -----
15
+ * [#1109](https://github.com/Shopify/shopify-app-cli/pull/1109): Abort app generation if name contains disallowed text.
10
16
  * [#1075](https://github.com/Shopify/shopify-app-cli/pull/1075): Add support for kebab-case flags
11
17
 
12
18
  Version 1.6.0
data/Gemfile.lock CHANGED
@@ -4,7 +4,7 @@ GEM
4
4
  addressable (2.7.0)
5
5
  public_suffix (>= 2.0.2, < 5.0)
6
6
  ansi (1.5.0)
7
- ast (2.4.1)
7
+ ast (2.4.2)
8
8
  builder (3.2.4)
9
9
  byebug (11.1.3)
10
10
  coderay (1.1.3)
@@ -22,7 +22,7 @@ GEM
22
22
  ruby-progressbar
23
23
  mocha (1.11.2)
24
24
  parallel (1.20.1)
25
- parser (2.7.2.0)
25
+ parser (3.0.0.0)
26
26
  ast (~> 2.4.1)
27
27
  pry (0.13.1)
28
28
  coderay (~> 1.1)
@@ -33,26 +33,26 @@ GEM
33
33
  public_suffix (4.0.6)
34
34
  rainbow (3.0.0)
35
35
  rake (13.0.1)
36
- regexp_parser (1.8.2)
36
+ regexp_parser (2.1.1)
37
37
  rexml (3.2.4)
38
- rubocop (1.4.1)
38
+ rubocop (1.11.0)
39
39
  parallel (~> 1.10)
40
- parser (>= 2.7.1.5)
40
+ parser (>= 3.0.0.0)
41
41
  rainbow (>= 2.2.2, < 4.0)
42
- regexp_parser (>= 1.8)
42
+ regexp_parser (>= 1.8, < 3.0)
43
43
  rexml
44
- rubocop-ast (>= 1.1.1)
44
+ rubocop-ast (>= 1.2.0, < 2.0)
45
45
  ruby-progressbar (~> 1.7)
46
- unicode-display_width (>= 1.4.0, < 2.0)
47
- rubocop-ast (1.1.1)
46
+ unicode-display_width (>= 1.4.0, < 3.0)
47
+ rubocop-ast (1.4.1)
48
48
  parser (>= 2.7.1.5)
49
49
  rubocop-minitest (0.10.1)
50
50
  rubocop (>= 0.87)
51
- rubocop-shopify (1.0.7)
52
- rubocop (~> 1.4)
53
- ruby-progressbar (1.10.1)
51
+ rubocop-shopify (2.0.1)
52
+ rubocop (~> 1.11)
53
+ ruby-progressbar (1.11.0)
54
54
  timecop (0.9.2)
55
- unicode-display_width (1.7.0)
55
+ unicode-display_width (2.0.0)
56
56
  webmock (3.9.3)
57
57
  addressable (>= 2.3.6)
58
58
  crack (>= 0.3.2)
@@ -89,7 +89,7 @@ module RDoc
89
89
  lines.shift if src =~ /\A.*#\ *File/i # remove '# File' comment
90
90
  lines.each do |line|
91
91
  next unless line =~ /^ *(?=\S)/
92
- n = $&.length
92
+ n = Regexp.last_match(0).length
93
93
  indent = n if n < indent
94
94
  break if n == 0
95
95
  end
@@ -0,0 +1,14 @@
1
+ query fetchSpecifications($api_key: String!) {
2
+ extensionSpecifications(apiKey: $api_key) {
3
+ name
4
+ identifier
5
+ options {
6
+ managementExperience
7
+ }
8
+ features {
9
+ argo {
10
+ surface
11
+ }
12
+ }
13
+ }
14
+ }
@@ -81,14 +81,4 @@ module Extension
81
81
 
82
82
  autoload :ExtensionProjectKeys, Project.project_filepath("extension_project_keys")
83
83
  autoload :ExtensionProject, Project.project_filepath("extension_project")
84
-
85
- def self.specifications
86
- @specifications ||= Models::Specifications.new(
87
- fetch_specifications: Tasks::FetchSpecifications
88
- )
89
- end
90
-
91
- def self.specifications=(specifications)
92
- @specifications = specifications
93
- end
94
84
  end
@@ -38,8 +38,8 @@ module Extension
38
38
  Usage: {{command:#{ShopifyCli::TOOL_NAME} create extension}}
39
39
  Options:
40
40
  {{command:--type=TYPE}} The type of extension you would like to create.
41
- {{command:--name=NAME}} The name of your extension (50 characters).”
42
- {{command:--api-key=KEY}} The API key of your app.”
41
+ {{command:--name=NAME}} The name of your extension (50 characters).
42
+ {{command:--api-key=KEY}} The API key of your app.
43
43
  HELP
44
44
  end
45
45
 
@@ -12,11 +12,15 @@ module Extension
12
12
  @extension_type ||= begin
13
13
  identifier = project.extension_type_identifier
14
14
  Models::LazySpecificationHandler.new(identifier) do
15
- unless Extension.specifications.valid?(identifier)
15
+ specifications = Models::Specifications.new(
16
+ fetch_specifications: Tasks::FetchSpecifications.new(api_key: project.app.api_key, context: @ctx)
17
+ )
18
+
19
+ unless specifications.valid?(identifier)
16
20
  @ctx.abort(@ctx.message("errors.unknown_type", project.extension_type_identifier))
17
21
  end
18
22
 
19
- Extension.specifications[identifier]
23
+ specifications[identifier]
20
24
  end
21
25
  end
22
26
  end
@@ -12,7 +12,7 @@ module Extension
12
12
 
13
13
  update_project_files(registration)
14
14
 
15
- @ctx.puts(@ctx.message("register.success", project.title, app.title))
15
+ @ctx.puts(@ctx.message("register.success", project.title))
16
16
  @ctx.puts(@ctx.message("register.success_info"))
17
17
  end
18
18
  end
@@ -28,7 +28,7 @@ module Extension
28
28
 
29
29
  def confirm_registration
30
30
  @ctx.puts(@ctx.message("register.confirm_info", extension_type.name))
31
- CLI::UI::Prompt.confirm(@ctx.message("register.confirm_question", app.title))
31
+ CLI::UI::Prompt.confirm(@ctx.message("register.confirm_question"))
32
32
  end
33
33
 
34
34
  def register_extension
@@ -10,6 +10,7 @@ module Extension
10
10
  if argo_admin?
11
11
  ShopifyCli::Tasks::EnsureEnv.call(@ctx, required: [:api_key, :secret, :shop])
12
12
  ShopifyCli::Tasks::EnsureDevStore.call(@ctx)
13
+ validate_env
13
14
  end
14
15
 
15
16
  CLI::UI::Frame.open(@ctx.message("serve.frame_title")) do
@@ -37,7 +38,14 @@ module Extension
37
38
  def argo_admin?
38
39
  ShopifyCli::Shopifolk.check &&
39
40
  ShopifyCli::Feature.enabled?(:argo_admin_beta) &&
40
- extension_type.specification.features&.argo&.surface_area == "admin"
41
+ extension_type.specification.features&.argo&.surface == "admin"
42
+ end
43
+
44
+ def validate_env
45
+ ExtensionProject.reload
46
+ @ctx.abort(@ctx.message("serve.serve_missing_information")) if
47
+ project.env.shop.nil? || project.env.api_key.nil? ||
48
+ project.env.shop.strip.empty? || project.env.api_key.strip.empty?
41
49
  end
42
50
  end
43
51
  end
@@ -23,6 +23,10 @@ module Extension
23
23
  }.compact
24
24
  ).write(context)
25
25
 
26
+ reload
27
+ end
28
+
29
+ def reload
26
30
  current.reload unless project_empty?
27
31
  end
28
32
 
@@ -11,25 +11,36 @@ module Extension
11
11
  default: -> { CLI::UI::Prompt.method(:ask) }
12
12
 
13
13
  def call(project_details)
14
+ specifications = Models::Specifications.new(
15
+ fetch_specifications: Tasks::FetchSpecifications.new(context: ctx, api_key: project_details.app.api_key)
16
+ )
17
+
14
18
  project_details.tap do |p|
15
- p.type = type.nil? ? choose_type : validate_given_type(type)
19
+ p.type = type.nil? ? choose_type(specifications) : validate_given_type(specifications, type)
16
20
  end
17
21
  end
18
22
 
19
23
  private
20
24
 
21
- def validate_given_type(type)
22
- return Extension.specifications[type] if Extension.specifications.valid?(type)
25
+ def validate_given_type(specifications, type)
26
+ return specifications[type] if specifications.valid?(type)
23
27
  ctx.abort(ctx.message("create.invalid_type")) unless type.nil?
24
28
  end
25
29
 
26
- def choose_type
30
+ def choose_type(specifications)
31
+ abort_due_to_missing_specifications if specifications.none?
32
+
27
33
  prompt.call(ctx.message("create.ask_type")) do |handler|
28
- Extension.specifications.each do |type|
34
+ specifications.each do |type|
29
35
  handler.option("#{type.name} #{type.tagline}") { type }
30
36
  end
31
37
  end
32
38
  end
39
+
40
+ def abort_due_to_missing_specifications
41
+ ctx.puts(@ctx.message("create.no_available_extensions"))
42
+ raise ShopifyCli::AbortSilent
43
+ end
33
44
  end
34
45
  end
35
46
  end
@@ -30,6 +30,7 @@ module Extension
30
30
  learn_about_apps: "{{*}} Learn more about building apps at <https://shopify.dev/concepts/apps>, " \
31
31
  "or try creating a new app using {{command:shopify create}}.",
32
32
  loading_apps: "Loading your apps...",
33
+ no_available_extensions: "{{x}} There are no available extensions for this app.",
33
34
  },
34
35
  build: {
35
36
  frame_title: "Building extension with: %s...",
@@ -40,9 +41,9 @@ module Extension
40
41
  waiting_text: "Registering with Shopify...",
41
42
  already_registered: "Extension is already registered.",
42
43
  confirm_info: "This will create a new extension registration for %s, which can’t be undone.",
43
- confirm_question: "Would you like to register this extension with {{green:%s}}? (y/n)",
44
+ confirm_question: "Would you like to register this extension? (y/n)",
44
45
  confirm_abort: "Extension was not registered.",
45
- success: "{{v}} Registered {{green:%s}} with {{green:%s}}.",
46
+ success: "{{v}} Registered {{green:%s}}.",
46
47
  success_info: "{{*}} Run {{command:shopify push}} to push your extension to Shopify.",
47
48
  },
48
49
  push: {
@@ -56,6 +57,7 @@ module Extension
56
57
  serve: {
57
58
  frame_title: "Serving extension...",
58
59
  serve_failure_message: "Failed to run extension code.",
60
+ serve_missing_information: "Missing shop or api_key.",
59
61
  },
60
62
  tunnel: {
61
63
  missing_token: "{{x}} {{red:auth requires a token argument}}. "\
@@ -7,7 +7,7 @@ module Extension
7
7
  class Argo
8
8
  include SmartProperties
9
9
 
10
- property! :surface_area, converts: :to_str
10
+ property! :surface, converts: :to_str
11
11
  property! :renderer_package_name, converts: :to_str
12
12
  property! :git_template, converts: :to_str
13
13
  end
@@ -18,14 +18,16 @@ module Extension
18
18
  .call(identifier, namespace: Features)
19
19
  .rescue { OpenStruct }
20
20
  .then { |c| c.new(**feature_attributes) }
21
- .unwrap { |error| raise error }
21
+ .unwrap { |error| raise(error) }
22
22
  end
23
23
  end
24
24
  end
25
25
 
26
26
  property! :identifier
27
+ property :name, converts: :to_str
27
28
  property :graphql_identifier, converts: :to_str
28
29
  property! :features, converts: Features.method(:build), default: -> { [] }
30
+ property! :options, converts: ->(options) { OpenStruct.new(options) }, default: -> { OpenStruct.new }
29
31
 
30
32
  def graphql_identifier
31
33
  super || identifier
@@ -19,7 +19,7 @@ module Extension
19
19
  end
20
20
 
21
21
  def name
22
- message("name")
22
+ message("name") || specification.name
23
23
  end
24
24
 
25
25
  def tagline
@@ -26,6 +26,10 @@ module Extension
26
26
  handlers.values.each(&block)
27
27
  end
28
28
 
29
+ def none?
30
+ each.none?
31
+ end
32
+
29
33
  protected
30
34
 
31
35
  def handlers
@@ -37,6 +41,8 @@ module Extension
37
41
  def fetch_specifications_and_build_handlers
38
42
  ShopifyCli::Result
39
43
  .call(&fetch_specifications)
44
+ .map(&ShopifyCli::TransformDataStructure.new(symbolize_keys: true, underscore_keys: true))
45
+ .then(&method(:select_cli_extensions))
40
46
  .then(&Tasks::ConfigureFeatures)
41
47
  .then(&method(:ensure_legacy_compatibility))
42
48
  .then(&method(:build_specifications))
@@ -64,7 +70,8 @@ module Extension
64
70
 
65
71
  def ensure_legacy_compatibility(specification_attribute_sets)
66
72
  specification_attribute_sets.each do |attributes|
67
- next unless attributes.fetch(:identifier) == "product_subscription"
73
+ next unless attributes.fetch(:identifier) == "subscription_management"
74
+ attributes[:identifier] = "product_subscription"
68
75
  attributes[:graphql_identifier] = "SUBSCRIPTION_MANAGEMENT"
69
76
  end
70
77
  end
@@ -72,6 +79,10 @@ module Extension
72
79
  def build_specifications(specification_attribute_sets)
73
80
  specification_attribute_sets.map { |attributes| Models::Specification.new(**attributes) }
74
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
75
86
  end
76
87
  end
77
88
  end
@@ -24,7 +24,7 @@ module Extension
24
24
  end
25
25
 
26
26
  def extract_surface_area(argo_configuration)
27
- argo_configuration.fetch(:surface_area) do
27
+ argo_configuration.fetch(:surface) do
28
28
  raise UnspecifiedSurfaceArea, "Argo configuration does not specify surface area"
29
29
  end
30
30
  end
@@ -3,35 +3,15 @@ module Extension
3
3
  class FetchSpecifications
4
4
  include ShopifyCli::MethodObject
5
5
 
6
- def call
7
- [
8
- product_subscription_specification,
9
- checkout_post_purchase_specification,
10
- ]
11
- end
12
-
13
- private
6
+ property :context
7
+ property :api_key
14
8
 
15
- def product_subscription_specification
16
- {
17
- identifier: "product_subscription",
18
- features: {
19
- argo: {
20
- surface_area: "admin",
21
- },
22
- },
23
- }
24
- end
25
-
26
- def checkout_post_purchase_specification
27
- {
28
- identifier: "checkout_post_purchase",
29
- features: {
30
- argo: {
31
- surface_area: "checkout",
32
- },
33
- },
34
- }
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
35
15
  end
36
16
  end
37
17
  end
@@ -8,8 +8,8 @@ module Node
8
8
 
9
9
  def ask
10
10
  self.title ||= CLI::UI::Prompt.ask(ctx.message("node.forms.create.app_name"))
11
+ self.name = format_name
11
12
  self.type = ask_type
12
- self.name = self.title.downcase.split(" ").join("_")
13
13
  res = ShopifyCli::Tasks::SelectOrgAndShop.call(ctx, organization_id: organization_id, shop_domain: shop_domain)
14
14
  self.organization_id = res[:organization_id]
15
15
  self.shop_domain = res[:shop_domain]
@@ -17,6 +17,15 @@ module Node
17
17
 
18
18
  private
19
19
 
20
+ def format_name
21
+ name = title.downcase.split(" ").join("_")
22
+
23
+ if name.include?("shopify")
24
+ ctx.abort(ctx.message("node.forms.create.error.invalid_app_name"))
25
+ end
26
+ name
27
+ end
28
+
20
29
  def ask_type
21
30
  if type.nil?
22
31
  return CLI::UI::Prompt.ask(ctx.message("node.forms.create.app_type.select")) do |handler|
@@ -202,6 +202,7 @@ module Node
202
202
  forms: {
203
203
  create: {
204
204
  error: {
205
+ invalid_app_name: "App name cannot contain 'Shopify'",
205
206
  invalid_app_type: "Invalid app type %s",
206
207
  },
207
208
  app_name: "App name",
@@ -20,8 +20,8 @@ module Rails
20
20
 
21
21
  def ask
22
22
  self.title ||= CLI::UI::Prompt.ask(ctx.message("rails.forms.create.app_name"))
23
+ self.name = format_name
23
24
  self.type = ask_type
24
- self.name = self.title.downcase.split(" ").join("_")
25
25
  res = ShopifyCli::Tasks::SelectOrgAndShop.call(ctx, organization_id: organization_id, shop_domain: shop_domain)
26
26
  self.organization_id = res[:organization_id]
27
27
  self.shop_domain = res[:shop_domain]
@@ -30,6 +30,16 @@ module Rails
30
30
 
31
31
  private
32
32
 
33
+ def format_name
34
+ name = title.downcase.split(" ").join("_")
35
+
36
+ if name.include?("shopify")
37
+ ctx.abort(ctx.message("rails.forms.create.error.invalid_app_name"))
38
+ end
39
+
40
+ name
41
+ end
42
+
33
43
  def ask_type
34
44
  if type.nil?
35
45
  return CLI::UI::Prompt.ask(ctx.message("rails.forms.create.app_type.select")) do |handler|
@@ -257,6 +257,7 @@ module Rails
257
257
  forms: {
258
258
  create: {
259
259
  error: {
260
+ invalid_app_name: "App name cannot contain 'Shopify'",
260
261
  invalid_app_type: "Invalid app type %s",
261
262
  invalid_db_type: "Invalid database type %s",
262
263
  },
@@ -27,3 +27,16 @@ tax_filter:
27
27
  package: "@shopify/extension-point-as-tax-filter"
28
28
  sdk-version: "^9.0.0"
29
29
  toolchain-version: "^5.0.0"
30
+ payment_methods:
31
+ domain: 'checkout'
32
+ assemblyscript:
33
+ package: "@shopify/scripts-checkout-apis"
34
+ toolchain-version: "^5.0.0"
35
+ sdk-version: "^9.0.0"
36
+ shipping_methods:
37
+ domain: 'checkout'
38
+ assemblyscript:
39
+ package: "@shopify/scripts-checkout-apis"
40
+ sdk-version: "^9.0.0"
41
+ toolchain-version: "^5.0.0"
42
+
@@ -27,11 +27,6 @@ module Script
27
27
  private
28
28
 
29
29
  DEFAULT_CONFIG_UI_FILENAME = "config-ui.yml"
30
- DEFAULT_CONFIG = {
31
- "version" => 1,
32
- "type" => "single",
33
- "fields" => [],
34
- }
35
30
 
36
31
  def setup_project(ctx:, language:, script_name:, extension_point:, description:, no_config_ui:)
37
32
  ScriptProject.create(ctx, script_name)
@@ -48,7 +43,7 @@ module Script
48
43
  identifiers.merge!(config_ui_file: DEFAULT_CONFIG_UI_FILENAME)
49
44
  Infrastructure::ConfigUiRepository
50
45
  .new(ctx: ctx)
51
- .create_config_ui(DEFAULT_CONFIG_UI_FILENAME, YAML.dump(DEFAULT_CONFIG))
46
+ .create_config_ui(DEFAULT_CONFIG_UI_FILENAME, default_config_ui_content(script_name))
52
47
  end
53
48
 
54
49
  ScriptProject.write(
@@ -72,6 +67,15 @@ module Script
72
67
  spinner.update_title(ctx.message("script.create.created"))
73
68
  end
74
69
  end
70
+
71
+ def default_config_ui_content(title)
72
+ YAML.dump({
73
+ "version" => 1,
74
+ "type" => "single",
75
+ "title" => title,
76
+ "fields" => [],
77
+ })
78
+ end
75
79
  end
76
80
  end
77
81
  end
@@ -4,17 +4,22 @@ module Script
4
4
  module Layers
5
5
  module Domain
6
6
  class ExtensionPoint
7
- attr_reader :type, :deprecated, :sdks
7
+ attr_reader :type, :deprecated, :sdks, :domain
8
8
 
9
9
  def initialize(type, config)
10
10
  @type = type
11
11
  @deprecated = config["deprecated"] || false
12
+ @domain = config["domain"] || nil
12
13
  @sdks = ExtensionPointSDKs.new(config)
13
14
  end
14
15
 
15
16
  def deprecated?
16
17
  @deprecated
17
18
  end
19
+
20
+ def dasherize_type
21
+ @type.gsub("_", "-")
22
+ end
18
23
  end
19
24
 
20
25
  class ExtensionPointSDKs
@@ -11,7 +11,10 @@ module Script
11
11
  property! :path_to_project, accepts: String
12
12
 
13
13
  BOOTSTRAP = "npx --no-install shopify-scripts-toolchain-as bootstrap --from %{extension_point} --dest %{base}"
14
+ BUILD = "shopify-scripts-toolchain-as build --src src/shopify_main.ts " \
15
+ "--binary build/%{script_name}.wasm --metadata build/metadata.json"
14
16
  MIN_NODE_VERSION = "14.5.0"
17
+ ASC_ARGS = "-- --lib node_modules --optimize --use Date="
15
18
 
16
19
  def setup_dependencies
17
20
  write_npmrc
@@ -19,8 +22,7 @@ module Script
19
22
  end
20
23
 
21
24
  def bootstrap
22
- type = extension_point.type.gsub("_", "-")
23
- out, status = ctx.capture2e(format(BOOTSTRAP, extension_point: type, base: path_to_project))
25
+ out, status = ctx.capture2e(bootstap_command)
24
26
  raise Domain::Errors::ServiceFailureError, out unless status.success?
25
27
  end
26
28
 
@@ -55,7 +57,7 @@ module Script
55
57
  },
56
58
  "scripts": {
57
59
  "test": "asp --summary --verbose",
58
- "build": "shopify-scripts-toolchain-as build --src src/shopify_main.ts --binary build/#{script_name}.wasm --metadata build/metadata.json -- --lib node_modules --optimize --use Date="
60
+ "build": "#{build_command}"
59
61
  },
60
62
  "engines": {
61
63
  "node": ">=#{MIN_NODE_VERSION}"
@@ -64,6 +66,30 @@ module Script
64
66
  HERE
65
67
  ctx.write("package.json", package_json)
66
68
  end
69
+
70
+ def bootstap_command
71
+ type = extension_point.dasherize_type
72
+ base_command = format(BOOTSTRAP, extension_point: type, base: path_to_project)
73
+ domain = extension_point.domain
74
+
75
+ if domain.nil?
76
+ base_command
77
+ else
78
+ "#{base_command} --domain #{domain}"
79
+ end
80
+ end
81
+
82
+ def build_command
83
+ type = extension_point.dasherize_type
84
+ base_command = format(BUILD, script_name: script_name)
85
+ domain = extension_point.domain
86
+
87
+ if domain.nil?
88
+ "#{base_command} #{ASC_ARGS}"
89
+ else
90
+ "#{base_command} --domain #{domain} --ep #{type} #{ASC_ARGS}"
91
+ end
92
+ end
67
93
  end
68
94
  end
69
95
  end
@@ -33,9 +33,7 @@ module Script
33
33
 
34
34
  def dependencies_installed?
35
35
  # Assuming if node_modules folder exist at root of script folder, all deps are installed
36
- return false unless ctx.dir_exist?("node_modules")
37
- check_if_ep_dependencies_up_to_date!
38
- true
36
+ ctx.dir_exist?("node_modules")
39
37
  end
40
38
 
41
39
  def metadata
@@ -91,39 +89,6 @@ module Script
91
89
 
92
90
  contents
93
91
  end
94
-
95
- def check_if_ep_dependencies_up_to_date!
96
- return true if ENV["SHOPIFY_CLI_SCRIPTS_IGNORE_OUTDATED"]
97
-
98
- # ignore exit code since it will not be 0 unless every package is up to date which they probably won't be
99
- out, _ = ctx.capture2e("npm", "outdated", "--json", "--depth", "0")
100
- parsed_outdated_check = JSON.parse(out)
101
- outdated_ep_packages = parsed_outdated_check
102
- .select { |package_name, _| package_name.start_with?("@shopify/extension-point-as-") }
103
- .select { |_, version_info| !package_is_up_to_date?(version_info) }
104
- .keys
105
- raise Errors::PackagesOutdatedError.new(outdated_ep_packages),
106
- "NPM packages out of date: #{outdated_ep_packages.join(", ")}" unless outdated_ep_packages.empty?
107
- end
108
-
109
- def package_is_up_to_date?(version_info)
110
- require "semantic/semantic"
111
- current_version = version_info["current"]
112
- latest_version = version_info["latest"]
113
-
114
- # making an assumption that the script developer knows what they're doing if they're not referencing a
115
- # semver version
116
- begin
117
- current_version = ::Semantic::Version.new(current_version)
118
- latest_version = ::Semantic::Version.new(latest_version)
119
- rescue ArgumentError
120
- return true
121
- end
122
-
123
- return false if current_version.major < latest_version.major
124
- return false if latest_version.major == 0 && current_version.minor < latest_version.minor
125
- true
126
- end
127
92
  end
128
93
  end
129
94
  end
@@ -60,15 +60,6 @@ module Script
60
60
  class ShopScriptConflictError < ScriptProjectError; end
61
61
  class ShopScriptUndefinedError < ScriptProjectError; end
62
62
  class TaskRunnerNotFoundError < ScriptProjectError; end
63
-
64
- class PackagesOutdatedError < ScriptProjectError
65
- attr_reader :outdated_packages
66
- def initialize(outdated_packages)
67
- super("EP packages are outdated and need to be updated: #{outdated_packages.join(", ")}")
68
- @outdated_packages = outdated_packages
69
- end
70
- end
71
-
72
63
  class BuildScriptNotFoundError < ScriptProjectError; end
73
64
  class InvalidBuildScriptError < ScriptProjectError; end
74
65
 
@@ -26,7 +26,7 @@ module Script
26
26
  extensionPointName: extension_point_type.upcase,
27
27
  title: script_name,
28
28
  description: description,
29
- configUi: config_ui.content,
29
+ configUi: config_ui&.content,
30
30
  sourceCode: Base64.encode64(script_content),
31
31
  language: compiled_type,
32
32
  force: force,
@@ -42,11 +42,11 @@ module Script
42
42
  if user_errors.any? { |e| e["tag"] == "already_exists_error" }
43
43
  raise Errors::ScriptRepushError, api_key
44
44
  elsif (e = user_errors.any? { |err| err["tag"] == "config_ui_syntax_error" })
45
- raise Errors::ConfigUiSyntaxError, config_ui.filename
45
+ raise Errors::ConfigUiSyntaxError, config_ui&.filename
46
46
  elsif (e = user_errors.find { |err| err["tag"] == "config_ui_missing_keys_error" })
47
- raise Errors::ConfigUiMissingKeysError.new(config_ui.filename, e["message"])
47
+ raise Errors::ConfigUiMissingKeysError.new(config_ui&.filename, e["message"])
48
48
  elsif (e = user_errors.find { |err| err["tag"] == "config_ui_fields_missing_keys_error" })
49
- raise Errors::ConfigUiFieldsMissingKeysError.new(config_ui.filename, e["message"])
49
+ raise Errors::ConfigUiFieldsMissingKeysError.new(config_ui&.filename, e["message"])
50
50
  else
51
51
  raise Errors::ScriptServiceUserError.new(query_name, user_errors.to_s)
52
52
  end
@@ -122,9 +122,6 @@ module Script
122
122
 
123
123
  shop_script_undefined_cause: "Script is already turned off in store.",
124
124
 
125
- packages_outdated_cause: "These npm packages are out of date: %s.",
126
- packages_outdated_help: "To update them, run {{cyan:npm install --save-dev %s}}.",
127
-
128
125
  invalid_build_script: "The root package.json contains an invalid build command that " \
129
126
  "is needed to compile your script to WebAssembly.",
130
127
  build_script_not_found: "The root package.json is missing the build command that " \
@@ -220,17 +220,6 @@ module Script
220
220
  {
221
221
  cause_of_error: ShopifyCli::Context.message("script.error.shop_script_undefined_cause"),
222
222
  }
223
- when Layers::Infrastructure::Errors::PackagesOutdatedError
224
- {
225
- cause_of_error: ShopifyCli::Context.message(
226
- "script.error.packages_outdated_cause",
227
- e.outdated_packages.join(", ")
228
- ),
229
- help_suggestion: ShopifyCli::Context.message(
230
- "script.error.packages_outdated_help",
231
- e.outdated_packages.collect { |package| "#{package}@latest" }.join(" ")
232
- ),
233
- }
234
223
  when Layers::Infrastructure::Errors::BuildScriptNotFoundError
235
224
  {
236
225
  cause_of_error: ShopifyCli::Context.message("script.error.build_script_not_found"),
@@ -5,7 +5,7 @@ module ShopifyCli
5
5
  class EnsureDevStore < ShopifyCli::Task
6
6
  def call(ctx)
7
7
  @ctx = ctx
8
- return ctx.puts(ctx.message(
8
+ return ctx.abort(ctx.message(
9
9
  "core.tasks.ensure_dev_store.could_not_verify_store", project.env.shop
10
10
  )) if shop.nil?
11
11
  return if shop["transferDisabled"] == true
@@ -68,7 +68,7 @@ module ShopifyCli
68
68
  def underscore_key(key)
69
69
  return key unless underscore_keys? && key.respond_to?(:to_str)
70
70
 
71
- key.to_str.dup.yield_self do |k|
71
+ key.to_str.dup.tap do |k|
72
72
  k.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
73
73
  k.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
74
74
  k.tr!("-", "_")
@@ -1,3 +1,3 @@
1
1
  module ShopifyCli
2
- VERSION = "1.7.1"
2
+ VERSION = "1.8.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-16 00:00:00.000000000 Z
11
+ date: 2021-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -126,6 +126,7 @@ files:
126
126
  - lib/graphql/create_product.graphql
127
127
  - lib/graphql/extension_create.graphql
128
128
  - lib/graphql/extension_update_draft.graphql
129
+ - lib/graphql/fetch_specifications.graphql
129
130
  - lib/graphql/find_organization.graphql
130
131
  - lib/graphql/get_app_by_api_key.graphql
131
132
  - lib/graphql/get_app_urls.graphql