Module: RunApi::Suno::Validators

Defined in:
lib/runapi/suno/validators.rb

Constant Summary collapse

MUSIC_PROMPT_SHAPE_ERROR =
"choose a valid vocal_mode: auto_lyrics, exact_lyrics, or instrumental"

Class Method Summary collapse

Class Method Details

.param(resource, params, key) ⇒ Object



198
199
200
# File 'lib/runapi/suno/validators.rb', line 198

def param(resource, params, key)
  resource.send(:param, params, key)
end

.require_all!(resource, params, *keys) ⇒ Object



190
191
192
# File 'lib/runapi/suno/validators.rb', line 190

def require_all!(resource, params, *keys)
  keys.each { |key| require_param!(resource, params, key) }
end

.require_param!(resource, params, key) ⇒ Object

Raises:

  • (Core::ValidationError)


194
195
196
# File 'lib/runapi/suno/validators.rb', line 194

def require_param!(resource, params, key)
  raise Core::ValidationError, "#{key} is required" if param(resource, params, key).nil?
end

.truthy?(value) ⇒ Boolean

Returns:

  • (Boolean)


206
207
208
# File 'lib/runapi/suno/validators.rb', line 206

def truthy?(value)
  [true, 1, "1", "true", "TRUE", "True"].include?(value)
end

.truthy_presence?(value) ⇒ Boolean

Returns:

  • (Boolean)


210
211
212
213
214
# File 'lib/runapi/suno/validators.rb', line 210

def truthy_presence?(value)
  return !value.empty? if value.respond_to?(:empty?)

  !value.nil?
end

.validate_add_instrumental!(params, resource) ⇒ Object



52
53
54
55
56
# File 'lib/runapi/suno/validators.rb', line 52

def validate_add_instrumental!(params, resource)
  require_all!(resource, params, :upload_url, :title, :negative_tags, :tags, :model)
  validate_optional!(resource, params, :model, Types::MODELS)
  validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
end

.validate_add_vocals!(params, resource) ⇒ Object



58
59
60
61
62
# File 'lib/runapi/suno/validators.rb', line 58

def validate_add_vocals!(params, resource)
  require_all!(resource, params, :upload_url, :lyrics, :title, :negative_tags, :style, :model)
  validate_optional!(resource, params, :model, Types::MODELS)
  validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
end

.validate_boost_style!(params, resource) ⇒ Object



147
148
149
# File 'lib/runapi/suno/validators.rb', line 147

def validate_boost_style!(params, resource)
  require_param!(resource, params, :description)
end

.validate_check_voice!(params, resource) ⇒ Object



139
140
141
# File 'lib/runapi/suno/validators.rb', line 139

def validate_check_voice!(params, resource)
  require_param!(resource, params, :task_id)
end

.validate_convert_audio!(params, resource) ⇒ Object



73
74
75
# File 'lib/runapi/suno/validators.rb', line 73

def validate_convert_audio!(params, resource)
  require_all!(resource, params, :task_id, :audio_id)
end

.validate_cover_audio!(params, resource) ⇒ Object



42
43
44
45
46
47
48
49
50
# File 'lib/runapi/suno/validators.rb', line 42

def validate_cover_audio!(params, resource)
  require_param!(resource, params, :upload_url)
  require_param!(resource, params, :model)
  validate_music_prompt_shape!(params, resource)
  validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
  validate_optional!(resource, params, :model, Types::MODELS)
  validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
  validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
end

.validate_create_mashup!(params, resource) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/runapi/suno/validators.rb', line 96

def validate_create_mashup!(params, resource)
  upload_url_list = param(resource, params, :upload_url_list)
  unless upload_url_list.is_a?(Array) && upload_url_list.size == 2
    raise Core::ValidationError, "upload_url_list must contain exactly 2 URLs"
  end
  require_param!(resource, params, :model)
  validate_music_prompt_shape!(params, resource)
  validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
  validate_optional!(resource, params, :model, Types::MODELS)
  validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
  validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
end

.validate_extend_music!(params, resource) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/runapi/suno/validators.rb', line 19

def validate_extend_music!(params, resource)
  unless %i[task_id audio_id audio_url upload_url].any? { |key| param(resource, params, key) }
    raise Core::ValidationError, "task_id, audio_id, audio_url, or upload_url is required"
  end
  require_param!(resource, params, :parameter_mode)
  require_param!(resource, params, :model)

  validate_optional!(resource, params, :parameter_mode, Types::PARAMETER_MODES)
  if param(resource, params, :parameter_mode) == "custom"
    require_param!(resource, params, :style)
    require_param!(resource, params, :title)
    require_param!(resource, params, :continue_at)
  end
  validate_extend_music_prompt_shape!(params, resource)
  validate_optional!(resource, params, :model, Types::MODELS)
  validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
  validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
end

.validate_extend_music_prompt_shape!(params, resource) ⇒ Object

Raises:

  • (Core::ValidationError)


173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/runapi/suno/validators.rb', line 173

def validate_extend_music_prompt_shape!(params, resource)
  return unless truthy_presence?(param(resource, params, :lyrics))

  if truthy_presence?(param(resource, params, :prompt))
    raise Core::ValidationError, "prompt cannot be combined with lyrics"
  end

  if truthy?(param(resource, params, :instrumental))
    raise Core::ValidationError, "lyrics cannot be used when instrumental is true"
  end

  upload_mode = %i[audio_url upload_url].any? { |key| truthy_presence?(param(resource, params, key)) }
  return if param(resource, params, :parameter_mode) == "custom" && upload_mode

  raise Core::ValidationError, "lyrics can only be used when extending uploaded audio with custom parameters"
end

.validate_generate_artwork!(params, resource) ⇒ Object



38
39
40
# File 'lib/runapi/suno/validators.rb', line 38

def validate_generate_artwork!(params, resource)
  require_param!(resource, params, :task_id)
end

.validate_generate_lyrics!(params, resource) ⇒ Object



81
82
83
# File 'lib/runapi/suno/validators.rb', line 81

def validate_generate_lyrics!(params, resource)
  require_param!(resource, params, :prompt)
end

.validate_generate_midi!(params, resource) ⇒ Object



69
70
71
# File 'lib/runapi/suno/validators.rb', line 69

def validate_generate_midi!(params, resource)
  require_param!(resource, params, :task_id)
end

.validate_generate_persona!(params, resource) ⇒ Object



143
144
145
# File 'lib/runapi/suno/validators.rb', line 143

def validate_generate_persona!(params, resource)
  require_all!(resource, params, :task_id, :audio_id, :name, :description)
end

.validate_generate_voice!(params, resource) ⇒ Object



134
135
136
137
# File 'lib/runapi/suno/validators.rb', line 134

def validate_generate_voice!(params, resource)
  require_all!(resource, params, :task_id, :verify_url)
  validate_optional!(resource, params, :singer_skill_level, Types::SINGER_SKILL_LEVELS)
end

.validate_get_timestamped_lyrics!(params, resource) ⇒ Object



85
86
87
# File 'lib/runapi/suno/validators.rb', line 85

def validate_get_timestamped_lyrics!(params, resource)
  require_all!(resource, params, :task_id, :audio_id)
end

.validate_music_prompt_shape!(params, resource) ⇒ Object

Raises:

  • (Core::ValidationError)


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/runapi/suno/validators.rb', line 151

def validate_music_prompt_shape!(params, resource)
  mode = param(resource, params, :vocal_mode).to_s
  has_prompt = truthy_presence?(param(resource, params, :prompt))
  has_lyrics = truthy_presence?(param(resource, params, :lyrics))
  has_style = truthy_presence?(param(resource, params, :style))
  has_title = truthy_presence?(param(resource, params, :title))

  valid_shape = case mode
  when "auto_lyrics"
    has_prompt && !has_lyrics && !has_style && !has_title
  when "exact_lyrics"
    !has_prompt && has_lyrics && has_style && has_title
  when "instrumental"
    !has_prompt && !has_lyrics && has_style && has_title
  else
    false
  end
  return if valid_shape

  raise Core::ValidationError, MUSIC_PROMPT_SHAPE_ERROR
end

.validate_optional!(resource, params, key, allowed) ⇒ Object



202
203
204
# File 'lib/runapi/suno/validators.rb', line 202

def validate_optional!(resource, params, key, allowed)
  resource.send(:validate_optional!, params, key, allowed)
end

.validate_regenerate_validation_phrase!(params, resource) ⇒ Object



130
131
132
# File 'lib/runapi/suno/validators.rb', line 130

def validate_regenerate_validation_phrase!(params, resource)
  require_param!(resource, params, :task_id)
end

.validate_replace_section!(params, resource) ⇒ Object



89
90
91
92
93
94
# File 'lib/runapi/suno/validators.rb', line 89

def validate_replace_section!(params, resource)
  require_all!(resource, params, :task_id, :audio_id, :lyrics, :tags, :title, :infill_start_time, :infill_end_time)
  if param(resource, params, :infill_end_time).to_f <= param(resource, params, :infill_start_time).to_f
    raise Core::ValidationError, "infill_end_time must be greater than infill_start_time"
  end
end

.validate_separate_audio_stems!(params, resource) ⇒ Object



64
65
66
67
# File 'lib/runapi/suno/validators.rb', line 64

def validate_separate_audio_stems!(params, resource)
  require_all!(resource, params, :task_id, :audio_id)
  validate_optional!(resource, params, :type, Types::SEPARATE_AUDIO_STEMS_TYPES)
end

.validate_text_to_music!(params, resource) ⇒ Object



10
11
12
13
14
15
16
17
# File 'lib/runapi/suno/validators.rb', line 10

def validate_text_to_music!(params, resource)
  validate_music_prompt_shape!(params, resource)
  require_param!(resource, params, :model)
  validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
  validate_optional!(resource, params, :model, Types::MODELS)
  validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
  validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
end

.validate_text_to_sound!(params, resource) ⇒ Object



109
110
111
112
113
114
115
116
117
# File 'lib/runapi/suno/validators.rb', line 109

def validate_text_to_sound!(params, resource)
  require_all!(resource, params, :prompt, :model)
  validate_optional!(resource, params, :model, Types::SOUND_MODELS)
  validate_optional!(resource, params, :sound_key, Types::SOUND_KEYS)
  tempo = param(resource, params, :sound_tempo)
  if tempo && !(1..300).cover?(tempo.to_i)
    raise Core::ValidationError, "sound_tempo must be between 1 and 300"
  end
end

.validate_visualize_music!(params, resource) ⇒ Object



77
78
79
# File 'lib/runapi/suno/validators.rb', line 77

def validate_visualize_music!(params, resource)
  require_all!(resource, params, :task_id, :audio_id)
end

.validate_voice_to_validation_phrase!(params, resource) ⇒ Object

Raises:

  • (Core::ValidationError)


119
120
121
122
123
124
125
126
127
128
# File 'lib/runapi/suno/validators.rb', line 119

def validate_voice_to_validation_phrase!(params, resource)
  require_all!(resource, params, :voice_url, :vocal_start_seconds, :vocal_end_seconds)
  validate_optional!(resource, params, :language, Types::VALIDATION_PHRASE_LANGUAGES)

  start_seconds = param(resource, params, :vocal_start_seconds).to_i
  end_seconds = param(resource, params, :vocal_end_seconds).to_i
  return if end_seconds > start_seconds

  raise Core::ValidationError, "vocal_end_seconds must be greater than vocal_start_seconds"
end