shopify-cli 1.6.0 → 1.9.1

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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +15 -2
  3. data/CHANGELOG.md +21 -0
  4. data/Gemfile +12 -12
  5. data/Gemfile.lock +14 -14
  6. data/Rakefile +32 -30
  7. data/bin/load_shopify.rb +6 -6
  8. data/bin/shopify +2 -2
  9. data/dev.yml +3 -0
  10. data/ext/shopify-cli/extconf.rb +7 -7
  11. data/lib/docgen/markdown.rb +12 -12
  12. data/lib/graphql/extension_create.graphql +17 -2
  13. data/lib/graphql/fetch_specifications.graphql +14 -0
  14. data/lib/{project_types/extension/graphql → graphql}/get_app_by_api_key.graphql +0 -0
  15. data/lib/project_types/extension/cli.rb +56 -55
  16. data/lib/project_types/extension/commands/build.rb +3 -3
  17. data/lib/project_types/extension/commands/create.rb +17 -10
  18. data/lib/project_types/extension/commands/extension_command.rb +14 -7
  19. data/lib/project_types/extension/commands/push.rb +10 -10
  20. data/lib/project_types/extension/commands/register.rb +22 -32
  21. data/lib/project_types/extension/commands/serve.rb +1 -7
  22. data/lib/project_types/extension/commands/tunnel.rb +12 -12
  23. data/lib/project_types/extension/extension_project.rb +22 -7
  24. data/lib/project_types/extension/extension_project_keys.rb +5 -4
  25. data/lib/project_types/extension/features/argo.rb +26 -42
  26. data/lib/project_types/extension/features/argo_config.rb +5 -5
  27. data/lib/project_types/extension/features/argo_dependencies.rb +5 -5
  28. data/lib/project_types/extension/features/argo_renderer_package.rb +47 -0
  29. data/lib/project_types/extension/features/argo_serve.rb +69 -0
  30. data/lib/project_types/extension/features/argo_setup.rb +3 -3
  31. data/lib/project_types/extension/features/argo_setup_steps.rb +4 -4
  32. data/lib/project_types/extension/forms/create.rb +28 -34
  33. data/lib/project_types/extension/forms/questions/ask_app.rb +53 -0
  34. data/lib/project_types/extension/forms/questions/ask_name.rb +40 -0
  35. data/lib/project_types/extension/forms/questions/ask_type.rb +47 -0
  36. data/lib/project_types/extension/messages/message_loading.rb +3 -1
  37. data/lib/project_types/extension/messages/messages.rb +55 -55
  38. data/lib/project_types/extension/models/lazy_specification_handler.rb +12 -0
  39. data/lib/project_types/extension/models/registration.rb +1 -0
  40. data/lib/project_types/extension/models/specification.rb +6 -2
  41. data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +1 -1
  42. data/lib/project_types/extension/models/specification_handlers/default.rb +10 -2
  43. data/lib/project_types/extension/models/specifications.rb +14 -3
  44. data/lib/project_types/extension/models/version.rb +1 -1
  45. data/lib/project_types/extension/tasks/configure_features.rb +7 -5
  46. data/lib/project_types/extension/tasks/converters/app_converter.rb +6 -6
  47. data/lib/project_types/extension/tasks/converters/registration_converter.rb +8 -6
  48. data/lib/project_types/extension/tasks/converters/validation_error_converter.rb +4 -4
  49. data/lib/project_types/extension/tasks/converters/version_converter.rb +7 -7
  50. data/lib/project_types/extension/tasks/create_extension.rb +4 -4
  51. data/lib/project_types/extension/tasks/fetch_specifications.rb +8 -28
  52. data/lib/project_types/extension/tasks/get_app.rb +4 -4
  53. data/lib/project_types/extension/tasks/get_apps.rb +3 -3
  54. data/lib/project_types/extension/tasks/update_draft.rb +4 -4
  55. data/lib/project_types/extension/tasks/user_errors.rb +4 -4
  56. data/lib/project_types/node/cli.rb +19 -19
  57. data/lib/project_types/node/commands/connect.rb +3 -3
  58. data/lib/project_types/node/commands/create.rb +40 -38
  59. data/lib/project_types/node/commands/deploy.rb +4 -4
  60. data/lib/project_types/node/commands/deploy/heroku.rb +24 -24
  61. data/lib/project_types/node/commands/generate.rb +2 -24
  62. data/lib/project_types/node/commands/open.rb +2 -2
  63. data/lib/project_types/node/commands/populate.rb +6 -6
  64. data/lib/project_types/node/commands/populate/customer.rb +5 -5
  65. data/lib/project_types/node/commands/populate/draft_order.rb +5 -5
  66. data/lib/project_types/node/commands/populate/product.rb +5 -5
  67. data/lib/project_types/node/commands/serve.rb +9 -9
  68. data/lib/project_types/node/commands/tunnel.rb +7 -7
  69. data/lib/project_types/node/forms/create.rb +17 -8
  70. data/lib/project_types/node/messages/messages.rb +8 -7
  71. data/lib/project_types/rails/cli.rb +21 -21
  72. data/lib/project_types/rails/commands/connect.rb +3 -3
  73. data/lib/project_types/rails/commands/create.rb +51 -48
  74. data/lib/project_types/rails/commands/deploy.rb +4 -4
  75. data/lib/project_types/rails/commands/deploy/heroku.rb +30 -30
  76. data/lib/project_types/rails/commands/generate.rb +7 -7
  77. data/lib/project_types/rails/commands/generate/webhook.rb +6 -6
  78. data/lib/project_types/rails/commands/open.rb +2 -2
  79. data/lib/project_types/rails/commands/populate.rb +6 -6
  80. data/lib/project_types/rails/commands/populate/customer.rb +5 -5
  81. data/lib/project_types/rails/commands/populate/draft_order.rb +5 -5
  82. data/lib/project_types/rails/commands/populate/product.rb +5 -5
  83. data/lib/project_types/rails/commands/serve.rb +11 -11
  84. data/lib/project_types/rails/commands/tunnel.rb +7 -7
  85. data/lib/project_types/rails/forms/create.rb +34 -24
  86. data/lib/project_types/rails/gem.rb +23 -23
  87. data/lib/project_types/rails/messages/messages.rb +9 -8
  88. data/lib/project_types/rails/ruby.rb +2 -2
  89. data/lib/project_types/script/cli.rb +36 -40
  90. data/lib/project_types/script/commands/create.rb +9 -13
  91. data/lib/project_types/script/commands/push.rb +6 -5
  92. data/lib/project_types/script/config/extension_points.yml +25 -10
  93. data/lib/project_types/script/errors.rb +1 -19
  94. data/lib/project_types/script/forms/create.rb +7 -18
  95. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +7 -5
  96. data/lib/project_types/script/graphql/script_service_proxy.graphql +1 -2
  97. data/lib/project_types/script/layers/application/build_script.rb +6 -8
  98. data/lib/project_types/script/layers/application/create_script.rb +34 -24
  99. data/lib/project_types/script/layers/application/extension_points.rb +3 -2
  100. data/lib/project_types/script/layers/application/project_dependencies.rb +4 -4
  101. data/lib/project_types/script/layers/application/push_script.rb +10 -15
  102. data/lib/project_types/script/layers/domain/config_ui.rb +16 -0
  103. data/lib/project_types/script/layers/domain/errors.rb +16 -0
  104. data/lib/project_types/script/layers/domain/extension_point.rb +60 -45
  105. data/lib/project_types/script/layers/domain/metadata.rb +18 -25
  106. data/lib/project_types/script/layers/domain/push_package.rb +9 -5
  107. data/lib/project_types/script/layers/domain/script_project.rb +38 -0
  108. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +39 -10
  109. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +9 -44
  110. data/lib/project_types/script/layers/infrastructure/errors.rb +50 -19
  111. data/lib/project_types/script/layers/infrastructure/extension_point_repository.rb +2 -2
  112. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +16 -21
  113. data/lib/project_types/script/layers/infrastructure/rust_project_creator.rb +4 -4
  114. data/lib/project_types/script/layers/infrastructure/rust_task_runner.rb +2 -2
  115. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +179 -0
  116. data/lib/project_types/script/layers/infrastructure/script_service.rb +35 -78
  117. data/lib/project_types/script/messages/messages.rb +33 -57
  118. data/lib/project_types/script/ui/error_handler.rb +116 -88
  119. data/lib/project_types/script/ui/printing_spinner.rb +1 -1
  120. data/lib/project_types/script/ui/strict_spinner.rb +1 -1
  121. data/lib/project_types/theme/cli.rb +19 -19
  122. data/lib/project_types/theme/commands/connect.rb +12 -12
  123. data/lib/project_types/theme/commands/create.rb +11 -11
  124. data/lib/project_types/theme/commands/deploy.rb +8 -8
  125. data/lib/project_types/theme/commands/generate.rb +3 -3
  126. data/lib/project_types/theme/commands/generate/env.rb +15 -15
  127. data/lib/project_types/theme/commands/push.rb +15 -15
  128. data/lib/project_types/theme/commands/serve.rb +5 -5
  129. data/lib/project_types/theme/forms/connect.rb +4 -4
  130. data/lib/project_types/theme/forms/create.rb +5 -5
  131. data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +22 -22
  132. data/lib/project_types/theme/themekit.rb +15 -15
  133. data/lib/rubygems_plugin.rb +3 -3
  134. data/lib/shopify-cli/admin_api.rb +11 -11
  135. data/lib/shopify-cli/admin_api/populate_resource_command.rb +17 -17
  136. data/lib/shopify-cli/admin_api/schema.rb +3 -3
  137. data/lib/shopify-cli/api.rb +10 -10
  138. data/lib/shopify-cli/command.rb +1 -1
  139. data/lib/shopify-cli/commands.rb +9 -9
  140. data/lib/shopify-cli/commands/config.rb +28 -52
  141. data/lib/shopify-cli/commands/connect.rb +10 -10
  142. data/lib/shopify-cli/commands/create.rb +5 -5
  143. data/lib/shopify-cli/commands/help.rb +6 -6
  144. data/lib/shopify-cli/commands/logout.rb +3 -3
  145. data/lib/shopify-cli/commands/system.rb +32 -32
  146. data/lib/shopify-cli/commands/version.rb +2 -2
  147. data/lib/shopify-cli/context.rb +51 -23
  148. data/lib/shopify-cli/core.rb +4 -4
  149. data/lib/shopify-cli/core/entry_point.rb +5 -5
  150. data/lib/shopify-cli/core/executor.rb +1 -1
  151. data/lib/shopify-cli/core/help_resolver.rb +2 -2
  152. data/lib/shopify-cli/core/monorail.rb +16 -16
  153. data/lib/shopify-cli/db.rb +2 -2
  154. data/lib/shopify-cli/feature.rb +1 -1
  155. data/lib/shopify-cli/form.rb +1 -1
  156. data/lib/shopify-cli/git.rb +17 -17
  157. data/lib/shopify-cli/helpers.rb +1 -1
  158. data/lib/shopify-cli/helpers/haikunator.rb +1 -1
  159. data/lib/shopify-cli/heroku.rb +28 -28
  160. data/lib/shopify-cli/http_request.rb +2 -2
  161. data/lib/shopify-cli/js_deps.rb +12 -12
  162. data/lib/shopify-cli/js_system.rb +7 -7
  163. data/lib/shopify-cli/lazy_delegator.rb +55 -0
  164. data/lib/shopify-cli/messages/messages.rb +7 -16
  165. data/lib/shopify-cli/method_object.rb +1 -1
  166. data/lib/shopify-cli/oauth.rb +27 -27
  167. data/lib/shopify-cli/oauth/servlet.rb +9 -9
  168. data/lib/shopify-cli/options.rb +3 -3
  169. data/lib/shopify-cli/packager.rb +25 -25
  170. data/lib/shopify-cli/partners_api.rb +16 -16
  171. data/lib/shopify-cli/partners_api/organizations.rb +10 -10
  172. data/lib/shopify-cli/process_supervision.rb +7 -7
  173. data/lib/shopify-cli/project.rb +16 -16
  174. data/lib/shopify-cli/project_type.rb +3 -3
  175. data/lib/shopify-cli/resolve_constant.rb +1 -1
  176. data/lib/shopify-cli/resources.rb +1 -1
  177. data/lib/shopify-cli/resources/env_file.rb +10 -10
  178. data/lib/shopify-cli/result.rb +11 -11
  179. data/lib/shopify-cli/shopifolk.rb +6 -9
  180. data/lib/shopify-cli/sub_command.rb +1 -1
  181. data/lib/shopify-cli/task.rb +3 -3
  182. data/lib/shopify-cli/tasks.rb +7 -7
  183. data/lib/shopify-cli/tasks/create_api_client.rb +5 -5
  184. data/lib/shopify-cli/tasks/ensure_dev_store.rb +12 -12
  185. data/lib/shopify-cli/tasks/ensure_env.rb +15 -15
  186. data/lib/shopify-cli/tasks/ensure_loopback_url.rb +4 -4
  187. data/lib/shopify-cli/tasks/select_org_and_shop.rb +19 -19
  188. data/lib/shopify-cli/tasks/update_dashboard_urls.rb +10 -10
  189. data/lib/shopify-cli/transform_data_structure.rb +86 -0
  190. data/lib/shopify-cli/tunnel.rb +30 -30
  191. data/lib/shopify-cli/version.rb +1 -1
  192. data/lib/shopify_cli.rb +56 -54
  193. data/shopify-cli.gemspec +6 -6
  194. data/vendor/deps/smart_properties/REVISION +1 -1
  195. data/vendor/deps/smart_properties/lib/smart_properties/property.rb +7 -1
  196. data/vendor/deps/smart_properties/lib/smart_properties/version.rb +1 -1
  197. data/vendor/gen/template/bin/update-deps +9 -9
  198. metadata +15 -11
  199. data/lib/project_types/extension/forms/register.rb +0 -47
  200. data/lib/project_types/script/commands/disable.rb +0 -25
  201. data/lib/project_types/script/commands/enable.rb +0 -78
  202. data/lib/project_types/script/graphql/shop_script_delete.graphql +0 -14
  203. data/lib/project_types/script/graphql/shop_script_update_or_create.graphql +0 -28
  204. data/lib/project_types/script/layers/application/disable_script.rb +0 -21
  205. data/lib/project_types/script/layers/application/enable_script.rb +0 -23
  206. data/lib/project_types/script/script_project.rb +0 -63
@@ -10,8 +10,8 @@ module Script
10
10
  property! :script_name, accepts: String
11
11
  property! :path_to_project, accepts: String
12
12
 
13
- ORIGIN_BRANCH = 'main'
14
- SAMPLE_PATH = 'default'
13
+ ORIGIN_BRANCH = "main"
14
+ SAMPLE_PATH = "default"
15
15
 
16
16
  def setup_dependencies
17
17
  git_init
@@ -60,8 +60,8 @@ module Script
60
60
  end
61
61
 
62
62
  def set_script_name
63
- config_file = 'Cargo.toml'
64
- upstream_name = "#{extension_point.type.gsub('_', '-')}-default"
63
+ config_file = "Cargo.toml"
64
+ upstream_name = "#{extension_point.type.gsub("_", "-")}-default"
65
65
  contents = File.read(config_file)
66
66
  new_contents = contents.sub(upstream_name, script_name)
67
67
  File.write(config_file, new_contents)
@@ -31,7 +31,7 @@ module Script
31
31
 
32
32
  def metadata
33
33
  unless @ctx.file_exist?(METADATA_FILE)
34
- msg = @ctx.message('script.error.metadata_not_found_cause', METADATA_FILE)
34
+ msg = @ctx.message("script.error.metadata_not_found_cause", METADATA_FILE)
35
35
  raise Domain::Errors::MetadataNotFoundError, msg
36
36
  end
37
37
 
@@ -51,7 +51,7 @@ module Script
51
51
  binary_path = "target/#{BUILD_TARGET}/release/#{binary_name}"
52
52
  raise Errors::WebAssemblyBinaryNotFoundError unless ctx.file_exist?(binary_path)
53
53
 
54
- File.read(binary_path)
54
+ ctx.binread(binary_path)
55
55
  end
56
56
  end
57
57
  end
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Layers
5
+ module Infrastructure
6
+ class ScriptProjectRepository
7
+ include SmartProperties
8
+ property! :ctx, accepts: ShopifyCli::Context
9
+
10
+ DEFAULT_CONFIG_UI_FILENAME = "config-ui.yml"
11
+ MUTABLE_ENV_VALUES = %i(uuid)
12
+
13
+ def create(script_name:, extension_point_type:, language:, no_config_ui:)
14
+ validate_metadata!(extension_point_type, language)
15
+
16
+ optional_identifiers = {}
17
+ config_ui_file = nil
18
+
19
+ unless no_config_ui
20
+ optional_identifiers.merge!(config_ui_file: DEFAULT_CONFIG_UI_FILENAME)
21
+ config_ui_file = ConfigUiRepository
22
+ .new(ctx: ctx)
23
+ .create(DEFAULT_CONFIG_UI_FILENAME, default_config_ui_content(script_name))
24
+ end
25
+
26
+ ShopifyCli::Project.write(
27
+ ctx,
28
+ project_type: :script,
29
+ organization_id: nil,
30
+ extension_point_type: extension_point_type,
31
+ script_name: script_name,
32
+ language: language,
33
+ **optional_identifiers
34
+ )
35
+
36
+ Domain::ScriptProject.new(
37
+ id: ctx.root,
38
+ env: project.env,
39
+ script_name: script_name,
40
+ extension_point_type: extension_point_type,
41
+ language: language,
42
+ config_ui: config_ui_file
43
+ )
44
+ end
45
+
46
+ def get
47
+ validate_metadata!(extension_point_type, language)
48
+
49
+ config_ui = ConfigUiRepository.new(ctx: ctx).get(config_ui_file)
50
+
51
+ Domain::ScriptProject.new(
52
+ id: project.directory,
53
+ env: project.env,
54
+ script_name: script_name,
55
+ extension_point_type: extension_point_type,
56
+ language: language,
57
+ config_ui: config_ui
58
+ )
59
+ end
60
+
61
+ def update_env(**args)
62
+ capture_io do
63
+ args.slice(*MUTABLE_ENV_VALUES).each do |key, value|
64
+ project.env.extra[key.to_s.upcase] = value
65
+ project.env.update(ctx, :extra, project.env.extra)
66
+ end
67
+ end
68
+
69
+ Domain::ScriptProject.new(
70
+ id: ctx.root,
71
+ env: project.env,
72
+ script_name: script_name,
73
+ extension_point_type: extension_point_type,
74
+ language: language,
75
+ config_ui: ConfigUiRepository.new(ctx: ctx).get(config_ui_file),
76
+ )
77
+ end
78
+
79
+ private
80
+
81
+ def capture_io(&block)
82
+ CLI::UI::StdoutRouter::Capture.new(&block).run
83
+ end
84
+
85
+ def extension_point_type
86
+ project_config_value!("extension_point_type")
87
+ end
88
+
89
+ def script_name
90
+ project_config_value!("script_name")
91
+ end
92
+
93
+ def config_ui_file
94
+ project_config_value("config_ui_file")
95
+ end
96
+
97
+ def language
98
+ project_config_value("language")&.downcase || default_language
99
+ end
100
+
101
+ def project_config_value(key)
102
+ return nil unless project.config.key?(key)
103
+ project.config[key]
104
+ end
105
+
106
+ def project_config_value!(key)
107
+ raise Errors::InvalidContextError, key unless project.config.key?(key)
108
+ project.config[key]
109
+ end
110
+
111
+ def project
112
+ ShopifyCli::Project.current
113
+ end
114
+
115
+ def default_config_ui_content(title)
116
+ require "yaml" # takes 20ms, so deferred as late as possible.
117
+ YAML.dump({
118
+ "version" => 1,
119
+ "inputMode" => "single",
120
+ "title" => title,
121
+ "description" => "",
122
+ "fields" => [],
123
+ })
124
+ end
125
+
126
+ def default_language
127
+ Domain::ExtensionPoint::ExtensionPointAssemblyScriptSDK.language
128
+ end
129
+
130
+ def validate_metadata!(extension_point_type, language)
131
+ if Application::ExtensionPoints.deprecated_types.include?(extension_point_type)
132
+ raise Errors::DeprecatedEPError, extension_point_type
133
+ elsif !Application::ExtensionPoints.supported_language?(type: extension_point_type, language: language)
134
+ raise Errors::InvalidLanguageError.new(language, extension_point_type)
135
+ end
136
+ end
137
+
138
+ class ConfigUiRepository
139
+ include SmartProperties
140
+ property! :ctx, accepts: ShopifyCli::Context
141
+
142
+ def create(filename, content)
143
+ File.write(filename, content)
144
+
145
+ Domain::ConfigUi.new(
146
+ filename: filename,
147
+ content: content,
148
+ )
149
+ end
150
+
151
+ def get(filename)
152
+ return nil unless filename
153
+
154
+ path = File.join(ctx.root, filename)
155
+ raise Domain::Errors::MissingSpecifiedConfigUiDefinitionError, filename unless File.exist?(path)
156
+
157
+ content = File.read(path)
158
+ raise Domain::Errors::InvalidConfigUiDefinitionError, filename unless valid_config_ui?(content)
159
+
160
+ Domain::ConfigUi.new(
161
+ filename: filename,
162
+ content: content,
163
+ )
164
+ end
165
+
166
+ private
167
+
168
+ def valid_config_ui?(raw_yaml)
169
+ require "yaml" # takes 20ms, so deferred as late as possible.
170
+ YAML.safe_load(raw_yaml)
171
+ true
172
+ rescue Psych::SyntaxError
173
+ false
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -11,20 +11,22 @@ module Script
11
11
  property! :ctx, accepts: ShopifyCli::Context
12
12
 
13
13
  def push(
14
+ uuid:,
14
15
  extension_point_type:,
15
16
  script_name:,
16
17
  script_content:,
17
18
  compiled_type:,
18
- description: nil,
19
19
  api_key: nil,
20
20
  force: false,
21
- metadata:
21
+ metadata:,
22
+ config_ui:
22
23
  )
23
24
  query_name = "app_script_update_or_create"
24
25
  variables = {
26
+ uuid: uuid,
25
27
  extensionPointName: extension_point_type.upcase,
26
28
  title: script_name,
27
- description: description,
29
+ configUi: config_ui&.content,
28
30
  sourceCode: Base64.encode64(script_content),
29
31
  language: compiled_type,
30
32
  force: force,
@@ -35,92 +37,47 @@ module Script
35
37
  resp_hash = script_service_request(query_name: query_name, api_key: api_key, variables: variables)
36
38
  user_errors = resp_hash["data"]["appScriptUpdateOrCreate"]["userErrors"]
37
39
 
38
- return resp_hash if user_errors.empty?
40
+ return resp_hash["data"]["appScriptUpdateOrCreate"]["appScript"]["uuid"] if user_errors.empty?
39
41
 
40
- if user_errors.any? { |e| e['tag'] == 'already_exists_error' }
42
+ if user_errors.any? { |e| e["tag"] == "already_exists_error" }
41
43
  raise Errors::ScriptRepushError, api_key
44
+ elsif (e = user_errors.any? { |err| err["tag"] == "config_ui_syntax_error" })
45
+ raise Errors::ConfigUiSyntaxError, config_ui&.filename
46
+ elsif (e = user_errors.find { |err| err["tag"] == "config_ui_missing_keys_error" })
47
+ raise Errors::ConfigUiMissingKeysError.new(config_ui&.filename, e["message"])
48
+ elsif (e = user_errors.find { |err| err["tag"] == "config_ui_invalid_input_mode_error" })
49
+ raise Errors::ConfigUiInvalidInputModeError.new(config_ui&.filename, e["message"])
50
+ elsif (e = user_errors.find { |err| err["tag"] == "config_ui_fields_missing_keys_error" })
51
+ raise Errors::ConfigUiFieldsMissingKeysError.new(config_ui&.filename, e["message"])
52
+ elsif (e = user_errors.find { |err| err["tag"] == "config_ui_fields_invalid_type_error" })
53
+ raise Errors::ConfigUiFieldsInvalidTypeError.new(config_ui&.filename, e["message"])
54
+ elsif user_errors.find { |err| %w(not_use_msgpack_error schema_version_argument_error).include?(err["tag"]) }
55
+ raise Domain::Errors::MetadataValidationError
42
56
  else
43
- raise Errors::ScriptServiceUserError.new(query_name, user_errors.to_s)
44
- end
45
- end
46
-
47
- def enable(api_key:, shop_domain:, configuration:, extension_point_type:, title:)
48
- query_name = "shop_script_update_or_create"
49
- variables = {
50
- extensionPointName: extension_point_type.upcase,
51
- configuration: configuration,
52
- title: title,
53
- }
54
-
55
- resp_hash = script_service_request(
56
- query_name: query_name,
57
- api_key: api_key,
58
- shop_domain: format_shop_domain(shop_domain),
59
- variables: variables,
60
- )
61
- user_errors = resp_hash["data"]["shopScriptUpdateOrCreate"]["userErrors"]
62
-
63
- return resp_hash if user_errors.empty?
64
-
65
- if user_errors.any? { |e| e['tag'] == 'app_script_not_found' }
66
- raise Errors::AppScriptUndefinedError, api_key
67
- elsif user_errors.any? { |e| e['tag'] == 'shop_script_conflict' }
68
- raise Errors::ShopScriptConflictError
69
- elsif user_errors.any? { |e| e['tag'] == 'app_script_not_pushed' }
70
- raise Errors::AppScriptNotPushedError
71
- else
72
- raise Errors::ScriptServiceUserError.new(query_name, user_errors.to_s)
73
- end
74
- end
75
-
76
- def disable(api_key:, shop_domain:, extension_point_type:)
77
- query_name = "shop_script_delete"
78
- variables = {
79
- extensionPointName: extension_point_type.upcase,
80
- }
81
-
82
- resp_hash = script_service_request(
83
- query_name: query_name,
84
- api_key: api_key,
85
- shop_domain: format_shop_domain(shop_domain),
86
- variables: variables,
87
- )
88
- user_errors = resp_hash["data"]["shopScriptDelete"]["userErrors"]
89
- return resp_hash if user_errors.empty?
90
-
91
- if user_errors.any? { |e| e['tag'] == 'shop_script_not_found' }
92
- raise Errors::ShopScriptUndefinedError, api_key
93
- else
94
- raise Errors::ScriptServiceUserError.new(query_name, user_errors.to_s)
57
+ raise Errors::GraphqlError, user_errors
95
58
  end
96
59
  end
97
60
 
98
61
  private
99
62
 
100
- def format_shop_domain(shop_domain)
101
- shop_domain.delete_suffix("/")
102
- end
103
-
104
63
  class ScriptServiceAPI < ShopifyCli::API
105
64
  property(:api_key, accepts: String)
106
- property(:shop_id, accepts: Integer)
107
65
 
108
- def self.query(ctx, query_name, api_key: nil, shop_domain: nil, variables: {})
109
- api_client(ctx, api_key, shop_domain).query(query_name, variables: variables)
66
+ def self.query(ctx, query_name, api_key: nil, variables: {})
67
+ api_client(ctx, api_key).query(query_name, variables: variables)
110
68
  end
111
69
 
112
- def self.api_client(ctx, api_key, shop_domain)
70
+ def self.api_client(ctx, api_key)
113
71
  new(
114
72
  ctx: ctx,
115
- url: 'https://script-service.myshopify.io/graphql',
116
- token: '',
117
- api_key: api_key,
118
- shop_id: shop_domain&.to_i
73
+ url: "https://script-service.myshopify.io/graphql",
74
+ token: "",
75
+ api_key: api_key
119
76
  )
120
77
  end
121
78
 
122
79
  def auth_headers(*)
123
- tokens = { "APP_KEY" => api_key, "SHOP_ID" => shop_id }.compact.to_json
80
+ tokens = { "APP_KEY" => api_key }.compact.to_json
124
81
  { "X-Shopify-Authenticated-Tokens" => tokens }
125
82
  end
126
83
  end
@@ -148,28 +105,28 @@ module Script
148
105
  options[:variables] = variables.to_json if variables
149
106
  resp = PartnersProxyAPI.query(ctx, query_name, **options)
150
107
  raise_if_graphql_failed(resp)
151
- JSON.parse(resp['data']['scriptServiceProxy'])
108
+ JSON.parse(resp["data"]["scriptServiceProxy"])
152
109
  end
153
110
 
154
111
  def raise_if_graphql_failed(response)
155
112
  raise Errors::EmptyResponseError if response.nil?
156
113
 
157
- return unless response.key?('errors')
158
- case error_code(response['errors'])
159
- when 'forbidden'
114
+ return unless response.key?("errors")
115
+ case error_code(response["errors"])
116
+ when "forbidden"
160
117
  raise Errors::ForbiddenError
161
- when 'forbidden_on_shop'
118
+ when "forbidden_on_shop"
162
119
  raise Errors::ShopAuthenticationError
163
- when 'app_not_installed_on_shop'
120
+ when "app_not_installed_on_shop"
164
121
  raise Errors::AppNotInstalledError
165
122
  else
166
- raise Errors::GraphqlError, response['errors'].map { |e| e['message'] }
123
+ raise Errors::GraphqlError, response["errors"]
167
124
  end
168
125
  end
169
126
 
170
127
  def error_code(errors)
171
128
  errors.map do |e|
172
- code = e.dig('extensions', 'code')
129
+ code = e.dig("extensions", "code")
173
130
  return code if code
174
131
  end
175
132
  end
@@ -21,20 +21,20 @@ module Script
21
21
  invalid_context_cause: "Your .shopify-cli.yml file is not correct.",
22
22
  invalid_context_help: "See https://help.shopify.com",
23
23
 
24
- invalid_config_props_cause: "{{command:--config_props}} is formatted incorrectly.",
24
+ invalid_config_props_cause: "{{command:--config-props}} is formatted incorrectly.",
25
25
  invalid_config_props_help: "Try again using this format: "\
26
- "{{cyan:--config_props='name1:value1, name2:value2'}}",
26
+ "{{cyan:--config-props='name1:value1, name2:value2'}}",
27
27
 
28
28
  invalid_script_name_cause: "Invalid script name.",
29
29
  invalid_script_name_help: "Replace or remove unsupported characters. Valid characters "\
30
30
  "are numbers, letters, hyphens, or underscores.",
31
31
 
32
32
  no_existing_apps_cause: "You don't have any apps.",
33
- no_existing_apps_help: "Please create an app with {{command:shopify create}} or "\
33
+ no_existing_apps_help: "Create an app with {{command:shopify create}} or "\
34
34
  "visit https://partners.shopify.com/.",
35
35
 
36
36
  no_existing_orgs_cause: "You don't have any partner organizations.",
37
- no_existing_orgs_help: "Please visit https://partners.shopify.com/ to create a partners account.",
37
+ no_existing_orgs_help: "Visit https://partners.shopify.com/ to create a partners account.",
38
38
 
39
39
  no_existing_stores_cause: "You don't have any stores.",
40
40
  no_existing_stores_help: "Visit https://partners.shopify.com/%{organization_id}/stores/ to create one.",
@@ -51,14 +51,36 @@ module Script
51
51
  invalid_config: "Can't change the configuration values because %1$s is missing or "\
52
52
  "it is not formatted properly.",
53
53
 
54
+ invalid_config_ui_definition_cause: "The UI configuration file %s contains invalid YAML.",
55
+ invalid_config_ui_definition_help: "Fix the errors and try again.",
56
+
57
+ missing_config_ui_definition_cause: "You are missing the UI configuration file %s.",
58
+ missing_config_ui_definition_help: "Create this file and try again.",
59
+
60
+ config_ui_syntax_error_cause: "The UI configuration file %{filename} is not formatted properly.",
61
+ config_ui_syntax_error_help: "Fix the errors and try again.",
62
+
63
+ config_ui_missing_keys_error_cause: "The UI configuration file %{filename} is missing required keys: "\
64
+ "%{missing_keys}.",
65
+ config_ui_missing_keys_error_help: "Add the keys and try again.",
66
+
67
+ config_ui_invalid_input_mode_error_cause: "The UI configuration file %{filename} only accept "\
68
+ "one of the following input mode(s): %{valid_input_modes}.",
69
+ config_ui_invalid_input_mode_error_help: "Change the input modes and try again.",
70
+
71
+ config_ui_fields_missing_keys_error_cause: "A field entry in the UI configuration file %{filename} is "\
72
+ "missing required keys: %{missing_keys}.",
73
+ config_ui_fields_missing_keys_error_help: "Add the keys and try again.",
74
+
75
+ config_ui_fields_invalid_type_error_cause: "The UI configuration file %{filename} fields only accept "\
76
+ "one of the following type(s): %{valid_types}.",
77
+ config_ui_fields_invalid_type_error_help: "Change the types and try again.",
78
+
54
79
  script_not_found_cause: "Couldn't find script %s for extension point %s",
55
80
 
56
81
  service_failure_cause: "Internal service error.",
57
82
  service_failure_help: "Ensure the 'shopify/scripts-toolchain-as' package is up to date.",
58
83
 
59
- user_error_cause: "Invalid script extension metadata.",
60
- user_error_help: "Ensure the 'shopify/scripts-toolchain-as' package is up to date.",
61
-
62
84
  metadata_validation_cause: "Invalid script extension metadata.",
63
85
  metadata_validation_help: "Ensure the 'shopify/scripts-toolchain-as' package is up to date.",
64
86
 
@@ -77,8 +99,6 @@ module Script
77
99
  "'--metadata build/metadata.json' argument",
78
100
  app_not_installed_cause: "App not installed on store.",
79
101
 
80
- app_script_not_pushed_help: "Script isn't on the app. Run {{command:shopify push}}, and then try again.",
81
-
82
102
  build_error_cause: "Something went wrong while building the script.",
83
103
  build_error_help: "Correct the errors and try again.",
84
104
 
@@ -99,22 +119,13 @@ module Script
99
119
  shop_auth_cause: "Unable to authenticate with the store.",
100
120
  shop_auth_help: "Try again.",
101
121
 
102
- shop_script_conflict_cause: "Another app in this store has already enabled a script "\
103
- "on this extension point.",
104
- shop_script_conflict_help: "Disable that script or uninstall that app and try again.",
105
-
106
- shop_script_undefined_cause: "Script is already turned off in store.",
107
-
108
- packages_outdated_cause: "These npm packages are out of date: %s.",
109
- packages_outdated_help: "To update them, run {{cyan:npm install --save-dev %s}}.",
110
-
111
122
  invalid_build_script: "The root package.json contains an invalid build command that " \
112
123
  "is needed to compile your script to WebAssembly.",
113
124
  build_script_not_found: "The root package.json is missing the build command that " \
114
125
  "is needed to compile your script to WebAssembly.",
115
126
  # rubocop:disable Layout/LineLength
116
127
  build_script_suggestion: "\n\nFor example, your package.json needs the following command:" \
117
- "\nbuild: npx shopify-scripts-toolchain-as build --src src/script.ts --binary build/<script_name>.wasm --metadata build/metadata.json -- --lib node_modules --optimize --use Date=",
128
+ "\nbuild: npx shopify-scripts-toolchain-as build --src src/shopify_main.ts --binary build/<script_name>.wasm --metadata build/metadata.json -- --lib node_modules --optimize --use Date=",
118
129
 
119
130
  web_assembly_binary_not_found: "WebAssembly binary not found.",
120
131
  web_assembly_binary_not_found_suggestion: "No WebAssembly binary found." \
@@ -128,8 +139,8 @@ module Script
128
139
  Usage: {{command:%1$s create script}}
129
140
  Options:
130
141
  {{command:--name=NAME}} Script project name. Use any string.
131
- {{command:--description=DESCRIPTION}} Description of the project. Use any string.
132
- {{command:--extension_point=TYPE}} Extension point name. Allowed values: %2$s.
142
+ {{command:--extension-point=TYPE}} Extension point name. Allowed values: %2$s.
143
+ {{command:--no-config-ui}} Specify this option if you don’t want Scripts to render an interface in the Shopify admin.
133
144
  HELP
134
145
 
135
146
  error: {
@@ -150,46 +161,12 @@ module Script
150
161
  HELP
151
162
 
152
163
  error: {
153
- operation_failed: "Couldn't push script to app.",
164
+ operation_failed: "Couldn't push script to app (API key: %{api_key}).",
154
165
  },
155
166
 
156
167
  script_pushed: "{{v}} Script pushed to app (API key: %{api_key}).",
157
168
  },
158
169
 
159
- disable: {
160
- help: <<~HELP,
161
- Turn off script in store.
162
- Usage: {{command:%s disable}}
163
- HELP
164
-
165
- error: {
166
- operation_failed: "Can't disable script.",
167
- },
168
-
169
- script_disabled: "{{v}} Script disabled. Script is turned off in store.",
170
- },
171
-
172
- enable: {
173
- help: <<~HELP,
174
- Turn on script in store.
175
- Usage: {{command:%s enable}}
176
- Options:
177
- {{command:--config_props='name1:value1, name2:value2'}} Optional. Define the configuration of your script by passing individual name and value pairs. If used with --config_file, then matching values in --config_props will override those set in the file.
178
- {{command:--config_file=<path/to/YAMLFilename>}} Optional. Define the configuration of your script using a YAML formatted file. --config_props values override properties in this file.
179
- HELP
180
-
181
- info: "{{*}} A script always remains enabled until you disable it - even after pushing "\
182
- "script changes with the same extension point to an app. To disable a script, use "\
183
- "the 'disable' command.",
184
-
185
- error: {
186
- operation_failed: "Can't enable script.",
187
- },
188
-
189
- script_enabled: "{{v}} Script enabled. %{type} script %{title} in app (API key: %{api_key}) "\
190
- "is turned on in store {{green:%{shop_domain}}}",
191
- },
192
-
193
170
  project_deps: {
194
171
  none_required: "{{v}} None required",
195
172
  checking_with_npm: "Checking dependencies with npm",
@@ -202,7 +179,6 @@ module Script
202
179
  select_extension_point: "Which extension point do you want to use?",
203
180
  select_language: "Which language do you want to use?",
204
181
  script_name: "Script Name",
205
- description: "Description",
206
182
  },
207
183
  },
208
184