cool_id 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cool_id/version.rb +1 -1
- data/lib/cool_id.rb +75 -43
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a61d8d06c3414dcec52ecd9a3f28696d0fafb683b2b206e025c33a1deb03de9
|
4
|
+
data.tar.gz: bc13a903ed6d5239eae6ee216f5da45699a525d755e914f9f9c2b81b6e33d26c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77aac33c12253962d7beabffc5d7101379f40d991b580c67ea0a306cd82f8d2befda21b23fbd3c3735a516863ef4c3565b18084f67ed001172b7a395527f3f4a
|
7
|
+
data.tar.gz: d3c269343bd10098fdd902424c10c22e676a0cea67d5dff404628863ea4d085319017b31d6c602364da024d36c30a470e1bd3ade7b687379bbbd3f011a72191c
|
data/lib/cool_id/version.rb
CHANGED
data/lib/cool_id.rb
CHANGED
@@ -3,76 +3,90 @@
|
|
3
3
|
require_relative "cool_id/version"
|
4
4
|
require "nanoid"
|
5
5
|
require "active_support/concern"
|
6
|
-
require "active_record"
|
7
6
|
|
8
7
|
module CoolId
|
9
8
|
class Error < StandardError; end
|
10
9
|
|
10
|
+
# defaults based on https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api
|
11
|
+
DEFAULT_SEPARATOR = "_"
|
12
|
+
DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"
|
13
|
+
DEFAULT_LENGTH = 12
|
14
|
+
|
15
|
+
Id = Struct.new(:key, :prefix, :id, :model_class)
|
16
|
+
|
11
17
|
class << self
|
12
|
-
attr_accessor :separator
|
18
|
+
attr_accessor :separator, :alphabet, :length
|
13
19
|
|
14
20
|
def configure
|
15
21
|
yield self
|
16
22
|
end
|
17
23
|
|
24
|
+
def reset_configuration
|
25
|
+
self.separator = DEFAULT_SEPARATOR
|
26
|
+
self.alphabet = DEFAULT_ALPHABET
|
27
|
+
self.length = DEFAULT_LENGTH
|
28
|
+
end
|
29
|
+
|
18
30
|
def registry
|
19
|
-
@
|
31
|
+
@prefix_map ||= Registry.new
|
20
32
|
end
|
21
33
|
|
22
34
|
def generate_id(config)
|
23
|
-
|
24
|
-
|
35
|
+
alphabet = config.alphabet || @alphabet
|
36
|
+
length = config.length || @length
|
37
|
+
id = Nanoid.generate(size: length, alphabet: alphabet)
|
38
|
+
|
39
|
+
"#{config.prefix}#{separator}#{id}"
|
25
40
|
end
|
26
41
|
end
|
27
42
|
|
28
|
-
self.separator =
|
43
|
+
self.separator = DEFAULT_SEPARATOR
|
44
|
+
self.alphabet = DEFAULT_ALPHABET
|
45
|
+
self.length = DEFAULT_LENGTH
|
29
46
|
|
30
47
|
class Registry
|
31
48
|
def initialize
|
32
|
-
@
|
49
|
+
@prefix_map = {}
|
33
50
|
end
|
34
51
|
|
35
52
|
def register(prefix, model_class)
|
36
|
-
@
|
53
|
+
@prefix_map[prefix] = model_class
|
37
54
|
end
|
38
55
|
|
39
|
-
def
|
40
|
-
|
56
|
+
def locate(id)
|
57
|
+
parsed = parse(id)
|
58
|
+
parsed&.model_class&.find_by(id: id)
|
41
59
|
end
|
42
60
|
|
43
|
-
def
|
44
|
-
prefix,
|
45
|
-
model_class =
|
46
|
-
model_class
|
47
|
-
|
48
|
-
|
49
|
-
def find_record!(id)
|
50
|
-
prefix, _ = id.split(CoolId.separator, 2)
|
51
|
-
model_class = find_model(prefix)
|
52
|
-
model_class&.find(id)
|
61
|
+
def parse(id)
|
62
|
+
prefix, key = id.split(CoolId.separator, 2)
|
63
|
+
model_class = @prefix_map[prefix]
|
64
|
+
return nil unless model_class
|
65
|
+
Id.new(key, prefix, id, model_class)
|
53
66
|
end
|
54
67
|
end
|
55
68
|
|
56
69
|
class Config
|
57
70
|
attr_reader :prefix, :length, :alphabet
|
58
71
|
|
59
|
-
def initialize(prefix
|
60
|
-
@prefix = prefix
|
72
|
+
def initialize(prefix:, length: nil, alphabet: nil)
|
61
73
|
@length = length
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
def alphabet=(value)
|
66
|
-
validate_alphabet(value)
|
67
|
-
@alphabet = value
|
74
|
+
@prefix = validate_prefix(prefix)
|
75
|
+
@alphabet = validate_alphabet(alphabet)
|
68
76
|
end
|
69
77
|
|
70
78
|
private
|
71
79
|
|
80
|
+
def validate_prefix(value)
|
81
|
+
raise ArgumentError, "Prefix cannot be nil" if value.nil?
|
82
|
+
raise ArgumentError, "Prefix cannot be empty" if value.empty?
|
83
|
+
value
|
84
|
+
end
|
85
|
+
|
72
86
|
def validate_alphabet(value)
|
73
|
-
if value.
|
74
|
-
|
75
|
-
|
87
|
+
return nil if value.nil?
|
88
|
+
raise ArgumentError, "Alphabet cannot include the separator '#{CoolId.separator}'" if value.include?(CoolId.separator)
|
89
|
+
value
|
76
90
|
end
|
77
91
|
end
|
78
92
|
|
@@ -80,39 +94,57 @@ module CoolId
|
|
80
94
|
extend ActiveSupport::Concern
|
81
95
|
|
82
96
|
class_methods do
|
83
|
-
|
84
|
-
|
85
|
-
def cool_id(options = {})
|
86
|
-
register_cool_id(options)
|
87
|
-
end
|
97
|
+
attr_accessor :cool_id_config
|
98
|
+
attr_accessor :cool_id_setup_required
|
88
99
|
|
89
|
-
def
|
90
|
-
raise ArgumentError, "Prefix cannot be empty" if options[:prefix] && options[:prefix].empty?
|
100
|
+
def cool_id(options)
|
91
101
|
@cool_id_config = Config.new(**options)
|
92
102
|
CoolId.registry.register(options[:prefix], self)
|
93
103
|
end
|
94
104
|
|
95
105
|
def generate_cool_id
|
96
|
-
CoolId.generate_id(@cool_id_config
|
106
|
+
CoolId.generate_id(@cool_id_config)
|
107
|
+
end
|
108
|
+
|
109
|
+
def ensure_cool_id_setup
|
110
|
+
@cool_id_setup_required = true
|
111
|
+
end
|
112
|
+
|
113
|
+
def skip_cool_id_setup
|
114
|
+
@cool_id_setup_required = false
|
115
|
+
end
|
116
|
+
|
117
|
+
def inherited(subclass)
|
118
|
+
super
|
119
|
+
if @cool_id_setup_required && !subclass.instance_variable_defined?(:@cool_id_setup_required)
|
120
|
+
subclass.instance_variable_set(:@cool_id_setup_required, true)
|
121
|
+
end
|
97
122
|
end
|
98
123
|
end
|
99
124
|
|
100
125
|
included do
|
101
126
|
before_create :set_cool_id
|
127
|
+
after_initialize :ensure_cool_id_configured
|
102
128
|
|
103
129
|
private
|
104
130
|
|
105
131
|
def set_cool_id
|
106
132
|
self.id = self.class.generate_cool_id if id.blank?
|
107
133
|
end
|
134
|
+
|
135
|
+
def ensure_cool_id_configured
|
136
|
+
if self.class.cool_id_setup_required && self.class.cool_id_config.nil?
|
137
|
+
raise Error, "CoolId not configured for #{self.class}. Use 'cool_id' to configure or 'skip_cool_id_setup' to opt out."
|
138
|
+
end
|
139
|
+
end
|
108
140
|
end
|
109
141
|
end
|
110
142
|
|
111
|
-
def self.
|
112
|
-
registry.
|
143
|
+
def self.locate(id)
|
144
|
+
registry.locate(id)
|
113
145
|
end
|
114
146
|
|
115
|
-
def self.
|
116
|
-
registry.
|
147
|
+
def self.parse(id)
|
148
|
+
registry.parse(id)
|
117
149
|
end
|
118
150
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cool_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Schilling
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-08-
|
11
|
+
date: 2024-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nanoid
|