shopify-cli 1.8.0 → 1.12.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 (95) 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/.rubocop_todo.yml +15 -2
  5. data/CHANGELOG.md +24 -1
  6. data/Gemfile.lock +4 -4
  7. data/README.md +2 -1
  8. data/dev.yml +3 -0
  9. data/lib/graphql/extension_create.graphql +17 -2
  10. data/lib/project_types/extension/cli.rb +8 -0
  11. data/lib/project_types/extension/commands/extension_command.rb +4 -4
  12. data/lib/project_types/extension/commands/push.rb +2 -2
  13. data/lib/project_types/extension/commands/register.rb +4 -3
  14. data/lib/project_types/extension/commands/serve.rb +62 -28
  15. data/lib/project_types/extension/commands/tunnel.rb +3 -1
  16. data/lib/project_types/extension/extension_project.rb +16 -4
  17. data/lib/project_types/extension/extension_project_keys.rb +2 -1
  18. data/lib/project_types/extension/features/argo.rb +19 -44
  19. data/lib/project_types/extension/features/argo_runtime.rb +84 -0
  20. data/lib/project_types/extension/features/argo_serve.rb +80 -0
  21. data/lib/project_types/extension/features/argo_serve_options.rb +41 -0
  22. data/lib/project_types/extension/features/argo_setup.rb +1 -1
  23. data/lib/project_types/extension/messages/message_loading.rb +3 -1
  24. data/lib/project_types/extension/messages/messages.rb +5 -4
  25. data/lib/project_types/extension/models/npm_package.rb +14 -0
  26. data/lib/project_types/extension/models/registration.rb +1 -0
  27. data/lib/project_types/extension/models/specification.rb +3 -0
  28. data/lib/project_types/extension/models/specification_handlers/checkout_argo_extension.rb +18 -0
  29. data/lib/project_types/extension/models/specification_handlers/default.rb +49 -1
  30. data/lib/project_types/extension/models/version.rb +1 -1
  31. data/lib/project_types/extension/tasks/choose_next_available_port.rb +36 -0
  32. data/lib/project_types/extension/tasks/configure_features.rb +4 -0
  33. data/lib/project_types/extension/tasks/converters/registration_converter.rb +2 -0
  34. data/lib/project_types/extension/tasks/find_npm_packages.rb +106 -0
  35. data/lib/project_types/node/commands/generate.rb +0 -22
  36. data/lib/project_types/node/messages/messages.rb +4 -4
  37. data/lib/project_types/rails/messages/messages.rb +4 -4
  38. data/lib/project_types/script/cli.rb +7 -8
  39. data/lib/project_types/script/commands/create.rb +0 -7
  40. data/lib/project_types/script/commands/push.rb +3 -3
  41. data/lib/project_types/script/config/extension_points.yml +4 -0
  42. data/lib/project_types/script/errors.rb +0 -19
  43. data/lib/project_types/script/forms/create.rb +3 -14
  44. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +5 -5
  45. data/lib/project_types/script/graphql/get_app_scripts.graphql +6 -0
  46. data/lib/project_types/script/graphql/script_service_proxy.graphql +1 -2
  47. data/lib/project_types/script/layers/application/build_script.rb +1 -2
  48. data/lib/project_types/script/layers/application/create_script.rb +30 -51
  49. data/lib/project_types/script/layers/application/extension_points.rb +3 -2
  50. data/lib/project_types/script/layers/application/push_script.rb +5 -5
  51. data/lib/project_types/script/layers/domain/errors.rb +0 -2
  52. data/lib/project_types/script/layers/domain/extension_point.rb +56 -46
  53. data/lib/project_types/script/layers/domain/metadata.rb +18 -25
  54. data/lib/project_types/script/layers/domain/push_package.rb +4 -4
  55. data/lib/project_types/script/layers/domain/script_project.rb +54 -0
  56. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +15 -16
  57. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +13 -7
  58. data/lib/project_types/script/layers/infrastructure/command_runner.rb +19 -0
  59. data/lib/project_types/script/layers/infrastructure/errors.rb +40 -11
  60. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +12 -13
  61. data/lib/project_types/script/layers/infrastructure/rust_project_creator.rb +9 -10
  62. data/lib/project_types/script/layers/infrastructure/rust_task_runner.rb +6 -7
  63. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +172 -0
  64. data/lib/project_types/script/layers/infrastructure/script_service.rb +21 -72
  65. data/lib/project_types/script/messages/messages.rb +20 -50
  66. data/lib/project_types/script/tasks/ensure_env.rb +85 -0
  67. data/lib/project_types/script/ui/error_handler.rb +32 -30
  68. data/lib/shopify-cli/context.rb +28 -0
  69. data/lib/shopify-cli/js_system.rb +2 -2
  70. data/lib/shopify-cli/messages/messages.rb +50 -45
  71. data/lib/shopify-cli/method_object.rb +4 -4
  72. data/lib/shopify-cli/oauth.rb +9 -3
  73. data/lib/shopify-cli/packager.rb +1 -1
  74. data/lib/shopify-cli/partners_api/organizations.rb +3 -3
  75. data/lib/shopify-cli/resolve_constant.rb +1 -1
  76. data/lib/shopify-cli/resources/env_file.rb +1 -1
  77. data/lib/shopify-cli/shopifolk.rb +1 -1
  78. data/lib/shopify-cli/tasks/select_org_and_shop.rb +6 -4
  79. data/lib/shopify-cli/transform_data_structure.rb +1 -1
  80. data/lib/shopify-cli/tunnel.rb +22 -1
  81. data/lib/shopify-cli/version.rb +1 -1
  82. data/lib/shopify_cli.rb +0 -1
  83. data/vendor/deps/smart_properties/REVISION +1 -1
  84. data/vendor/deps/smart_properties/lib/smart_properties/property.rb +7 -1
  85. data/vendor/deps/smart_properties/lib/smart_properties/version.rb +1 -1
  86. metadata +16 -12
  87. data/.travis.yml +0 -14
  88. data/lib/project_types/script/commands/disable.rb +0 -25
  89. data/lib/project_types/script/commands/enable.rb +0 -80
  90. data/lib/project_types/script/graphql/shop_script_delete.graphql +0 -14
  91. data/lib/project_types/script/graphql/shop_script_update_or_create.graphql +0 -28
  92. data/lib/project_types/script/layers/application/disable_script.rb +0 -21
  93. data/lib/project_types/script/layers/application/enable_script.rb +0 -23
  94. data/lib/project_types/script/layers/infrastructure/config_ui_repository.rb +0 -46
  95. data/lib/project_types/script/script_project.rb +0 -64
@@ -5,9 +5,9 @@ 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
- :description,
11
11
  :config_ui,
12
12
  :script_content,
13
13
  :compiled_type,
@@ -15,18 +15,18 @@ module Script
15
15
 
16
16
  def initialize(
17
17
  id:,
18
+ uuid:,
18
19
  extension_point_type:,
19
20
  script_name:,
20
- description:,
21
21
  script_content:,
22
22
  compiled_type:,
23
23
  metadata:,
24
24
  config_ui:
25
25
  )
26
26
  @id = id
27
+ @uuid = uuid
27
28
  @extension_point_type = extension_point_type
28
29
  @script_name = script_name
29
- @description = description
30
30
  @script_content = script_content
31
31
  @compiled_type = compiled_type
32
32
  @metadata = metadata
@@ -35,9 +35,9 @@ module Script
35
35
 
36
36
  def push(script_service, api_key, force)
37
37
  script_service.push(
38
+ uuid: @uuid,
38
39
  extension_point_type: @extension_point_type,
39
40
  script_name: @script_name,
40
- description: @description,
41
41
  script_content: @script_content,
42
42
  compiled_type: @compiled_type,
43
43
  api_key: api_key,
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Layers
5
+ module Domain
6
+ class ScriptProject
7
+ include SmartProperties
8
+
9
+ UUID_ENV_KEY = "UUID"
10
+
11
+ property! :id, accepts: String
12
+ property :env, accepts: ShopifyCli::Resources::EnvFile
13
+
14
+ property! :extension_point_type, accepts: String
15
+ property! :script_name, accepts: String
16
+ property! :language, accepts: String
17
+
18
+ property :config_ui, accepts: ConfigUi
19
+
20
+ def initialize(*)
21
+ super
22
+
23
+ ShopifyCli::Core::Monorail.metadata = {
24
+ "script_name" => script_name,
25
+ "extension_point_type" => extension_point_type,
26
+ "language" => language,
27
+ }
28
+ end
29
+
30
+ def 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)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -12,7 +12,7 @@ module Script
12
12
 
13
13
  BOOTSTRAP = "npx --no-install shopify-scripts-toolchain-as bootstrap --from %{extension_point} --dest %{base}"
14
14
  BUILD = "shopify-scripts-toolchain-as build --src src/shopify_main.ts " \
15
- "--binary build/%{script_name}.wasm --metadata build/metadata.json"
15
+ "--binary build/script.wasm --metadata build/metadata.json"
16
16
  MIN_NODE_VERSION = "14.5.0"
17
17
  ASC_ARGS = "-- --lib node_modules --optimize --use Date="
18
18
 
@@ -22,25 +22,25 @@ module Script
22
22
  end
23
23
 
24
24
  def bootstrap
25
- out, status = ctx.capture2e(bootstap_command)
26
- raise Domain::Errors::ServiceFailureError, out unless status.success?
25
+ command_runner.call(bootstap_command)
27
26
  end
28
27
 
29
28
  private
30
29
 
30
+ def command_runner
31
+ @command_runner ||= CommandRunner.new(ctx: ctx)
32
+ end
33
+
31
34
  def write_npmrc
32
- ctx.system(
33
- "npm", "--userconfig", "./.npmrc", "config", "set", "@shopify:registry", "https://registry.npmjs.com"
34
- )
35
- ctx.system(
36
- "npm", "--userconfig", "./.npmrc", "config", "set", "engine-strict", "true"
37
- )
35
+ command_runner.call("npm --userconfig ./.npmrc config set @shopify:registry https://registry.npmjs.com")
36
+ command_runner.call("npm --userconfig ./.npmrc config set engine-strict true")
38
37
  end
39
38
 
40
39
  def extension_point_version
41
- out, status = ctx.capture2e("npm show #{extension_point.sdks.assemblyscript.package} version --json")
42
- raise Domain::Errors::ServiceFailureError, out unless status.success?
43
- JSON.parse(out)
40
+ return extension_point.sdks.assemblyscript.version if extension_point.sdks.assemblyscript.versioned?
41
+
42
+ out = command_runner.call("npm show #{extension_point.sdks.assemblyscript.package} version --json")
43
+ "^#{JSON.parse(out)}"
44
44
  end
45
45
 
46
46
  def write_package_json
@@ -51,7 +51,7 @@ module Script
51
51
  "devDependencies": {
52
52
  "@shopify/scripts-sdk-as": "#{extension_point.sdks.assemblyscript.sdk_version}",
53
53
  "@shopify/scripts-toolchain-as": "#{extension_point.sdks.assemblyscript.toolchain_version}",
54
- "#{extension_point.sdks.assemblyscript.package}": "^#{extension_point_version}",
54
+ "#{extension_point.sdks.assemblyscript.package}": "#{extension_point_version}",
55
55
  "@as-pect/cli": "^6.0.0",
56
56
  "assemblyscript": "^0.18.13"
57
57
  },
@@ -81,13 +81,12 @@ module Script
81
81
 
82
82
  def build_command
83
83
  type = extension_point.dasherize_type
84
- base_command = format(BUILD, script_name: script_name)
85
84
  domain = extension_point.domain
86
85
 
87
86
  if domain.nil?
88
- "#{base_command} #{ASC_ARGS}"
87
+ "#{BUILD} #{ASC_ARGS}"
89
88
  else
90
- "#{base_command} --domain #{domain} --ep #{type} #{ASC_ARGS}"
89
+ "#{BUILD} --domain #{domain} --ep #{type} #{ASC_ARGS}"
91
90
  end
92
91
  end
93
92
  end
@@ -63,9 +63,7 @@ module Script
63
63
 
64
64
  def compile
65
65
  check_compilation_dependencies!
66
-
67
- out, status = ctx.capture2e(SCRIPT_SDK_BUILD)
68
- raise Domain::Errors::ServiceFailureError, out unless status.success?
66
+ CommandRunner.new(ctx: ctx).call(SCRIPT_SDK_BUILD)
69
67
  end
70
68
 
71
69
  def check_compilation_dependencies!
@@ -81,11 +79,19 @@ module Script
81
79
  end
82
80
 
83
81
  def bytecode
84
- blob = format(BYTECODE_FILE, name: script_name)
85
- raise Errors::WebAssemblyBinaryNotFoundError unless @ctx.file_exist?(blob)
82
+ legacy_filename = format(BYTECODE_FILE, name: script_name)
83
+ filename = format(BYTECODE_FILE, name: "script")
84
+
85
+ bytecode_file = if ctx.file_exist?(filename)
86
+ filename
87
+ elsif ctx.file_exist?(legacy_filename)
88
+ legacy_filename
89
+ else
90
+ raise Errors::WebAssemblyBinaryNotFoundError
91
+ end
86
92
 
87
- contents = File.read(blob)
88
- @ctx.rm(blob)
93
+ contents = ctx.binread(bytecode_file)
94
+ ctx.rm(bytecode_file)
89
95
 
90
96
  contents
91
97
  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
@@ -5,8 +5,6 @@ module Script
5
5
  module Infrastructure
6
6
  module Errors
7
7
  class AppNotInstalledError < ScriptProjectError; end
8
- class AppScriptNotPushedError < ScriptProjectError; end
9
- class AppScriptUndefinedError < ScriptProjectError; end
10
8
  class BuildError < ScriptProjectError; end
11
9
  class ConfigUiSyntaxError < ScriptProjectError; end
12
10
 
@@ -19,6 +17,15 @@ module Script
19
17
  end
20
18
  end
21
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
+
22
29
  class ConfigUiFieldsMissingKeysError < ScriptProjectError
23
30
  attr_reader :filename, :missing_keys
24
31
  def initialize(filename, missing_keys)
@@ -28,9 +35,29 @@ module Script
28
35
  end
29
36
  end
30
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
+
31
47
  class DependencyInstallError < ScriptProjectError; end
48
+ class DeprecatedEPError < ScriptProjectError; end
32
49
  class EmptyResponseError < ScriptProjectError; end
33
50
  class ForbiddenError < ScriptProjectError; end
51
+ class InvalidContextError < ScriptProjectError; end
52
+
53
+ class InvalidLanguageError < ScriptProjectError
54
+ attr_reader :language, :extension_point_type
55
+ def initialize(language, extension_point_type)
56
+ super()
57
+ @language = language
58
+ @extension_point_type = extension_point_type
59
+ end
60
+ end
34
61
 
35
62
  class GraphqlError < ScriptProjectError
36
63
  attr_reader :errors
@@ -42,23 +69,25 @@ module Script
42
69
 
43
70
  class ProjectCreatorNotFoundError < ScriptProjectError; end
44
71
 
45
- class ScriptRepushError < ScriptProjectError
46
- attr_reader :api_key
47
- def initialize(api_key)
72
+ class SystemCallFailureError < ScriptProjectError
73
+ attr_reader :out, :cmd
74
+ def initialize(out:, cmd:)
48
75
  super()
49
- @api_key = api_key
76
+ @out = out
77
+ @cmd = cmd
50
78
  end
51
79
  end
52
80
 
53
- class ScriptServiceUserError < ScriptProjectError
54
- def initialize(query_name, errors)
55
- super("Failed performing #{query_name}. Errors: #{errors}.")
81
+ class ScriptRepushError < ScriptProjectError
82
+ attr_reader :uuid
83
+ def initialize(uuid)
84
+ super()
85
+ @uuid = uuid
56
86
  end
57
87
  end
58
88
 
89
+ class ScriptProjectAlreadyExistsError < ScriptProjectError; end
59
90
  class ShopAuthenticationError < ScriptProjectError; end
60
- class ShopScriptConflictError < ScriptProjectError; end
61
- class ShopScriptUndefinedError < ScriptProjectError; end
62
91
  class TaskRunnerNotFoundError < ScriptProjectError; end
63
92
  class BuildScriptNotFoundError < ScriptProjectError; end
64
93
  class InvalidBuildScriptError < ScriptProjectError; end
@@ -7,37 +7,36 @@ module Script
7
7
  include SmartProperties
8
8
  property! :ctx, accepts: ShopifyCli::Context
9
9
 
10
- def create_push_package(script_project:, script_content:, compiled_type:, metadata:, config_ui:)
11
- build_file_path = file_path(script_project.script_name, compiled_type)
10
+ def create_push_package(script_project:, script_content:, compiled_type:, metadata:)
11
+ build_file_path = file_path(script_project.id, compiled_type)
12
12
  write_to_path(build_file_path, script_content)
13
13
 
14
14
  Domain::PushPackage.new(
15
15
  id: build_file_path,
16
+ uuid: script_project.uuid,
16
17
  extension_point_type: script_project.extension_point_type,
17
18
  script_name: script_project.script_name,
18
- description: script_project.description,
19
19
  script_content: script_content,
20
20
  compiled_type: compiled_type,
21
21
  metadata: metadata,
22
- config_ui: config_ui,
22
+ config_ui: script_project.config_ui,
23
23
  )
24
24
  end
25
25
 
26
- def get_push_package(script_project:, compiled_type:, metadata:, config_ui:)
27
- build_file_path = file_path(script_project.script_name, compiled_type)
26
+ def get_push_package(script_project:, compiled_type:, metadata:)
27
+ build_file_path = file_path(script_project.id, compiled_type)
28
28
  raise Domain::PushPackageNotFoundError unless ctx.file_exist?(build_file_path)
29
29
 
30
- script_content = File.read(build_file_path)
31
-
30
+ script_content = ctx.binread(build_file_path)
32
31
  Domain::PushPackage.new(
33
32
  id: build_file_path,
33
+ uuid: script_project.uuid,
34
34
  extension_point_type: script_project.extension_point_type,
35
35
  script_name: script_project.script_name,
36
- description: script_project.description,
37
36
  script_content: script_content,
38
37
  compiled_type: compiled_type,
39
38
  metadata: metadata,
40
- config_ui: config_ui,
39
+ config_ui: script_project.config_ui,
41
40
  )
42
41
  end
43
42
 
@@ -45,11 +44,11 @@ module Script
45
44
 
46
45
  def write_to_path(path, content)
47
46
  ctx.mkdir_p(File.dirname(path))
48
- ctx.write(path, content)
47
+ ctx.binwrite(path, content)
49
48
  end
50
49
 
51
- def file_path(script_name, compiled_type)
52
- "#{ScriptProject.current.directory}/build/#{script_name}.#{compiled_type}"
50
+ def file_path(path_to_script, compiled_type)
51
+ "#{path_to_script}/build/script.#{compiled_type}"
53
52
  end
54
53
  end
55
54
  end
@@ -27,28 +27,27 @@ module Script
27
27
 
28
28
  private
29
29
 
30
+ def command_runner
31
+ @command_runner ||= CommandRunner.new(ctx: ctx)
32
+ end
33
+
30
34
  def git_init
31
- out, status = ctx.capture2e("git init")
32
- raise Domain::Errors::ServiceFailureError, out unless status.success?
35
+ command_runner.call("git init")
33
36
  end
34
37
 
35
38
  def setup_remote
36
39
  repo = extension_point.sdks.rust.package
37
- out, status = ctx.capture2e("git remote add -f origin #{repo}")
38
- raise Domain::Errors::ServiceFailureError, out unless status.success?
40
+ command_runner.call("git remote add -f origin #{repo}")
39
41
  end
40
42
 
41
43
  def setup_sparse_checkout
42
44
  type = extension_point.type
43
- out, status = ctx.capture2e("git config core.sparsecheckout true")
44
- raise Domain::Errors::ServiceFailureError, out unless status.success?
45
- out, status = ctx.capture2e("echo #{type}/#{SAMPLE_PATH} >> .git/info/sparse-checkout")
46
- raise Domain::Errors::ServiceFailureError, out unless status.success?
45
+ command_runner.call("git config core.sparsecheckout true")
46
+ command_runner.call("echo #{type}/#{SAMPLE_PATH} >> .git/info/sparse-checkout")
47
47
  end
48
48
 
49
49
  def pull
50
- out, status = ctx.capture2e("git pull origin #{ORIGIN_BRANCH}")
51
- raise Domain::Errors::ServiceFailureError, out unless status.success?
50
+ command_runner.call("git pull origin #{ORIGIN_BRANCH}")
52
51
  end
53
52
 
54
53
  def clean
@@ -3,14 +3,14 @@ module Script
3
3
  module Layers
4
4
  module Infrastructure
5
5
  class RustTaskRunner
6
- attr_reader :ctx, :script_name
6
+ attr_reader :ctx
7
7
 
8
8
  BUILD_TARGET = "wasm32-unknown-unknown"
9
9
  METADATA_FILE = "build/metadata.json"
10
+ CARGO_BUILD_CMD = "cargo build --target=#{BUILD_TARGET} --release"
10
11
 
11
- def initialize(ctx, script_name)
12
+ def initialize(ctx, _)
12
13
  @ctx = ctx
13
- @script_name = script_name
14
14
  end
15
15
 
16
16
  def dependencies_installed?
@@ -42,16 +42,15 @@ module Script
42
42
  private
43
43
 
44
44
  def compile
45
- out, status = ctx.capture2e("cargo build --target=#{BUILD_TARGET} --release")
46
- raise Domain::Errors::ServiceFailureError, out unless status.success?
45
+ CommandRunner.new(ctx: ctx).call(CARGO_BUILD_CMD)
47
46
  end
48
47
 
49
48
  def bytecode
50
- binary_name = "#{script_name}.wasm"
49
+ binary_name = "script.wasm"
51
50
  binary_path = "target/#{BUILD_TARGET}/release/#{binary_name}"
52
51
  raise Errors::WebAssemblyBinaryNotFoundError unless ctx.file_exist?(binary_path)
53
52
 
54
- File.read(binary_path)
53
+ ctx.binread(binary_path)
55
54
  end
56
55
  end
57
56
  end