worldwide 1.27.0 → 1.28.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49d1675cfafac47dc58a9af5c3fc11bf4f3926b81acae2475136046642c762a2
4
- data.tar.gz: bacfd6668d53c592656ed70c1fddff894a748b4009e7a9934e55a58dd7a47408
3
+ metadata.gz: afc3540f3eaf751ee10b556f119aaee8388238ae648242af64cc87df2eb8faa4
4
+ data.tar.gz: bc26455e86b23aa4ce3446966fb61dd96ec4fa7b463d5df9903e8f5654a4ff3d
5
5
  SHA512:
6
- metadata.gz: 4715015cdf99318440751f709a90fea983674a52564f1fc2d8c6b9e67bbac388222c0664fba5ceaefe5dfe0ccce2fb0b315400357665b53b554a670a01de25cc
7
- data.tar.gz: b2921509899d3dd2f249d258315f5ea97c186b05a65eb92a57007fb75a61fe9be02a8340d96f3182a21baf5849e9555ab6a0ac50f24b839c5e90c0e88d92fb66
6
+ metadata.gz: dd96594b69a597d00ada229bc983892e9e117d248edbdd7f2c3bb3ea9a83265b7dedaa3f396744d247566dfdfaa418bf80c31e42647fcd6732ff25e28c446fe8
7
+ data.tar.gz: 717ad7d14a176b38563072f8dbff0fe8b182c3fc92926b660357d9cfd511051514891e820baf146feae5805359ea3d3f8663d0ab875f2a645194259a3531031f
@@ -0,0 +1,7 @@
1
+ # CODEOWNERS file for worldwide
2
+ # This file defines code owners for specific files/patterns in this repository
3
+
4
+ # Address team reviews all changes except Gemfile.lock and RBI files
5
+ * @Shopify/address
6
+ Gemfile.lock
7
+ sorbet/rbi/gems/**
data/CHANGELOG.md CHANGED
@@ -29,6 +29,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
29
29
 
30
30
  ---
31
31
 
32
+ ## [1.28.1] - 2026-09-23
33
+
34
+ - Accept `USDC` as the only supported non-ISO currency code, while malformed and other unknown codes stay out of the currency cache. [#607](https://github.com/Shopify/worldwide/pull/607)
35
+ - Apply CLDR fallbacks for hosts that read `I18n.fallbacks` from `Thread.current`, which stopped seeing them in 1.25.6. [#607](https://github.com/Shopify/worldwide/pull/607)
36
+
37
+ ---
38
+
39
+ ## [1.28.0] - 2026-09-21
40
+
41
+ - Add `Region#iso_3166_code_assigned?` to distinguish currently assigned ISO 3166-1 alpha-2 codes from other region codes. [#598](https://github.com/Shopify/worldwide/pull/598)
42
+ - Reject malformed currency codes before caching. [#596](https://github.com/Shopify/worldwide/pull/596)
43
+ - Add IE Eircode routing keys `N39` (Longford) and `N41` (Carrick-on-Shannon) to each other's `zips_crossing_provinces` entries, so both are valid for Longford and Leitrim. [#601](https://github.com/Shopify/worldwide/pull/601)
44
+ - Avoid retaining unknown locale codes in the global locale cache. [#597](https://github.com/Shopify/worldwide/pull/597)
45
+ - Avoid excessive backtracking in Dutch address fallback parsing. [#599](https://github.com/Shopify/worldwide/pull/599)
46
+
47
+ ---
48
+
32
49
  ## [1.27.0] - 2026-09-11
33
50
  - Add the 81 province (il) zones for Türkiye (`TR-01`..`TR-81`), staged behind `ignore_provinces` and `hide_provinces_from_addresses`. Each zone carries its plaka number as a `zip_prefix`, so a province can be inferred from the postal code. Address forms and validation are unchanged until the flags are removed.
34
51
 
data/Gemfile.lock CHANGED
@@ -13,7 +13,7 @@ GIT
13
13
  PATH
14
14
  remote: .
15
15
  specs:
16
- worldwide (1.27.0)
16
+ worldwide (1.28.1)
17
17
  activesupport (>= 7.0)
18
18
  i18n (>= 1.15)
19
19
  phonelib (~> 0.8)
data/README.md CHANGED
@@ -230,6 +230,7 @@ and also answer questions about its status:
230
230
  - `continent?`: is this region a continent?
231
231
  - `country?`: is this region a "country"? (Note that, for backward compatibility with legacy code in Shopify's ecosystem, we do not consider dependent territories of Spain and the United States to be countries, but we do consider dependencies of Australia, Britain, Denmark, Finland, France and Norway to be "countries")
232
232
  - `deprecated?`: has this territory ceased to exist? (e.g. `AN` which dissolved in 2010)
233
+ - `iso_3166_code_assigned?`: is this region's own code currently assigned in ISO 3166-1 alpha-2? Returns false for reserved, withdrawn, user-assigned, unknown, subdivision, and numeric region codes. This checks the resolved region's code, not the original lookup input.
233
234
 
234
235
  ```ruby
235
236
  $ ca = Worldwide.region(code: "CA")
@@ -0,0 +1,252 @@
1
+ ---
2
+ # Currently assigned ISO 3166-1 alpha-2 codes, checked on 2026-09-17.
3
+ # https://www.iso.org/iso-3166-country-codes.html
4
+ - AD
5
+ - AE
6
+ - AF
7
+ - AG
8
+ - AI
9
+ - AL
10
+ - AM
11
+ - AO
12
+ - AQ
13
+ - AR
14
+ - AS
15
+ - AT
16
+ - AU
17
+ - AW
18
+ - AX
19
+ - AZ
20
+ - BA
21
+ - BB
22
+ - BD
23
+ - BE
24
+ - BF
25
+ - BG
26
+ - BH
27
+ - BI
28
+ - BJ
29
+ - BL
30
+ - BM
31
+ - BN
32
+ - BO
33
+ - BQ
34
+ - BR
35
+ - BS
36
+ - BT
37
+ - BV
38
+ - BW
39
+ - BY
40
+ - BZ
41
+ - CA
42
+ - CC
43
+ - CD
44
+ - CF
45
+ - CG
46
+ - CH
47
+ - CI
48
+ - CK
49
+ - CL
50
+ - CM
51
+ - CN
52
+ - CO
53
+ - CR
54
+ - CU
55
+ - CV
56
+ - CW
57
+ - CX
58
+ - CY
59
+ - CZ
60
+ - DE
61
+ - DJ
62
+ - DK
63
+ - DM
64
+ - DO
65
+ - DZ
66
+ - EC
67
+ - EE
68
+ - EG
69
+ - EH
70
+ - ER
71
+ - ES
72
+ - ET
73
+ - FI
74
+ - FJ
75
+ - FK
76
+ - FM
77
+ - FO
78
+ - FR
79
+ - GA
80
+ - GB
81
+ - GD
82
+ - GE
83
+ - GF
84
+ - GG
85
+ - GH
86
+ - GI
87
+ - GL
88
+ - GM
89
+ - GN
90
+ - GP
91
+ - GQ
92
+ - GR
93
+ - GS
94
+ - GT
95
+ - GU
96
+ - GW
97
+ - GY
98
+ - HK
99
+ - HM
100
+ - HN
101
+ - HR
102
+ - HT
103
+ - HU
104
+ - ID
105
+ - IE
106
+ - IL
107
+ - IM
108
+ - IN
109
+ - IO
110
+ - IQ
111
+ - IR
112
+ - IS
113
+ - IT
114
+ - JE
115
+ - JM
116
+ - JO
117
+ - JP
118
+ - KE
119
+ - KG
120
+ - KH
121
+ - KI
122
+ - KM
123
+ - KN
124
+ - KP
125
+ - KR
126
+ - KW
127
+ - KY
128
+ - KZ
129
+ - LA
130
+ - LB
131
+ - LC
132
+ - LI
133
+ - LK
134
+ - LR
135
+ - LS
136
+ - LT
137
+ - LU
138
+ - LV
139
+ - LY
140
+ - MA
141
+ - MC
142
+ - MD
143
+ - ME
144
+ - MF
145
+ - MG
146
+ - MH
147
+ - MK
148
+ - ML
149
+ - MM
150
+ - MN
151
+ - MO
152
+ - MP
153
+ - MQ
154
+ - MR
155
+ - MS
156
+ - MT
157
+ - MU
158
+ - MV
159
+ - MW
160
+ - MX
161
+ - MY
162
+ - MZ
163
+ - NA
164
+ - NC
165
+ - NE
166
+ - NF
167
+ - NG
168
+ - NI
169
+ - NL
170
+ - 'NO'
171
+ - NP
172
+ - NR
173
+ - NU
174
+ - NZ
175
+ - OM
176
+ - PA
177
+ - PE
178
+ - PF
179
+ - PG
180
+ - PH
181
+ - PK
182
+ - PL
183
+ - PM
184
+ - PN
185
+ - PR
186
+ - PS
187
+ - PT
188
+ - PW
189
+ - PY
190
+ - QA
191
+ - RE
192
+ - RO
193
+ - RS
194
+ - RU
195
+ - RW
196
+ - SA
197
+ - SB
198
+ - SC
199
+ - SD
200
+ - SE
201
+ - SG
202
+ - SH
203
+ - SI
204
+ - SJ
205
+ - SK
206
+ - SL
207
+ - SM
208
+ - SN
209
+ - SO
210
+ - SR
211
+ - SS
212
+ - ST
213
+ - SV
214
+ - SX
215
+ - SY
216
+ - SZ
217
+ - TC
218
+ - TD
219
+ - TF
220
+ - TG
221
+ - TH
222
+ - TJ
223
+ - TK
224
+ - TL
225
+ - TM
226
+ - TN
227
+ - TO
228
+ - TR
229
+ - TT
230
+ - TV
231
+ - TW
232
+ - TZ
233
+ - UA
234
+ - UG
235
+ - UM
236
+ - US
237
+ - UY
238
+ - UZ
239
+ - VA
240
+ - VC
241
+ - VE
242
+ - VG
243
+ - VI
244
+ - VN
245
+ - VU
246
+ - WF
247
+ - WS
248
+ - YE
249
+ - YT
250
+ - ZA
251
+ - ZM
252
+ - ZW
data/data/regions/IE.yml CHANGED
@@ -643,10 +643,12 @@ zips_crossing_provinces:
643
643
  - LD
644
644
  - CN
645
645
  - RN
646
+ - LM
646
647
  N41:
647
648
  - LM
648
649
  - CN
649
650
  - RN
651
+ - LD
650
652
  P36:
651
653
  - CO
652
654
  - WD
data/data/regions/NL.yml CHANGED
@@ -33,7 +33,8 @@ format:
33
33
  format_extended:
34
34
  edit: "{country}_{firstName}{lastName}_{company}_{streetName}{streetNumber}_{address2}_{zip}{city}_{phone}"
35
35
  address1_regex:
36
- - "^(?<streetName>(?:\\d+[a-z]+\\s+)?[^\\d]+)\\s+(?<streetNumber>\\d+(?:-[A-Za-z0-9]+)?(?: ?[A-Za-z])?)$"
36
+ # streetName already consumes extra whitespace; repeated separators cause backtracking.
37
+ - "^(?<streetName>(?:\\d+[a-z]+\\s)?[^\\d]+)\\s(?<streetNumber>\\d+(?:-[A-Za-z0-9]+)?(?: ?[A-Za-z])?)$"
37
38
  additional_address_fields:
38
39
  - name: streetName
39
40
  required: true
@@ -82,15 +82,20 @@ module Worldwide
82
82
  # application's global fallbacks.
83
83
  original_config = STORAGE.config
84
84
  original_fallbacks = STORAGE.fallbacks
85
+ # Some hosts patch I18n.fallbacks to keep reading Thread.current, the slot
86
+ # used before i18n 1.15, so they must also see the CLDR fallbacks.
87
+ original_thread_fallbacks = Thread.current[:i18n_fallbacks]
85
88
  locale = I18n.locale
86
89
 
87
90
  STORAGE.config = config
88
91
  STORAGE.fallbacks = fallbacks
92
+ Thread.current[:i18n_fallbacks] = fallbacks
89
93
 
90
94
  I18n.with_locale(locale, &block)
91
95
  ensure
92
96
  STORAGE.config = original_config
93
97
  STORAGE.fallbacks = original_fallbacks
98
+ Thread.current[:i18n_fallbacks] = original_thread_fallbacks
94
99
  end
95
100
  end
96
101
  end
@@ -6,9 +6,11 @@ module Worldwide
6
6
  include PluralizationHelper
7
7
 
8
8
  EXCEPTIONS = { HKD: "HK$" }
9
+ # Extended codes must be explicit so the process cache remains bounded.
10
+ SUPPORTED_NON_ISO_CODES = ["USDC"].freeze
9
11
  SUPPORTED_ALTERNATE_FORMATS = [:japan]
10
12
  TEXT_ENCLOSED_BY_PARENTHESES = /\((.)+\)/
11
- private_constant :TEXT_ENCLOSED_BY_PARENTHESES
13
+ private_constant :SUPPORTED_NON_ISO_CODES, :TEXT_ENCLOSED_BY_PARENTHESES
12
14
 
13
15
  class << self
14
16
  def digits_and_rounding
@@ -28,10 +30,10 @@ module Worldwide
28
30
 
29
31
  def initialize(code:)
30
32
  adjusted_code = code.to_s.upcase.rjust(3, "0")
31
- if adjusted_code.match?(/[A-Z][A-Z][A-Z]/)
33
+ if adjusted_code.match?(/\A[A-Z]{3}\z/) || SUPPORTED_NON_ISO_CODES.include?(adjusted_code)
32
34
  @currency_code = adjusted_code
33
35
  @numeric_code = Currencies.numeric_code_for(adjusted_code)
34
- elsif adjusted_code.match?(/[0-9]+/)
36
+ elsif adjusted_code.match?(/\A[0-9]{3}\z/)
35
37
  @currency_code = Currencies.alpha_code_for(adjusted_code)
36
38
  @numeric_code = adjusted_code
37
39
  else
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "set"
4
+
3
5
  module Worldwide
4
6
  class Region
5
7
  # When faced with the question, "Is a postal code required in this country?", we treat the answer
@@ -9,6 +11,12 @@ module Worldwide
9
11
  RECOMMENDED = "recommended"
10
12
  OPTIONAL = "optional"
11
13
 
14
+ ISO_3166_ASSIGNED_COUNTRY_CODES = YAML.safe_load_file(
15
+ File.join(Worldwide::Paths::DATA_ROOT, "iso_3166_assigned_country_codes.yml"),
16
+ freeze: true,
17
+ ).to_set.freeze
18
+ private_constant :ISO_3166_ASSIGNED_COUNTRY_CODES
19
+
12
20
  # Accpetable format types of the postal code.
13
21
  FORMAT_TYPES = {
14
22
  ALPHANUMERIC: "ALPHANUMERIC",
@@ -372,6 +380,11 @@ module Worldwide
372
380
  @deprecated
373
381
  end
374
382
 
383
+ # Is this region's own code currently assigned in ISO 3166-1 alpha-2?
384
+ def iso_3166_code_assigned?
385
+ ISO_3166_ASSIGNED_COUNTRY_CODES.include?(iso_code)
386
+ end
387
+
375
388
  # An Worldwide::Field that can be used to ask about the field, including
376
389
  # labels, error messages, and an autofill value if there is one.
377
390
  def field(key:)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Worldwide
4
- VERSION = "1.27.0"
4
+ VERSION = "1.28.1"
5
5
  end
data/lib/worldwide.rb CHANGED
@@ -69,7 +69,11 @@ module Worldwide
69
69
  end
70
70
 
71
71
  def locale(code:)
72
- @locales_cache[code] ||= Locale.new(code)
72
+ @locales_cache.fetch(code) do
73
+ locale = Locale.new(code)
74
+ @locales_cache[code] = locale if locales.include?(locale.code)
75
+ locale
76
+ end
73
77
  end
74
78
 
75
79
  def locales
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: worldwide
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.27.0
4
+ version: 1.28.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
@@ -59,6 +59,7 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
+ - ".github/CODEOWNERS"
62
63
  - ".github/CODE_OF_CONDUCT.md"
63
64
  - ".github/CONTRIBUTING.md"
64
65
  - ".github/dependabot.yml"
@@ -4715,6 +4716,7 @@ files:
4715
4716
  - data/country_codes.yml
4716
4717
  - data/extant_outcodes.yml
4717
4718
  - data/iana_to_rails_time_zone.yml
4719
+ - data/iso_3166_assigned_country_codes.yml
4718
4720
  - data/other/currency/bg.yml
4719
4721
  - data/other/currency/cs.yml
4720
4722
  - data/other/currency/da.yml
@@ -8736,7 +8738,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
8736
8738
  - !ruby/object:Gem::Version
8737
8739
  version: '0'
8738
8740
  requirements: []
8739
- rubygems_version: 4.0.19
8741
+ rubygems_version: 4.0.21
8740
8742
  specification_version: 4
8741
8743
  summary: Internationalization and localization APIs
8742
8744
  test_files: []