require "semantic/semantic" module ShopifyCLI module Services module App module Create class NodeService < BaseService attr_reader :context, :name, :organization_id, :store_domain, :type, :verbose def initialize(name:, organization_id:, store_domain:, type:, verbose:, context:) @name = name @organization_id = organization_id @store_domain = store_domain @type = type @verbose = verbose @context = context super() end def call form = form_data({ name: name, organization_id: organization_id, shop_domain: store_domain, type: type, verbose: verbose, }) raise ShopifyCLI::AbortSilent if form.nil? check_node check_npm build(form.name) ShopifyCLI::Project.write( context, project_type: "node", organization_id: form.organization_id, ) api_client = if ShopifyCLI::Environment.acceptance_test? { "apiKey" => "public_api_key", "apiSecretKeys" => [ { "secret" => "api_secret_key", }, ], } else ShopifyCLI::Tasks::CreateApiClient.call( context, org_id: form.organization_id, title: form.name, type: form.type, ) end ShopifyCLI::Resources::EnvFile.new( api_key: api_client["apiKey"], secret: api_client["apiSecretKeys"].first["secret"], shop: form.shop_domain, scopes: "write_products,write_customers,write_draft_orders", ).write(context) partners_url = ShopifyCLI::PartnersAPI.partners_url_for(form.organization_id, api_client["id"]) context.puts(context.message("apps.create.info.created", form.name, partners_url)) context.puts(context.message("apps.create.info.serve", form.name, ShopifyCLI::TOOL_NAME)) unless ShopifyCLI::Shopifolk.acting_as_shopify_organization? context.puts(context.message("apps.create.info.install", partners_url, form.name)) end end private def form_data(form_options) if ShopifyCLI::Environment.acceptance_test? Struct.new(:name, :organization_id, :type, :shop_domain, keyword_init: true).new( name: form_options[:name], organization_id: form_options[:organization_id] || "123", shop_domain: form_options[:shop_domain] || "test.shopify.io", type: form_options[:type] || "public", ) else Node::Forms::Create.ask(context, [], form_options) end end def check_node version = ShopifyCLI::Environment.node_version(context: context) context.done(context.message("core.app.create.node.node_version", version)) end def check_npm version = ShopifyCLI::Environment.npm_version(context: context) context.done(context.message("core.app.create.node.npm_version", version)) end def set_npm_config # check available npmrc (either user or system) for production registry registry, _ = context.capture2("npm config get @shopify:registry") return if registry.include?("https://registry.yarnpkg.com") # available npmrc doesn't have production registry => # set a project-based .npmrc context.system( "npm", "--userconfig", "./.npmrc", "config", "set", "@shopify:registry", "https://registry.yarnpkg.com", chdir: context.root ) end def build(name) ShopifyCLI::Git.clone("https://github.com/Shopify/shopify-app-template-node.git#cli_two", name) context.root = File.join(context.root, name) set_npm_config ShopifyCLI::JsDeps.install(context, verbose) begin context.rm_r(".git") context.rm_r(".github") context.rm(File.join("server", "handlers", "client.js")) context.rename( File.join("server", "handlers", "client.cli.js"), File.join("server", "handlers", "client.js") ) rescue Errno::ENOENT => e context.debug(e) end end end end end end end