encoded_id 1.0.0.rc2 → 1.0.0.rc3
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 +4 -4
- data/CHANGELOG.md +21 -4
- data/Gemfile +12 -2
- data/README.md +37 -16
- data/lib/encoded_id/alphabet.rb +32 -8
- data/lib/encoded_id/reversible_id.rb +44 -23
- data/lib/encoded_id/version.rb +1 -1
- data/lib/encoded_id.rb +2 -0
- data/sig/encoded_id.rbs +12 -5
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44375d994a7eabe8245cf6bcb0e889e4d9de13f3e67feb98ee77959bc8f076a5
|
4
|
+
data.tar.gz: 4e6db397ee9564375ae7387d57f341266f22fd58214ccecc890b7fb68d8cc4ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aade9242ac4d6fffd5ea3957af76a065d14143e547e31b4e7fda5203dcb2aa27f05166e5e803a8677f874bb443fc136196f0ce3bdd78b514606f251721f95d27
|
7
|
+
data.tar.gz: fa4cc2385cbb6a726fc00bdbb5e70d1546abe46b86ba020243327942f32886a4928b8b65bc7a76c9e134bb162c17f4c69798a5e0080c43bf2e7802f92dfa580f
|
data/CHANGELOG.md
CHANGED
@@ -1,15 +1,32 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
## [
|
3
|
+
## [2.0.0.alpha1] - unreleased
|
4
|
+
|
5
|
+
### Breaking changes
|
6
|
+
|
7
|
+
- `ReversibleId` now no longer downcases the encodedid input string by default on decode, ie the `decode` option `downcase` is now `false`. In a future release the `downcase` option will be removed.
|
8
|
+
|
9
|
+
## [1.0.0.rc3] - 2023-10-23
|
10
|
+
|
11
|
+
- Add an optional `max_length` argument to `ReversibleId`, thanks to [@jugglebird](https://github.com/jugglebird)
|
12
|
+
- Alphabet validations to prevent whitespace and null chars
|
13
|
+
- Add `Alphabet#to_a`, `Alphabet#to_s`, `Alphabet#size` and a custom `Alphabet#inspect`
|
14
|
+
- Fixes to input validations
|
15
|
+
- hashids are case-sensitive, as are `Alphabet`s, however `ReversibleId` was always `downcase`ing the encodedid input string on decode. A new option has been added to `decode` and `decode_hex`, `downcase`, which defaults to `true`. Thus, the default behaviour is unchanged, but you can opt out to allow mixed case encodedid decode. *Note:* In V2 this will default to `false`.
|
16
|
+
|
17
|
+
## [1.0.0.rc2] - 2023-08-07
|
18
|
+
|
19
|
+
- `Alphabet` now has `#include?` and `#unique_charaters` methods
|
20
|
+
|
21
|
+
## [1.0.0.rc1] - 2023-08-06
|
4
22
|
|
5
23
|
- Improved RBS definitions
|
6
24
|
- Improved test coverage
|
7
|
-
- `Alphabet` now has `#include?` and `#unique_charaters` methods
|
8
25
|
|
9
26
|
## [0.4.0] - 2022-12-04
|
10
27
|
|
11
|
-
- Support custom split character which must not be in the alphabet
|
12
|
-
- Ability to provide a custom character
|
28
|
+
- Support custom 'split' character which must not be in the alphabet
|
29
|
+
- Ability to provide a custom character equivalence mapping
|
13
30
|
|
14
31
|
## [0.3.0] - 2022-10-12
|
15
32
|
|
data/Gemfile
CHANGED
@@ -7,8 +7,18 @@ gemspec
|
|
7
7
|
|
8
8
|
gem "rake", "~> 13.0"
|
9
9
|
|
10
|
-
gem "minitest"
|
10
|
+
gem "minitest"
|
11
11
|
|
12
12
|
gem "standard", "~> 1.30"
|
13
13
|
|
14
|
-
gem "
|
14
|
+
gem "rbs"
|
15
|
+
|
16
|
+
gem "steep"
|
17
|
+
|
18
|
+
gem "simplecov"
|
19
|
+
|
20
|
+
gem "benchmark-ips"
|
21
|
+
|
22
|
+
gem "benchmark-memory"
|
23
|
+
|
24
|
+
gem "fuzzbert"
|
data/README.md
CHANGED
@@ -33,16 +33,27 @@ coder.decode("z2j7-Odmw") # (note the capital 'o' instead of zero)
|
|
33
33
|
|
34
34
|
## Features
|
35
35
|
|
36
|
-
* encoded IDs are reversible (uses with https://hashids.org))
|
37
|
-
* supports multiple IDs encoded in one encoded string (eg `7aq6-0zqw` decodes to `[78, 45]`)
|
38
|
-
* supports
|
39
|
-
* supports custom alphabets for the encoded string (at least 16 characters needed)
|
36
|
+
* 🔄 encoded IDs are reversible (uses with https://hashids.org))
|
37
|
+
* 👥 supports multiple IDs encoded in one encoded string (eg `7aq6-0zqw` decodes to `[78, 45]`)
|
38
|
+
* 🔡 supports custom alphabets for the encoded string (at least 16 characters needed)
|
40
39
|
- by default uses a variation of the Crockford reduced character set (https://www.crockford.com/base32.html)
|
41
|
-
- easily confused characters (eg `i` and `j`, `0` and `O`, `1` and `I` etc) are mapped to counterpart characters, to help
|
40
|
+
- 👓 easily confused characters (eg `i` and `j`, `0` and `O`, `1` and `I` etc) are mapped to counterpart characters, to help
|
42
41
|
avoid common readability mistakes when reading/sharing
|
43
|
-
- build in profanity limitation
|
44
|
-
* encoded string can be split into groups of letters to improve human-readability
|
42
|
+
- 🤬 build in profanity limitation
|
43
|
+
* 🤓 encoded string can be split into groups of letters to improve human-readability
|
45
44
|
- eg `nft9hr834htu` as `nft9-hr83-4htu`
|
45
|
+
* 🥽 supports limits on length to prevent resource exhaustion on encoding and decoding
|
46
|
+
* configured with sensible defaults
|
47
|
+
|
48
|
+
I aim for 100% test coverage and have fuzz tested quite extensively. But please report any issues!
|
49
|
+
|
50
|
+
### Experimental
|
51
|
+
|
52
|
+
* support for encoding of hex strings (eg UUIDs), including multiple IDs encoded in one string
|
53
|
+
|
54
|
+
### Coming soon
|
55
|
+
|
56
|
+
Performance improvements and benchmarking!
|
46
57
|
|
47
58
|
### Rails support `encoded_id-rails`
|
48
59
|
|
@@ -117,9 +128,18 @@ The encoded ID is configurable. The following can be changed:
|
|
117
128
|
|
118
129
|
The actual length of the encoded string can be longer if the inputs cannot be represented in the minimum length.
|
119
130
|
|
131
|
+
### `max_length`
|
132
|
+
|
133
|
+
`max_length`: the maximum length of the encoded string. The default is 128 characters.
|
134
|
+
|
135
|
+
The maximum length represents both the longest encoded string that will be generated and also a limit on
|
136
|
+
the maximum input length that will be decoded. If the encoded string exceeds `max_length` then a
|
137
|
+
`EncodedIdLengthError` will be raised. If the input exceeds `max_length` then a `InvalidInputError` will
|
138
|
+
be raised. If `max_length` is set to `nil`, then no validation, even using the default will be performed.
|
139
|
+
|
120
140
|
### `alphabet`
|
121
141
|
|
122
|
-
`alphabet`: the alphabet used in the encoded string. By default it uses a variation of the Crockford reduced character set (https://www.crockford.com/base32.html).
|
142
|
+
`alphabet`: the alphabet used in the encoded string. By default, it uses a variation of the Crockford reduced character set (https://www.crockford.com/base32.html).
|
123
143
|
|
124
144
|
`alphabet` must be an instance of `EncodedId::Alphabet`.
|
125
145
|
|
@@ -137,7 +157,8 @@ alphabet = EncodedId::Alphabet.new("0123456789abcdef")
|
|
137
157
|
|
138
158
|
`characters`: the characters of the alphabet. Can be a string or array of strings.
|
139
159
|
|
140
|
-
Note that the `characters` of the alphabet must be at least 16 _unique_ characters long
|
160
|
+
Note that the `characters` of the alphabet must be at least 16 _unique_ characters long and must not contain any
|
161
|
+
whitespace characters.
|
141
162
|
|
142
163
|
|
143
164
|
```ruby
|
@@ -268,16 +289,17 @@ coder.decode_hex("5jjy-c8d9-hxp2-qsve-rgh9-rxnt-7nb5-tve7-bf84-vr")
|
|
268
289
|
|
269
290
|
## Development
|
270
291
|
|
271
|
-
After checking out the repo, run `bin/setup` to install dependencies.
|
272
|
-
|
292
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
293
|
+
|
294
|
+
Run `bin/console` for an interactive prompt that will allow you to experiment.
|
273
295
|
|
274
|
-
|
275
|
-
|
276
|
-
|
296
|
+
### Running tests
|
297
|
+
|
298
|
+
Run `bundle exec rake test` to run the tests.
|
277
299
|
|
278
300
|
### Type check
|
279
301
|
|
280
|
-
First install dependencies:
|
302
|
+
First install RBS dependencies:
|
281
303
|
|
282
304
|
```bash
|
283
305
|
rbs collection install
|
@@ -289,7 +311,6 @@ Then run:
|
|
289
311
|
steep check
|
290
312
|
```
|
291
313
|
|
292
|
-
|
293
314
|
## See also
|
294
315
|
|
295
316
|
- https://hashids.org
|
data/lib/encoded_id/alphabet.rb
CHANGED
@@ -20,8 +20,9 @@ module EncodedId
|
|
20
20
|
def initialize(characters, equivalences = nil)
|
21
21
|
raise_invalid_alphabet! unless valid_input_characters?(characters)
|
22
22
|
@unique_characters = unique_character_alphabet(characters)
|
23
|
-
|
24
|
-
|
23
|
+
raise_invalid_alphabet! unless valid_characters?
|
24
|
+
raise_character_set_too_small! unless sufficient_characters?
|
25
|
+
raise_invalid_equivalences! unless valid_equivalences?(equivalences)
|
25
26
|
|
26
27
|
@characters = unique_characters.join
|
27
28
|
@equivalences = equivalences
|
@@ -33,29 +34,52 @@ module EncodedId
|
|
33
34
|
unique_characters.include?(character)
|
34
35
|
end
|
35
36
|
|
37
|
+
def to_a
|
38
|
+
unique_characters.dup
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
@characters.dup
|
43
|
+
end
|
44
|
+
|
45
|
+
def inspect
|
46
|
+
"#<#{self.class.name} chars: #{unique_characters.inspect}>"
|
47
|
+
end
|
48
|
+
|
49
|
+
def size
|
50
|
+
unique_characters.size
|
51
|
+
end
|
52
|
+
alias_method :length, :size
|
53
|
+
|
36
54
|
private
|
37
55
|
|
38
56
|
def valid_input_characters?(characters)
|
39
|
-
|
57
|
+
return false unless characters.is_a?(Array) || characters.is_a?(String)
|
58
|
+
characters.size > 0
|
40
59
|
end
|
41
60
|
|
42
61
|
def unique_character_alphabet(characters)
|
43
62
|
(characters.is_a?(Array) ? characters : characters.chars).uniq
|
44
63
|
end
|
45
64
|
|
46
|
-
def
|
47
|
-
size
|
65
|
+
def valid_characters?
|
66
|
+
unique_characters.size > 0 && unique_characters.grep(/\s|\0/).size == 0
|
67
|
+
end
|
68
|
+
|
69
|
+
def sufficient_characters?
|
70
|
+
unique_characters.size >= MIN_UNIQUE_CHARACTERS
|
48
71
|
end
|
49
72
|
|
50
|
-
def valid_equivalences?(equivalences
|
73
|
+
def valid_equivalences?(equivalences)
|
51
74
|
return true if equivalences.nil?
|
52
75
|
return false unless equivalences.is_a?(Hash)
|
76
|
+
return false if equivalences.any? { |key, value| key.size != 1 || value.size != 1 }
|
53
77
|
|
54
78
|
(unique_characters & equivalences.keys).empty? && (equivalences.values - unique_characters).empty?
|
55
79
|
end
|
56
80
|
|
57
81
|
def raise_invalid_alphabet!
|
58
|
-
raise InvalidAlphabetError, "Alphabet must be a string or array."
|
82
|
+
raise InvalidAlphabetError, "Alphabet must be a string or array and not contain whitespace."
|
59
83
|
end
|
60
84
|
|
61
85
|
def raise_character_set_too_small!
|
@@ -63,7 +87,7 @@ module EncodedId
|
|
63
87
|
end
|
64
88
|
|
65
89
|
def raise_invalid_equivalences!
|
66
|
-
raise InvalidConfigurationError, "Character equivalences must be a hash or nil."
|
90
|
+
raise InvalidConfigurationError, "Character equivalences must be a hash or nil and contain mappings to valid alphabet characters."
|
67
91
|
end
|
68
92
|
end
|
69
93
|
end
|
@@ -8,13 +8,14 @@ require "hashids"
|
|
8
8
|
# Note hashIds already has a built in profanity limitation algorithm
|
9
9
|
module EncodedId
|
10
10
|
class ReversibleId
|
11
|
-
def initialize(salt:, length: 8, split_at: 4, split_with: "-", alphabet: Alphabet.modified_crockford, hex_digit_encoding_group_size: 4)
|
11
|
+
def initialize(salt:, length: 8, split_at: 4, split_with: "-", alphabet: Alphabet.modified_crockford, hex_digit_encoding_group_size: 4, max_length: 128)
|
12
12
|
@alphabet = validate_alphabet(alphabet)
|
13
13
|
@salt = validate_salt(salt)
|
14
14
|
@length = validate_length(length)
|
15
15
|
@split_at = validate_split_at(split_at)
|
16
16
|
@split_with = validate_split_with(split_with, alphabet)
|
17
17
|
@hex_represention_encoder = HexRepresentation.new(hex_digit_encoding_group_size)
|
18
|
+
@max_length = validate_max_length(max_length)
|
18
19
|
end
|
19
20
|
|
20
21
|
# Encode the input values into a hash
|
@@ -22,6 +23,9 @@ module EncodedId
|
|
22
23
|
inputs = prepare_input(values)
|
23
24
|
encoded_id = encoded_id_generator.encode(inputs)
|
24
25
|
encoded_id = humanize_length(encoded_id) unless split_at.nil?
|
26
|
+
|
27
|
+
raise EncodedIdLengthError if max_length_exceeded?(encoded_id)
|
28
|
+
|
25
29
|
encoded_id
|
26
30
|
end
|
27
31
|
|
@@ -31,15 +35,17 @@ module EncodedId
|
|
31
35
|
end
|
32
36
|
|
33
37
|
# Decode the hash to original array
|
34
|
-
def decode(str)
|
35
|
-
|
38
|
+
def decode(str, downcase: true)
|
39
|
+
raise InvalidInputError if max_length_exceeded?(str)
|
40
|
+
|
41
|
+
encoded_id_generator.decode(convert_to_hash(str, downcase))
|
36
42
|
rescue ::Hashids::InputError => e
|
37
43
|
raise EncodedIdFormatError, e.message
|
38
44
|
end
|
39
45
|
|
40
46
|
# Decode hex strings from a hash
|
41
|
-
def decode_hex(str)
|
42
|
-
integers = encoded_id_generator.decode(convert_to_hash(str))
|
47
|
+
def decode_hex(str, downcase: true)
|
48
|
+
integers = encoded_id_generator.decode(convert_to_hash(str, downcase))
|
43
49
|
hex_represention_encoder.integers_as_hex(integers)
|
44
50
|
end
|
45
51
|
|
@@ -50,37 +56,43 @@ module EncodedId
|
|
50
56
|
:alphabet,
|
51
57
|
:split_at,
|
52
58
|
:split_with,
|
53
|
-
:hex_represention_encoder
|
59
|
+
:hex_represention_encoder,
|
60
|
+
:max_length
|
54
61
|
|
55
62
|
def validate_alphabet(alphabet)
|
56
|
-
|
57
|
-
alphabet
|
63
|
+
return alphabet if alphabet.is_a?(Alphabet)
|
64
|
+
raise InvalidAlphabetError, "alphabet must be an instance of Alphabet"
|
58
65
|
end
|
59
66
|
|
60
67
|
def validate_salt(salt)
|
61
|
-
|
62
|
-
|
68
|
+
return salt if salt.is_a?(String) && salt.size > 3
|
69
|
+
raise InvalidConfigurationError, "Salt must be a string and longer than 3 characters"
|
63
70
|
end
|
64
71
|
|
65
72
|
# Target length of the encoded string (the minimum but not maximum length)
|
66
73
|
def validate_length(length)
|
67
|
-
|
68
|
-
|
74
|
+
return length if valid_integer_option?(length)
|
75
|
+
raise InvalidConfigurationError, "Length must be an integer greater than 0"
|
76
|
+
end
|
77
|
+
|
78
|
+
def validate_max_length(max_length)
|
79
|
+
return max_length if valid_integer_option?(max_length) || max_length.nil?
|
80
|
+
raise InvalidConfigurationError, "Max length must be an integer greater than 0"
|
69
81
|
end
|
70
82
|
|
71
83
|
# Split the encoded string into groups of this size
|
72
84
|
def validate_split_at(split_at)
|
73
|
-
|
74
|
-
|
75
|
-
end
|
76
|
-
split_at
|
85
|
+
return split_at if valid_integer_option?(split_at) || split_at.nil?
|
86
|
+
raise InvalidConfigurationError, "Split at must be an integer greater than 0 or nil"
|
77
87
|
end
|
78
88
|
|
79
89
|
def validate_split_with(split_with, alphabet)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
90
|
+
return split_with if split_with.is_a?(String) && !alphabet.characters.include?(split_with)
|
91
|
+
raise InvalidConfigurationError, "Split with must be a string and not part of the alphabet"
|
92
|
+
end
|
93
|
+
|
94
|
+
def valid_integer_option?(value)
|
95
|
+
value.is_a?(Integer) && value > 0
|
84
96
|
end
|
85
97
|
|
86
98
|
def prepare_input(value)
|
@@ -102,16 +114,25 @@ module EncodedId
|
|
102
114
|
hash.gsub(split_regex, "\\0#{split_with}")
|
103
115
|
end
|
104
116
|
|
105
|
-
def convert_to_hash(str)
|
106
|
-
clean = str.
|
107
|
-
|
117
|
+
def convert_to_hash(str, downcase)
|
118
|
+
clean = str.gsub(split_with, "")
|
119
|
+
clean = clean.downcase if downcase
|
120
|
+
map_equivalent_characters(clean)
|
108
121
|
end
|
109
122
|
|
110
123
|
def map_equivalent_characters(str)
|
124
|
+
return str unless alphabet.equivalences
|
125
|
+
|
111
126
|
alphabet.equivalences.reduce(str) do |cleaned, ceq|
|
112
127
|
from, to = ceq
|
113
128
|
cleaned.tr(from, to)
|
114
129
|
end
|
115
130
|
end
|
131
|
+
|
132
|
+
def max_length_exceeded?(str)
|
133
|
+
return false if max_length.nil?
|
134
|
+
|
135
|
+
str.length > max_length
|
136
|
+
end
|
116
137
|
end
|
117
138
|
end
|
data/lib/encoded_id/version.rb
CHANGED
data/lib/encoded_id.rb
CHANGED
data/sig/encoded_id.rbs
CHANGED
@@ -3,17 +3,18 @@ module EncodedId
|
|
3
3
|
|
4
4
|
InvalidConfigurationError: ::StandardError
|
5
5
|
EncodedIdFormatError: ::ArgumentError
|
6
|
+
EncodedIdLengthError: ::ArgumentError
|
6
7
|
InvalidAlphabetError: ::ArgumentError
|
7
8
|
InvalidInputError: ::ArgumentError
|
8
9
|
|
9
10
|
class Alphabet
|
10
11
|
MIN_UNIQUE_CHARACTERS: ::Integer
|
11
12
|
|
12
|
-
def initialize: (String,
|
13
|
+
def initialize: (String | ::Array[::String] characters, ::Hash[::String, ::String] ?equivalences) -> void
|
13
14
|
|
14
15
|
attr_reader unique_characters: ::Array[::String]
|
15
16
|
attr_reader characters: String
|
16
|
-
attr_reader equivalences: ::Hash[::String, ::String]
|
17
|
+
attr_reader equivalences: ::Hash[::String, ::String] | nil
|
17
18
|
|
18
19
|
def include?: (::String character) -> bool
|
19
20
|
|
@@ -23,11 +24,13 @@ module EncodedId
|
|
23
24
|
|
24
25
|
def valid_input_characters?: ((::Array[::String] | ::String) characters) -> bool
|
25
26
|
|
26
|
-
def
|
27
|
+
def valid_characters?: -> bool
|
28
|
+
|
29
|
+
def sufficient_characters?: -> bool
|
27
30
|
|
28
31
|
def unique_character_alphabet: ((::Array[::String] | ::String) characters) -> ::Array[::String]
|
29
32
|
|
30
|
-
def valid_equivalences?: (::Hash[::String, ::String] equivalences
|
33
|
+
def valid_equivalences?: (::Hash[::String, ::String] ?equivalences) -> bool
|
31
34
|
|
32
35
|
def raise_character_set_too_small!: -> untyped
|
33
36
|
|
@@ -56,7 +59,7 @@ module EncodedId
|
|
56
59
|
end
|
57
60
|
|
58
61
|
class ReversibleId
|
59
|
-
def initialize: (salt: ::String, ?length: ::Integer, ?split_at: ::Integer, ?split_with: ::String, ?alphabet: Alphabet, ?hex_digit_encoding_group_size: ::Integer) -> void
|
62
|
+
def initialize: (salt: ::String, ?length: ::Integer, ?split_at: ::Integer, ?split_with: ::String, ?alphabet: Alphabet, ?hex_digit_encoding_group_size: ::Integer, ?max_length: ::Integer) -> void
|
60
63
|
|
61
64
|
# Encode the input values into a hash
|
62
65
|
def encode: (encodeableValue values) -> ::String
|
@@ -79,6 +82,7 @@ module EncodedId
|
|
79
82
|
attr_reader salt: ::String
|
80
83
|
|
81
84
|
attr_reader length: ::Integer
|
85
|
+
attr_reader max_length: ::Integer | nil
|
82
86
|
|
83
87
|
attr_reader alphabet: Alphabet
|
84
88
|
|
@@ -90,9 +94,11 @@ module EncodedId
|
|
90
94
|
def validate_alphabet: (Alphabet) -> Alphabet
|
91
95
|
def validate_salt: (::String) -> ::String
|
92
96
|
def validate_length: (::Integer) -> ::Integer
|
97
|
+
def validate_max_length: (::Integer | nil) -> (::Integer | nil)
|
93
98
|
def validate_split_at: (::Integer | nil) -> (::Integer | nil)
|
94
99
|
def validate_split_with: (::String, Alphabet) -> ::String
|
95
100
|
def validate_hex_digit_encoding_group_size: (::Integer) -> ::Integer
|
101
|
+
def valid_integer_option?: (::Integer | nil) -> bool
|
96
102
|
|
97
103
|
def prepare_input: (untyped value) -> ::Array[::Integer]
|
98
104
|
|
@@ -105,5 +111,6 @@ module EncodedId
|
|
105
111
|
def convert_to_hash: (::String str) -> ::String
|
106
112
|
|
107
113
|
def map_equivalent_characters: (::String str) -> ::String
|
114
|
+
def max_length_exceeded?: (::String str) -> bool
|
108
115
|
end
|
109
116
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: encoded_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.rc3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Ierodiaconou
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashids
|
@@ -71,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: 1.3.1
|
73
73
|
requirements: []
|
74
|
-
rubygems_version: 3.4.
|
74
|
+
rubygems_version: 3.4.20
|
75
75
|
signing_key:
|
76
76
|
specification_version: 4
|
77
77
|
summary: EncodedId is a gem for creating reversible obfuscated IDs from numerical
|