shopify-cli 1.9.0 → 1.13.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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.github/PULL_REQUEST_TEMPLATE.md +1 -0
  3. data/.github/workflows/build.yml +28 -0
  4. data/.github/workflows/release.yml +2 -4
  5. data/CHANGELOG.md +27 -0
  6. data/Gemfile.lock +1 -1
  7. data/README.md +2 -1
  8. data/lib/project_types/extension/cli.rb +7 -1
  9. data/lib/project_types/extension/commands/serve.rb +69 -1
  10. data/lib/project_types/extension/commands/tunnel.rb +3 -1
  11. data/lib/project_types/extension/extension_project.rb +1 -0
  12. data/lib/project_types/extension/features/argo.rb +18 -49
  13. data/lib/project_types/extension/features/argo_runtime.rb +81 -0
  14. data/lib/project_types/extension/features/argo_serve.rb +35 -27
  15. data/lib/project_types/extension/features/argo_serve_options.rb +41 -0
  16. data/lib/project_types/extension/features/argo_setup.rb +1 -1
  17. data/lib/project_types/extension/messages/messages.rb +5 -4
  18. data/lib/project_types/extension/models/npm_package.rb +14 -0
  19. data/lib/project_types/extension/models/specification.rb +3 -2
  20. data/lib/project_types/extension/models/specification_handlers/checkout_argo_extension.rb +18 -0
  21. data/lib/project_types/extension/models/specification_handlers/default.rb +33 -3
  22. data/lib/project_types/extension/models/version.rb +1 -1
  23. data/lib/project_types/extension/tasks/choose_next_available_port.rb +36 -0
  24. data/lib/project_types/extension/tasks/configure_features.rb +2 -0
  25. data/lib/project_types/extension/tasks/find_npm_packages.rb +106 -0
  26. data/lib/project_types/node/messages/messages.rb +4 -4
  27. data/lib/project_types/rails/messages/messages.rb +4 -4
  28. data/lib/project_types/script/cli.rb +17 -12
  29. data/lib/project_types/script/commands/push.rb +1 -1
  30. data/lib/project_types/script/config/extension_points.yml +2 -3
  31. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +5 -2
  32. data/lib/project_types/script/graphql/get_app_scripts.graphql +6 -0
  33. data/lib/project_types/script/layers/application/create_script.rb +2 -2
  34. data/lib/project_types/script/layers/application/push_script.rb +6 -3
  35. data/lib/project_types/script/layers/domain/errors.rb +0 -2
  36. data/lib/project_types/script/layers/domain/push_package.rb +4 -0
  37. data/lib/project_types/script/layers/domain/script_project.rb +21 -1
  38. data/lib/project_types/script/layers/infrastructure/command_runner.rb +19 -0
  39. data/lib/project_types/script/layers/infrastructure/errors.rb +30 -3
  40. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +97 -0
  41. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +103 -0
  42. data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +26 -0
  43. data/lib/project_types/script/layers/infrastructure/languages/rust_project_creator.rb +73 -0
  44. data/lib/project_types/script/layers/infrastructure/languages/rust_task_runner.rb +60 -0
  45. data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +21 -0
  46. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +6 -5
  47. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +61 -34
  48. data/lib/project_types/script/layers/infrastructure/script_service.rb +14 -2
  49. data/lib/project_types/script/messages/messages.rb +20 -3
  50. data/lib/project_types/script/tasks/ensure_env.rb +85 -0
  51. data/lib/project_types/script/ui/error_handler.rb +25 -6
  52. data/lib/shopify-cli/admin_api.rb +7 -4
  53. data/lib/shopify-cli/js_system.rb +2 -2
  54. data/lib/shopify-cli/messages/messages.rb +51 -45
  55. data/lib/shopify-cli/method_object.rb +4 -4
  56. data/lib/shopify-cli/oauth.rb +9 -3
  57. data/lib/shopify-cli/packager.rb +1 -1
  58. data/lib/shopify-cli/partners_api.rb +7 -4
  59. data/lib/shopify-cli/partners_api/organizations.rb +3 -3
  60. data/lib/shopify-cli/resolve_constant.rb +1 -1
  61. data/lib/shopify-cli/resources/env_file.rb +2 -2
  62. data/lib/shopify-cli/shopifolk.rb +1 -1
  63. data/lib/shopify-cli/tasks/select_org_and_shop.rb +6 -4
  64. data/lib/shopify-cli/transform_data_structure.rb +1 -1
  65. data/lib/shopify-cli/tunnel.rb +22 -1
  66. data/lib/shopify-cli/version.rb +1 -1
  67. data/lib/shopify_cli.rb +0 -1
  68. data/vendor/deps/smart_properties/REVISION +1 -1
  69. data/vendor/deps/smart_properties/lib/smart_properties/property.rb +7 -1
  70. data/vendor/deps/smart_properties/lib/smart_properties/version.rb +1 -1
  71. metadata +19 -11
  72. data/.travis.yml +0 -14
  73. data/lib/project_types/extension/features/argo_renderer_package.rb +0 -32
  74. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +0 -100
  75. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +0 -95
  76. data/lib/project_types/script/layers/infrastructure/project_creator.rb +0 -24
  77. data/lib/project_types/script/layers/infrastructure/rust_project_creator.rb +0 -72
  78. data/lib/project_types/script/layers/infrastructure/rust_task_runner.rb +0 -59
  79. data/lib/project_types/script/layers/infrastructure/task_runner.rb +0 -19
@@ -8,7 +8,7 @@ module Script
8
8
  end
9
9
 
10
10
  def call(_args, _name)
11
- ShopifyCli::Tasks::EnsureEnv.call(@ctx, required: [:api_key, :secret, :shop])
11
+ Tasks::EnsureEnv.call(@ctx)
12
12
 
13
13
  api_key = Layers::Infrastructure::ScriptProjectRepository.new(ctx: @ctx).get.api_key
14
14
  return @ctx.puts(self.class.help) unless api_key
@@ -11,6 +11,7 @@ unit_limit_per_order:
11
11
  sdk-version: "^9.0.0"
12
12
  toolchain-version: "^5.0.0"
13
13
  payment_filter:
14
+ deprecated: true
14
15
  assemblyscript:
15
16
  package: "@shopify/extension-point-as-payment-filter"
16
17
  sdk-version: "^9.0.0"
@@ -19,6 +20,7 @@ payment_filter:
19
20
  beta: true
20
21
  package: "https://github.com/Shopify/scripts-apis-rs"
21
22
  shipping_filter:
23
+ deprecated: true
22
24
  assemblyscript:
23
25
  package: "@shopify/extension-point-as-shipping-filter"
24
26
  sdk-version: "^9.0.0"
@@ -34,11 +36,8 @@ payment_methods:
34
36
  assemblyscript:
35
37
  package: "@shopify/scripts-checkout-apis"
36
38
  toolchain-version: "^5.0.0"
37
- sdk-version: "^9.0.0"
38
39
  shipping_methods:
39
40
  domain: 'checkout'
40
41
  assemblyscript:
41
42
  package: "@shopify/scripts-checkout-apis"
42
- sdk-version: "^9.0.0"
43
43
  toolchain-version: "^5.0.0"
44
-
@@ -7,7 +7,8 @@ mutation AppScriptUpdateOrCreate(
7
7
  $force: Boolean,
8
8
  $schemaMajorVersion: String,
9
9
  $schemaMinorVersion: String,
10
- $useMsgpack: Boolean
10
+ $useMsgpack: Boolean,
11
+ $uuid: String
11
12
  ) {
12
13
  appScriptUpdateOrCreate(
13
14
  extensionPointName: $extensionPointName
@@ -18,7 +19,8 @@ mutation AppScriptUpdateOrCreate(
18
19
  force: $force
19
20
  schemaMajorVersion: $schemaMajorVersion
20
21
  schemaMinorVersion: $schemaMinorVersion
21
- useMsgpack: $useMsgpack
22
+ useMsgpack: $useMsgpack,
23
+ uuid: $uuid
22
24
  ) {
23
25
  userErrors {
24
26
  field
@@ -26,6 +28,7 @@ mutation AppScriptUpdateOrCreate(
26
28
  tag
27
29
  }
28
30
  appScript {
31
+ uuid
29
32
  appKey
30
33
  configSchema
31
34
  extensionPointName
@@ -0,0 +1,6 @@
1
+ query GetAppScripts($appKey: String!, $extensionPointName: ExtensionPointName!) {
2
+ appScripts(appKeys: [$appKey], extensionPointName: $extensionPointName) {
3
+ uuid
4
+ title
5
+ }
6
+ }
@@ -18,7 +18,7 @@ module Script
18
18
  language: language,
19
19
  no_config_ui: no_config_ui
20
20
  )
21
- project_creator = Infrastructure::ProjectCreator
21
+ project_creator = Infrastructure::Languages::ProjectCreator
22
22
  .for(ctx, language, extension_point, script_name, project.id)
23
23
  install_dependencies(ctx, language, script_name, project_creator)
24
24
  bootstrap(ctx, project_creator)
@@ -29,7 +29,7 @@ module Script
29
29
  private
30
30
 
31
31
  def install_dependencies(ctx, language, script_name, project_creator)
32
- task_runner = Infrastructure::TaskRunner.for(ctx, language, script_name)
32
+ task_runner = Infrastructure::Languages::TaskRunner.for(ctx, language, script_name)
33
33
  project_creator.setup_dependencies
34
34
  ProjectDependencies.install(ctx: ctx, task_runner: task_runner)
35
35
  end
@@ -6,8 +6,10 @@ module Script
6
6
  class PushScript
7
7
  class << self
8
8
  def call(ctx:, force:)
9
- script_project = Infrastructure::ScriptProjectRepository.new(ctx: ctx).get
10
- task_runner = Infrastructure::TaskRunner.for(ctx, script_project.language, script_project.script_name)
9
+ script_project_repo = Infrastructure::ScriptProjectRepository.new(ctx: ctx)
10
+ script_project = script_project_repo.get
11
+ task_runner = Infrastructure::Languages::TaskRunner
12
+ .for(ctx, script_project.language, script_project.script_name)
11
13
 
12
14
  ProjectDependencies.install(ctx: ctx, task_runner: task_runner)
13
15
  BuildScript.call(ctx: ctx, task_runner: task_runner, script_project: script_project)
@@ -18,7 +20,8 @@ module Script
18
20
  compiled_type: task_runner.compiled_type,
19
21
  metadata: task_runner.metadata,
20
22
  )
21
- package.push(Infrastructure::ScriptService.new(ctx: p_ctx), script_project.api_key, force)
23
+ uuid = package.push(Infrastructure::ScriptService.new(ctx: p_ctx), script_project.api_key, force)
24
+ script_project_repo.update_env(uuid: uuid)
22
25
  spinner.update_title(p_ctx.message("script.application.pushed"))
23
26
  end
24
27
  end
@@ -39,8 +39,6 @@ module Script
39
39
  end
40
40
  end
41
41
 
42
- class ServiceFailureError < ScriptProjectError; end
43
-
44
42
  class MetadataNotFoundError < ScriptProjectError; end
45
43
 
46
44
  class MetadataValidationError < ScriptProjectError; end
@@ -5,6 +5,7 @@ module Script
5
5
  module Domain
6
6
  class PushPackage
7
7
  attr_reader :id,
8
+ :uuid,
8
9
  :extension_point_type,
9
10
  :script_name,
10
11
  :config_ui,
@@ -14,6 +15,7 @@ module Script
14
15
 
15
16
  def initialize(
16
17
  id:,
18
+ uuid:,
17
19
  extension_point_type:,
18
20
  script_name:,
19
21
  script_content:,
@@ -22,6 +24,7 @@ module Script
22
24
  config_ui:
23
25
  )
24
26
  @id = id
27
+ @uuid = uuid
25
28
  @extension_point_type = extension_point_type
26
29
  @script_name = script_name
27
30
  @script_content = script_content
@@ -32,6 +35,7 @@ module Script
32
35
 
33
36
  def push(script_service, api_key, force)
34
37
  script_service.push(
38
+ uuid: @uuid,
35
39
  extension_point_type: @extension_point_type,
36
40
  script_name: @script_name,
37
41
  script_content: @script_content,
@@ -6,6 +6,8 @@ module Script
6
6
  class ScriptProject
7
7
  include SmartProperties
8
8
 
9
+ UUID_ENV_KEY = "UUID"
10
+
9
11
  property! :id, accepts: String
10
12
  property :env, accepts: ShopifyCli::Resources::EnvFile
11
13
 
@@ -26,7 +28,25 @@ module Script
26
28
  end
27
29
 
28
30
  def api_key
29
- env[:api_key]
31
+ env&.api_key
32
+ end
33
+
34
+ def api_secret
35
+ env&.secret
36
+ end
37
+
38
+ def uuid
39
+ uuid_defined? && !raw_uuid.empty? ? raw_uuid : nil
40
+ end
41
+
42
+ def uuid_defined?
43
+ !raw_uuid.nil?
44
+ end
45
+
46
+ private
47
+
48
+ def raw_uuid
49
+ env&.extra&.[](UUID_ENV_KEY)
30
50
  end
31
51
  end
32
52
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Layers
5
+ module Infrastructure
6
+ class CommandRunner
7
+ include SmartProperties
8
+
9
+ property! :ctx, accepts: ShopifyCli::Context
10
+
11
+ def call(cmd)
12
+ out, status = ctx.capture2e(cmd)
13
+ raise Errors::SystemCallFailureError.new(out: out.chomp, cmd: cmd) unless status.success?
14
+ out
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -17,6 +17,15 @@ module Script
17
17
  end
18
18
  end
19
19
 
20
+ class ConfigUiInvalidInputModeError < ScriptProjectError
21
+ attr_reader :filename, :valid_input_modes
22
+ def initialize(filename, valid_input_modes)
23
+ super()
24
+ @filename = filename
25
+ @valid_input_modes = valid_input_modes
26
+ end
27
+ end
28
+
20
29
  class ConfigUiFieldsMissingKeysError < ScriptProjectError
21
30
  attr_reader :filename, :missing_keys
22
31
  def initialize(filename, missing_keys)
@@ -26,6 +35,15 @@ module Script
26
35
  end
27
36
  end
28
37
 
38
+ class ConfigUiFieldsInvalidTypeError < ScriptProjectError
39
+ attr_reader :filename, :valid_types
40
+ def initialize(filename, valid_types)
41
+ super()
42
+ @filename = filename
43
+ @valid_types = valid_types
44
+ end
45
+ end
46
+
29
47
  class DependencyInstallError < ScriptProjectError; end
30
48
  class DeprecatedEPError < ScriptProjectError; end
31
49
  class EmptyResponseError < ScriptProjectError; end
@@ -51,11 +69,20 @@ module Script
51
69
 
52
70
  class ProjectCreatorNotFoundError < ScriptProjectError; end
53
71
 
72
+ class SystemCallFailureError < ScriptProjectError
73
+ attr_reader :out, :cmd
74
+ def initialize(out:, cmd:)
75
+ super(out)
76
+ @out = out
77
+ @cmd = cmd
78
+ end
79
+ end
80
+
54
81
  class ScriptRepushError < ScriptProjectError
55
- attr_reader :api_key
56
- def initialize(api_key)
82
+ attr_reader :uuid
83
+ def initialize(uuid)
57
84
  super()
58
- @api_key = api_key
85
+ @uuid = uuid
59
86
  end
60
87
  end
61
88
 
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Layers
5
+ module Infrastructure
6
+ module Languages
7
+ class AssemblyScriptProjectCreator
8
+ include SmartProperties
9
+ property! :ctx, accepts: ShopifyCli::Context
10
+ property! :extension_point, accepts: Domain::ExtensionPoint
11
+ property! :script_name, accepts: String
12
+ property! :path_to_project, accepts: String
13
+
14
+ BOOTSTRAP = "npx --no-install shopify-scripts-toolchain-as bootstrap --from %{extension_point} --dest %{base}"
15
+ BUILD = "shopify-scripts-toolchain-as build --src src/shopify_main.ts " \
16
+ "--binary build/script.wasm --metadata build/metadata.json"
17
+ MIN_NODE_VERSION = "14.5.0"
18
+ ASC_ARGS = "-- --lib node_modules --optimize --use Date="
19
+
20
+ def setup_dependencies
21
+ write_npmrc
22
+ write_package_json
23
+ end
24
+
25
+ def bootstrap
26
+ command_runner.call(bootstap_command)
27
+ end
28
+
29
+ private
30
+
31
+ def command_runner
32
+ @command_runner ||= CommandRunner.new(ctx: ctx)
33
+ end
34
+
35
+ def write_npmrc
36
+ command_runner.call("npm --userconfig ./.npmrc config set @shopify:registry https://registry.npmjs.com")
37
+ command_runner.call("npm --userconfig ./.npmrc config set engine-strict true")
38
+ end
39
+
40
+ def extension_point_version
41
+ return extension_point.sdks.assemblyscript.version if extension_point.sdks.assemblyscript.versioned?
42
+
43
+ out = command_runner.call("npm show #{extension_point.sdks.assemblyscript.package} version --json")
44
+ "^#{JSON.parse(out)}"
45
+ end
46
+
47
+ def write_package_json
48
+ package_json = <<~HERE
49
+ {
50
+ "name": "#{script_name}",
51
+ "version": "1.0.0",
52
+ "devDependencies": {
53
+ "@shopify/scripts-sdk-as": "#{extension_point.sdks.assemblyscript.sdk_version}",
54
+ "@shopify/scripts-toolchain-as": "#{extension_point.sdks.assemblyscript.toolchain_version}",
55
+ "#{extension_point.sdks.assemblyscript.package}": "#{extension_point_version}",
56
+ "@as-pect/cli": "^6.0.0",
57
+ "assemblyscript": "^0.18.13"
58
+ },
59
+ "scripts": {
60
+ "test": "asp --summary --verbose",
61
+ "build": "#{build_command}"
62
+ },
63
+ "engines": {
64
+ "node": ">=#{MIN_NODE_VERSION}"
65
+ }
66
+ }
67
+ HERE
68
+ ctx.write("package.json", package_json)
69
+ end
70
+
71
+ def bootstap_command
72
+ type = extension_point.dasherize_type
73
+ base_command = format(BOOTSTRAP, extension_point: type, base: path_to_project)
74
+ domain = extension_point.domain
75
+
76
+ if domain.nil?
77
+ base_command
78
+ else
79
+ "#{base_command} --domain #{domain}"
80
+ end
81
+ end
82
+
83
+ def build_command
84
+ type = extension_point.dasherize_type
85
+ domain = extension_point.domain
86
+
87
+ if domain.nil?
88
+ "#{BUILD} #{ASC_ARGS}"
89
+ else
90
+ "#{BUILD} --domain #{domain} --ep #{type} #{ASC_ARGS}"
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Layers
5
+ module Infrastructure
6
+ module Languages
7
+ class AssemblyScriptTaskRunner
8
+ BYTECODE_FILE = "build/%{name}.wasm"
9
+ METADATA_FILE = "build/metadata.json"
10
+ SCRIPT_SDK_BUILD = "npm run build"
11
+
12
+ attr_reader :ctx, :script_name
13
+
14
+ def initialize(ctx, script_name)
15
+ @ctx = ctx
16
+ @script_name = script_name
17
+ end
18
+
19
+ def build
20
+ compile
21
+ bytecode
22
+ end
23
+
24
+ def compiled_type
25
+ "wasm"
26
+ end
27
+
28
+ def install_dependencies
29
+ check_node_version!
30
+
31
+ output, status = ctx.capture2e("npm install --no-audit --no-optional --legacy-peer-deps --loglevel error")
32
+ raise Errors::DependencyInstallError, output unless status.success?
33
+ end
34
+
35
+ def dependencies_installed?
36
+ # Assuming if node_modules folder exist at root of script folder, all deps are installed
37
+ ctx.dir_exist?("node_modules")
38
+ end
39
+
40
+ def metadata
41
+ unless @ctx.file_exist?(METADATA_FILE)
42
+ msg = @ctx.message("script.error.metadata_not_found_cause", METADATA_FILE)
43
+ raise Domain::Errors::MetadataNotFoundError, msg
44
+ end
45
+
46
+ raw_contents = File.read(METADATA_FILE)
47
+ Domain::Metadata.create_from_json(@ctx, raw_contents)
48
+ end
49
+
50
+ private
51
+
52
+ def check_node_version!
53
+ output, status = @ctx.capture2e("node", "--version")
54
+ raise Errors::DependencyInstallError, output unless status.success?
55
+
56
+ require "semantic/semantic"
57
+ version = ::Semantic::Version.new(output[1..-1])
58
+ unless version >= ::Semantic::Version.new(AssemblyScriptProjectCreator::MIN_NODE_VERSION)
59
+ raise Errors::DependencyInstallError,
60
+ "Node version must be >= v#{AssemblyScriptProjectCreator::MIN_NODE_VERSION}. "\
61
+ "Current version: #{output.strip}."
62
+ end
63
+ end
64
+
65
+ def compile
66
+ check_compilation_dependencies!
67
+ CommandRunner.new(ctx: ctx).call(SCRIPT_SDK_BUILD)
68
+ end
69
+
70
+ def check_compilation_dependencies!
71
+ pkg = JSON.parse(File.read("package.json"))
72
+ build_script = pkg.dig("scripts", "build")
73
+
74
+ raise Errors::BuildScriptNotFoundError,
75
+ "Build script not found" if build_script.nil?
76
+
77
+ unless build_script.start_with?("shopify-scripts")
78
+ raise Errors::InvalidBuildScriptError, "Invalid build script"
79
+ end
80
+ end
81
+
82
+ def bytecode
83
+ legacy_filename = format(BYTECODE_FILE, name: script_name)
84
+ filename = format(BYTECODE_FILE, name: "script")
85
+
86
+ bytecode_file = if ctx.file_exist?(filename)
87
+ filename
88
+ elsif ctx.file_exist?(legacy_filename)
89
+ legacy_filename
90
+ else
91
+ raise Errors::WebAssemblyBinaryNotFoundError
92
+ end
93
+
94
+ contents = ctx.binread(bytecode_file)
95
+ ctx.rm(bytecode_file)
96
+
97
+ contents
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end