validates_im 1.0.0 → 2.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5cfe1d609f713d30dcf5b90085dab8637eab5698c0f6e4353339a2dc6665837c
4
+ data.tar.gz: 6c88205ae65806151b99b58825268ccb6e8b6be226ab0060438c116ec8c93f65
5
+ SHA512:
6
+ metadata.gz: 90b9c447eedb4d79e1d03b61b3a9eaf9c8db9a1a8258461235b83a769223836fc7b160044d239a38f42187b7c643117bb77e55c0caeeab74dcbed8d521ee2fb1
7
+ data.tar.gz: c0a71cc4bcedc20b4d693afa6e989377219df7d365fb75e1c7576bb60803304ec306559f59dd7ed127522146d1b3bd3be5901013c07a389b1da98522913e4543
data/CHANGELOG.md ADDED
@@ -0,0 +1,48 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [2.0.0] - 2026-05-14
9
+
10
+ ### Added
11
+ - `DiscordValidator` (`discord: true`) — modern Discord usernames (2-32 chars,
12
+ `a-z0-9._`, no leading/trailing or consecutive periods, no discriminator).
13
+ - `TelegramValidator` (`telegram: true`) — 5-32 chars, alphanumeric + underscore,
14
+ must start with a letter, cannot end with `_`. Optional leading `@` is stripped.
15
+ - `MatrixValidator` (`matrix: true`) — full Matrix user ID syntax
16
+ (`@localpart:domain.tld`) per the current Matrix specification; max 255 chars.
17
+ - `SignalValidator` (`signal: true`) — Signal usernames (2024+), of the form
18
+ `<base>.<digits>` with a 2+ digit discriminator.
19
+ - `min_length 3` / `max_length 12` on `XboxLiveValidator` so empty / overlong
20
+ gamertags now produce sensible errors instead of crashing on `nil[0]`.
21
+ - Modern, hand-written gemspec with `rubygems_mfa_required` metadata.
22
+ - `lib/validates_im/version.rb` exposing `ValidatesIm::VERSION`.
23
+ - GitHub Actions matrix CI across Ruby 3.1-3.4 and ActiveModel 7.0-8.0.
24
+
25
+ ### Changed
26
+ - Validator regex anchors use `\A` and `\z` instead of `^` and `$`, closing a
27
+ multi-line bypass where an embedded newline would cause obviously-invalid
28
+ values to pass.
29
+ - Bumped minimum supported Ruby to 3.1, minimum ActiveModel/ActiveSupport to 6.1.
30
+ - Replaced the activerecord runtime dependency with `activemodel` (and
31
+ `activesupport`); the gem never required ActiveRecord.
32
+ - Replaced jeweler-driven packaging with a standard gemspec, `bin/console`,
33
+ `bin/setup`, modern `Gemfile` / `Rakefile`.
34
+
35
+ ### Fixed
36
+ - `lib/validates_im.rb` no longer self-requires itself in an infinite loop.
37
+ - Removed duplicate `add_dependency` entries (activerecord, rspec, yard, jeweler)
38
+ and stale `README.textile` references in the gemspec.
39
+ - Gemfile now declares `redcarpet` consistently with the Rakefile's YARD setup
40
+ (previous mismatch with `RedCloth` in the gemspec).
41
+
42
+ ### Removed
43
+ - Jeweler-managed gemspec template / `VERSION` text file.
44
+ - The legacy `.travis.yml` and old `ruby.yml` workflow (superseded by `ci.yml`).
45
+
46
+ ## [1.1.0]
47
+
48
+ Previous release. See git history.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Tim Morgan
1
+ Copyright (c) 2010 Tim Morgan
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ validates_im
2
+ ============
3
+
4
+ [![CI](https://github.com/RISCfuture/validates_im/actions/workflows/ci.yml/badge.svg)](https://github.com/RISCfuture/validates_im/actions/workflows/ci.yml)
5
+ [![Gem Version](https://img.shields.io/gem/v/validates_im.svg)](https://rubygems.org/gems/validates_im)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+
8
+ **Instant messenger account validators for ActiveModel / Rails**
9
+
10
+ `validates_im` is a small gem that gives you a collection of
11
+ `ActiveModel::EachValidator`s for common instant-messaging and gaming-service
12
+ account names. Drop one onto an attribute and your model will reject malformed
13
+ account IDs at validation time.
14
+
15
+ Supported services
16
+ ------------------
17
+
18
+ Modern services:
19
+
20
+ | Validator | DSL key | Description |
21
+ |:-----------------------|:--------------|:-----------------------------------------------------------------------------|
22
+ | `DiscordValidator` | `discord:` | Discord usernames (post-2023 format, no discriminator) |
23
+ | `TelegramValidator` | `telegram:` | Telegram usernames (`@handle` style; leading `@` is stripped automatically) |
24
+ | `MatrixValidator` | `matrix:` | Matrix IDs of the form `@localpart:domain.tld` per the Matrix specification |
25
+ | `SignalValidator` | `signal:` | Signal usernames (`base.NN` with a 2+ digit discriminator) |
26
+ | `SteamValidator` | `steam:` | Steam account IDs |
27
+ | `XboxLiveValidator` | `xbox_live:` | Xbox Live gamertags |
28
+
29
+ Legacy services (kept for backwards compatibility; these services are largely
30
+ defunct):
31
+
32
+ | Validator | DSL key | Description |
33
+ |:----------------------|:-------------|:-------------------------------------|
34
+ | `AimValidator` | `aim:` | AOL Instant Messenger screen names |
35
+ | `YahooImValidator` | `yahoo_im:` | Yahoo! Messenger screen names |
36
+ | `SkypeValidator` | `skype:` | Skype account names |
37
+
38
+ Installation
39
+ ------------
40
+
41
+ Add this line to your application's `Gemfile`:
42
+
43
+ ```ruby
44
+ gem "validates_im"
45
+ ```
46
+
47
+ And then execute:
48
+
49
+ ```shell
50
+ bundle install
51
+ ```
52
+
53
+ Or install it yourself as:
54
+
55
+ ```shell
56
+ gem install validates_im
57
+ ```
58
+
59
+ Requires Ruby 3.1+ and ActiveModel 6.1+. The gem works in any project that uses
60
+ ActiveModel validations — Rails is not required, just ActiveModel.
61
+
62
+ Usage
63
+ -----
64
+
65
+ The validators are standard `EachValidator`s. Use them via `validates`:
66
+
67
+ ```ruby
68
+ class Account < ApplicationRecord
69
+ validates :discord_handle, discord: true, allow_blank: true
70
+ validates :telegram_handle, telegram: true, allow_blank: true
71
+ validates :matrix_id, matrix: true, allow_blank: true
72
+ validates :signal_username, signal: true, allow_blank: true
73
+ validates :steam_id, steam: true, allow_blank: true
74
+ validates :xbox_gamertag, xbox_live: true, allow_blank: true
75
+ end
76
+ ```
77
+
78
+ The DSL key for a validator is its class name with the `Validator` suffix
79
+ stripped and underscored — so `XboxLiveValidator` becomes `xbox_live:`.
80
+
81
+ Each validator supports the usual `:allow_nil`, `:allow_blank`, and `:message`
82
+ options. Error messages are localized via Rails i18n; the localization keys are
83
+ documented in each validator's class comment.
84
+
85
+ Writing your own validator
86
+ --------------------------
87
+
88
+ `AccountNameValidator` provides a small DSL for declarative account-name
89
+ validators. To add a hypothetical "Talkalot" service:
90
+
91
+ ```ruby
92
+ class TalkalotValidator < AccountNameValidator
93
+ min_length 5
94
+ max_length 64
95
+ valid_chars "A-Za-z0-9_"
96
+ first_char "A-Za-z"
97
+
98
+ add_validation(:no_double_underscore) { |value| !value.include?("__") }
99
+ end
100
+ ```
101
+
102
+ For services whose IDs don't fit the simple "single account-name string" mould
103
+ (like Matrix's full `@user:server.tld` syntax), subclass
104
+ `ActiveModel::EachValidator` directly — see `MatrixValidator` for an example.
105
+
106
+ License
107
+ -------
108
+
109
+ MIT. See `LICENSE`.
@@ -1,4 +1,8 @@
1
- # Generic @EachValidator@ that validates account names on various communication
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/filters"
4
+
5
+ # Generic `EachValidator` that validates account names on various communication
2
6
  # services such as Skype, Yahoo!, etc. This class provides a simple DSL for
3
7
  # describing valid account names on these sites, performing all validation for
4
8
  # you.
@@ -6,67 +10,68 @@
6
10
  # Subclass this class and use the provided DSL to describe account names on a
7
11
  # given site. An example for a fictional service called Talkalot:
8
12
  #
9
- # <pre><code>
13
+ # ```` ruby
10
14
  # class TalkalotValidator < AccountNameValidator
11
15
  # min_length 5
12
16
  # max_length 64
13
17
  # valid_chars "A-Z0-9_"
14
18
  # end
15
- # </code></pre>
19
+ # ````
16
20
  #
17
21
  # With your validator defined you can now use it in your Active Record models
18
- # like any other @EachValidator@:
22
+ # like any other `EachValidator`:
19
23
  #
20
- # <pre><code>
24
+ # ```` ruby
21
25
  # validates :talkalot_id,
22
26
  # talkalot: true
23
- # </code></pre>
27
+ # ````
24
28
  #
25
29
  # This class automatically handles the following options passed to the
26
- # @validates@ method:
30
+ # `validates` method:
27
31
  #
28
- # | @:allow_nil@ | Allows @nil@ values. |
29
- # | @:message@ | Provide a custom error message. |
32
+ # | | |
33
+ # |:-------------|:--------------------------------|
34
+ # | `:allow_nil` | Allows `nil` values. |
35
+ # | `:message` | Provide a custom error message. |
30
36
  #
31
37
  # Error messages generated by this class are stored in the translation table.
32
38
  # The localization keys used are generated by the
33
- # @ActiveModel::Errors#generate_message@ method (see its documentation for more
39
+ # `ActiveModel::Errors#generate_message` method (see its documentation for more
34
40
  # information). The lastmost element of the localization key is the error
35
41
  # message key. The error message key is a combination of a validator subclass's
36
42
  # {.error_key_prefix} and the error key suffix for a given constraint.
37
43
  #
38
44
  # By default the error key prefix is the underscored
39
45
  #
40
- # As an example, for the @TalkalotValidator@ example above, the error message
46
+ # As an example, for the `TalkalotValidator` example above, the error message
41
47
  # key used in the event that a two-letter account name is given would be
42
- # @:talkalot_too_short@. If you wanted to override the prefix, you could do:
48
+ # `:talkalot_too_short`. If you wanted to override the prefix, you could do:
43
49
  #
44
- # <pre><code>
50
+ # ```` ruby
45
51
  # class TalkalotValidator < AccountNameValidator
46
52
  # error_key_prefix :talky
47
53
  # end
48
- # </code></pre>
54
+ # ````
49
55
  #
50
56
  # In this case the error message key for a two-letter account name would be
51
- # @:talky_too_short@. (You'd do this if Talkalot accounts were called "talkies,"
57
+ # `:talky_too_short`. (You'd do this if Talkalot accounts were called "talkies,"
52
58
  # for example.)
53
59
  #
54
60
  # @abstract Subclass this validator to perform your specific account name
55
61
  # validations.
56
62
 
57
63
  class AccountNameValidator < ActiveModel::EachValidator
58
- class_inheritable_array :validations
64
+ class_attribute :validations
59
65
  self.validations = Array.new
60
66
 
61
67
  # @private
62
68
  def validate_each(record, attribute, value)
63
- return if options[:allow_nil] and value.nil?
64
- return if options[:allow_blank] and value.blank?
69
+ return if options[:allow_nil] && value.nil?
70
+ return if options[:allow_blank] && value.blank?
65
71
  return unless self.class.validations
66
- self.class.validations.each { |block, key| record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :"#{self.class.error_key_prefix}_#{key}")) if !block[value.to_s] }
67
- end
68
72
 
69
- protected
73
+ self.class.validations.each { |block, key| record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :"#{self.class.error_key_prefix}_#{key}")) unless block[value.to_s] }
74
+ end
70
75
 
71
76
  # @overload error_key_prefix
72
77
  # Returns the prefix for error message keys used by this class.
@@ -77,11 +82,9 @@ class AccountNameValidator < ActiveModel::EachValidator
77
82
  # @param [Symbol] value The new error message key prefix.
78
83
 
79
84
  def self.error_key_prefix(value=nil)
80
- if value then
81
- @error_key_prefix = value
82
- else
83
- return @error_key_prefix || to_s.demodulize.sub(/Validator$/, '').underscore.to_sym
84
- end
85
+ return @error_key_prefix || to_s.demodulize.sub(/Validator$/, "").underscore.to_sym unless value
86
+
87
+ @error_key_prefix = value
85
88
  end
86
89
 
87
90
  # Describes a custom restraint on account names.
@@ -89,12 +92,13 @@ class AccountNameValidator < ActiveModel::EachValidator
89
92
  # @param [Symbol] key The error message key suffix to use.
90
93
  # @yield [value] The custom validation.
91
94
  # @yieldparam [String] value The value to validate. This will have been
92
- # coerced into a @String@.
95
+ # coerced into a `String`.
93
96
  # @yieldreturn [true, false] Whether or not the validation succeeded.
94
97
 
95
98
  def self.add_validation(key, &block)
96
- return unless block_given?
97
- self.validations << [ block, key ]
99
+ return unless block
100
+
101
+ self.validations += [[block, key]]
98
102
  end
99
103
 
100
104
  # Enforces a minimum length on account names. Uses the "too_short" error
@@ -122,7 +126,7 @@ class AccountNameValidator < ActiveModel::EachValidator
122
126
  # format (e.g., "[A-Z0-9_]").
123
127
 
124
128
  def self.valid_chars(charlist)
125
- add_validation(:invalid_chars) { |value| value =~ /^[#{charlist}]+$/ }
129
+ add_validation(:invalid_chars) { |value| value =~ /\A[#{charlist}]+\z/ }
126
130
  end
127
131
 
128
132
  # Enforces a valid set of characters for the first character of the account
@@ -132,6 +136,6 @@ class AccountNameValidator < ActiveModel::EachValidator
132
136
  # format (e.g., "[A-Z0-9_]").
133
137
 
134
138
  def self.first_char(charlist)
135
- add_validation(:invalid_first_char) { |value| value[0] =~ /^[#{charlist}]$/ }
139
+ add_validation(:invalid_first_char) { |value| value[0] =~ /\A[#{charlist}]\z/ }
136
140
  end
137
141
  end
data/lib/aim_validator.rb CHANGED
@@ -1,25 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Validates AOL Instant Messenger screen names. According to the AOL website:
2
4
  #
3
- # bq. 3-16 letters or numbers. It must start with a letter.
5
+ # > 3-16 letters or numbers. It must start with a letter.
4
6
  #
5
7
  # The following error message keys are used to localize invalid screen names:
6
8
  #
7
- # | @aim_too_short@ | Screen name is less than 3 characters. |
8
- # | @aim_too_long@ | Screen name is over 16 characters. |
9
- # | @aim_invalid_chars@ | Screen name contains invalid characters. |
10
- # | @aim_invalid_first_char@ | Screen name doesn't start with a letter. |
9
+ # | | |
10
+ # |:-------------------------|:-----------------------------------------|
11
+ # | `aim_too_short` | Screen name is less than 3 characters. |
12
+ # | `aim_too_long` | Screen name is over 16 characters. |
13
+ # | `aim_invalid_chars` | Screen name contains invalid characters. |
14
+ # | `aim_invalid_first_char` | Screen name doesn't start with a letter. |
11
15
  #
12
16
  # @example
13
17
  # validates :aim_screen_name, aim: true
14
18
  #
15
- # h2. Options
19
+ # Options
20
+ # -------
16
21
  #
17
- # | @:message@ | A custom message to use if the email is invalid. |
18
- # | @:allow_nil@ | If true, @nil@ values are allowed. |
22
+ # | | |
23
+ # |:-------------|:-------------------------------------------------|
24
+ # | `:message` | A custom message to use if the email is invalid. |
25
+ # | `:allow_nil` | If true, `nil` values are allowed. |
19
26
 
20
27
  class AimValidator < AccountNameValidator
21
28
  min_length 3
22
29
  max_length 16
23
- valid_chars 'A-Za-z0-9'
24
- first_char 'A-Za-z'
30
+ valid_chars "A-Za-z0-9"
31
+ first_char "A-Za-z"
25
32
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Validates Discord usernames using the modern (post-2023) username format.
4
+ # Discord eliminated the four-digit `#1234` discriminator system in 2023; usernames
5
+ # are now globally unique and use the rules below:
6
+ #
7
+ # * 2-32 characters long
8
+ # * Lowercase letters (`a`-`z`), digits (`0`-`9`), underscore (`_`), and period (`.`)
9
+ # * No consecutive periods (`..`)
10
+ # * Cannot start or end with a period
11
+ #
12
+ # The following error message keys are used to localize invalid usernames:
13
+ #
14
+ # | | |
15
+ # |:-----------------------------|:--------------------------------------------------------|
16
+ # | `discord_too_short` | Username is less than 2 characters. |
17
+ # | `discord_too_long` | Username is over 32 characters. |
18
+ # | `discord_invalid_chars` | Username contains characters outside `[a-z0-9._]`. |
19
+ # | `discord_invalid_format` | Username has consecutive periods or starts/ends with a period. |
20
+ #
21
+ # @example
22
+ # validates :discord, discord: true
23
+ #
24
+ # Options
25
+ # -------
26
+ #
27
+ # | | |
28
+ # |:-------------|:-------------------------------------------------|
29
+ # | `:message` | A custom message to use if the username is invalid. |
30
+ # | `:allow_nil` | If true, `nil` values are allowed. |
31
+
32
+ class DiscordValidator < AccountNameValidator
33
+ min_length 2
34
+ max_length 32
35
+ valid_chars "a-z0-9._"
36
+ add_validation(:invalid_format) do |value|
37
+ !value.include?("..") && !value.start_with?(".") && !value.end_with?(".")
38
+ end
39
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Validates Matrix user IDs in the form `@localpart:domain.tld` per the Matrix
4
+ # specification (https://spec.matrix.org/latest/appendices/#user-identifiers).
5
+ #
6
+ # * Begins with `@`.
7
+ # * Localpart consists of lowercase letters `a`-`z`, digits `0`-`9`, and any of
8
+ # `-`, `_`, `.`, `=`, `/`, `+`.
9
+ # * `:` separator between the localpart and the server name (domain).
10
+ # * The server name is a hostname (with optional port).
11
+ # * The entire ID must be 255 characters or fewer.
12
+ #
13
+ # Historical Matrix IDs allowed additional characters in the localpart; this
14
+ # validator enforces the current ("grammar") rules from the spec.
15
+ #
16
+ # The following error message keys are used to localize invalid IDs:
17
+ #
18
+ # | | |
19
+ # |:-------------------------|:--------------------------------------|
20
+ # | `matrix_too_long` | ID is over 255 characters. |
21
+ # | `matrix_invalid_format` | ID does not match `@localpart:domain`. |
22
+ #
23
+ # @example
24
+ # validates :matrix_id, matrix: true
25
+ #
26
+ # Options
27
+ # -------
28
+ #
29
+ # | | |
30
+ # |:-------------|:-------------------------------------------------|
31
+ # | `:message` | A custom message to use if the ID is invalid. |
32
+ # | `:allow_nil` | If true, `nil` values are allowed. |
33
+
34
+ class MatrixValidator < ActiveModel::EachValidator
35
+ MAX_LENGTH = 255
36
+
37
+ # Localpart per the Matrix spec, restricted to the documented character set.
38
+ LOCALPART = %r{[a-z0-9._=/+\-]+}.freeze
39
+
40
+ # A reasonably-strict hostname or IP literal, optionally followed by `:port`.
41
+ HOSTNAME_LABEL = /[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?/.freeze
42
+ HOSTNAME = /#{HOSTNAME_LABEL}(?:\.#{HOSTNAME_LABEL})*/.freeze
43
+ IPV4 = /(?:\d{1,3}\.){3}\d{1,3}/.freeze
44
+ IPV6 = /\[[0-9A-Fa-f:.]+\]/.freeze
45
+ SERVERNAME = /(?:#{IPV6}|#{IPV4}|#{HOSTNAME})(?::\d{1,5})?/.freeze
46
+
47
+ FORMAT = /\A@#{LOCALPART}:#{SERVERNAME}\z/.freeze
48
+
49
+ def validate_each(record, attribute, value)
50
+ return if options[:allow_nil] && value.nil?
51
+ return if options[:allow_blank] && value.blank?
52
+
53
+ str = value.to_s
54
+
55
+ if str.length > MAX_LENGTH
56
+ record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :matrix_too_long))
57
+ end
58
+
59
+ unless str.match?(FORMAT)
60
+ record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :matrix_invalid_format))
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Validates Signal usernames. Signal introduced usernames in 2024; they consist
4
+ # of a base name and a numeric discriminator separated by a period:
5
+ #
6
+ # <base>.<digits>
7
+ #
8
+ # * Base: starts with a letter, contains letters, digits, and underscores.
9
+ # * Discriminator: two or more digits (leading zeros allowed, e.g. `0123`).
10
+ # * Combined length 3-32 characters (matching Signal's UI constraints).
11
+ #
12
+ # The following error message keys are used to localize invalid usernames:
13
+ #
14
+ # | | |
15
+ # |:-----------------------------|:---------------------------------------------------------------|
16
+ # | `signal_too_short` | Username is less than 3 characters. |
17
+ # | `signal_too_long` | Username is over 32 characters. |
18
+ # | `signal_invalid_format` | Username doesn't match `<base>.<digits>` with a valid base. |
19
+ #
20
+ # @example
21
+ # validates :signal_username, signal: true
22
+ #
23
+ # Options
24
+ # -------
25
+ #
26
+ # | | |
27
+ # |:-------------|:-------------------------------------------------|
28
+ # | `:message` | A custom message to use if the username is invalid. |
29
+ # | `:allow_nil` | If true, `nil` values are allowed. |
30
+
31
+ class SignalValidator < AccountNameValidator
32
+ FORMAT = /\A[A-Za-z][A-Za-z0-9_]*\.\d{2,}\z/.freeze
33
+
34
+ min_length 3
35
+ max_length 32
36
+ add_validation(:invalid_format) { |value| value.match?(FORMAT) }
37
+ end
@@ -1,26 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Validates Skype screen names. From the Skype website:
2
4
  #
3
- # bq. It must be between 6-32 characters, start with a letter and contain only
4
- # letters and numbers (no spaces or special characters).
5
+ # > It must be between 6-32 characters, start with a letter and contain only
6
+ # > letters and numbers (no spaces or special characters).
5
7
  #
6
8
  # The following error message keys are used to localize invalid screen names.
7
9
  #
8
- # | @skype_too_short@ | Skype name is less than 6 characters. |
9
- # | @skype_too_long@ | Skype name is over 32 characters. |
10
- # | @skype_invalid_chars@ | Skype name contains invalid characters. |
11
- # | @skype_invalid_first_char@ | Skype name doesn't start with a letter. |
10
+ # | | |
11
+ # |:---------------------------|:----------------------------------------|
12
+ # | `skype_too_short` | Skype name is less than 6 characters. |
13
+ # | `skype_too_long` | Skype name is over 32 characters. |
14
+ # | `skype_invalid_chars` | Skype name contains invalid characters. |
15
+ # | `skype_invalid_first_char` | Skype name doesn't start with a letter. |
12
16
  #
13
17
  # @example
14
18
  # validates :skype_name, skype: true
15
19
  #
16
- # h2. Options
20
+ # Options
21
+ # -------
17
22
  #
18
- # | @:message@ | A custom message to use if the email is invalid. |
19
- # | @:allow_nil@ | If true, @nil@ values are allowed. |
23
+ # | | |
24
+ # |:-------------|:-------------------------------------------------|
25
+ # | `:message` | A custom message to use if the email is invalid. |
26
+ # | `:allow_nil` | If true, `nil` values are allowed. |
20
27
 
21
28
  class SkypeValidator < AccountNameValidator
22
29
  min_length 6
23
30
  max_length 32
24
- valid_chars 'A-Za-z0-9'
25
- first_char 'A-Za-z'
31
+ valid_chars "A-Za-z0-9"
32
+ first_char "A-Za-z"
26
33
  end
@@ -1,18 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Validates steam account IDs. Steam IDs are between 3 and 63 characters long
2
4
  # and consist of letters, numbers, or underscores.
3
5
  #
4
6
  # The following error message keys are used to localize invalid screen names.
5
7
  #
6
- # | @steam_too_short@ | Steam ID is less than 6 characters. |
7
- # | @steam_too_long@ | Steam ID is over 32 characters. |
8
- # | @steam_invalid_chars@ | Steam ID contains invalid characters. |
9
- # | @steam_invalid_first_char@ | Steam ID doesn't start with a letter. |
8
+ # | | |
9
+ # |:----------------------|:--------------------------------------|
10
+ # | `steam_too_short` | Steam ID is less than 6 characters. |
11
+ # | `steam_too_long` | Steam ID is over 32 characters. |
12
+ # | `steam_invalid_chars` | Steam ID contains invalid characters. |
10
13
  #
11
14
  # @example
12
15
  # validates :steam_id, steam: true
16
+ #
17
+ # Options
18
+ # -------
19
+ #
20
+ # | | |
21
+ # |:-------------|:-------------------------------------------------|
22
+ # | `:message` | A custom message to use if the email is invalid. |
23
+ # | `:allow_nil` | If true, `nil` values are allowed. |
13
24
 
14
25
  class SteamValidator < AccountNameValidator
15
26
  min_length 3
16
27
  max_length 63
17
- valid_chars 'A-Za-z0-9_'
28
+ valid_chars "A-Za-z0-9_"
18
29
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Validates Telegram usernames. Telegram usernames are 5-32 characters of
4
+ # alphanumerics and underscores; they must start with a letter and cannot end
5
+ # with an underscore. Username lookups are case-insensitive. A leading `@` is
6
+ # stripped before validation.
7
+ #
8
+ # The following error message keys are used to localize invalid usernames:
9
+ #
10
+ # | | |
11
+ # |:-------------------------------|:------------------------------------------------------|
12
+ # | `telegram_too_short` | Username is less than 5 characters. |
13
+ # | `telegram_too_long` | Username is over 32 characters. |
14
+ # | `telegram_invalid_chars` | Username contains characters outside `[A-Za-z0-9_]`. |
15
+ # | `telegram_invalid_first_char` | Username doesn't start with a letter. |
16
+ # | `telegram_trailing_underscore` | Username ends with an underscore. |
17
+ #
18
+ # @example
19
+ # validates :telegram, telegram: true
20
+ #
21
+ # Options
22
+ # -------
23
+ #
24
+ # | | |
25
+ # |:-------------|:-------------------------------------------------|
26
+ # | `:message` | A custom message to use if the username is invalid. |
27
+ # | `:allow_nil` | If true, `nil` values are allowed. |
28
+
29
+ class TelegramValidator < AccountNameValidator
30
+ min_length 5
31
+ max_length 32
32
+ valid_chars "A-Za-z0-9_"
33
+ first_char "A-Za-z"
34
+ add_validation(:trailing_underscore) { |value| !value.end_with?("_") }
35
+
36
+ # Overrides {AccountNameValidator#validate_each} to strip an optional leading
37
+ # `@` before applying validations.
38
+ def validate_each(record, attribute, value)
39
+ if value.is_a?(String) && value.start_with?("@")
40
+ value = value[1..]
41
+ end
42
+ super
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ValidatesIm
4
+ VERSION = "2.0.0"
5
+ end
data/lib/validates_im.rb CHANGED
@@ -1,7 +1,16 @@
1
- require 'account_name_validator'
2
- require 'aim_validator'
3
- require 'skype_validator'
4
- require 'steam_validator'
5
- require 'validates_im'
6
- require 'xbox_live_validator'
7
- require 'yahoo_im_validator'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model"
4
+
5
+ require "validates_im/version"
6
+
7
+ require "account_name_validator"
8
+ require "aim_validator"
9
+ require "discord_validator"
10
+ require "matrix_validator"
11
+ require "signal_validator"
12
+ require "skype_validator"
13
+ require "steam_validator"
14
+ require "telegram_validator"
15
+ require "xbox_live_validator"
16
+ require "yahoo_im_validator"