shopify-cli 1.11.0 → 2.0.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/.github/CODEOWNERS +1 -1
- data/.github/CONTRIBUTING.md +7 -7
- data/.github/DESIGN.md +3 -3
- data/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- data/.github/workflows/build.yml +1 -1
- data/.gitignore +3 -0
- data/.rubocop.yml +3 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +48 -20
- data/Gemfile +4 -0
- data/Gemfile.lock +32 -0
- data/LICENSE +4 -1
- data/README.md +92 -26
- data/RELEASING.md +29 -7
- data/Rakefile +2 -2
- data/SECURITY.md +1 -1
- data/bin/load_shopify.rb +1 -1
- data/bin/shopify +3 -3
- data/dev.yml +1 -1
- data/docs/app/node/index.md +1 -1
- data/docs/app/rails/index.md +1 -1
- data/docs/core/index.md +1 -1
- data/docs/getting-started/index.md +1 -1
- data/docs/getting-started/install/index.md +1 -1
- data/docs/getting-started/migrate/index.md +1 -1
- data/docs/getting-started/uninstall/index.md +1 -1
- data/docs/getting-started/upgrade/index.md +1 -1
- data/docs/help/start-app/index.md +1 -1
- data/docs/index.md +1 -1
- data/ext/shopify-cli/extconf.rb +17 -5
- data/install.sh +1 -1
- data/lib/docgen/index_template.md.erb +2 -2
- data/lib/graphql/all_orgs_with_extensions.graphql +37 -0
- data/lib/graphql/find_organization.graphql +2 -1
- data/lib/project_types/extension/cli.rb +18 -15
- data/lib/project_types/extension/commands/build.rb +4 -5
- data/lib/project_types/extension/commands/connect.rb +35 -0
- data/lib/project_types/extension/commands/create.rb +12 -16
- data/lib/project_types/extension/commands/extension_command.rb +2 -2
- data/lib/project_types/extension/commands/info.rb +86 -0
- data/lib/project_types/extension/commands/push.rb +8 -7
- data/lib/project_types/extension/commands/register.rb +4 -5
- data/lib/project_types/extension/commands/serve.rb +5 -8
- data/lib/project_types/extension/commands/tunnel.rb +3 -1
- data/lib/project_types/extension/errors.rb +9 -0
- data/lib/project_types/extension/extension_project.rb +5 -0
- data/lib/project_types/extension/features/argo.rb +6 -6
- data/lib/project_types/extension/features/argo_runtime.rb +22 -38
- data/lib/project_types/extension/features/argo_serve.rb +25 -20
- data/lib/project_types/extension/forms/connect.rb +42 -0
- data/lib/project_types/extension/forms/questions/ask_name.rb +14 -6
- data/lib/project_types/extension/forms/questions/ask_registration.rb +51 -0
- data/lib/project_types/extension/messages/messages.rb +75 -11
- data/lib/project_types/extension/models/specification.rb +1 -0
- data/lib/project_types/extension/models/specification_handlers/{checkout_argo_extension.rb → checkout_ui_extension.rb} +3 -1
- data/lib/project_types/extension/models/specification_handlers/default.rb +21 -6
- data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +86 -0
- data/lib/project_types/extension/models/specifications.rb +1 -0
- data/lib/project_types/extension/tasks/configure_features.rb +6 -7
- data/lib/project_types/extension/tasks/configure_options.rb +20 -0
- data/lib/project_types/extension/tasks/get_extensions.rb +32 -0
- data/lib/project_types/node/cli.rb +9 -21
- data/lib/project_types/node/commands/connect.rb +8 -2
- data/lib/project_types/node/commands/create.rb +9 -5
- data/lib/project_types/node/commands/deploy.rb +15 -5
- data/lib/project_types/node/commands/deploy/heroku.rb +29 -29
- data/lib/project_types/node/commands/generate.rb +4 -2
- data/lib/project_types/node/commands/open.rb +4 -2
- data/lib/project_types/node/commands/serve.rb +3 -2
- data/lib/project_types/node/commands/tunnel.rb +4 -2
- data/lib/project_types/node/messages/messages.rb +46 -89
- data/lib/project_types/rails/cli.rb +9 -21
- data/lib/project_types/rails/commands/connect.rb +8 -2
- data/lib/project_types/rails/commands/create.rb +10 -6
- data/lib/project_types/rails/commands/deploy.rb +15 -5
- data/lib/project_types/rails/commands/deploy/heroku.rb +84 -82
- data/lib/project_types/rails/commands/generate.rb +15 -5
- data/lib/project_types/rails/commands/generate/webhook.rb +28 -26
- data/lib/project_types/rails/commands/open.rb +4 -2
- data/lib/project_types/rails/commands/serve.rb +3 -2
- data/lib/project_types/rails/commands/tunnel.rb +4 -2
- data/lib/project_types/rails/messages/messages.rb +54 -101
- data/lib/project_types/script/cli.rb +18 -20
- data/lib/project_types/script/commands/create.rb +3 -1
- data/lib/project_types/script/commands/push.rb +12 -5
- data/lib/project_types/script/config/extension_points.yml +0 -3
- data/lib/project_types/script/graphql/app_script_update_or_create.graphql +9 -3
- data/lib/project_types/script/layers/application/create_script.rb +6 -5
- data/lib/project_types/script/layers/application/push_script.rb +2 -1
- data/lib/project_types/script/layers/domain/errors.rb +6 -11
- data/lib/project_types/script/layers/domain/push_package.rb +4 -8
- data/lib/project_types/script/layers/domain/script_json.rb +32 -0
- data/lib/project_types/script/layers/domain/script_project.rb +1 -1
- data/lib/project_types/script/layers/infrastructure/errors.rb +14 -18
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +105 -0
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +103 -0
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +26 -0
- data/lib/project_types/script/layers/infrastructure/languages/rust_project_creator.rb +73 -0
- data/lib/project_types/script/layers/infrastructure/languages/rust_task_runner.rb +60 -0
- data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +21 -0
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +2 -4
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +45 -34
- data/lib/project_types/script/layers/infrastructure/script_service.rb +20 -14
- data/lib/project_types/script/messages/messages.rb +66 -55
- data/lib/project_types/script/tasks/ensure_env.rb +22 -1
- data/lib/project_types/script/ui/error_handler.rb +32 -32
- data/lib/project_types/theme/cli.rb +15 -27
- data/lib/project_types/theme/commands/check.rb +33 -0
- data/lib/project_types/theme/commands/delete.rb +64 -0
- data/lib/project_types/theme/commands/language_server.rb +16 -0
- data/lib/project_types/theme/commands/package.rb +55 -0
- data/lib/project_types/theme/commands/publish.rb +43 -0
- data/lib/project_types/theme/commands/pull.rb +51 -0
- data/lib/project_types/theme/commands/push.rb +58 -32
- data/lib/project_types/theme/commands/serve.rb +7 -17
- data/lib/project_types/theme/forms/confirm_store.rb +15 -0
- data/lib/project_types/theme/forms/select.rb +59 -0
- data/lib/project_types/theme/messages/messages.rb +110 -106
- data/lib/project_types/theme/ui/sync_progress_bar.rb +20 -0
- data/lib/shopify-cli/admin_api.rb +53 -35
- data/lib/shopify-cli/admin_api/populate_resource_command.rb +6 -14
- data/lib/shopify-cli/admin_api/schema.rb +1 -10
- data/lib/shopify-cli/api.rb +29 -14
- data/lib/shopify-cli/command.rb +15 -3
- data/lib/shopify-cli/commands.rb +7 -2
- data/lib/shopify-cli/commands/help.rb +2 -29
- data/lib/shopify-cli/commands/login.rb +95 -0
- data/lib/shopify-cli/commands/logout.rb +24 -8
- data/lib/shopify-cli/commands/populate.rb +23 -0
- data/lib/{project_types/node → shopify-cli}/commands/populate/customer.rb +2 -8
- data/lib/{project_types/node → shopify-cli}/commands/populate/draft_order.rb +2 -2
- data/lib/{project_types/node → shopify-cli}/commands/populate/product.rb +2 -8
- data/lib/shopify-cli/commands/store.rb +15 -0
- data/lib/shopify-cli/commands/switch.rb +39 -0
- data/lib/shopify-cli/commands/system.rb +12 -0
- data/lib/shopify-cli/commands/whoami.rb +28 -0
- data/lib/shopify-cli/connect.rb +32 -0
- data/lib/shopify-cli/context.rb +65 -4
- data/lib/shopify-cli/core/entry_point.rb +3 -22
- data/lib/shopify-cli/db.rb +4 -4
- data/lib/shopify-cli/http_request.rb +10 -0
- data/lib/shopify-cli/identity_auth.rb +282 -0
- data/lib/shopify-cli/{oauth → identity_auth}/servlet.rb +11 -12
- data/lib/shopify-cli/messages/messages.rb +133 -39
- data/lib/shopify-cli/partners_api.rb +21 -41
- data/lib/shopify-cli/partners_api/organizations.rb +8 -0
- data/lib/shopify-cli/project_commands.rb +16 -0
- data/lib/shopify-cli/project_type.rb +0 -31
- data/lib/shopify-cli/resources/env_file.rb +1 -1
- data/lib/shopify-cli/shopifolk.rb +8 -11
- data/lib/shopify-cli/sub_command.rb +1 -0
- data/lib/shopify-cli/tasks.rb +3 -0
- data/lib/shopify-cli/tasks/confirm_store.rb +18 -0
- data/lib/shopify-cli/tasks/create_api_client.rb +2 -2
- data/lib/shopify-cli/tasks/ensure_authenticated.rb +13 -0
- data/lib/shopify-cli/tasks/ensure_loopback_url.rb +1 -1
- data/lib/shopify-cli/tasks/ensure_project_type.rb +12 -0
- data/lib/shopify-cli/tasks/select_org_and_shop.rb +0 -3
- data/lib/shopify-cli/theme/dev_server.rb +98 -0
- data/lib/shopify-cli/theme/dev_server/certificate_manager.rb +79 -0
- data/lib/shopify-cli/theme/dev_server/header_hash.rb +94 -0
- data/lib/shopify-cli/theme/dev_server/hot-reload.js +93 -0
- data/lib/shopify-cli/theme/dev_server/hot_reload.rb +76 -0
- data/lib/shopify-cli/theme/dev_server/local_assets.rb +87 -0
- data/lib/shopify-cli/theme/dev_server/proxy.rb +205 -0
- data/lib/shopify-cli/theme/dev_server/sse.rb +75 -0
- data/lib/shopify-cli/theme/dev_server/watcher.rb +59 -0
- data/lib/shopify-cli/theme/dev_server/web_server.rb +140 -0
- data/lib/shopify-cli/theme/development_theme.rb +69 -0
- data/lib/shopify-cli/theme/file.rb +112 -0
- data/lib/shopify-cli/theme/ignore_filter.rb +109 -0
- data/lib/shopify-cli/theme/mime_type.rb +34 -0
- data/lib/shopify-cli/theme/syncer.rb +328 -0
- data/lib/shopify-cli/theme/theme.rb +204 -0
- data/lib/shopify-cli/version.rb +1 -1
- data/lib/shopify_cli.rb +18 -11
- data/shopify-cli.gemspec +12 -5
- data/shopify.fish +1 -1
- data/shopify.sh +1 -1
- metadata +95 -41
- data/.github/workflows/release.yml +0 -61
- data/lib/project_types/extension/features/argo_serve_options.rb +0 -40
- data/lib/project_types/node/commands/populate.rb +0 -23
- data/lib/project_types/rails/commands/populate.rb +0 -23
- data/lib/project_types/rails/commands/populate/customer.rb +0 -31
- data/lib/project_types/rails/commands/populate/draft_order.rb +0 -28
- data/lib/project_types/rails/commands/populate/product.rb +0 -30
- data/lib/project_types/script/layers/domain/config_ui.rb +0 -16
- data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +0 -95
- data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +0 -101
- data/lib/project_types/script/layers/infrastructure/project_creator.rb +0 -24
- data/lib/project_types/script/layers/infrastructure/rust_project_creator.rb +0 -71
- data/lib/project_types/script/layers/infrastructure/rust_task_runner.rb +0 -58
- data/lib/project_types/script/layers/infrastructure/task_runner.rb +0 -19
- data/lib/project_types/theme/commands/connect.rb +0 -54
- data/lib/project_types/theme/commands/create.rb +0 -48
- data/lib/project_types/theme/commands/deploy.rb +0 -38
- data/lib/project_types/theme/commands/generate.rb +0 -20
- data/lib/project_types/theme/commands/generate/env.rb +0 -79
- data/lib/project_types/theme/forms/connect.rb +0 -34
- data/lib/project_types/theme/forms/create.rb +0 -22
- data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +0 -78
- data/lib/project_types/theme/themekit.rb +0 -113
- data/lib/shopify-cli/commands/connect.rb +0 -64
- data/lib/shopify-cli/commands/create.rb +0 -50
- data/lib/shopify-cli/oauth.rb +0 -198
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Forms
|
|
5
|
+
class Connect < ShopifyCli::Form
|
|
6
|
+
attr_reader :registration, :app
|
|
7
|
+
|
|
8
|
+
flag_arguments :type
|
|
9
|
+
|
|
10
|
+
class ExtensionProjectDetails
|
|
11
|
+
include SmartProperties
|
|
12
|
+
|
|
13
|
+
property :registration, accepts: Models::Registration
|
|
14
|
+
property :app, accepts: Models::App
|
|
15
|
+
|
|
16
|
+
def complete?
|
|
17
|
+
!!(registration && app)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def ask
|
|
22
|
+
ShopifyCli::Result.wrap(ExtensionProjectDetails.new)
|
|
23
|
+
.then(&Questions::AskRegistration.new(ctx: ctx, type: type))
|
|
24
|
+
.unwrap { |e| raise e }
|
|
25
|
+
.tap do |project_details|
|
|
26
|
+
ctx.abort(ctx.message("connect.incomplete_configuration")) unless project_details.complete?
|
|
27
|
+
|
|
28
|
+
self.registration = project_details.registration
|
|
29
|
+
self.app = project_details.app
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def directory_name
|
|
34
|
+
name.strip.gsub(/( )/, "_").downcase
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
attr_writer :registration, :app
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -11,17 +11,25 @@ module Extension
|
|
|
11
11
|
default: -> { CLI::UI::Prompt.method(:ask) }
|
|
12
12
|
|
|
13
13
|
def call(project_details)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
if theme_app_extension?(project_details)
|
|
15
|
+
project_details.name = name || "theme-app-extension"
|
|
16
|
+
else
|
|
17
|
+
project_details.name = ask_with_reprompt(
|
|
18
|
+
initial_value: name,
|
|
19
|
+
break_condition: -> (current_name) { Models::Registration.valid_title?(current_name) },
|
|
20
|
+
prompt_message: ctx.message("create.ask_name"),
|
|
21
|
+
reprompt_message: ctx.message("create.invalid_name", Models::Registration::MAX_TITLE_LENGTH)
|
|
22
|
+
)
|
|
23
|
+
end
|
|
20
24
|
project_details
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
private
|
|
24
28
|
|
|
29
|
+
def theme_app_extension?(project_details)
|
|
30
|
+
project_details&.type&.identifier == "THEME_APP_EXTENSION"
|
|
31
|
+
end
|
|
32
|
+
|
|
25
33
|
def ask_with_reprompt(initial_value:, break_condition:, prompt_message:, reprompt_message:)
|
|
26
34
|
value = initial_value
|
|
27
35
|
reprompt = false
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Forms
|
|
5
|
+
module Questions
|
|
6
|
+
class AskRegistration
|
|
7
|
+
include ShopifyCli::MethodObject
|
|
8
|
+
|
|
9
|
+
property! :ctx
|
|
10
|
+
property! :type
|
|
11
|
+
property! :prompt,
|
|
12
|
+
converts: :to_proc,
|
|
13
|
+
default: -> { CLI::UI::Prompt.method(:ask) }
|
|
14
|
+
|
|
15
|
+
def call(project_details)
|
|
16
|
+
project_details.tap(&method(:prompt_for_registration))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def prompt_for_registration(project_details)
|
|
22
|
+
apps_and_registrations = load_registrations(type)
|
|
23
|
+
app, registration = choose_interactively(apps_and_registrations)
|
|
24
|
+
project_details.app = app
|
|
25
|
+
project_details.registration = registration
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def choose_interactively(apps_and_registrations)
|
|
29
|
+
prompt.call(ctx.message("connect.ask_registration")) do |handler|
|
|
30
|
+
apps_and_registrations.each do |(app, extension)|
|
|
31
|
+
handler.option("#{app.title} by #{app.business_name}: #{extension.title}") { [app, extension] }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def load_registrations(type)
|
|
37
|
+
ctx.puts(@ctx.message("connect.loading_extensions"))
|
|
38
|
+
registrations = Tasks::GetExtensions.call(context: ctx, type: type)
|
|
39
|
+
|
|
40
|
+
registrations.empty? ? abort_no_registrations : registrations
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def abort_no_registrations
|
|
44
|
+
ctx.puts(@ctx.message("connect.no_extensions", type))
|
|
45
|
+
ctx.puts(@ctx.message("connect.learn_about_extensions"))
|
|
46
|
+
raise ShopifyCli::AbortSilent
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -4,7 +4,21 @@ require "shopify_cli"
|
|
|
4
4
|
module Extension
|
|
5
5
|
module Messages
|
|
6
6
|
MESSAGES = {
|
|
7
|
+
extension: {
|
|
8
|
+
help: <<~HELP,
|
|
9
|
+
Suite of commands for developing app extensions. See {{command:%1$s extension <command> --help}} for usage of each command.
|
|
10
|
+
Usage: {{command:%1$s extension [ %2$s ]}}
|
|
11
|
+
HELP
|
|
12
|
+
},
|
|
7
13
|
create: {
|
|
14
|
+
help: <<~HELP,
|
|
15
|
+
Create a new app extension.
|
|
16
|
+
Usage: {{command:%s extension create <name>}}
|
|
17
|
+
Options:
|
|
18
|
+
{{command:--type=TYPE}} The type of extension you would like to create.
|
|
19
|
+
{{command:--name=NAME}} The name of your extension (50 characters).
|
|
20
|
+
{{command:--api-key=KEY}} The API key of your app.
|
|
21
|
+
HELP
|
|
8
22
|
ask_name: "Extension name",
|
|
9
23
|
invalid_name: "Extension name must be under %s characters",
|
|
10
24
|
ask_type: "What type of extension are you creating?",
|
|
@@ -13,13 +27,13 @@ module Extension
|
|
|
13
27
|
ready_to_start: <<~MESSAGE,
|
|
14
28
|
{{v}} A new folder was generated at {{green:./%s}}.
|
|
15
29
|
{{*}} You’re ready to start building {{green:%s}}!
|
|
16
|
-
Navigate to the new folder, then run {{command:shopify serve}} to start a local server.
|
|
30
|
+
Navigate to the new folder, then run {{command:shopify extension serve}} to start a local server.
|
|
17
31
|
MESSAGE
|
|
18
32
|
learn_more: <<~MESSAGE,
|
|
19
33
|
{{*}} Once you're ready to version and publish your extension,
|
|
20
|
-
run {{command:shopify register}} to register this extension with one of your apps.
|
|
34
|
+
run {{command:shopify extension register}} to register this extension with one of your apps.
|
|
21
35
|
MESSAGE
|
|
22
|
-
try_again: "{{*}} Fix the errors and run {{command:shopify create
|
|
36
|
+
try_again: "{{*}} Fix the errors and run {{command:shopify extension create}} again.",
|
|
23
37
|
errors: {
|
|
24
38
|
directory_exists: "Directory ‘%s’ already exists. Please remove it or choose a new name for your project.",
|
|
25
39
|
},
|
|
@@ -28,15 +42,39 @@ module Extension
|
|
|
28
42
|
ask_app: "Which app would you like to register this extension with?",
|
|
29
43
|
no_apps: "{{x}} You don’t have any apps.",
|
|
30
44
|
learn_about_apps: "{{*}} Learn more about building apps at <https://shopify.dev/concepts/apps>, " \
|
|
31
|
-
"or try creating a new app using {{command:shopify create}}.",
|
|
45
|
+
"or try creating a new app using {{command:shopify [node|rails] create}}.",
|
|
32
46
|
loading_apps: "Loading your apps...",
|
|
33
47
|
no_available_extensions: "{{x}} There are no available extensions for this app.",
|
|
34
48
|
},
|
|
49
|
+
connect: {
|
|
50
|
+
connected: "Project now connected to {{green:%s: %s}}",
|
|
51
|
+
incomplete_configuration: "Cannot connect extension due to missing configuration information",
|
|
52
|
+
invalid_api_key: "The API key %s does not match any of your apps.",
|
|
53
|
+
ask_registration: "Which extension would you like to connect to?",
|
|
54
|
+
loading_extensions: "Loading your extensions...",
|
|
55
|
+
no_extensions: "{{x}} You don't have any extensions of type %s",
|
|
56
|
+
learn_about_extensions: "{{*}} Learn more about building extensions at <https://shopify.dev/concepts/apps>, " \
|
|
57
|
+
"or try creating a new extension using {{command:shopify extension create}}.",
|
|
58
|
+
help: <<~HELP,
|
|
59
|
+
{{command:%s extension connect}}: Connects an existing extension to Shopify CLI. Creates a config file.
|
|
60
|
+
Usage: {{command:%s extension connect}}
|
|
61
|
+
HELP
|
|
62
|
+
},
|
|
35
63
|
build: {
|
|
64
|
+
help: <<~HELP,
|
|
65
|
+
Build your extension to prepare for deployment.
|
|
66
|
+
Usage: {{command:%s extension build}}
|
|
67
|
+
HELP
|
|
36
68
|
frame_title: "Building extension with: %s...",
|
|
37
69
|
build_failure_message: "Failed to build extension code.",
|
|
38
70
|
},
|
|
39
71
|
register: {
|
|
72
|
+
help: <<~HELP,
|
|
73
|
+
Register your local extension to a Shopify app
|
|
74
|
+
Usage: {{command:%s extension register}}
|
|
75
|
+
Options:
|
|
76
|
+
{{command:--api-key=API_KEY}} The API key used to register an app with the extension. This can be found on the app page on Partners Dashboard.
|
|
77
|
+
HELP
|
|
40
78
|
frame_title: "Registering Extension",
|
|
41
79
|
waiting_text: "Registering with Shopify...",
|
|
42
80
|
already_registered: "Extension is already registered.",
|
|
@@ -44,17 +82,28 @@ module Extension
|
|
|
44
82
|
confirm_question: "Would you like to register this extension? (y/n)",
|
|
45
83
|
confirm_abort: "Extension was not registered.",
|
|
46
84
|
success: "{{v}} Registered {{green:%s}}.",
|
|
47
|
-
success_info: "{{*}} Run {{command:shopify push}} to push your extension to Shopify.",
|
|
85
|
+
success_info: "{{*}} Run {{command:shopify extension push}} to push your extension to Shopify.",
|
|
48
86
|
},
|
|
49
87
|
push: {
|
|
88
|
+
help: <<~HELP,
|
|
89
|
+
Push the current extension to Shopify.
|
|
90
|
+
Usage: {{command:%s extension push}}
|
|
91
|
+
HELP
|
|
50
92
|
frame_title: "Pushing your extension to Shopify",
|
|
51
93
|
waiting_text: "Pushing code to Shopify...",
|
|
52
94
|
pushed_with_errors: "{{x}} Code pushed to Shopify with errors on %s.",
|
|
53
|
-
push_with_errors_info: "{{*}} Fix these errors and run {{command:shopify push}} to
|
|
95
|
+
push_with_errors_info: "{{*}} Fix these errors and run {{command:shopify extension push}} to " \
|
|
96
|
+
"revalidate your extension.",
|
|
54
97
|
success_confirmation: "{{v}} Pushed {{green:%s}} to a draft on %s.",
|
|
55
98
|
success_info: "{{*}} Visit %s to version and publish your extension.",
|
|
56
99
|
},
|
|
57
100
|
serve: {
|
|
101
|
+
help: <<~HELP,
|
|
102
|
+
Serve your extension in a local simulator for development.
|
|
103
|
+
Usage: {{command:%s extension serve}}
|
|
104
|
+
Options:
|
|
105
|
+
{{command:--tunnel=TUNNEL}} Establish an ngrok tunnel (default: false)
|
|
106
|
+
HELP
|
|
58
107
|
frame_title: "Serving extension...",
|
|
59
108
|
no_available_ports_found: "No available ports found to run extension.",
|
|
60
109
|
serve_failure_message: "Failed to run extension code.",
|
|
@@ -69,25 +118,25 @@ module Extension
|
|
|
69
118
|
tunnel_running_at: "Tunnel running at: {{underline:%s}}",
|
|
70
119
|
help: <<~HELP,
|
|
71
120
|
Start or stop an http tunnel to your local development extension using ngrok.
|
|
72
|
-
Usage: {{command:%s tunnel [ auth | start | stop | status ]}}
|
|
121
|
+
Usage: {{command:%s extension tunnel [ auth | start | stop | status ]}}
|
|
73
122
|
HELP
|
|
74
123
|
extended_help: <<~HELP,
|
|
75
124
|
{{bold:Subcommands:}}
|
|
76
125
|
|
|
77
126
|
{{cyan:auth}}: Writes an ngrok auth token to ~/.ngrok2/ngrok.yml to connect with an ngrok account.
|
|
78
127
|
Visit https://dashboard.ngrok.com/signup to sign up.
|
|
79
|
-
Usage: {{command:%1$s tunnel auth <token>}}
|
|
128
|
+
Usage: {{command:%1$s extension tunnel auth <token>}}
|
|
80
129
|
|
|
81
130
|
{{cyan:start}}: Starts an ngrok tunnel, will print the URL for an existing tunnel if already running.
|
|
82
|
-
Usage: {{command:%1$s tunnel start}}
|
|
131
|
+
Usage: {{command:%1$s extension tunnel start}}
|
|
83
132
|
Options:
|
|
84
133
|
{{command:--port=PORT}} Forward the ngrok subdomain to local port PORT. Defaults to %2$s.
|
|
85
134
|
|
|
86
135
|
{{cyan:stop}}: Stops the ngrok tunnel.
|
|
87
|
-
Usage: {{command:%1$s tunnel stop}}
|
|
136
|
+
Usage: {{command:%1$s extension tunnel stop}}
|
|
88
137
|
|
|
89
138
|
{{cyan:status}}: Output the current status of the ngrok tunnel.
|
|
90
|
-
Usage: {{command:%1$s tunnel status}}
|
|
139
|
+
Usage: {{command:%1$s extension tunnel status}}
|
|
91
140
|
HELP
|
|
92
141
|
},
|
|
93
142
|
features: {
|
|
@@ -134,6 +183,21 @@ module Extension
|
|
|
134
183
|
checkout_post_purchase: {
|
|
135
184
|
name: "Checkout Post Purchase",
|
|
136
185
|
},
|
|
186
|
+
theme_app_extension: {
|
|
187
|
+
name: "Theme App Extension",
|
|
188
|
+
tagline: "(limit 1 per app)",
|
|
189
|
+
overrides: {
|
|
190
|
+
register: {
|
|
191
|
+
confirm_info: "You can only create one %s extension per app, which can’t be undone.",
|
|
192
|
+
},
|
|
193
|
+
create: {
|
|
194
|
+
ready_to_start: <<~MESSAGE,
|
|
195
|
+
{{v}} A new folder was generated at {{green:./%s}}.
|
|
196
|
+
{{*}} You’re ready to start building {{green:%s}}!
|
|
197
|
+
MESSAGE
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
137
201
|
}
|
|
138
202
|
end
|
|
139
203
|
end
|
|
@@ -17,6 +17,7 @@ module Extension
|
|
|
17
17
|
|
|
18
18
|
def self.build(feature_set_attributes)
|
|
19
19
|
feature_set_attributes.each_with_object(OpenStruct.new) do |(identifier, feature_attributes), feature_set|
|
|
20
|
+
next if feature_attributes.nil?
|
|
20
21
|
feature_set[identifier] = ShopifyCli::ResolveConstant
|
|
21
22
|
.call(identifier, namespace: Features)
|
|
22
23
|
.rescue { OpenStruct }
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Extension
|
|
4
4
|
module Models
|
|
5
5
|
module SpecificationHandlers
|
|
6
|
-
class
|
|
6
|
+
class CheckoutUiExtension < Default
|
|
7
7
|
PERMITTED_CONFIG_KEYS = [:metafields, :extension_points]
|
|
8
8
|
|
|
9
9
|
def config(context)
|
|
@@ -13,6 +13,8 @@ module Extension
|
|
|
13
13
|
}
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
CheckoutArgoExtension = CheckoutUiExtension
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
end
|
|
@@ -30,7 +30,7 @@ module Extension
|
|
|
30
30
|
argo.config(context)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
def create(directory_name, context)
|
|
33
|
+
def create(directory_name, context, **_args)
|
|
34
34
|
argo.create(directory_name, identifier, context)
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -43,16 +43,21 @@ module Extension
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def choose_port?(context)
|
|
46
|
-
argo_runtime(context).
|
|
46
|
+
argo_runtime(context).supports?(:port)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def establish_tunnel?(context)
|
|
50
|
-
argo_runtime(context).
|
|
50
|
+
argo_runtime(context).supports?(:public_url)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def serve(context:, port:, tunnel_url:)
|
|
54
|
-
Features::ArgoServe.new(
|
|
55
|
-
|
|
54
|
+
Features::ArgoServe.new(
|
|
55
|
+
specification_handler: self,
|
|
56
|
+
argo_runtime: argo_runtime(context),
|
|
57
|
+
context: context,
|
|
58
|
+
port: port,
|
|
59
|
+
tunnel_url: tunnel_url,
|
|
60
|
+
).call
|
|
56
61
|
end
|
|
57
62
|
|
|
58
63
|
def renderer_package(context)
|
|
@@ -62,7 +67,7 @@ module Extension
|
|
|
62
67
|
def argo_runtime(context)
|
|
63
68
|
@argo_runtime ||= Features::ArgoRuntime.new(
|
|
64
69
|
renderer: renderer_package(context),
|
|
65
|
-
cli: cli_package(context)
|
|
70
|
+
cli: cli_package(context),
|
|
66
71
|
)
|
|
67
72
|
end
|
|
68
73
|
|
|
@@ -75,6 +80,16 @@ module Extension
|
|
|
75
80
|
.unwrap { |_e| context.abort(context.message("errors.package_not_found", cli_package_name)) }
|
|
76
81
|
end
|
|
77
82
|
|
|
83
|
+
def message_for_extension(key, *params)
|
|
84
|
+
override_key = "overrides.#{key}"
|
|
85
|
+
key_parts = override_key.split(".").map(&:to_sym)
|
|
86
|
+
if (str = messages.dig(*key_parts))
|
|
87
|
+
str % params
|
|
88
|
+
else
|
|
89
|
+
ShopifyCli::Context.message(key, *params)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
78
93
|
protected
|
|
79
94
|
|
|
80
95
|
def argo
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "base64"
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Extension
|
|
6
|
+
module Models
|
|
7
|
+
module SpecificationHandlers
|
|
8
|
+
class ThemeAppExtension < Default
|
|
9
|
+
SUPPORTED_BUCKETS = %w(assets blocks snippets)
|
|
10
|
+
BUNDLE_SIZE_LIMIT = 10 * 1024 * 1024 # 10MB
|
|
11
|
+
LIQUID_SIZE_LIMIT = 100 * 1024 # 100kb
|
|
12
|
+
SUPPORTED_ASSET_EXTS = %w(.jpg .js .css .png .svg)
|
|
13
|
+
|
|
14
|
+
def create(directory_name, context, getting_started: false)
|
|
15
|
+
context.root = File.join(context.root, directory_name)
|
|
16
|
+
|
|
17
|
+
if getting_started
|
|
18
|
+
ShopifyCli::Git.clone("https://github.com/Shopify/theme-extension-getting-started", context.root)
|
|
19
|
+
context.rm_r(".git")
|
|
20
|
+
else
|
|
21
|
+
FileUtils.makedirs(SUPPORTED_BUCKETS.map { |b| File.join(context.root, b) })
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def config(context)
|
|
26
|
+
current_size = 0
|
|
27
|
+
current_liquid_size = 0
|
|
28
|
+
Dir.chdir(context.root) do
|
|
29
|
+
Dir["**/*"].select { |filename| File.file?(filename) && validate(filename) }
|
|
30
|
+
.map do |filename|
|
|
31
|
+
dirname = File.dirname(filename)
|
|
32
|
+
if dirname == "assets"
|
|
33
|
+
# Assets should be read as binary data, since they could be images
|
|
34
|
+
mode = "rb"
|
|
35
|
+
encoding = "BINARY"
|
|
36
|
+
else
|
|
37
|
+
# Other assets should be treated as UTF-8 encoded text
|
|
38
|
+
mode = "rt"
|
|
39
|
+
encoding = "UTF-8"
|
|
40
|
+
current_liquid_size += File.size(filename)
|
|
41
|
+
end
|
|
42
|
+
current_size += File.size(filename)
|
|
43
|
+
if current_size > BUNDLE_SIZE_LIMIT
|
|
44
|
+
raise Extension::Errors::BundleTooLargeError,
|
|
45
|
+
"Total size of all files must be less than #{CLI::Kit::Util.to_filesize(BUNDLE_SIZE_LIMIT)}"
|
|
46
|
+
end
|
|
47
|
+
if current_liquid_size > LIQUID_SIZE_LIMIT
|
|
48
|
+
raise Extension::Errors::BundleTooLargeError,
|
|
49
|
+
"Total size of all liquid must be less than #{CLI::Kit::Util.to_filesize(LIQUID_SIZE_LIMIT)}"
|
|
50
|
+
end
|
|
51
|
+
[filename, Base64.encode64(File.read(filename, mode: mode, encoding: encoding))]
|
|
52
|
+
end
|
|
53
|
+
.yield_self do |encoded_files_by_name|
|
|
54
|
+
{ "theme_extension" => { "files" => encoded_files_by_name.to_h } }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def name
|
|
60
|
+
"Theme App Extension"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def validate(filename)
|
|
66
|
+
dirname = File.dirname(filename)
|
|
67
|
+
unless SUPPORTED_BUCKETS.include?(dirname)
|
|
68
|
+
raise Extension::Errors::InvalidFilenameError, "Invalid directory: #{dirname}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
ext = File.extname(filename)
|
|
72
|
+
if dirname == "assets"
|
|
73
|
+
unless SUPPORTED_ASSET_EXTS.include?(ext)
|
|
74
|
+
raise Extension::Errors::InvalidFilenameError,
|
|
75
|
+
"Invalid filename: #{filename}; #{ext} is not supported"
|
|
76
|
+
end
|
|
77
|
+
elsif ext != ".liquid"
|
|
78
|
+
raise Extension::Errors::InvalidFilenameError,
|
|
79
|
+
"Invalid filename: #{filename}; Only .liquid allowed in #{dirname}"
|
|
80
|
+
end
|
|
81
|
+
true
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|