worldwide 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5239439f9dda5abcf62fc8cbb59343a420a34ef5abe96c7b6cd23a17a633623a
4
- data.tar.gz: 8438623520e1065231f78707ebaadeee25c0bd2f5ec4f795cbde00284a69fd45
3
+ metadata.gz: 70f7f2806122734340656c024d816ec4028060de514b5dc4773529ce8bff4f37
4
+ data.tar.gz: 3c5c2237879ab05f1a77505432bca89ad50e9d5667ff1d1951b501c07f43050e
5
5
  SHA512:
6
- metadata.gz: 578e7e33cf986cda84b85c4d9e2f1092d13e3fd513b63667ee757cc6bbc937b84855ca4718a262ea5b6ecffa4203924a7fc1c5395fde98582c31adda4e1ab78d
7
- data.tar.gz: 2e28c5c0b5823979d7114b466e931429ec7376a90d1e1eb7de34c93a9dff059068ae65b548f0f3cf0f75c29c6f16051f9050ae1eb337ac51486ed0949d31c54c
6
+ metadata.gz: 1f8e9fa1416ccc24d3818e609acf7d05da6534cdb9b1e780af496151559bbb5e73540df416d85d554a3083a5add5691df2ab512fa023da3ca43d85251a89c18d
7
+ data.tar.gz: d55d1ed819560e45099c6ae1fc9e1cc5f62e0a6b62c4e9b24aa97daa78b7aae0e6cb8636dc0b6086ca5ba7f3a715badc0e7d4c60ddde09df49cb2b2c00677e8c
data/CHANGELOG.md CHANGED
@@ -28,6 +28,24 @@ Nil.
28
28
 
29
29
  ---
30
30
 
31
+ [0.3.0] - 2023-11-03
32
+ - Add code alternates for Japan [#23](https://github.com/Shopify/worldwide/pull/23)
33
+ - Add code alternates for Puerto Rico [#24](https://github.com/Shopify/worldwide/pull/24)
34
+ - Record multiple parents per region [#27](https://github.com/Shopify/worldwide/pull/27)
35
+ - Add region.building_number_may_be_in_address2 [#28](https://github.com/Shopify/worldwide/pull/28)
36
+ - Lookup by parent-child ISO and CLDR codes for dual-status territories
37
+ [#29](https://github.com/Shopify/worldwide/pull/29)
38
+ - Handle ISO_CODE only zones lookup [#26](https://github.com/Shopify/worldwide/pull/26)
39
+
40
+
41
+ [0.2.0] - 2023-11-01
42
+
43
+ - Add Region#group and Region#group_name [#15](https://github.com/Shopify/worldwide/pull/15)
44
+ - Ensure Region#has_zip? returns a boolean for all regions [#17](https://github.com/Shopify/worldwide/pull/17)
45
+ - Zip normalization bugfix when parent isocode is not set [#6](https://github.com/Shopify/worldwide/pull/6)
46
+ - Update region parent when alternates are defined [#18](https://github.com/Shopify/worldwide/pull/18)
47
+ - Add partial matching for Region#valid_zip? [#19](https://github.com/Shopify/worldwide/pull/19)
48
+
31
49
  [0.1.1] - 2023-10-27
32
50
 
33
51
  - Fix issue with deploy to rubygems.org failing
data/Gemfile.lock CHANGED
@@ -13,7 +13,7 @@ GIT
13
13
  PATH
14
14
  remote: .
15
15
  specs:
16
- worldwide (0.1.1)
16
+ worldwide (0.3.0)
17
17
  activesupport (~> 7.0)
18
18
  i18n (~> 1.12.0)
19
19
  phonelib (~> 0.8)
data/README.md CHANGED
@@ -99,7 +99,7 @@ Worldwide exposes the notion of a "region", or political subdivision. This can
99
99
 
100
100
  Note that, when exposing geographic information to users, you should be careful what you refer
101
101
  to as a "country". For backward compatibility with historical APIs, we use the term "country"
102
- to refer to what CLDR refers to as a "territory", and what we describe in our user interfarce as
102
+ to refer to what CLDR refers to as a "territory", and what we describe in our user interface as
103
103
  a "country / region". Examples of such entities include Canada, the United States, and Russia,
104
104
  but also territories with a "dual" status such as Guernsey, Hong Kong, and Martinique.
105
105
 
@@ -14,6 +14,7 @@ zip_regex: "^(IT?-?)?\\d{5}$"
14
14
  zip_example: '00144'
15
15
  phone_number_prefix: 39
16
16
  building_number_required: true
17
+ building_number_may_be_in_address2: true
17
18
  week_start_day: monday
18
19
  languages:
19
20
  - it
@@ -19,6 +19,8 @@ module Worldwide
19
19
  :example_city,
20
20
  :flag,
21
21
  :format,
22
+ :group,
23
+ :group_name,
22
24
  :cldr_code,
23
25
  :iso_code,
24
26
  :languages,
@@ -32,7 +34,9 @@ module Worldwide
32
34
  :zip_requirement,
33
35
  ]
34
36
 
35
- attr_accessor :parent
37
+ # A region may have more than one parent.
38
+ # For example, Puerto Rico (PR/US-PR) is associated with both the US and the Caribbean (029)
39
+ attr_accessor :parents
36
40
 
37
41
  # ISO-3166 three-letter code for this region, if there is one.
38
42
  # Otherwise, nil.
@@ -43,6 +47,10 @@ module Worldwide
43
47
  # If we require a building number in an address, then this will be true.
44
48
  attr_accessor :building_number_required
45
49
 
50
+ # In some countries, an address may have the building number in address2.
51
+ # If we are allowed to have a building number in address2, then this will be true.
52
+ attr_accessor :building_number_may_be_in_address2
53
+
46
54
  # Alternate codes which may be used to designate this region
47
55
  attr_accessor :code_alternates
48
56
 
@@ -65,6 +73,14 @@ module Worldwide
65
73
  # - show: how to arrange the fields when formatting an address for display
66
74
  attr_accessor :format
67
75
 
76
+ # The string that results from appending " Countries" to the adjectival form of the {group_name}
77
+ # @example
78
+ # CountryDb.country(code: "CA").group == "North American Countries"
79
+ attr_accessor :group
80
+
81
+ # The continent that this region is part of.
82
+ attr_accessor :group_name
83
+
68
84
  # If this flag is set, then we support provinces "under the hood" for this country, but we do not
69
85
  # show them as part of a formatted address. If the province is missing, we will auto-infer it
70
86
  # based on the zip (note that this auto-inference may be wrong for some addresses near a border).
@@ -207,9 +223,12 @@ module Worldwide
207
223
  @use_zone_code_as_short_name = use_zone_code_as_short_name
208
224
 
209
225
  @building_number_required = false
226
+ @building_number_may_be_in_address2 = false
210
227
  @currency = nil
211
228
  @flag = nil
212
229
  @format = {}
230
+ @group = nil
231
+ @group_name = nil
213
232
  @languages = []
214
233
  @neighbours = []
215
234
  @partial_zip_regex = nil
@@ -224,7 +243,7 @@ module Worldwide
224
243
  @zip_prefixes = []
225
244
  @zip_regex = nil
226
245
 
227
- @parent = nil
246
+ @parents = [].to_set
228
247
  @zones = []
229
248
  end
230
249
 
@@ -237,12 +256,18 @@ module Worldwide
237
256
  def add_zone(region)
238
257
  return if @zones.include?(region)
239
258
 
240
- region.parent = self
259
+ region.parents << self
241
260
  @zones.append(region)
242
261
  end
243
262
 
244
263
  # Attributes
245
264
 
265
+ def associated_country
266
+ return self if country?
267
+
268
+ parent_country
269
+ end
270
+
246
271
  # The value with which to autofill the zip, if this region has zip autofill active;
247
272
  # otherwise, nil.
248
273
  def autofill_zip
@@ -289,7 +314,7 @@ module Worldwide
289
314
 
290
315
  # Does this region have postal codes?
291
316
  def has_zip?
292
- format["show"]&.include?("{zip}")
317
+ !!format["show"]&.include?("{zip}")
293
318
  end
294
319
 
295
320
  # Is this Region considered a "province" (political subdivision of a "country")?
@@ -321,7 +346,8 @@ module Worldwide
321
346
 
322
347
  zones.find do |region|
323
348
  [search_code, alt_search_code].any? do |candidate|
324
- candidate == region.alpha_three ||
349
+ candidate == subdivision_code(region.iso_code) ||
350
+ candidate == region.alpha_three ||
325
351
  candidate == region.iso_code ||
326
352
  candidate == region.legacy_code ||
327
353
  candidate == region.numeric_three ||
@@ -357,12 +383,12 @@ module Worldwide
357
383
  end
358
384
 
359
385
  # is the given postal code value valid for this region?
360
- def valid_zip?(zip)
386
+ def valid_zip?(zip, partial_match: false)
361
387
  normalized = Zip.normalize(
362
- country_code: province? ? parent.iso_code : iso_code,
388
+ country_code: province? && associated_country.iso_code ? associated_country.iso_code : iso_code,
363
389
  zip: zip,
364
390
  )
365
- valid_normalized_zip?(normalized)
391
+ valid_normalized_zip?(normalized, partial_match: partial_match)
366
392
  end
367
393
 
368
394
  # are zones optional for this region?
@@ -372,6 +398,21 @@ module Worldwide
372
398
 
373
399
  private
374
400
 
401
+ def answers_to_cldr_code(search_code)
402
+ return false if Util.blank?(search_code) || Util.blank?(cldr_code)
403
+ return true if search_code.casecmp(cldr_code).zero?
404
+
405
+ pc = parent_country
406
+ "#{pc&.cldr_code&.downcase}#{cldr_code.downcase}" == search_code.downcase
407
+ end
408
+
409
+ def answers_to_iso_code(search_code)
410
+ return true if search_code == iso_code
411
+
412
+ pc = parent_country
413
+ "#{pc&.iso_code}-#{iso_code}" == search_code
414
+ end
415
+
375
416
  def cross_border_zip_includes_province?(zip:, province_code:)
376
417
  return false unless country?
377
418
 
@@ -396,11 +437,17 @@ module Worldwide
396
437
  INSPECTION_FIELDS.map { |field_name| "@#{field_name}=#{send(field_name).inspect}" }.join(", ")
397
438
  end
398
439
 
440
+ def parent_country
441
+ parents.find(&:country?)
442
+ end
443
+
399
444
  # Checks whether the given value is acceptable according to the regular expression defined for the country.
400
445
  # @param value [String] for the postal code
401
446
  # @return [Boolean]
402
447
  def passes_country_zip_regexp?(value:, partial_match: false)
403
- return parent.send(:passes_country_zip_regexp?, value: value, partial_match: partial_match) if province?
448
+ if province?
449
+ return associated_country.send(:passes_country_zip_regexp?, value: value, partial_match: partial_match)
450
+ end
404
451
 
405
452
  return false if partial_match && partial_zip_regex.nil?
406
453
 
@@ -433,11 +480,18 @@ module Worldwide
433
480
  end&.first
434
481
  end
435
482
 
483
+ def subdivision_code(iso_code)
484
+ return iso_code if iso_code.nil? || iso_code.length < 3
485
+
486
+ country_code, subdivision_code = iso_code.split("-")
487
+ return subdivision_code if country_code.casecmp(associated_country.iso_code).zero?
488
+ end
489
+
436
490
  def valid_normalized_zip?(normalized, province_code: nil, partial_match: false)
437
491
  if country?
438
492
  country = self
439
493
  elsif province?
440
- country = parent
494
+ country = associated_country
441
495
  province_code ||= legacy_code
442
496
  end
443
497
 
@@ -32,13 +32,13 @@ module Worldwide
32
32
  search_code = cldr.to_s.upcase
33
33
 
34
34
  @regions.find do |r|
35
- r.cldr_code.upcase == search_code
35
+ r.send(:answers_to_cldr_code, search_code)
36
36
  end
37
37
  elsif code
38
38
  search_code = code.to_s.upcase
39
39
 
40
40
  @regions.find do |r|
41
- r.iso_code == search_code || r.alpha_three == search_code || r.numeric_three == search_code
41
+ r.send(:answers_to_iso_code, search_code) || r.alpha_three == search_code || r.numeric_three == search_code
42
42
  end
43
43
  else # search by name
44
44
  search_name = name.upcase
@@ -46,6 +46,7 @@ module Worldwide
46
46
  @regions << current_region
47
47
  end
48
48
 
49
+ current_region.parents << parent if Util.present?(parent)
49
50
  parent&.add_zone(current_region)
50
51
  return current_region if children.nil?
51
52
 
@@ -58,10 +59,13 @@ module Worldwide
58
59
 
59
60
  def apply_territory_attributes(region, spec)
60
61
  region.building_number_required = spec["building_number_required"] || true
62
+ region.building_number_may_be_in_address2 = spec["building_number_may_be_in_address2"] || false
61
63
  currency_code = spec["currency"]
62
64
  region.currency = Worldwide.currency(code: currency_code) unless currency_code.nil?
63
65
  region.flag = spec["emoji"]
64
66
  region.format = spec["format"]
67
+ region.group = spec["group"]
68
+ region.group_name = spec["group_name"]
65
69
  region.hide_provinces_from_addresses = spec["hide_provinces_from_addresses"] || false
66
70
  region.languages = spec["languages"]
67
71
  region.partial_zip_regex = spec["partial_zip_regex"]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Worldwide
4
- VERSION = "0.1.1"
4
+ VERSION = "0.3.0"
5
5
  end
data/worldwide.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.email = "developers@shopify.com"
12
12
 
13
13
  spec.summary = "Internationalization and localization APIs"
14
- spec.description = "APIs to support i18n and l10n of Ruby code"
14
+ spec.description = "APIs for I18n, I10n, and mailing address operations in Ruby."
15
15
  spec.homepage = "https://github.com/Shopify/worldwide"
16
16
 
17
17
  spec.metadata["allowed_push_host"] = "https://rubygems.org/"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: worldwide
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-27 00:00:00.000000000 Z
11
+ date: 2023-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -52,7 +52,7 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0.8'
55
- description: APIs to support i18n and l10n of Ruby code
55
+ description: APIs for I18n, I10n, and mailing address operations in Ruby.
56
56
  email: developers@shopify.com
57
57
  executables: []
58
58
  extensions: []