# frozen_string_literal: true module Script module Layers module Infrastructure class ScriptProjectRepository include SmartProperties property! :ctx, accepts: ShopifyCLI::Context SCRIPT_JSON_FILENAME = "script.json" MUTABLE_ENV_VALUES = %i(uuid) def create(script_name:, extension_point_type:, language:) validate_metadata!(extension_point_type, language) ShopifyCLI::Project.write( ctx, project_type: :script, organization_id: nil, extension_point_type: extension_point_type, script_name: script_name, language: language ) Domain::ScriptProject.new( id: ctx.root, env: project.env, script_name: script_name, extension_point_type: extension_point_type, language: language ) end def get validate_metadata!(extension_point_type, language) Domain::ScriptProject.new( id: project.directory, env: project.env, script_name: script_name, extension_point_type: extension_point_type, language: language, script_json: ScriptJsonRepository.new(ctx: ctx).get ) end def update_env(**args) capture_io do args.slice(*MUTABLE_ENV_VALUES).each do |key, value| project.env.extra[key.to_s.upcase] = value project.env.update(ctx, :extra, project.env.extra) end end Domain::ScriptProject.new( id: ctx.root, env: project.env, script_name: script_name, extension_point_type: extension_point_type, language: language, script_json: ScriptJsonRepository.new(ctx: ctx).get, ) end def create_env(api_key:, secret:, uuid:) ShopifyCLI::Resources::EnvFile.new( api_key: api_key, secret: secret, extra: { Domain::ScriptProject::UUID_ENV_KEY => uuid, } ).write(ctx) Domain::ScriptProject.new( id: ctx.root, env: project.env, script_name: script_name, extension_point_type: extension_point_type, language: language, script_json: ScriptJsonRepository.new(ctx: ctx).get, ) end def update_or_create_script_json(title:) script_json = ScriptJsonRepository .new(ctx: ctx) .update_or_create(title: title) Domain::ScriptProject.new( id: ctx.root, env: project.env, script_name: script_name, extension_point_type: extension_point_type, language: language, script_json: script_json, ) end private def capture_io(&block) CLI::UI::StdoutRouter::Capture.new(&block).run end def extension_point_type project_config_value!("extension_point_type") end def script_name project_config_value!("script_name") end def language project_config_value("language")&.downcase || default_language end def project_config_value(key) return nil unless project.config.key?(key) project.config[key] end def project_config_value!(key) raise Errors::InvalidContextError, key unless project.config.key?(key) project.config[key] end def project @project ||= ShopifyCLI::Project.current(force_reload: true) end def default_language "assemblyscript" end def validate_metadata!(extension_point_type, language) if Application::ExtensionPoints.deprecated_types.include?(extension_point_type) raise Errors::DeprecatedEPError, extension_point_type elsif !Application::ExtensionPoints.supported_language?(type: extension_point_type, language: language) raise Errors::InvalidLanguageError.new(language, extension_point_type) end end class ScriptJsonRepository include SmartProperties property! :ctx, accepts: ShopifyCLI::Context def get current_script_json || raise(Domain::Errors::NoScriptJsonFile) end def update_or_create(title:) json = current_script_json&.content || {} json["version"] ||= "1" json["title"] = title ctx.write(SCRIPT_JSON_FILENAME, JSON.pretty_generate(json)) Domain::ScriptJson.new(content: json) end private def current_script_json return nil unless ctx.file_exist?(SCRIPT_JSON_FILENAME) content = ctx.read(SCRIPT_JSON_FILENAME) raise Domain::Errors::InvalidScriptJsonDefinitionError unless valid_script_json?(content) Domain::ScriptJson.new(content: JSON.parse(content)) end def valid_script_json?(content) JSON.parse(content) true rescue JSON::ParserError false end end end end end end