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.
- 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
|