shopify-cli 1.7.1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +13 -13
- data/lib/docgen/markdown.rb +1 -1
- data/lib/graphql/fetch_specifications.graphql +14 -0
- data/lib/project_types/extension/cli.rb +0 -10
- data/lib/project_types/extension/commands/create.rb +2 -2
- data/lib/project_types/extension/commands/extension_command.rb +6 -2
- data/lib/project_types/extension/commands/register.rb +2 -2
- data/lib/project_types/extension/commands/serve.rb +9 -1
- data/lib/project_types/extension/extension_project.rb +4 -0
- data/lib/project_types/extension/forms/questions/ask_type.rb +16 -5
- data/lib/project_types/extension/messages/messages.rb +4 -2
- data/lib/project_types/extension/models/specification.rb +4 -2
- data/lib/project_types/extension/models/specification_handlers/default.rb +1 -1
- data/lib/project_types/extension/models/specifications.rb +12 -1
- data/lib/project_types/extension/tasks/configure_features.rb +1 -1
- data/lib/project_types/extension/tasks/fetch_specifications.rb +8 -28
- data/lib/project_types/node/forms/create.rb +10 -1
- data/lib/project_types/node/messages/messages.rb +1 -0
- data/lib/project_types/rails/forms/create.rb +11 -1
- data/lib/project_types/rails/messages/messages.rb +1 -0
- data/lib/project_types/script/config/extension_points.yml +13 -0
- data/lib/project_types/script/layers/application/create_script.rb +10 -6
- data/lib/project_types/script/layers/domain/extension_point.rb +6 -1
- data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +29 -3
- data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +1 -36
- data/lib/project_types/script/layers/infrastructure/errors.rb +0 -9
- data/lib/project_types/script/layers/infrastructure/script_service.rb +4 -4
- data/lib/project_types/script/messages/messages.rb +0 -3
- data/lib/project_types/script/ui/error_handler.rb +0 -11
- data/lib/shopify-cli/tasks/ensure_dev_store.rb +1 -1
- data/lib/shopify-cli/transform_data_structure.rb +1 -1
- data/lib/shopify-cli/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30e766112b0e09d6de0e907ecf7e002377fe8a0ecb6776bf0975ec1677a5858a
|
4
|
+
data.tar.gz: 3fbcc004481a0b06c8ccfcd0fb5890d7ab4bf6ee778a6b4dc43c773508376a05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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 (
|
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.
|
36
|
+
regexp_parser (2.1.1)
|
37
37
|
rexml (3.2.4)
|
38
|
-
rubocop (1.
|
38
|
+
rubocop (1.11.0)
|
39
39
|
parallel (~> 1.10)
|
40
|
-
parser (>=
|
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.
|
44
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
45
45
|
ruby-progressbar (~> 1.7)
|
46
|
-
unicode-display_width (>= 1.4.0, <
|
47
|
-
rubocop-ast (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 (
|
52
|
-
rubocop (~> 1.
|
53
|
-
ruby-progressbar (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 (
|
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)
|
data/lib/docgen/markdown.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
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"
|
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&.
|
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
|
@@ -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
|
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
|
-
|
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
|
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}}
|
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! :
|
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
|
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
|
@@ -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) == "
|
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
|
@@ -3,35 +3,15 @@ module Extension
|
|
3
3
|
class FetchSpecifications
|
4
4
|
include ShopifyCli::MethodObject
|
5
5
|
|
6
|
-
|
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
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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|
|
@@ -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|
|
@@ -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,
|
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
|
-
|
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": "
|
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
|
-
|
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
|
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
|
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
|
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
|
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.
|
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.
|
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!("-", "_")
|
data/lib/shopify-cli/version.rb
CHANGED
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.
|
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-
|
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
|