encoded_id 1.0.0.rc5 → 1.0.0.rc7
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 +99 -3
- data/README.md +86 -329
- data/context/encoded_id.md +437 -0
- data/lib/encoded_id/alphabet.rb +34 -3
- data/lib/encoded_id/blocklist.rb +100 -0
- data/lib/encoded_id/encoders/base_configuration.rb +154 -0
- data/lib/encoded_id/encoders/hashid.rb +527 -0
- data/lib/encoded_id/encoders/hashid_configuration.rb +40 -0
- data/lib/encoded_id/encoders/hashid_consistent_shuffle.rb +110 -0
- data/lib/encoded_id/encoders/hashid_ordinal_alphabet_separator_guards.rb +244 -0
- data/lib/encoded_id/encoders/hashid_salt.rb +51 -0
- data/lib/encoded_id/encoders/my_sqids.rb +454 -0
- data/lib/encoded_id/encoders/sqids.rb +59 -0
- data/lib/encoded_id/encoders/sqids_configuration.rb +22 -0
- data/lib/encoded_id/encoders/sqids_with_blocklist_mode.rb +54 -0
- data/lib/encoded_id/hex_representation.rb +29 -14
- data/lib/encoded_id/reversible_id.rb +115 -82
- data/lib/encoded_id/version.rb +3 -1
- data/lib/encoded_id.rb +34 -4
- metadata +34 -26
- data/.devcontainer/Dockerfile +0 -9
- data/.devcontainer/compose.yml +0 -8
- data/.devcontainer/devcontainer.json +0 -8
- data/.standard.yml +0 -2
- data/Gemfile +0 -36
- data/Rakefile +0 -20
- data/Steepfile +0 -5
- data/ext/encoded_id/extconf.rb +0 -3
- data/ext/encoded_id/extension.c +0 -123
- data/ext/encoded_id/hashids.c +0 -939
- data/ext/encoded_id/hashids.h +0 -139
- data/lib/encoded_id/hash_id.rb +0 -227
- data/lib/encoded_id/hash_id_consistent_shuffle.rb +0 -27
- data/lib/encoded_id/hash_id_salt.rb +0 -15
- data/lib/encoded_id/ordinal_alphabet_separator_guards.rb +0 -90
- data/rbs_collection.yaml +0 -24
- data/sig/encoded_id.rbs +0 -189
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
3
5
|
module EncodedId
|
|
6
|
+
# @rbs!
|
|
7
|
+
# type encodeableHexValue = Array[String] | String
|
|
8
|
+
|
|
4
9
|
class HexRepresentation
|
|
10
|
+
# @rbs @hex_digit_encoding_group_size: Integer
|
|
11
|
+
# @rbs @hex_string_separator: Integer
|
|
12
|
+
|
|
13
|
+
# @rbs (Integer hex_digit_encoding_group_size) -> void
|
|
5
14
|
def initialize(hex_digit_encoding_group_size)
|
|
6
15
|
@hex_digit_encoding_group_size = validate_hex_digit_encoding_group_size(hex_digit_encoding_group_size)
|
|
7
16
|
end
|
|
8
17
|
|
|
18
|
+
# @rbs (encodeableHexValue hexs) -> Array[Integer]
|
|
9
19
|
def hex_as_integers(hexs)
|
|
10
20
|
integer_representation(hexs)
|
|
11
21
|
end
|
|
12
22
|
|
|
23
|
+
# @rbs (Array[Integer] integers) -> Array[String]
|
|
13
24
|
def integers_as_hex(integers)
|
|
14
25
|
integers_to_hex_strings(integers)
|
|
15
26
|
end
|
|
@@ -18,6 +29,7 @@ module EncodedId
|
|
|
18
29
|
|
|
19
30
|
# Number of hex digits to encode in each group, larger values will result in shorter hashes for longer inputs.
|
|
20
31
|
# Vice versa for smaller values, ie a smaller value will result in smaller hashes for small inputs.
|
|
32
|
+
# @rbs (Integer hex_digit_encoding_group_size) -> Integer
|
|
21
33
|
def validate_hex_digit_encoding_group_size(hex_digit_encoding_group_size)
|
|
22
34
|
if !hex_digit_encoding_group_size.is_a?(Integer) || hex_digit_encoding_group_size < 1 || hex_digit_encoding_group_size > 32
|
|
23
35
|
raise InvalidConfigurationError, "hex_digit_encoding_group_size must be > 0 and <= 32"
|
|
@@ -25,25 +37,24 @@ module EncodedId
|
|
|
25
37
|
hex_digit_encoding_group_size
|
|
26
38
|
end
|
|
27
39
|
|
|
28
|
-
#
|
|
40
|
+
# @rbs (encodeableHexValue hexs) -> Array[Integer]
|
|
29
41
|
def integer_representation(hexs)
|
|
30
42
|
inputs = Array(hexs).map(&:to_s)
|
|
31
|
-
digits_to_encode = []
|
|
43
|
+
digits_to_encode = [] #: Array[Integer]
|
|
32
44
|
|
|
33
45
|
inputs.map { |hex_string| hex_string_as_integer_representation(hex_string) }.each do |integer_groups|
|
|
34
46
|
digits_to_encode.concat(integer_groups)
|
|
35
47
|
digits_to_encode << hex_string_separator
|
|
36
48
|
end
|
|
37
49
|
|
|
38
|
-
# Remove the last marker
|
|
39
50
|
digits_to_encode.pop unless digits_to_encode.empty?
|
|
40
51
|
digits_to_encode
|
|
41
52
|
end
|
|
42
53
|
|
|
43
|
-
#
|
|
54
|
+
# @rbs (Array[Integer] integers) -> Array[String]
|
|
44
55
|
def integers_to_hex_strings(integers)
|
|
45
|
-
hex_strings = []
|
|
46
|
-
hex_string = []
|
|
56
|
+
hex_strings = [] #: Array[String]
|
|
57
|
+
hex_string = [] #: Array[String]
|
|
47
58
|
add_leading = false
|
|
48
59
|
|
|
49
60
|
integers.reverse_each do |integer|
|
|
@@ -52,38 +63,42 @@ module EncodedId
|
|
|
52
63
|
hex_string = []
|
|
53
64
|
add_leading = false
|
|
54
65
|
else
|
|
66
|
+
# Add leading zeros to maintain group size for all groups except the first
|
|
55
67
|
hex_string << (add_leading ? "%.#{@hex_digit_encoding_group_size}x" % integer : integer.to_s(16))
|
|
56
68
|
add_leading = true
|
|
57
69
|
end
|
|
58
70
|
end
|
|
59
71
|
|
|
60
|
-
# Add the last hex string
|
|
61
72
|
hex_strings << hex_string.join unless hex_string.empty?
|
|
62
73
|
hex_strings.reverse
|
|
63
74
|
end
|
|
64
75
|
|
|
76
|
+
# @rbs (String hex_string) -> Array[Integer]
|
|
65
77
|
def hex_string_as_integer_representation(hex_string)
|
|
66
78
|
cleaned = remove_non_hex_characters(hex_string)
|
|
67
79
|
convert_to_integer_groups(cleaned)
|
|
68
80
|
end
|
|
69
81
|
|
|
70
82
|
# Marker to separate hex strings, must be greater than largest value encoded
|
|
83
|
+
# @rbs return: Integer
|
|
71
84
|
def hex_string_separator
|
|
72
|
-
@hex_string_separator ||= 2.pow(@hex_digit_encoding_group_size * 4)
|
|
85
|
+
@hex_string_separator ||= 2.pow(@hex_digit_encoding_group_size * 4).to_i
|
|
73
86
|
end
|
|
74
87
|
|
|
88
|
+
# @rbs (String hex_string) -> String
|
|
75
89
|
def remove_non_hex_characters(hex_string)
|
|
76
90
|
hex_string.gsub(/[^0-9a-f]/i, "")
|
|
77
91
|
end
|
|
78
92
|
|
|
93
|
+
# @rbs (String hex_string_cleaned) -> Array[Integer]
|
|
79
94
|
def convert_to_integer_groups(hex_string_cleaned)
|
|
80
|
-
groups = []
|
|
81
|
-
hex_string_cleaned.chars.reverse.each_with_index do |char,
|
|
82
|
-
group_id =
|
|
83
|
-
groups[group_id] ||= []
|
|
84
|
-
|
|
95
|
+
groups = [] #: Array[Array[String]]
|
|
96
|
+
hex_string_cleaned.chars.reverse.each_with_index do |char, index|
|
|
97
|
+
group_id = index / @hex_digit_encoding_group_size
|
|
98
|
+
group = (groups[group_id] ||= [])
|
|
99
|
+
group.unshift(char)
|
|
85
100
|
end
|
|
86
|
-
groups.map {
|
|
101
|
+
groups.map { _1.join.to_i(16) }
|
|
87
102
|
end
|
|
88
103
|
end
|
|
89
104
|
end
|
|
@@ -1,144 +1,177 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
3
5
|
# Hashid with a reduced character set Crockford alphabet and split groups
|
|
4
6
|
# See: https://www.crockford.com/wrmg/base32.html
|
|
5
|
-
# Build with https://hashids.org
|
|
6
|
-
# Note hashIds already has a built in profanity limitation algorithm
|
|
7
|
+
# Build with support for https://hashids.org and https://sqids.org
|
|
7
8
|
module EncodedId
|
|
9
|
+
# @rbs!
|
|
10
|
+
# type encodeableValue = Array[String | Integer] | String | Integer
|
|
11
|
+
|
|
8
12
|
class ReversibleId
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@max_inputs_per_id = validate_max_input(max_inputs_per_id)
|
|
13
|
+
# @rbs @config: Encoders::BaseConfiguration
|
|
14
|
+
# @rbs @hex_represention_encoder: HexRepresentation
|
|
15
|
+
# @rbs @encoder: untyped
|
|
16
|
+
|
|
17
|
+
# Factory method to create a Hashid-based reversible ID
|
|
18
|
+
# @rbs (salt: String, **untyped options) -> ReversibleId
|
|
19
|
+
def self.hashid(salt:, **options)
|
|
20
|
+
new(Encoders::HashidConfiguration.new(salt: salt, **options))
|
|
18
21
|
end
|
|
19
22
|
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
# Factory method to create a Sqids-based reversible ID (default)
|
|
24
|
+
# @rbs (**untyped options) -> ReversibleId
|
|
25
|
+
def self.sqids(**options)
|
|
26
|
+
new(Encoders::SqidsConfiguration.new(**options))
|
|
27
|
+
end
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
# Initialize with a configuration object
|
|
30
|
+
# Defaults to Sqids configuration if called with no arguments
|
|
31
|
+
# @rbs (?Encoders::BaseConfiguration? config) -> void
|
|
32
|
+
def initialize(config = nil)
|
|
33
|
+
@config = config || Encoders::SqidsConfiguration.new
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
unless @config.is_a?(Encoders::BaseConfiguration)
|
|
36
|
+
raise InvalidConfigurationError, "config must be an instance of Encoders::BaseConfiguration (or nil for default Sqids)"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
@hex_represention_encoder = HexRepresentation.new(@config.hex_digit_encoding_group_size)
|
|
40
|
+
@encoder = create_encoder
|
|
29
41
|
end
|
|
30
42
|
|
|
31
|
-
#
|
|
32
|
-
def
|
|
33
|
-
|
|
43
|
+
# @rbs () -> String?
|
|
44
|
+
def salt
|
|
45
|
+
config = @config
|
|
46
|
+
return config.salt if config.is_a?(Encoders::HashidConfiguration)
|
|
47
|
+
nil
|
|
34
48
|
end
|
|
35
49
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
50
|
+
def min_length
|
|
51
|
+
@config.min_length
|
|
52
|
+
end
|
|
39
53
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
raise EncodedIdFormatError, e.message
|
|
54
|
+
def alphabet
|
|
55
|
+
@config.alphabet
|
|
43
56
|
end
|
|
44
57
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
integers = encoded_id_generator.decode(convert_to_hash(str, downcase))
|
|
48
|
-
hex_represention_encoder.integers_as_hex(integers)
|
|
58
|
+
def split_at
|
|
59
|
+
@config.split_at
|
|
49
60
|
end
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
def split_with
|
|
63
|
+
@config.split_with
|
|
64
|
+
end
|
|
52
65
|
|
|
53
|
-
attr_reader :
|
|
54
|
-
:length,
|
|
55
|
-
:alphabet,
|
|
56
|
-
:split_at,
|
|
57
|
-
:split_with,
|
|
58
|
-
:hex_represention_encoder,
|
|
59
|
-
:max_length
|
|
66
|
+
attr_reader :hex_represention_encoder
|
|
60
67
|
|
|
61
|
-
def
|
|
62
|
-
|
|
63
|
-
raise InvalidAlphabetError, "alphabet must be an instance of Alphabet"
|
|
68
|
+
def max_length
|
|
69
|
+
@config.max_length
|
|
64
70
|
end
|
|
65
71
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
raise InvalidConfigurationError, "Salt must be a string and longer than 3 characters"
|
|
72
|
+
def blocklist
|
|
73
|
+
@config.blocklist
|
|
69
74
|
end
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
def validate_length(length)
|
|
73
|
-
return length if valid_integer_option?(length)
|
|
74
|
-
raise InvalidConfigurationError, "Length must be an integer greater than 0"
|
|
75
|
-
end
|
|
76
|
+
attr_reader :encoder #: untyped
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
# Encode the input values into a hash
|
|
79
|
+
# @rbs (encodeableValue values) -> String
|
|
80
|
+
def encode(values)
|
|
81
|
+
inputs = prepare_input(values)
|
|
82
|
+
encoded_id = encoder.encode(inputs)
|
|
83
|
+
encoded_id = humanize_length(encoded_id) if @config.split_with && @config.split_at
|
|
84
|
+
|
|
85
|
+
raise EncodedIdLengthError if max_length_exceeded?(encoded_id)
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
return max_inputs_per_id if valid_integer_option?(max_inputs_per_id)
|
|
84
|
-
raise InvalidConfigurationError, "Max inputs per ID must be an integer greater than 0"
|
|
87
|
+
encoded_id
|
|
85
88
|
end
|
|
86
89
|
|
|
87
|
-
#
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
# Encode hex strings into a hash
|
|
91
|
+
# @rbs (encodeableHexValue hexs) -> String
|
|
92
|
+
def encode_hex(hexs)
|
|
93
|
+
encode(@hex_represention_encoder.hex_as_integers(hexs))
|
|
91
94
|
end
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
# Decode the hash to original array
|
|
97
|
+
# @rbs (String str, ?downcase: bool) -> Array[Integer]
|
|
98
|
+
def decode(str, downcase: false)
|
|
99
|
+
raise EncodedIdFormatError, "Max length of input exceeded" if max_length_exceeded?(str)
|
|
100
|
+
|
|
101
|
+
encoder.decode(convert_to_hash(str, downcase))
|
|
102
|
+
rescue InvalidInputError => error
|
|
103
|
+
raise EncodedIdFormatError, error.message
|
|
96
104
|
end
|
|
97
105
|
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
# Decode hex strings from a hash
|
|
107
|
+
# @rbs (String str, ?downcase: bool) -> Array[String]
|
|
108
|
+
def decode_hex(str, downcase: false)
|
|
109
|
+
integers = encoder.decode(convert_to_hash(str, downcase))
|
|
110
|
+
@hex_represention_encoder.integers_as_hex(integers)
|
|
100
111
|
end
|
|
101
112
|
|
|
113
|
+
private
|
|
114
|
+
|
|
115
|
+
# @rbs (encodeableValue value) -> Array[Integer]
|
|
102
116
|
def prepare_input(value)
|
|
103
117
|
inputs = value.is_a?(Array) ? value.map(&:to_i) : [value.to_i]
|
|
118
|
+
raise ::EncodedId::InvalidInputError, "Cannot encode an empty array" if inputs.empty?
|
|
104
119
|
raise ::EncodedId::InvalidInputError, "Integer IDs to be encoded can only be positive" if inputs.any?(&:negative?)
|
|
105
|
-
|
|
106
|
-
raise ::EncodedId::InvalidInputError, "%d integer IDs provided, maximum amount of IDs is %d" % [inputs.length, @max_inputs_per_id] if inputs.length > @max_inputs_per_id
|
|
120
|
+
raise ::EncodedId::InvalidInputError, "%d integer IDs provided, maximum amount of IDs is %d" % [inputs.length, @config.max_inputs_per_id] if inputs.length > @config.max_inputs_per_id
|
|
107
121
|
|
|
108
122
|
inputs
|
|
109
123
|
end
|
|
110
124
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def split_regex
|
|
116
|
-
@split_regex ||= /.{#{split_at}}(?=.)/
|
|
125
|
+
# @rbs () -> untyped
|
|
126
|
+
def create_encoder
|
|
127
|
+
@config.create_encoder
|
|
117
128
|
end
|
|
118
129
|
|
|
130
|
+
# Splits long encoded strings into groups for readability
|
|
131
|
+
# e.g., "ABCDEFGH" with split_at=4, split_with="-" becomes "ABCD-EFGH"
|
|
132
|
+
# @rbs (String hash) -> String
|
|
119
133
|
def humanize_length(hash)
|
|
120
|
-
hash.
|
|
134
|
+
len = hash.length
|
|
135
|
+
at = @config.split_at #: Integer
|
|
136
|
+
with = @config.split_with #: String
|
|
137
|
+
return hash if len <= at
|
|
138
|
+
|
|
139
|
+
separator_count = (len - 1) / at
|
|
140
|
+
result = hash.dup
|
|
141
|
+
insert_offset = 0
|
|
142
|
+
(1..separator_count).each do |separator_index|
|
|
143
|
+
insert_pos = separator_index * at + insert_offset
|
|
144
|
+
result.insert(insert_pos, with)
|
|
145
|
+
insert_offset += with.length
|
|
146
|
+
end
|
|
147
|
+
result
|
|
121
148
|
end
|
|
122
149
|
|
|
150
|
+
# Reverses humanize_length transformation: removes separators and optionally downcases
|
|
151
|
+
# @rbs (String str, bool downcase) -> String
|
|
123
152
|
def convert_to_hash(str, downcase)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
map_equivalent_characters(
|
|
153
|
+
str = str.gsub(@config.split_with, "") if @config.split_with
|
|
154
|
+
str = str.downcase if downcase
|
|
155
|
+
map_equivalent_characters(str)
|
|
127
156
|
end
|
|
128
157
|
|
|
158
|
+
# Maps equivalent characters based on alphabet configuration (e.g., 'O' -> '0', 'I' -> '1')
|
|
159
|
+
# @rbs (String str) -> String
|
|
129
160
|
def map_equivalent_characters(str)
|
|
130
|
-
|
|
161
|
+
equivalences = @config.alphabet.equivalences
|
|
162
|
+
return str unless equivalences
|
|
131
163
|
|
|
132
|
-
|
|
164
|
+
equivalences.reduce(str) do |cleaned, ceq|
|
|
133
165
|
from, to = ceq
|
|
134
166
|
cleaned.tr(from, to)
|
|
135
167
|
end
|
|
136
168
|
end
|
|
137
169
|
|
|
170
|
+
# @rbs (String str) -> bool
|
|
138
171
|
def max_length_exceeded?(str)
|
|
139
|
-
return false if max_length.nil?
|
|
172
|
+
return false if @config.max_length.nil?
|
|
140
173
|
|
|
141
|
-
str.length > max_length
|
|
174
|
+
str.length > @config.max_length
|
|
142
175
|
end
|
|
143
176
|
end
|
|
144
177
|
end
|
data/lib/encoded_id/version.rb
CHANGED
data/lib/encoded_id.rb
CHANGED
|
@@ -1,26 +1,56 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
3
5
|
require_relative "encoded_id/version"
|
|
4
6
|
require_relative "encoded_id/alphabet"
|
|
5
7
|
require_relative "encoded_id/hex_representation"
|
|
8
|
+
require_relative "encoded_id/blocklist"
|
|
9
|
+
|
|
10
|
+
# Load the encoder framework
|
|
11
|
+
require_relative "encoded_id/encoders/hashid_salt"
|
|
12
|
+
require_relative "encoded_id/encoders/hashid_consistent_shuffle"
|
|
13
|
+
require_relative "encoded_id/encoders/hashid_ordinal_alphabet_separator_guards"
|
|
14
|
+
require_relative "encoded_id/encoders/hashid"
|
|
15
|
+
|
|
16
|
+
require "sqids"
|
|
17
|
+
# TODO: move back to only using gem once upstreamed our changes
|
|
18
|
+
require_relative "encoded_id/encoders/my_sqids"
|
|
19
|
+
require_relative "encoded_id/encoders/sqids_with_blocklist_mode"
|
|
6
20
|
|
|
7
|
-
require_relative "encoded_id/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
require_relative "encoded_id/
|
|
21
|
+
require_relative "encoded_id/encoders/sqids"
|
|
22
|
+
|
|
23
|
+
# Load configuration classes
|
|
24
|
+
require_relative "encoded_id/encoders/base_configuration"
|
|
25
|
+
require_relative "encoded_id/encoders/hashid_configuration"
|
|
26
|
+
require_relative "encoded_id/encoders/sqids_configuration"
|
|
11
27
|
|
|
12
28
|
require_relative "encoded_id/reversible_id"
|
|
13
29
|
|
|
30
|
+
# @rbs!
|
|
31
|
+
# module Sqids
|
|
32
|
+
# DEFAULT_BLOCKLIST: Array[String]
|
|
33
|
+
# end
|
|
34
|
+
|
|
14
35
|
module EncodedId
|
|
36
|
+
# @rbs InvalidConfigurationError: singleton(StandardError)
|
|
15
37
|
class InvalidConfigurationError < StandardError; end
|
|
16
38
|
|
|
39
|
+
# @rbs InvalidAlphabetError: singleton(ArgumentError)
|
|
17
40
|
class InvalidAlphabetError < ArgumentError; end
|
|
18
41
|
|
|
42
|
+
# @rbs EncodedIdFormatError: singleton(ArgumentError)
|
|
19
43
|
class EncodedIdFormatError < ArgumentError; end
|
|
20
44
|
|
|
45
|
+
# @rbs EncodedIdLengthError: singleton(ArgumentError)
|
|
21
46
|
class EncodedIdLengthError < ArgumentError; end
|
|
22
47
|
|
|
48
|
+
# @rbs InvalidInputError: singleton(ArgumentError)
|
|
23
49
|
class InvalidInputError < ArgumentError; end
|
|
24
50
|
|
|
51
|
+
# @rbs BlocklistError: singleton(StandardError)
|
|
52
|
+
class BlocklistError < StandardError; end
|
|
53
|
+
|
|
54
|
+
# @rbs SaltError: singleton(ArgumentError)
|
|
25
55
|
class SaltError < ArgumentError; end
|
|
26
56
|
end
|
metadata
CHANGED
|
@@ -1,74 +1,82 @@
|
|
|
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.rc7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stephen Ierodiaconou
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
-
dependencies:
|
|
10
|
+
date: 2025-11-20 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: sqids
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.2'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.2'
|
|
12
26
|
description: Encode your numerical IDs (eg record primary keys) into obfuscated strings
|
|
13
27
|
that can be used in URLs. The obfuscated strings are reversible, so you can decode
|
|
14
28
|
them back into the original numerical IDs. Supports encoding multiple IDs at once,
|
|
15
29
|
and generating IDs with custom alphabets and separators to make the IDs easier to
|
|
16
|
-
read or share.
|
|
30
|
+
read or share. Uses Sqids by default, with HashIds as an alternative.
|
|
17
31
|
email:
|
|
18
32
|
- stevegeek@gmail.com
|
|
19
33
|
executables: []
|
|
20
34
|
extensions: []
|
|
21
35
|
extra_rdoc_files: []
|
|
22
36
|
files:
|
|
23
|
-
- ".devcontainer/Dockerfile"
|
|
24
|
-
- ".devcontainer/compose.yml"
|
|
25
|
-
- ".devcontainer/devcontainer.json"
|
|
26
|
-
- ".standard.yml"
|
|
27
37
|
- CHANGELOG.md
|
|
28
|
-
- Gemfile
|
|
29
38
|
- LICENSE.txt
|
|
30
39
|
- README.md
|
|
31
|
-
-
|
|
32
|
-
- Steepfile
|
|
33
|
-
- ext/encoded_id/extconf.rb
|
|
34
|
-
- ext/encoded_id/extension.c
|
|
35
|
-
- ext/encoded_id/hashids.c
|
|
36
|
-
- ext/encoded_id/hashids.h
|
|
40
|
+
- context/encoded_id.md
|
|
37
41
|
- lib/encoded_id.rb
|
|
38
42
|
- lib/encoded_id/alphabet.rb
|
|
39
|
-
- lib/encoded_id/
|
|
40
|
-
- lib/encoded_id/
|
|
41
|
-
- lib/encoded_id/
|
|
43
|
+
- lib/encoded_id/blocklist.rb
|
|
44
|
+
- lib/encoded_id/encoders/base_configuration.rb
|
|
45
|
+
- lib/encoded_id/encoders/hashid.rb
|
|
46
|
+
- lib/encoded_id/encoders/hashid_configuration.rb
|
|
47
|
+
- lib/encoded_id/encoders/hashid_consistent_shuffle.rb
|
|
48
|
+
- lib/encoded_id/encoders/hashid_ordinal_alphabet_separator_guards.rb
|
|
49
|
+
- lib/encoded_id/encoders/hashid_salt.rb
|
|
50
|
+
- lib/encoded_id/encoders/my_sqids.rb
|
|
51
|
+
- lib/encoded_id/encoders/sqids.rb
|
|
52
|
+
- lib/encoded_id/encoders/sqids_configuration.rb
|
|
53
|
+
- lib/encoded_id/encoders/sqids_with_blocklist_mode.rb
|
|
42
54
|
- lib/encoded_id/hex_representation.rb
|
|
43
|
-
- lib/encoded_id/ordinal_alphabet_separator_guards.rb
|
|
44
55
|
- lib/encoded_id/reversible_id.rb
|
|
45
56
|
- lib/encoded_id/version.rb
|
|
46
|
-
- rbs_collection.yaml
|
|
47
|
-
- sig/encoded_id.rbs
|
|
48
57
|
homepage: https://github.com/stevegeek/encoded_id
|
|
49
58
|
licenses:
|
|
50
59
|
- MIT
|
|
51
60
|
metadata:
|
|
52
61
|
homepage_uri: https://github.com/stevegeek/encoded_id
|
|
53
62
|
source_code_uri: https://github.com/stevegeek/encoded_id
|
|
54
|
-
changelog_uri: https://github.com/stevegeek/encoded_id/blob/
|
|
63
|
+
changelog_uri: https://github.com/stevegeek/encoded_id/blob/main/CHANGELOG.md
|
|
55
64
|
rdoc_options: []
|
|
56
65
|
require_paths:
|
|
57
66
|
- lib
|
|
58
|
-
- ext
|
|
59
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
60
68
|
requirements:
|
|
61
69
|
- - ">="
|
|
62
70
|
- !ruby/object:Gem::Version
|
|
63
|
-
version: 2.
|
|
71
|
+
version: 3.2.0
|
|
64
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
73
|
requirements:
|
|
66
74
|
- - ">="
|
|
67
75
|
- !ruby/object:Gem::Version
|
|
68
76
|
version: '0'
|
|
69
77
|
requirements: []
|
|
70
|
-
rubygems_version: 3.6.
|
|
78
|
+
rubygems_version: 3.6.2
|
|
71
79
|
specification_version: 4
|
|
72
80
|
summary: EncodedId is a gem for creating reversible obfuscated IDs from numerical
|
|
73
|
-
IDs. It uses
|
|
81
|
+
IDs. It uses Sqids by default.
|
|
74
82
|
test_files: []
|
data/.devcontainer/Dockerfile
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version or gemspec
|
|
2
|
-
ARG RUBY_VERSION=3.4.2
|
|
3
|
-
FROM ghcr.io/rails/devcontainer/images/ruby:$RUBY_VERSION
|
|
4
|
-
|
|
5
|
-
USER vscode
|
|
6
|
-
|
|
7
|
-
# Ensure binding is always 0.0.0.0
|
|
8
|
-
# Binds the server to all IP addresses of the container, so it can be accessed from outside the container.
|
|
9
|
-
ENV BINDING="0.0.0.0"
|
data/.devcontainer/compose.yml
DELETED
data/.standard.yml
DELETED
data/Gemfile
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
source "https://rubygems.org"
|
|
4
|
-
|
|
5
|
-
# Specify your gem's dependencies in encoded_id.gemspec
|
|
6
|
-
gemspec
|
|
7
|
-
|
|
8
|
-
gem "rake"
|
|
9
|
-
|
|
10
|
-
gem "minitest"
|
|
11
|
-
|
|
12
|
-
gem "standard"
|
|
13
|
-
|
|
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"
|
|
25
|
-
|
|
26
|
-
gem "singed"
|
|
27
|
-
|
|
28
|
-
gem "memory_profiler"
|
|
29
|
-
|
|
30
|
-
gem "hashids" # For benchmarking against
|
|
31
|
-
|
|
32
|
-
gem "base64"
|
|
33
|
-
|
|
34
|
-
# gem "pf2", require: false, github: "osyoyu/pf2", branch: "main"
|
|
35
|
-
|
|
36
|
-
# gem "vernier", require: false
|
data/Rakefile
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/gem_tasks"
|
|
4
|
-
require "rake/testtask"
|
|
5
|
-
|
|
6
|
-
Rake::TestTask.new(:test) do |t|
|
|
7
|
-
t.libs << "test"
|
|
8
|
-
t.libs << "lib"
|
|
9
|
-
t.test_files = FileList["test/**/test_*.rb"]
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
task default: %i[test standard]
|
|
13
|
-
|
|
14
|
-
task :compile_ext do
|
|
15
|
-
puts "Compiling extension"
|
|
16
|
-
`cd ext/encoded_id && make clean`
|
|
17
|
-
`cd ext/encoded_id && ruby extconf.rb`
|
|
18
|
-
`cd ext/encoded_id && make`
|
|
19
|
-
puts "Done"
|
|
20
|
-
end
|
data/Steepfile
DELETED
data/ext/encoded_id/extconf.rb
DELETED