cpf-utilities 0.0.0 → 1.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 +4 -4
- data/CHANGELOG.md +18 -0
- data/LICENSE +9 -0
- data/README.md +657 -0
- data/README.pt.md +642 -0
- data/src/cpf-utilities/cpf_fmt.rb +10 -0
- data/src/cpf-utilities/cpf_gen.rb +10 -0
- data/src/cpf-utilities/cpf_utils.rb +395 -0
- data/src/cpf-utilities/cpf_val.rb +9 -0
- data/src/cpf-utilities/errors.rb +23 -0
- data/src/cpf-utilities/version.rb +7 -2
- data/src/cpf-utilities.rb +23 -9
- metadata +40 -11
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'cpf-fmt'
|
|
4
|
+
require 'cpf-gen'
|
|
5
|
+
require 'cpf-val'
|
|
6
|
+
|
|
7
|
+
require_relative 'errors'
|
|
8
|
+
|
|
9
|
+
# Unified API for CPF (Cadastro da Pessoa Física) formatting, generation, and
|
|
10
|
+
# validation. Wraps a configurable formatter, generator, and validator so you
|
|
11
|
+
# can format, generate, and validate CPF values from a single instance.
|
|
12
|
+
#
|
|
13
|
+
# Public API:
|
|
14
|
+
#
|
|
15
|
+
# - {CpfUtils.format}, {CpfUtils.generate}, {CpfUtils.is_valid} — class helpers
|
|
16
|
+
# that alias {CpfUtils::DEFAULT} (preferred quick path)
|
|
17
|
+
# - {CpfUtils::DEFAULT} — mutable process-wide singleton (JS/Python parity; not
|
|
18
|
+
# thread-isolated — prefer {.new} / per-call options under concurrency)
|
|
19
|
+
# - {CpfUtils#format}, {CpfUtils#generate}, {CpfUtils#is_valid} — instance API
|
|
20
|
+
# - {CpfUtils::VERSION}
|
|
21
|
+
# - {CpfUtils::InvalidArgumentCombinationError} (API misuse)
|
|
22
|
+
#
|
|
23
|
+
# Two-tier access: main-class shortcuts ({CpfUtils::CpfFormatter}, etc.) and
|
|
24
|
+
# nested package modules ({CpfUtils::CpfFmt}, etc.). Root siblings {CpfFmt},
|
|
25
|
+
# {CpfGen}, and {CpfVal} remain loadable after +require 'cpf-utilities'+.
|
|
26
|
+
#
|
|
27
|
+
# Mutating {CpfUtils::DEFAULT} (e.g. via setters) affects subsequent class-helper
|
|
28
|
+
# calls process-wide (shared across threads). Prefer {CpfUtils.new} or per-call
|
|
29
|
+
# options for concurrent or isolated work. Custom instances are independent of
|
|
30
|
+
# +DEFAULT+.
|
|
31
|
+
#
|
|
32
|
+
# @example
|
|
33
|
+
# require 'cpf-utilities'
|
|
34
|
+
#
|
|
35
|
+
# CpfUtils.format('12345678909') # => "123.456.789-09"
|
|
36
|
+
# CpfUtils.generate(format: true) # => e.g. "529.982.247-25"
|
|
37
|
+
# CpfUtils.is_valid('52998224725') # => true
|
|
38
|
+
class CpfUtils
|
|
39
|
+
SETTINGS_KEYS = %i[formatter generator validator].freeze
|
|
40
|
+
|
|
41
|
+
FORMATTER_OPTION_KEYS = CpfFmt::CpfFormatterOptions::OPTION_KEYS
|
|
42
|
+
GENERATOR_OPTION_KEYS = CpfGen::CpfGeneratorOptions::OPTION_KEYS
|
|
43
|
+
|
|
44
|
+
private_constant :SETTINGS_KEYS, :FORMATTER_OPTION_KEYS, :GENERATOR_OPTION_KEYS
|
|
45
|
+
|
|
46
|
+
# Internal helpers for constructing owned component instances and merging
|
|
47
|
+
# settings / per-call option arguments.
|
|
48
|
+
module Helpers
|
|
49
|
+
module_function
|
|
50
|
+
|
|
51
|
+
def resolve_settings(settings, keywords)
|
|
52
|
+
keyword_settings = compact_settings(keywords)
|
|
53
|
+
raise_ambiguous_settings! if !settings.nil? && !keyword_settings.empty?
|
|
54
|
+
return normalize_settings(settings) unless settings.nil?
|
|
55
|
+
|
|
56
|
+
keyword_settings
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def normalize_settings(settings)
|
|
60
|
+
raise TypeMismatchError, "CpfUtils settings must be a Hash. Got #{settings.class}." unless settings.is_a?(Hash)
|
|
61
|
+
|
|
62
|
+
SETTINGS_KEYS.each_with_object({}) do |key, resolved|
|
|
63
|
+
if settings.key?(key)
|
|
64
|
+
resolved[key] = settings[key]
|
|
65
|
+
elsif settings.key?(key.to_s)
|
|
66
|
+
resolved[key] = settings[key.to_s]
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def compact_settings(keywords)
|
|
72
|
+
SETTINGS_KEYS.each_with_object({}) do |key, resolved|
|
|
73
|
+
value = keywords[key]
|
|
74
|
+
resolved[key] = value unless value.nil?
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def resolve_formatter(value)
|
|
79
|
+
return CpfFmt::CpfFormatter.new if value.nil?
|
|
80
|
+
return value if value.is_a?(CpfFmt::CpfFormatter)
|
|
81
|
+
return CpfFmt::CpfFormatter.new(value) if value.is_a?(CpfFmt::CpfFormatterOptions) || value.is_a?(Hash)
|
|
82
|
+
|
|
83
|
+
# Duck-typed / test doubles: use the given object by reference (Python parity).
|
|
84
|
+
value
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def resolve_generator(value)
|
|
88
|
+
return CpfGen::CpfGenerator.new if value.nil?
|
|
89
|
+
return value if value.is_a?(CpfGen::CpfGenerator)
|
|
90
|
+
return CpfGen::CpfGenerator.new(value) if value.is_a?(CpfGen::CpfGeneratorOptions) || value.is_a?(Hash)
|
|
91
|
+
|
|
92
|
+
# Duck-typed / test doubles: use the given object by reference (Python parity).
|
|
93
|
+
value
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def resolve_validator(value)
|
|
97
|
+
return CpfVal::CpfValidator.new if value.nil?
|
|
98
|
+
return value if value.is_a?(CpfVal::CpfValidator)
|
|
99
|
+
|
|
100
|
+
# Duck-typed / test doubles: use the given object by reference (Python parity).
|
|
101
|
+
# Unlike CNPJ, CPF has no validator Options class — Hash is not accepted as options.
|
|
102
|
+
value
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def ensure_exclusive_options!(options, keywords, option_keys)
|
|
106
|
+
return if options.nil?
|
|
107
|
+
return if keywords.none? { |_key, value| !value.nil? }
|
|
108
|
+
|
|
109
|
+
raise_ambiguous_options!(option_keys)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def compact_keyword_overrides(keywords, option_keys)
|
|
113
|
+
option_keys.each_with_object({}) do |key, overrides|
|
|
114
|
+
value = keywords[key]
|
|
115
|
+
overrides[key] = value unless value.nil?
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def raise_ambiguous_settings!
|
|
120
|
+
option_keywords = SETTINGS_KEYS.map { |key| "#{key}:" }.join(', ')
|
|
121
|
+
|
|
122
|
+
raise InvalidArgumentCombinationError,
|
|
123
|
+
'Pass either a settings Hash to `settings`, or keyword arguments ' \
|
|
124
|
+
"(#{option_keywords}), not both."
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def raise_ambiguous_options!(option_keys)
|
|
128
|
+
option_keywords = option_keys.map { |key| "#{key}:" }.join(', ')
|
|
129
|
+
|
|
130
|
+
raise InvalidArgumentCombinationError,
|
|
131
|
+
"Pass either an options instance/Hash to `options`, or keyword arguments (#{option_keywords}), " \
|
|
132
|
+
'not both.'
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
private_constant :Helpers
|
|
136
|
+
|
|
137
|
+
# Creates a new {CpfUtils} with customized options. Each of +:formatter+ and
|
|
138
|
+
# +:generator+ can be omitted (defaults are used), or provided as an instance,
|
|
139
|
+
# an options object, or a plain {Hash} of options. +:validator+ accepts an
|
|
140
|
+
# instance, +nil+, or a duck-typed object — not an options Hash.
|
|
141
|
+
#
|
|
142
|
+
# When a component instance is passed, it is used directly (same reference).
|
|
143
|
+
# When +nil+ is passed for a component, a new instance with default options is
|
|
144
|
+
# created.
|
|
145
|
+
#
|
|
146
|
+
# +settings+ and the keyword arguments are never merged with each other: when
|
|
147
|
+
# +settings+ is given (a {Hash} with +:formatter+, +:generator+, and/or
|
|
148
|
+
# +:validator+ keys), it alone determines the components; otherwise, the
|
|
149
|
+
# components are built exclusively from the keyword arguments. Passing
|
|
150
|
+
# +settings+ together with any non-+nil+ keyword argument raises
|
|
151
|
+
# {InvalidArgumentCombinationError} instead of silently ignoring the keywords.
|
|
152
|
+
#
|
|
153
|
+
# @param settings [Hash, nil] settings Hash with +:formatter+, +:generator+,
|
|
154
|
+
# and/or +:validator+ keys (+:formatter+/+:generator+: instance, options
|
|
155
|
+
# instance, options Hash, or +nil+; +:validator+: instance, +nil+, or
|
|
156
|
+
# duck-typed object — not an options Hash)
|
|
157
|
+
# @param keywords [Hash] +:formatter+, +:generator+, +:validator+ (mutually
|
|
158
|
+
# exclusive with +settings+)
|
|
159
|
+
# @raise [InvalidArgumentCombinationError] if +settings+ and a keyword argument
|
|
160
|
+
# are both given
|
|
161
|
+
# @raise [TypeMismatchError] if +settings+ is given and is not a +Hash+
|
|
162
|
+
# @raise [CpfFmt::TypeMismatchError] if formatter options have an invalid type
|
|
163
|
+
# @raise [CpfFmt::OutOfRangeError] if formatter +hidden_start+ or +hidden_end+
|
|
164
|
+
# are out of valid range
|
|
165
|
+
# @raise [CpfFmt::ValidationError] if any formatter key option contains a
|
|
166
|
+
# disallowed character
|
|
167
|
+
# @raise [CpfGen::TypeMismatchError] if generator options have an invalid type
|
|
168
|
+
# @raise [CpfGen::ValidationError] if generator +prefix+ is invalid
|
|
169
|
+
def initialize(settings = nil, **keywords)
|
|
170
|
+
resolved = Helpers.resolve_settings(settings, keywords)
|
|
171
|
+
|
|
172
|
+
@formatter = Helpers.resolve_formatter(resolved[:formatter])
|
|
173
|
+
@generator = Helpers.resolve_generator(resolved[:generator])
|
|
174
|
+
@validator = Helpers.resolve_validator(resolved[:validator])
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Returns the formatter used by this utils instance.
|
|
178
|
+
#
|
|
179
|
+
# @return [CpfFmt::CpfFormatter]
|
|
180
|
+
attr_reader :formatter
|
|
181
|
+
|
|
182
|
+
# Returns the generator used by this utils instance.
|
|
183
|
+
#
|
|
184
|
+
# @return [CpfGen::CpfGenerator]
|
|
185
|
+
attr_reader :generator
|
|
186
|
+
|
|
187
|
+
# Returns the validator used by this utils instance.
|
|
188
|
+
#
|
|
189
|
+
# @return [CpfVal::CpfValidator]
|
|
190
|
+
attr_reader :validator
|
|
191
|
+
|
|
192
|
+
# Sets the active formatter used by this utils instance.
|
|
193
|
+
#
|
|
194
|
+
# It is flexible and can handle any of these inputs:
|
|
195
|
+
#
|
|
196
|
+
# 1. A complete new instance of {CpfFmt::CpfFormatter}
|
|
197
|
+
# 2. An instance of {CpfFmt::CpfFormatterOptions}
|
|
198
|
+
# 3. A partial {Hash} with options for the formatter
|
|
199
|
+
# 4. +nil+ creates a brand new {CpfFmt::CpfFormatter} with default options
|
|
200
|
+
#
|
|
201
|
+
# Note that this resets the formatter instance completely. Any previous
|
|
202
|
+
# options will be overridden. To alter only a single option or a few options
|
|
203
|
+
# of the existing instance, access it directly (e.g.
|
|
204
|
+
# +utils.formatter.options.hidden = true+).
|
|
205
|
+
#
|
|
206
|
+
# @param value [CpfFmt::CpfFormatter, CpfFmt::CpfFormatterOptions, Hash, nil]
|
|
207
|
+
# @raise [CpfFmt::TypeMismatchError] if options have an invalid type
|
|
208
|
+
# @raise [CpfFmt::OutOfRangeError] if +hidden_start+ or +hidden_end+ are out
|
|
209
|
+
# of valid range
|
|
210
|
+
# @raise [CpfFmt::ValidationError] if any key option contains a disallowed
|
|
211
|
+
# character
|
|
212
|
+
def formatter=(value)
|
|
213
|
+
@formatter = Helpers.resolve_formatter(value)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Sets the active generator used by this utils instance.
|
|
217
|
+
#
|
|
218
|
+
# It is flexible and can handle any of these inputs:
|
|
219
|
+
#
|
|
220
|
+
# 1. A complete new instance of {CpfGen::CpfGenerator}
|
|
221
|
+
# 2. An instance of {CpfGen::CpfGeneratorOptions}
|
|
222
|
+
# 3. A partial {Hash} with options for the generator
|
|
223
|
+
# 4. +nil+ creates a brand new {CpfGen::CpfGenerator} with default options
|
|
224
|
+
#
|
|
225
|
+
# Note that this resets the generator instance completely. Any previous
|
|
226
|
+
# options will be overridden. To alter only a single option or a few options
|
|
227
|
+
# of the existing instance, access it directly (e.g.
|
|
228
|
+
# +utils.generator.options.format = true+).
|
|
229
|
+
#
|
|
230
|
+
# @param value [CpfGen::CpfGenerator, CpfGen::CpfGeneratorOptions, Hash, nil]
|
|
231
|
+
# @raise [CpfGen::TypeMismatchError] if options have an invalid type
|
|
232
|
+
# @raise [CpfGen::ValidationError] if +prefix+ is invalid
|
|
233
|
+
def generator=(value)
|
|
234
|
+
@generator = Helpers.resolve_generator(value)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Sets the active validator used by this utils instance.
|
|
238
|
+
#
|
|
239
|
+
# It is flexible and can handle any of these inputs:
|
|
240
|
+
#
|
|
241
|
+
# 1. A complete new instance of {CpfVal::CpfValidator}
|
|
242
|
+
# 2. +nil+ creates a brand new {CpfVal::CpfValidator}
|
|
243
|
+
# 3. A duck-typed object used by reference (test doubles)
|
|
244
|
+
#
|
|
245
|
+
# Note that this resets the validator instance completely. CPF has no
|
|
246
|
+
# validator options class — a +Hash+ is treated as a duck-typed object, not
|
|
247
|
+
# as options.
|
|
248
|
+
#
|
|
249
|
+
# @param value [CpfVal::CpfValidator, Object, nil]
|
|
250
|
+
def validator=(value)
|
|
251
|
+
@validator = Helpers.resolve_validator(value)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# Formats a CPF value into a human-readable string.
|
|
255
|
+
#
|
|
256
|
+
# Normalizes and optionally masks, HTML-escapes, or URL-encodes the input.
|
|
257
|
+
# Delegates to the instance formatter; per-call options override the
|
|
258
|
+
# formatter's defaults for this call only.
|
|
259
|
+
#
|
|
260
|
+
# Input is normalized by stripping non-digit characters. If the result length
|
|
261
|
+
# is not exactly 11, the configured +on_fail+ callback is invoked with the
|
|
262
|
+
# original value and an error; its return value is used as the result.
|
|
263
|
+
#
|
|
264
|
+
# When valid, the result may be further transformed according to options:
|
|
265
|
+
#
|
|
266
|
+
# - If +hidden+ is +true+, characters between +hidden_start+ and +hidden_end+
|
|
267
|
+
# (inclusive) are replaced with +hidden_key+.
|
|
268
|
+
# - If +escape+ is +true+, HTML special characters are escaped.
|
|
269
|
+
# - If +encode+ is +true+, the string is URL-encoded.
|
|
270
|
+
#
|
|
271
|
+
# +options+ and the keyword arguments are never merged with each other: when
|
|
272
|
+
# +options+ is given alone it is forwarded as the per-call override; otherwise
|
|
273
|
+
# any non-+nil+ keyword argument is forwarded. Passing +options+ together with
|
|
274
|
+
# any non-+nil+ keyword argument raises {InvalidArgumentCombinationError}.
|
|
275
|
+
#
|
|
276
|
+
# @param cpf_input [String, Array<String>] CPF value as a string or array of
|
|
277
|
+
# strings
|
|
278
|
+
# @param options [CpfFmt::CpfFormatterOptions, Hash, nil] per-call overrides
|
|
279
|
+
# @param keywords [Hash] per-call option keyword overrides (mutually exclusive
|
|
280
|
+
# with +options+; see {CpfFmt::CpfFormatterOptions})
|
|
281
|
+
# @return [String] formatted CPF string, or the +on_fail+ callback result
|
|
282
|
+
# @raise [InvalidArgumentCombinationError] if +options+ and a keyword argument
|
|
283
|
+
# are both given
|
|
284
|
+
# @raise [CpfFmt::TypeMismatchError] if the input is not a +String+ or
|
|
285
|
+
# +Array<String>+, or if any option has an invalid type
|
|
286
|
+
# @raise [CpfFmt::OutOfRangeError] if +hidden_start+ or +hidden_end+ are out
|
|
287
|
+
# of valid range
|
|
288
|
+
# @raise [CpfFmt::ValidationError] if any key option contains a disallowed
|
|
289
|
+
# character
|
|
290
|
+
def format(cpf_input, options = nil, **keywords)
|
|
291
|
+
Helpers.ensure_exclusive_options!(options, keywords, FORMATTER_OPTION_KEYS)
|
|
292
|
+
return @formatter.format(cpf_input, options) unless options.nil?
|
|
293
|
+
|
|
294
|
+
keyword_overrides = Helpers.compact_keyword_overrides(keywords, FORMATTER_OPTION_KEYS)
|
|
295
|
+
return @formatter.format(cpf_input, **keyword_overrides) unless keyword_overrides.empty?
|
|
296
|
+
|
|
297
|
+
@formatter.format(cpf_input)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Generates a valid 11-digit CPF, optionally with a prefix and formatting.
|
|
301
|
+
#
|
|
302
|
+
# Builds an 11-digit CPF from the configured +prefix+ (if any), a random
|
|
303
|
+
# sequence of digits, and two computed check digits. If +format+ is enabled,
|
|
304
|
+
# the result is returned as +XXX.XXX.XXX-XX+.
|
|
305
|
+
#
|
|
306
|
+
# Delegates to the instance generator; per-call options override the
|
|
307
|
+
# generator's defaults for this call only.
|
|
308
|
+
#
|
|
309
|
+
# +options+ and the keyword arguments are never merged with each other: when
|
|
310
|
+
# +options+ is given alone it is forwarded as the per-call override; otherwise
|
|
311
|
+
# any non-+nil+ keyword argument is forwarded. Passing +options+ together with
|
|
312
|
+
# any non-+nil+ keyword argument raises {InvalidArgumentCombinationError}.
|
|
313
|
+
#
|
|
314
|
+
# @param options [CpfGen::CpfGeneratorOptions, Hash, nil] per-call overrides
|
|
315
|
+
# @param keywords [Hash] per-call option keyword overrides (mutually exclusive
|
|
316
|
+
# with +options+; see {CpfGen::CpfGeneratorOptions})
|
|
317
|
+
# @return [String] generated CPF
|
|
318
|
+
# @raise [InvalidArgumentCombinationError] if +options+ and a keyword argument
|
|
319
|
+
# are both given
|
|
320
|
+
# @raise [CpfGen::TypeMismatchError] if any option has an invalid type
|
|
321
|
+
# @raise [CpfGen::ValidationError] if +prefix+ is invalid
|
|
322
|
+
def generate(options = nil, **keywords)
|
|
323
|
+
Helpers.ensure_exclusive_options!(options, keywords, GENERATOR_OPTION_KEYS)
|
|
324
|
+
return @generator.generate(options) unless options.nil?
|
|
325
|
+
|
|
326
|
+
keyword_overrides = Helpers.compact_keyword_overrides(keywords, GENERATOR_OPTION_KEYS)
|
|
327
|
+
return @generator.generate(**keyword_overrides) unless keyword_overrides.empty?
|
|
328
|
+
|
|
329
|
+
@generator.generate
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# Returns whether the given value is a valid CPF.
|
|
333
|
+
#
|
|
334
|
+
# Delegates to the instance validator. CPF has no per-call validator options.
|
|
335
|
+
#
|
|
336
|
+
# @param cpf_input [String, Array<String>] CPF value as a string or array of
|
|
337
|
+
# strings
|
|
338
|
+
# @return [Boolean] +true+ when valid, +false+ otherwise
|
|
339
|
+
# @raise [CpfVal::TypeMismatchError] if the input is not a +String+ or
|
|
340
|
+
# +Array<String>+
|
|
341
|
+
# rubocop:disable Naming/PredicatePrefix -- public API matches JS/Python `is_valid`
|
|
342
|
+
def is_valid(cpf_input)
|
|
343
|
+
@validator.is_valid(cpf_input)
|
|
344
|
+
end
|
|
345
|
+
# rubocop:enable Naming/PredicatePrefix
|
|
346
|
+
|
|
347
|
+
# Default {CpfUtils} instance with default formatter, generator, and
|
|
348
|
+
# validator options (parity with the JS default export / Python +cpf_utils+
|
|
349
|
+
# singleton). Configuration is process-wide and shared across threads:
|
|
350
|
+
# mutating this instance (e.g. via setters) affects subsequent
|
|
351
|
+
# {CpfUtils.format}, {CpfUtils.generate}, and {CpfUtils.is_valid} calls for
|
|
352
|
+
# every caller in the process. Prefer {CpfUtils.new} or per-call options for
|
|
353
|
+
# threaded or isolated work.
|
|
354
|
+
DEFAULT = new
|
|
355
|
+
|
|
356
|
+
class << self
|
|
357
|
+
# Formats a CPF using {DEFAULT} (alias of {CpfUtils#format} on that instance).
|
|
358
|
+
#
|
|
359
|
+
# @param cpf_input [String, Array<String>] CPF value as a string or array of
|
|
360
|
+
# strings
|
|
361
|
+
# @param options [CpfFmt::CpfFormatterOptions, Hash, nil] per-call overrides
|
|
362
|
+
# @param keywords [Hash] per-call option keyword overrides (mutually exclusive
|
|
363
|
+
# with +options+)
|
|
364
|
+
# @return [String] formatted CPF string, or the +on_fail+ callback result
|
|
365
|
+
# @see CpfUtils#format
|
|
366
|
+
def format(cpf_input, options = nil, **keywords)
|
|
367
|
+
DEFAULT.format(cpf_input, options, **keywords)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# Generates a valid CPF using {DEFAULT} (alias of {CpfUtils#generate} on that
|
|
371
|
+
# instance).
|
|
372
|
+
#
|
|
373
|
+
# @param options [CpfGen::CpfGeneratorOptions, Hash, nil] per-call overrides
|
|
374
|
+
# @param keywords [Hash] per-call option keyword overrides (mutually exclusive
|
|
375
|
+
# with +options+)
|
|
376
|
+
# @return [String] generated CPF
|
|
377
|
+
# @see CpfUtils#generate
|
|
378
|
+
def generate(options = nil, **keywords)
|
|
379
|
+
DEFAULT.generate(options, **keywords)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# Validates a CPF using {DEFAULT} (alias of {CpfUtils#is_valid} on that
|
|
383
|
+
# instance).
|
|
384
|
+
#
|
|
385
|
+
# @param cpf_input [String, Array<String>] CPF value as a string or array of
|
|
386
|
+
# strings
|
|
387
|
+
# @return [Boolean] +true+ when valid, +false+ otherwise
|
|
388
|
+
# @see CpfUtils#is_valid
|
|
389
|
+
# rubocop:disable Naming/PredicatePrefix -- public API matches instance `#is_valid`
|
|
390
|
+
def is_valid(cpf_input)
|
|
391
|
+
DEFAULT.is_valid(cpf_input)
|
|
392
|
+
end
|
|
393
|
+
# rubocop:enable Naming/PredicatePrefix
|
|
394
|
+
end
|
|
395
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CpfUtils
|
|
4
|
+
# Marker module mixed into every custom error raised by this library.
|
|
5
|
+
#
|
|
6
|
+
# Use +rescue CpfUtils::Error+ to catch every library error regardless of
|
|
7
|
+
# native ancestry. Component packages raise their own error hierarchies;
|
|
8
|
+
# this gem only defines the misuse errors it raises itself.
|
|
9
|
+
module Error; end
|
|
10
|
+
|
|
11
|
+
# API misuse error raised when an argument's runtime type does not match the
|
|
12
|
+
# type required by the API contract (for example, a non-Hash +settings+ value).
|
|
13
|
+
class TypeMismatchError < TypeError
|
|
14
|
+
include Error
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# API misuse error raised when the combination of provided arguments does not
|
|
18
|
+
# match any valid overload-style signature (for example, a settings/options
|
|
19
|
+
# Hash together with keyword overrides).
|
|
20
|
+
class InvalidArgumentCombinationError < ArgumentError
|
|
21
|
+
include Error
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
# Placeholder class so the gemspec (and any early require of this file) can read
|
|
4
|
+
# {CpfUtils::VERSION}. The façade implementation reopens this class.
|
|
5
|
+
class CpfUtils
|
|
6
|
+
# Gem version string. Placeholder replaced at build/publish time.
|
|
7
|
+
#
|
|
8
|
+
# @return [String]
|
|
9
|
+
VERSION = '1.0.0'
|
|
5
10
|
end
|
data/src/cpf-utilities.rb
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require_relative
|
|
3
|
+
require 'cpf-fmt'
|
|
4
|
+
require 'cpf-gen'
|
|
5
|
+
require 'cpf-val'
|
|
6
|
+
require_relative 'cpf-utilities/version'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
# Entry point for the +cpf-utilities+ gem.
|
|
9
|
+
#
|
|
10
|
+
# Loads sibling packages (+cpf-fmt+, +cpf-gen+, +cpf-val+) and defines the
|
|
11
|
+
# {CpfUtils} façade class. +version.rb+ declares the placeholder class so the
|
|
12
|
+
# gemspec can read {CpfUtils::VERSION}; later files reopen that same class.
|
|
13
|
+
#
|
|
14
|
+
# Two-tier access after +require 'cpf-utilities'+:
|
|
15
|
+
#
|
|
16
|
+
# - *Main shortcuts* at the façade root: {CpfUtils::CpfFormatter},
|
|
17
|
+
# {CpfUtils::CpfGenerator}, {CpfUtils::CpfValidator}.
|
|
18
|
+
# - *Package nests* for the full sibling surface (Options, helpers, errors,
|
|
19
|
+
# types): {CpfUtils::CpfFmt}, {CpfUtils::CpfGen}, {CpfUtils::CpfVal}
|
|
20
|
+
# (same objects as +::CpfFmt+, +::CpfGen+, +::CpfVal+).
|
|
21
|
+
# - Root siblings (+CpfFmt+, +CpfGen+, +CpfVal+) remain supported unchanged.
|
|
22
|
+
require_relative 'cpf-utilities/errors'
|
|
23
|
+
require_relative 'cpf-utilities/cpf_utils'
|
|
24
|
+
require_relative 'cpf-utilities/cpf_fmt'
|
|
25
|
+
require_relative 'cpf-utilities/cpf_gen'
|
|
26
|
+
require_relative 'cpf-utilities/cpf_val'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cpf-utilities
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Julio L. Muller
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cpf-fmt
|
|
@@ -16,54 +16,83 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 1.0.0
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 1.1.0
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
27
|
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
29
|
+
version: 1.0.0
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 1.1.0
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: cpf-gen
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
30
36
|
requirements:
|
|
31
37
|
- - ">="
|
|
32
38
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
39
|
+
version: 1.0.0
|
|
40
|
+
- - "<"
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: 1.1.0
|
|
34
43
|
type: :runtime
|
|
35
44
|
prerelease: false
|
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
46
|
requirements:
|
|
38
47
|
- - ">="
|
|
39
48
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
49
|
+
version: 1.0.0
|
|
50
|
+
- - "<"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: 1.1.0
|
|
41
53
|
- !ruby/object:Gem::Dependency
|
|
42
54
|
name: cpf-val
|
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
|
44
56
|
requirements:
|
|
45
57
|
- - ">="
|
|
46
58
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
59
|
+
version: 1.0.0
|
|
60
|
+
- - "<"
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: 1.1.0
|
|
48
63
|
type: :runtime
|
|
49
64
|
prerelease: false
|
|
50
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
66
|
requirements:
|
|
52
67
|
- - ">="
|
|
53
68
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
55
|
-
|
|
69
|
+
version: 1.0.0
|
|
70
|
+
- - "<"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: 1.1.0
|
|
73
|
+
description: Utilities to deal with CPF (Brazilian Individual's Taxpayer ID)
|
|
56
74
|
email:
|
|
75
|
+
- juliolmuller@outlook.com
|
|
57
76
|
executables: []
|
|
58
77
|
extensions: []
|
|
59
78
|
extra_rdoc_files: []
|
|
60
79
|
files:
|
|
80
|
+
- CHANGELOG.md
|
|
81
|
+
- LICENSE
|
|
82
|
+
- README.md
|
|
83
|
+
- README.pt.md
|
|
61
84
|
- src/cpf-utilities.rb
|
|
85
|
+
- src/cpf-utilities/cpf_fmt.rb
|
|
86
|
+
- src/cpf-utilities/cpf_gen.rb
|
|
87
|
+
- src/cpf-utilities/cpf_utils.rb
|
|
88
|
+
- src/cpf-utilities/cpf_val.rb
|
|
89
|
+
- src/cpf-utilities/errors.rb
|
|
62
90
|
- src/cpf-utilities/version.rb
|
|
63
91
|
homepage: https://github.com/LacusSolutions/br-utils-ruby
|
|
64
92
|
licenses:
|
|
65
93
|
- MIT
|
|
66
94
|
metadata:
|
|
95
|
+
source_code_uri: https://github.com/LacusSolutions/br-utils-ruby
|
|
67
96
|
rubygems_mfa_required: 'true'
|
|
68
97
|
post_install_message:
|
|
69
98
|
rdoc_options: []
|
|
@@ -73,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
73
102
|
requirements:
|
|
74
103
|
- - ">="
|
|
75
104
|
- !ruby/object:Gem::Version
|
|
76
|
-
version: '3.
|
|
105
|
+
version: '3.1'
|
|
77
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
107
|
requirements:
|
|
79
108
|
- - ">="
|
|
@@ -83,5 +112,5 @@ requirements: []
|
|
|
83
112
|
rubygems_version: 3.4.19
|
|
84
113
|
signing_key:
|
|
85
114
|
specification_version: 4
|
|
86
|
-
summary:
|
|
115
|
+
summary: Utilities to deal with CPF (Brazilian Individual's Taxpayer ID)
|
|
87
116
|
test_files: []
|