shopify-cli 1.9.0 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
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