shopify-cli 0.9.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 +7 -0
- data/.github/CODEOWNERS +1 -0
- data/.github/CODE_OF_CONDUCT.md +73 -0
- data/.github/CONTRIBUTING.md +51 -0
- data/.github/DESIGN.md +153 -0
- data/.github/ISSUE_TEMPLATE.md +38 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +22 -0
- data/.github/probots.yml +3 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +47 -0
- data/.ruby-version +1 -0
- data/.travis.yml +12 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +77 -0
- data/LICENSE.md +7 -0
- data/README.md +13 -0
- data/Rakefile +101 -0
- data/SECURITY.md +59 -0
- data/Vagrantfile +17 -0
- data/bin/load_shopify.rb +20 -0
- data/bin/shopify +32 -0
- data/dev.yml +17 -0
- data/docs/Gemfile +5 -0
- data/docs/Gemfile.lock +248 -0
- data/docs/_config.yml +16 -0
- data/docs/_data/nav.yml +26 -0
- data/docs/_includes/footer.html +15 -0
- data/docs/_includes/head.html +19 -0
- data/docs/_includes/sidebar_nav.html +22 -0
- data/docs/_includes/toc.html +112 -0
- data/docs/_layouts/default.html +79 -0
- data/docs/app/node/commands/index.md +82 -0
- data/docs/app/node/index.md +35 -0
- data/docs/app/rails/commands/index.md +80 -0
- data/docs/app/rails/index.md +36 -0
- data/docs/core/index.md +70 -0
- data/docs/css/docs.css +157 -0
- data/docs/getting-started/index.md +61 -0
- data/docs/help/start-app/index.md +6 -0
- data/docs/images/header.png +0 -0
- data/docs/index.md +27 -0
- data/docs/installing-ruby.md +28 -0
- data/ext/shopify-cli/extconf.rb +27 -0
- data/install.sh +7 -0
- data/lib/docgen/class_template.md.erb +81 -0
- data/lib/docgen/index_template.md.erb +5 -0
- data/lib/docgen/markdown.rb +101 -0
- data/lib/graphql/admin_introspection.graphql +87 -0
- data/lib/graphql/all_organizations.graphql +19 -0
- data/lib/graphql/all_orgs_with_apps.graphql +30 -0
- data/lib/graphql/api_versions.graphql +6 -0
- data/lib/graphql/convert_dev_to_test_store.graphql +10 -0
- data/lib/graphql/create_app.graphql +20 -0
- data/lib/graphql/create_customer.graphql +9 -0
- data/lib/graphql/create_draft_order.graphql +8 -0
- data/lib/graphql/create_product.graphql +9 -0
- data/lib/graphql/extension_create.graphql +21 -0
- data/lib/graphql/extension_update_draft.graphql +18 -0
- data/lib/graphql/find_organization.graphql +17 -0
- data/lib/graphql/get_app_urls.graphql +6 -0
- data/lib/graphql/update_dashboard_urls.graphql +8 -0
- data/lib/project_types/extension/cli.rb +71 -0
- data/lib/project_types/extension/commands/build.rb +29 -0
- data/lib/project_types/extension/commands/create.rb +49 -0
- data/lib/project_types/extension/commands/extension_command.rb +22 -0
- data/lib/project_types/extension/commands/push.rb +69 -0
- data/lib/project_types/extension/commands/register.rb +78 -0
- data/lib/project_types/extension/commands/serve.rb +24 -0
- data/lib/project_types/extension/commands/tunnel.rb +69 -0
- data/lib/project_types/extension/extension_project.rb +85 -0
- data/lib/project_types/extension/extension_project_keys.rb +10 -0
- data/lib/project_types/extension/features/argo.rb +48 -0
- data/lib/project_types/extension/features/argo_dependencies.rb +28 -0
- data/lib/project_types/extension/features/argo_setup.rb +54 -0
- data/lib/project_types/extension/features/argo_setup_step.rb +31 -0
- data/lib/project_types/extension/features/argo_setup_steps.rb +53 -0
- data/lib/project_types/extension/features/tunnel_url.rb +20 -0
- data/lib/project_types/extension/forms/create.rb +52 -0
- data/lib/project_types/extension/forms/register.rb +48 -0
- data/lib/project_types/extension/messages/message_loading.rb +37 -0
- data/lib/project_types/extension/messages/messages.rb +126 -0
- data/lib/project_types/extension/models/app.rb +14 -0
- data/lib/project_types/extension/models/registration.rb +19 -0
- data/lib/project_types/extension/models/type.rb +76 -0
- data/lib/project_types/extension/models/types/checkout_post_purchase.rb +20 -0
- data/lib/project_types/extension/models/types/subscription_management.rb +20 -0
- data/lib/project_types/extension/models/validation_error.rb +17 -0
- data/lib/project_types/extension/models/version.rb +15 -0
- data/lib/project_types/extension/tasks/converters/registration_converter.rb +26 -0
- data/lib/project_types/extension/tasks/converters/validation_error_converter.rb +25 -0
- data/lib/project_types/extension/tasks/converters/version_converter.rb +28 -0
- data/lib/project_types/extension/tasks/create_extension.rb +31 -0
- data/lib/project_types/extension/tasks/get_apps.rb +34 -0
- data/lib/project_types/extension/tasks/update_draft.rb +29 -0
- data/lib/project_types/extension/tasks/user_errors.rb +45 -0
- data/lib/project_types/node/cli.rb +37 -0
- data/lib/project_types/node/commands/create.rb +117 -0
- data/lib/project_types/node/commands/deploy.rb +22 -0
- data/lib/project_types/node/commands/deploy/heroku.rb +91 -0
- data/lib/project_types/node/commands/generate.rb +51 -0
- data/lib/project_types/node/commands/generate/billing.rb +37 -0
- data/lib/project_types/node/commands/generate/page.rb +55 -0
- data/lib/project_types/node/commands/generate/webhook.rb +33 -0
- data/lib/project_types/node/commands/open.rb +16 -0
- data/lib/project_types/node/commands/populate.rb +23 -0
- data/lib/project_types/node/commands/populate/customer.rb +31 -0
- data/lib/project_types/node/commands/populate/draft_order.rb +28 -0
- data/lib/project_types/node/commands/populate/product.rb +30 -0
- data/lib/project_types/node/commands/serve.rb +45 -0
- data/lib/project_types/node/commands/tunnel.rb +39 -0
- data/lib/project_types/node/forms/create.rb +87 -0
- data/lib/project_types/node/messages/messages.rb +260 -0
- data/lib/project_types/rails/cli.rb +41 -0
- data/lib/project_types/rails/commands/create.rb +126 -0
- data/lib/project_types/rails/commands/deploy.rb +22 -0
- data/lib/project_types/rails/commands/deploy/heroku.rb +113 -0
- data/lib/project_types/rails/commands/generate.rb +49 -0
- data/lib/project_types/rails/commands/generate/webhook.rb +39 -0
- data/lib/project_types/rails/commands/open.rb +16 -0
- data/lib/project_types/rails/commands/populate.rb +23 -0
- data/lib/project_types/rails/commands/populate/customer.rb +31 -0
- data/lib/project_types/rails/commands/populate/draft_order.rb +28 -0
- data/lib/project_types/rails/commands/populate/product.rb +30 -0
- data/lib/project_types/rails/commands/serve.rb +47 -0
- data/lib/project_types/rails/commands/tunnel.rb +39 -0
- data/lib/project_types/rails/forms/create.rb +116 -0
- data/lib/project_types/rails/gem.rb +56 -0
- data/lib/project_types/rails/messages/messages.rb +283 -0
- data/lib/project_types/rails/ruby.rb +17 -0
- data/lib/project_types/script/cli.rb +76 -0
- data/lib/project_types/script/commands/create.rb +45 -0
- data/lib/project_types/script/commands/disable.rb +36 -0
- data/lib/project_types/script/commands/enable.rb +46 -0
- data/lib/project_types/script/commands/push.rb +39 -0
- data/lib/project_types/script/config/extension_points.yml +18 -0
- data/lib/project_types/script/errors.rb +16 -0
- data/lib/project_types/script/forms/create.rb +29 -0
- data/lib/project_types/script/forms/enable.rb +24 -0
- data/lib/project_types/script/forms/push.rb +19 -0
- data/lib/project_types/script/forms/script_form.rb +66 -0
- data/lib/project_types/script/graphql/app_script_update_or_create.graphql +27 -0
- data/lib/project_types/script/graphql/script_service_proxy.graphql +8 -0
- data/lib/project_types/script/graphql/shop_script_delete.graphql +14 -0
- data/lib/project_types/script/graphql/shop_script_update_or_create.graphql +28 -0
- data/lib/project_types/script/layers/application/build_script.rb +43 -0
- data/lib/project_types/script/layers/application/create_script.rb +47 -0
- data/lib/project_types/script/layers/application/disable_script.rb +19 -0
- data/lib/project_types/script/layers/application/enable_script.rb +21 -0
- data/lib/project_types/script/layers/application/extension_points.rb +17 -0
- data/lib/project_types/script/layers/application/project_dependencies.rb +34 -0
- data/lib/project_types/script/layers/application/push_script.rb +30 -0
- data/lib/project_types/script/layers/domain/errors.rb +25 -0
- data/lib/project_types/script/layers/domain/extension_point.rb +29 -0
- data/lib/project_types/script/layers/domain/push_package.rb +29 -0
- data/lib/project_types/script/layers/domain/script.rb +18 -0
- data/lib/project_types/script/layers/infrastructure/assemblyscript_dependency_manager.rb +73 -0
- data/lib/project_types/script/layers/infrastructure/assemblyscript_tsconfig.rb +38 -0
- data/lib/project_types/script/layers/infrastructure/assemblyscript_wasm_builder.rb +39 -0
- data/lib/project_types/script/layers/infrastructure/dependency_manager.rb +36 -0
- data/lib/project_types/script/layers/infrastructure/errors.rb +38 -0
- data/lib/project_types/script/layers/infrastructure/extension_point_repository.rb +31 -0
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +47 -0
- data/lib/project_types/script/layers/infrastructure/script_builder.rb +34 -0
- data/lib/project_types/script/layers/infrastructure/script_repository.rb +89 -0
- data/lib/project_types/script/layers/infrastructure/script_service.rb +165 -0
- data/lib/project_types/script/layers/infrastructure/test_suite_repository.rb +59 -0
- data/lib/project_types/script/messages/messages.rb +204 -0
- data/lib/project_types/script/script_project.rb +37 -0
- data/lib/project_types/script/templates/ts/as-pect.config.js +21 -0
- data/lib/project_types/script/ui/error_handler.rb +136 -0
- data/lib/project_types/script/ui/strict_spinner.rb +22 -0
- data/lib/rubygems_plugin.rb +18 -0
- data/lib/shopify-cli/admin_api.rb +99 -0
- data/lib/shopify-cli/admin_api/populate_resource_command.rb +165 -0
- data/lib/shopify-cli/admin_api/schema.rb +32 -0
- data/lib/shopify-cli/api.rb +104 -0
- data/lib/shopify-cli/command.rb +67 -0
- data/lib/shopify-cli/commands.rb +28 -0
- data/lib/shopify-cli/commands/connect.rb +108 -0
- data/lib/shopify-cli/commands/create.rb +50 -0
- data/lib/shopify-cli/commands/help.rb +79 -0
- data/lib/shopify-cli/commands/logout.rb +23 -0
- data/lib/shopify-cli/commands/system.rb +135 -0
- data/lib/shopify-cli/commands/version.rb +15 -0
- data/lib/shopify-cli/context.rb +372 -0
- data/lib/shopify-cli/core.rb +9 -0
- data/lib/shopify-cli/core/entry_point.rb +40 -0
- data/lib/shopify-cli/core/executor.rb +21 -0
- data/lib/shopify-cli/core/help_resolver.rb +20 -0
- data/lib/shopify-cli/core/monorail.rb +118 -0
- data/lib/shopify-cli/db.rb +114 -0
- data/lib/shopify-cli/form.rb +40 -0
- data/lib/shopify-cli/git.rb +141 -0
- data/lib/shopify-cli/helpers.rb +5 -0
- data/lib/shopify-cli/helpers/haikunator.rb +92 -0
- data/lib/shopify-cli/heroku.rb +97 -0
- data/lib/shopify-cli/js_deps.rb +110 -0
- data/lib/shopify-cli/js_system.rb +98 -0
- data/lib/shopify-cli/messages/messages.rb +287 -0
- data/lib/shopify-cli/oauth.rb +192 -0
- data/lib/shopify-cli/oauth/servlet.rb +61 -0
- data/lib/shopify-cli/options.rb +40 -0
- data/lib/shopify-cli/packager.rb +116 -0
- data/lib/shopify-cli/partners_api.rb +114 -0
- data/lib/shopify-cli/partners_api/organizations.rb +32 -0
- data/lib/shopify-cli/process_supervision.rb +187 -0
- data/lib/shopify-cli/project.rb +191 -0
- data/lib/shopify-cli/project_type.rb +83 -0
- data/lib/shopify-cli/resources.rb +5 -0
- data/lib/shopify-cli/resources/env_file.rb +96 -0
- data/lib/shopify-cli/sub_command.rb +15 -0
- data/lib/shopify-cli/task.rb +10 -0
- data/lib/shopify-cli/tasks.rb +32 -0
- data/lib/shopify-cli/tasks/create_api_client.rb +29 -0
- data/lib/shopify-cli/tasks/ensure_dev_store.rb +41 -0
- data/lib/shopify-cli/tasks/ensure_env.rb +31 -0
- data/lib/shopify-cli/tasks/ensure_loopback_url.rb +20 -0
- data/lib/shopify-cli/tasks/update_dashboard_urls.rb +44 -0
- data/lib/shopify-cli/tunnel.rb +154 -0
- data/lib/shopify-cli/version.rb +3 -0
- data/lib/shopify_cli.rb +132 -0
- data/shopify-cli.gemspec +40 -0
- data/shopify.fish +12 -0
- data/shopify.sh +11 -0
- data/vendor/deps/cli-kit/REVISION +1 -0
- data/vendor/deps/cli-kit/lib/cli/kit.rb +60 -0
- data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +21 -0
- data/vendor/deps/cli-kit/lib/cli/kit/base_command.rb +49 -0
- data/vendor/deps/cli-kit/lib/cli/kit/command_registry.rb +94 -0
- data/vendor/deps/cli-kit/lib/cli/kit/config.rb +133 -0
- data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +115 -0
- data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +81 -0
- data/vendor/deps/cli-kit/lib/cli/kit/ini.rb +102 -0
- data/vendor/deps/cli-kit/lib/cli/kit/levenshtein.rb +82 -0
- data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +76 -0
- data/vendor/deps/cli-kit/lib/cli/kit/resolver.rb +60 -0
- data/vendor/deps/cli-kit/lib/cli/kit/ruby_backports/enumerable.rb +6 -0
- data/vendor/deps/cli-kit/lib/cli/kit/support.rb +9 -0
- data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +244 -0
- data/vendor/deps/cli-kit/lib/cli/kit/system.rb +207 -0
- data/vendor/deps/cli-kit/lib/cli/kit/util.rb +189 -0
- data/vendor/deps/cli-kit/lib/cli/kit/version.rb +5 -0
- data/vendor/deps/cli-ui/REVISION +1 -0
- data/vendor/deps/cli-ui/lib/cli/ui.rb +187 -0
- data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +153 -0
- data/vendor/deps/cli-ui/lib/cli/ui/box.rb +15 -0
- data/vendor/deps/cli-ui/lib/cli/ui/color.rb +79 -0
- data/vendor/deps/cli-ui/lib/cli/ui/formatter.rb +179 -0
- data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +310 -0
- data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +78 -0
- data/vendor/deps/cli-ui/lib/cli/ui/progress.rb +88 -0
- data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +248 -0
- data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +472 -0
- data/vendor/deps/cli-ui/lib/cli/ui/prompt/options_handler.rb +24 -0
- data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +48 -0
- data/vendor/deps/cli-ui/lib/cli/ui/spinner/async.rb +40 -0
- data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +241 -0
- data/vendor/deps/cli-ui/lib/cli/ui/stdout_router.rb +227 -0
- data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +36 -0
- data/vendor/deps/cli-ui/lib/cli/ui/truncater.rb +102 -0
- data/vendor/deps/cli-ui/lib/cli/ui/version.rb +5 -0
- data/vendor/deps/smart_properties/REVISION +1 -0
- data/vendor/deps/smart_properties/lib/smart_properties.rb +174 -0
- data/vendor/deps/smart_properties/lib/smart_properties/errors.rb +114 -0
- data/vendor/deps/smart_properties/lib/smart_properties/property.rb +162 -0
- data/vendor/deps/smart_properties/lib/smart_properties/property_collection.rb +83 -0
- data/vendor/deps/smart_properties/lib/smart_properties/validations.rb +8 -0
- data/vendor/deps/smart_properties/lib/smart_properties/validations/ancestor.rb +27 -0
- data/vendor/deps/smart_properties/lib/smart_properties/version.rb +3 -0
- data/vendor/lib/semantic/LICENSE +20 -0
- data/vendor/lib/semantic/semantic.rb +4 -0
- data/vendor/lib/semantic/version.rb +180 -0
- metadata +374 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Features
|
|
5
|
+
class ArgoDependencies
|
|
6
|
+
def self.node_installed(min_major:, min_minor: nil)
|
|
7
|
+
-> (context) do
|
|
8
|
+
out, status = CLI::Kit::System.capture2('node', '-v')
|
|
9
|
+
context.abort(context.message('features.argo.dependencies.node.node_not_installed')) unless status.success?
|
|
10
|
+
|
|
11
|
+
min_version = 'v' + min_major .to_s + '.' + (min_minor.nil? ? 'x' : min_minor.to_s) + '.x'
|
|
12
|
+
version = out.strip
|
|
13
|
+
parsed_version = version.match(/v(?<major>\d+).(?<minor>\d+).(?<patch>\d+)/)
|
|
14
|
+
|
|
15
|
+
unless min_major.nil? || parsed_version[:major].to_i >= min_major
|
|
16
|
+
context.abort(context.message('features.argo.dependencies.node.version_too_low', version, min_version))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
return if parsed_version[:major].to_i > min_major
|
|
20
|
+
|
|
21
|
+
unless min_minor.nil? || parsed_version[:minor].to_i >= min_minor
|
|
22
|
+
context.abort(context.message('features.argo.dependencies.node.version_too_low', version, min_version))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Features
|
|
5
|
+
class ArgoSetup
|
|
6
|
+
include SmartProperties
|
|
7
|
+
|
|
8
|
+
GIT_DIRECTORY = '.git'
|
|
9
|
+
SCRIPTS_DIRECTORY = 'scripts'
|
|
10
|
+
|
|
11
|
+
property! :git_template, accepts: String
|
|
12
|
+
property! :dependency_checks, default: []
|
|
13
|
+
|
|
14
|
+
def call(directory_name, identifier, context)
|
|
15
|
+
steps = [
|
|
16
|
+
ArgoSetupSteps.check_dependencies(dependency_checks),
|
|
17
|
+
ArgoSetupSteps.clone_template(git_template),
|
|
18
|
+
ArgoSetupSteps.install_dependencies,
|
|
19
|
+
ArgoSetupSteps.initialize_project,
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
install_result = run_install_steps(context, steps, identifier, directory_name)
|
|
23
|
+
|
|
24
|
+
cleanup(context, install_result, directory_name)
|
|
25
|
+
install_result
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def run_install_steps(context, steps, identifier, directory_name)
|
|
29
|
+
system = ShopifyCli::JsSystem.new(ctx: context)
|
|
30
|
+
|
|
31
|
+
steps.inject(true) do |success, setup_step|
|
|
32
|
+
success && setup_step.call(context, identifier, directory_name, system)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def cleanup(context, install_result, directory_name)
|
|
37
|
+
install_result ? cleanup_template(context) : cleanup_on_failure(context, directory_name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def cleanup_template(context)
|
|
41
|
+
context.rm_r(GIT_DIRECTORY)
|
|
42
|
+
context.rm_r(SCRIPTS_DIRECTORY)
|
|
43
|
+
rescue Errno::ENOENT => e
|
|
44
|
+
context.debug(e)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def cleanup_on_failure(context, directory_name)
|
|
48
|
+
FileUtils.rm_r(directory_name) if Dir.exist?(directory_name)
|
|
49
|
+
rescue Errno::ENOENT => e
|
|
50
|
+
context.debug(e)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Features
|
|
5
|
+
class ArgoSetupStep
|
|
6
|
+
include SmartProperties
|
|
7
|
+
|
|
8
|
+
property! :step
|
|
9
|
+
property! :can_fail, accepts: [true, false], reader: :can_fail?
|
|
10
|
+
|
|
11
|
+
def call(context, identifier, directory_name, js_system)
|
|
12
|
+
step_result = step.call(context, identifier, directory_name, js_system)
|
|
13
|
+
can_fail? ? step_result : true
|
|
14
|
+
rescue ShopifyCli::Abort => e
|
|
15
|
+
context.puts(e.message)
|
|
16
|
+
false
|
|
17
|
+
rescue StandardError => e
|
|
18
|
+
context.puts("{{x}} #{e.message}")
|
|
19
|
+
false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.default(&block)
|
|
23
|
+
ArgoSetupStep.new(step: block, can_fail: true)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.always_successful(&block)
|
|
27
|
+
ArgoSetupStep.new(step: block, can_fail: false)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Features
|
|
5
|
+
module ArgoSetupSteps
|
|
6
|
+
YARN_INITIALIZE_COMMAND = %w(generate).freeze
|
|
7
|
+
NPM_INITIALIZE_COMMAND = %w(run generate --).freeze
|
|
8
|
+
INITIALIZE_TYPE_PARAMETER = '--type=%s'
|
|
9
|
+
|
|
10
|
+
def self.check_dependencies(dependency_checks)
|
|
11
|
+
ArgoSetupStep.always_successful do |context, _identifier, _directory_name, _js_system|
|
|
12
|
+
dependency_checks.each do |dependency_check|
|
|
13
|
+
dependency_check.call(context)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.clone_template(git_template)
|
|
19
|
+
ArgoSetupStep.default do |context, _identifier, directory_name, _js_system|
|
|
20
|
+
begin
|
|
21
|
+
ShopifyCli::Git.clone(git_template, directory_name, ctx: context)
|
|
22
|
+
context.root = File.join(context.root, directory_name)
|
|
23
|
+
rescue StandardError
|
|
24
|
+
context.puts('{{x}} Unable to clone the repository.')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.install_dependencies
|
|
30
|
+
ArgoSetupStep.default do |context, _identifier, _directory_name, js_system|
|
|
31
|
+
ShopifyCli::JsDeps.new(ctx: context, system: js_system).install
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.initialize_project
|
|
36
|
+
ArgoSetupStep.default do |context, identifier, _directory_name, js_system|
|
|
37
|
+
frame_title = context.message('create.setup_project_frame_title')
|
|
38
|
+
failure_message = context.message('features.argo.initialization_error')
|
|
39
|
+
|
|
40
|
+
result = true
|
|
41
|
+
CLI::UI::Frame.open(frame_title, failure_text: failure_message) do
|
|
42
|
+
result = js_system.call(
|
|
43
|
+
yarn: YARN_INITIALIZE_COMMAND + [INITIALIZE_TYPE_PARAMETER % identifier],
|
|
44
|
+
npm: NPM_INITIALIZE_COMMAND + [INITIALIZE_TYPE_PARAMETER % identifier]
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
result
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'base64'
|
|
3
|
+
|
|
4
|
+
module Extension
|
|
5
|
+
module Features
|
|
6
|
+
module TunnelUrl
|
|
7
|
+
NGROK_TUNNELS_URI = URI.parse('http://localhost:4040/api/tunnels')
|
|
8
|
+
TUNNELS_FIELD = 'tunnels'
|
|
9
|
+
PUBLIC_URL_FIELD = 'public_url'
|
|
10
|
+
|
|
11
|
+
def self.fetch
|
|
12
|
+
response = Net::HTTP.get_response(NGROK_TUNNELS_URI)
|
|
13
|
+
json = JSON.parse(response.body)
|
|
14
|
+
json.dig(TUNNELS_FIELD, 0, PUBLIC_URL_FIELD)
|
|
15
|
+
rescue
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Forms
|
|
5
|
+
class Create < ShopifyCli::Form
|
|
6
|
+
flag_arguments :name, :type
|
|
7
|
+
|
|
8
|
+
def ask
|
|
9
|
+
self.type = ask_type
|
|
10
|
+
self.name = ask_name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def directory_name
|
|
14
|
+
@directory_name ||= name.strip.gsub(/( )/, '_').downcase
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def ask_name
|
|
20
|
+
ask_with_reprompt(
|
|
21
|
+
initial_value: name,
|
|
22
|
+
break_condition: -> (current_name) { Models::Registration.valid_title?(current_name) },
|
|
23
|
+
prompt_message: ctx.message('create.ask_name'),
|
|
24
|
+
reprompt_message: ctx.message('create.invalid_name', Models::Registration::MAX_TITLE_LENGTH)
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def ask_type
|
|
29
|
+
return Models::Type.load_type(type) if Models::Type.valid?(type)
|
|
30
|
+
ctx.puts(ctx.message('create.invalid_type')) unless type.nil?
|
|
31
|
+
|
|
32
|
+
CLI::UI::Prompt.ask(ctx.message('create.ask_type')) do |handler|
|
|
33
|
+
Models::Type.repository.values.each do |type|
|
|
34
|
+
handler.option("#{type.name} #{type.tagline}") { type }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def ask_with_reprompt(initial_value:, break_condition:, prompt_message:, reprompt_message:)
|
|
40
|
+
value = initial_value
|
|
41
|
+
reprompt = false
|
|
42
|
+
|
|
43
|
+
until break_condition.call(value)
|
|
44
|
+
ctx.puts(reprompt_message) if reprompt
|
|
45
|
+
value = CLI::UI::Prompt.ask(prompt_message)&.strip
|
|
46
|
+
reprompt = true
|
|
47
|
+
end
|
|
48
|
+
value
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Forms
|
|
5
|
+
class Register < ShopifyCli::Form
|
|
6
|
+
flag_arguments :api_key
|
|
7
|
+
|
|
8
|
+
attr_reader :app
|
|
9
|
+
|
|
10
|
+
def ask
|
|
11
|
+
self.app = ask_app
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
attr_writer :app
|
|
17
|
+
|
|
18
|
+
def ask_app
|
|
19
|
+
apps = load_apps
|
|
20
|
+
|
|
21
|
+
if !api_key.nil?
|
|
22
|
+
found_app = apps.find { |app| app.api_key == api_key }
|
|
23
|
+
ctx.abort(ctx.message('register.invalid_api_key', api_key)) if found_app.nil?
|
|
24
|
+
found_app
|
|
25
|
+
else
|
|
26
|
+
CLI::UI::Prompt.ask(ctx.message('register.ask_app')) do |handler|
|
|
27
|
+
apps.each do |app|
|
|
28
|
+
handler.option("#{app.title} by #{app.business_name}") { app }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def load_apps
|
|
35
|
+
ctx.puts(@ctx.message('register.loading_apps'))
|
|
36
|
+
apps = Tasks::GetApps.call(context: ctx)
|
|
37
|
+
|
|
38
|
+
apps.empty? ? abort_no_apps : apps
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def abort_no_apps
|
|
42
|
+
ctx.puts(@ctx.message('register.no_apps'))
|
|
43
|
+
ctx.puts(@ctx.message('register.learn_about_apps'))
|
|
44
|
+
raise ShopifyCli::AbortSilent
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Extension
|
|
4
|
+
module Messages
|
|
5
|
+
module MessageLoading
|
|
6
|
+
def self.load
|
|
7
|
+
type_specific_messages = load_current_type_messages
|
|
8
|
+
return Messages::MESSAGES if type_specific_messages.nil?
|
|
9
|
+
|
|
10
|
+
if type_specific_messages.key?(:overrides)
|
|
11
|
+
deep_merge(Messages::MESSAGES, type_specific_messages[:overrides])
|
|
12
|
+
else
|
|
13
|
+
Messages::MESSAGES
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.load_current_type_messages
|
|
18
|
+
return unless ShopifyCli::Project.has_current?
|
|
19
|
+
messages_for_type(ShopifyCli::Project.current.config[Extension::ExtensionProjectKeys::EXTENSION_TYPE_KEY])
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.messages_for_type(type_identifier)
|
|
23
|
+
return if type_identifier.nil?
|
|
24
|
+
|
|
25
|
+
type_identifier_symbol = type_identifier.downcase.to_sym
|
|
26
|
+
return unless Messages::TYPES.key?(type_identifier_symbol)
|
|
27
|
+
|
|
28
|
+
TYPES[type_identifier_symbol]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.deep_merge(first, second)
|
|
32
|
+
merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
|
|
33
|
+
first.merge(second, &merger)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'shopify_cli'
|
|
3
|
+
|
|
4
|
+
module Extension
|
|
5
|
+
module Messages
|
|
6
|
+
MESSAGES = {
|
|
7
|
+
create: {
|
|
8
|
+
ask_name: 'Extension name',
|
|
9
|
+
invalid_name: 'Extension name must be under %s characters',
|
|
10
|
+
ask_type: 'What type of extension are you creating?',
|
|
11
|
+
invalid_type: 'Extension type is invalid.',
|
|
12
|
+
setup_project_frame_title: 'Initializing project',
|
|
13
|
+
ready_to_start: <<~MESSAGE,
|
|
14
|
+
{{v}} A new folder was generated at {{green:./%s}}.
|
|
15
|
+
{{*}} You’re ready to start building {{green:%s}}!
|
|
16
|
+
Navigate to the new folder, then run {{command:shopify serve}} to start a local server.
|
|
17
|
+
MESSAGE
|
|
18
|
+
learn_more: <<~MESSAGE,
|
|
19
|
+
{{*}} Once you're ready to version and publish your extension,
|
|
20
|
+
run {{command:shopify register}} to register this extension with one of your apps.
|
|
21
|
+
MESSAGE
|
|
22
|
+
try_again: '{{*}} Fix the errors and run {{command:shopify create extension}} again.',
|
|
23
|
+
errors: {
|
|
24
|
+
directory_exists: 'Directory ‘%s’ already exists. Please remove it or choose a new name for your project.',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
build: {
|
|
28
|
+
frame_title: 'Building extension with: %s...',
|
|
29
|
+
build_failure_message: 'Failed to build extension code.',
|
|
30
|
+
},
|
|
31
|
+
register: {
|
|
32
|
+
frame_title: 'Registering Extension',
|
|
33
|
+
waiting_text: 'Registering with Shopify...',
|
|
34
|
+
already_registered: 'Extension is already registered.',
|
|
35
|
+
loading_apps: 'Loading your apps...',
|
|
36
|
+
ask_app: 'Which app would you like to register this extension with?',
|
|
37
|
+
no_apps: '{{x}} You don’t have any apps.',
|
|
38
|
+
learn_about_apps: '{{*}} Learn more about building apps at <https://shopify.dev/concepts/apps>, ' \
|
|
39
|
+
'or try creating a new app using {{command:shopify create}}.',
|
|
40
|
+
invalid_api_key: 'The API key %s does not match any of your apps.',
|
|
41
|
+
confirm_info: 'This will create a new extension registration for %s, which can’t be undone.',
|
|
42
|
+
confirm_question: 'Would you like to register this extension with {{green:%s}}? (y/n)',
|
|
43
|
+
confirm_abort: 'Extension was not registered.',
|
|
44
|
+
success: '{{v}} Registered {{green:%s}} with {{green:%s}}.',
|
|
45
|
+
success_info: '{{*}} Run {{command:shopify push}} to push your extension to Shopify.',
|
|
46
|
+
},
|
|
47
|
+
push: {
|
|
48
|
+
frame_title: 'Pushing your extension to Shopify',
|
|
49
|
+
waiting_text: 'Pushing code to Shopify...',
|
|
50
|
+
pushed_with_errors: '{{x}} Code pushed to Shopify with errors on %s.',
|
|
51
|
+
push_with_errors_info: '{{*}} Fix these errors and run {{command:shopify push}} to revalidate your extension.',
|
|
52
|
+
success_confirmation: '{{v}} Pushed {{green:%s}} to a draft on %s.',
|
|
53
|
+
success_info: '{{*}} Visit %s to version and publish your extension.',
|
|
54
|
+
},
|
|
55
|
+
serve: {
|
|
56
|
+
frame_title: 'Serving extension...',
|
|
57
|
+
serve_failure_message: 'Failed to run extension code.',
|
|
58
|
+
},
|
|
59
|
+
tunnel: {
|
|
60
|
+
missing_token: '{{x}} {{red:auth requires a token argument}}. '\
|
|
61
|
+
'Find it on your ngrok dashboard: {{underline:https://dashboard.ngrok.com/auth/your-authtoken}}.',
|
|
62
|
+
invalid_port: '%s is not a valid port.',
|
|
63
|
+
no_tunnel_running: 'No tunnel running.',
|
|
64
|
+
tunnel_running_at: 'Tunnel running at: {{underline:%s}}',
|
|
65
|
+
help: <<~HELP,
|
|
66
|
+
Start or stop an http tunnel to your local development extension using ngrok.
|
|
67
|
+
Usage: {{command:%s tunnel [ auth | start | stop | status ]}}
|
|
68
|
+
HELP
|
|
69
|
+
extended_help: <<~HELP,
|
|
70
|
+
{{bold:Subcommands:}}
|
|
71
|
+
|
|
72
|
+
{{cyan:auth}}: Writes an ngrok auth token to ~/.ngrok2/ngrok.yml to connect with an ngrok account.
|
|
73
|
+
Visit https://dashboard.ngrok.com/signup to sign up.
|
|
74
|
+
Usage: {{command:%1$s tunnel auth <token>}}
|
|
75
|
+
|
|
76
|
+
{{cyan:start}}: Starts an ngrok tunnel, will print the URL for an existing tunnel if already running.
|
|
77
|
+
Usage: {{command:%1$s tunnel start}}
|
|
78
|
+
Options:
|
|
79
|
+
{{command:--port=PORT}} Forward the ngrok subdomain to local port PORT. Defaults to %2$s.
|
|
80
|
+
|
|
81
|
+
{{cyan:stop}}: Stops the ngrok tunnel.
|
|
82
|
+
Usage: {{command:%1$s tunnel stop}}
|
|
83
|
+
|
|
84
|
+
{{cyan:status}}: Output the current status of the ngrok tunnel.
|
|
85
|
+
Usage: {{command:%1$s tunnel status}}
|
|
86
|
+
HELP
|
|
87
|
+
},
|
|
88
|
+
features: {
|
|
89
|
+
argo: {
|
|
90
|
+
missing_file_error: 'Could not find built extension file.',
|
|
91
|
+
script_prepare_error: 'An error occurred while attempting to prepare your script.',
|
|
92
|
+
initialization_error: '{{x}} There was an error while initializing the project.',
|
|
93
|
+
dependencies: {
|
|
94
|
+
node: {
|
|
95
|
+
node_not_installed: 'Node must be installed to create this extension.',
|
|
96
|
+
version_too_low: 'Your node version %s does not meet the minimum required version %s',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
tasks: {
|
|
102
|
+
errors: {
|
|
103
|
+
parse_error: 'Unable to parse response from Partners Dashboard.',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
errors: {
|
|
107
|
+
unknown_type: 'Unknown extension type %s',
|
|
108
|
+
},
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
TYPES = {
|
|
112
|
+
subscription_management: {
|
|
113
|
+
name: 'Subscription Management',
|
|
114
|
+
tagline: '(limit 1 per app)',
|
|
115
|
+
overrides: {
|
|
116
|
+
register: {
|
|
117
|
+
confirm_info: 'You can only create one %s extension per app, which can’t be undone.',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
checkout_post_purchase: {
|
|
122
|
+
name: 'Checkout Post Purchase',
|
|
123
|
+
},
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
end
|