worldwide 0.11.0 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c088cf8b57df5d8d9de377cee8b3b0e29517c5b997fe0bf70ee3b8970499f97d
4
- data.tar.gz: 90ae4641252f4a7f2a8262794782f7287fc176253cf62047f24a24e447580a56
3
+ metadata.gz: 1aced99de70bc88aa872fd56bf0aea847c81bcf3b12987e031ce39a51e9dbdd0
4
+ data.tar.gz: de70d75e3374938d1611ef3c0541ce7d880d4dbf5ad3b45fb4dddeeb6ef75382
5
5
  SHA512:
6
- metadata.gz: 0156d547c2c0fba8c5d7b89bde2cdc441a05e8dceb7285cf990e6b79cbd1d7d6564e52a8cc5ce873e247147ed7caeeaf2f28515f047146b5c200a041548edb0e
7
- data.tar.gz: '09cbfa47fd5e9b79dbb129cda279d2da44aa98f7bfc3800439830fbdfbb4d1bfb9cba420d25530679f24c7d91af47975a6e6bdc25633fddf3d8e4c7dfad077e5'
6
+ metadata.gz: e77fdb3041498e31ab8cec400ca4be14e531939e9f99fa800aae011d1a7be0e076fc6b4e65ea4ca877b98a051dc6e88994b71d27582cb083fb8c71ac0645e65f
7
+ data.tar.gz: bb7c2b6963ab30589320b70db8af56942ce454d01cbf6dc7f13c7da74c86964513de2711a31bd9fa07457e96fcb810f482d89e31a214acf5454f47ec21517dfc
data/CHANGELOG.md CHANGED
@@ -27,10 +27,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
27
27
 
28
28
  ## [Unreleased]
29
29
 
30
- - Nil.
31
-
32
30
  ---
33
31
 
32
+ ## [0.12.0] - 2024-05-15
33
+
34
+ - Add pry-byebug gem [#149](https://github.com/Shopify/worldwide/pull/149)
35
+ - Introduce additional_address_fields to Region class and define them for BE, BR, CL, CO, ES, ID, MX, NL, PH, TR, VN [#148](https://github.com/Shopify/worldwide/pull/148)
36
+ - Define format_extended attribute on 12 country regions [#150](https://github.com/Shopify/worldwide/pull/150)
37
+
38
+ ## [0.11.1] - 2024-05-13
39
+
40
+ - Handle blank strings for Region, country_code parameter in Zip normalization
41
+ [#138](https://github.com/Shopify/worldwide/pull/138)
42
+ - Reposition zip in NF show: format to come after country, not before city. [#142](https://github.com/Shopify/worldwide/pull/142)
43
+ - Allow building number on address2 for CH [#143](https://github.com/Shopify/worldwide/pull/143)
44
+ - Attempt to fix stringio incompatibility with Ruby 3.3 (deployment error) [#145](https://github.com/Shopify/worldwide/pull/145)
45
+
34
46
  ## [0.11.0] - 2024-04-11
35
47
 
36
48
  - Add country_prefix to phone [#133](https://github.com/Shopify/worldwide/pull/133)
data/Gemfile CHANGED
@@ -19,6 +19,7 @@ group :development do
19
19
  gem "rubocop-shopify", require: false
20
20
  gem "rubocop", require: false
21
21
  gem "ruby-lsp", require: false
22
+ gem "pry-byebug", require: false
22
23
  end
23
24
 
24
25
  group :test do
data/Gemfile.lock CHANGED
@@ -13,7 +13,7 @@ GIT
13
13
  PATH
14
14
  remote: .
15
15
  specs:
16
- worldwide (0.11.0)
16
+ worldwide (0.12.0)
17
17
  activesupport (~> 7.0)
18
18
  i18n
19
19
  phonelib (~> 0.8)
@@ -36,6 +36,8 @@ GEM
36
36
  base64 (0.1.1)
37
37
  bigdecimal (3.1.4)
38
38
  builder (3.2.4)
39
+ byebug (11.1.3)
40
+ coderay (1.1.3)
39
41
  concurrent-ruby (1.2.2)
40
42
  connection_pool (2.4.1)
41
43
  drb (2.1.1)
@@ -44,6 +46,7 @@ GEM
44
46
  concurrent-ruby (~> 1.0)
45
47
  json (2.7.1)
46
48
  language_server-protocol (3.17.0.3)
49
+ method_source (1.1.0)
47
50
  minitest (5.17.0)
48
51
  minitest-focus (1.3.1)
49
52
  minitest (>= 4, < 6)
@@ -55,9 +58,9 @@ GEM
55
58
  mocha (2.0.2)
56
59
  ruby2_keywords (>= 0.0.5)
57
60
  mutex_m (0.1.2)
58
- nokogiri (1.16.2-arm64-darwin)
61
+ nokogiri (1.16.5-arm64-darwin)
59
62
  racc (~> 1.4)
60
- nokogiri (1.16.2-x86_64-linux)
63
+ nokogiri (1.16.5-x86_64-linux)
61
64
  racc (~> 1.4)
62
65
  parallel (1.24.0)
63
66
  parser (3.3.0.5)
@@ -65,6 +68,12 @@ GEM
65
68
  racc
66
69
  phonelib (0.8.7)
67
70
  prettier_print (1.2.0)
71
+ pry (0.14.2)
72
+ coderay (~> 1.1)
73
+ method_source (~> 1.0)
74
+ pry-byebug (3.10.1)
75
+ byebug (~> 11.0)
76
+ pry (>= 0.13, < 0.15)
68
77
  psych (5.1.0)
69
78
  stringio
70
79
  racc (1.7.3)
@@ -104,7 +113,7 @@ GEM
104
113
  ruby2_keywords (0.0.5)
105
114
  rubyzip (2.3.2)
106
115
  sorbet-runtime (0.5.10648)
107
- stringio (3.0.6)
116
+ stringio (3.1.0)
108
117
  syntax_tree (5.3.0)
109
118
  prettier_print (>= 1.2.0)
110
119
  thor (1.2.1)
@@ -122,6 +131,7 @@ DEPENDENCIES
122
131
  minitest-focus
123
132
  minitest-reporters
124
133
  mocha
134
+ pry-byebug
125
135
  rake (~> 13.0)
126
136
  rake-compiler
127
137
  rubocop
data/README.md CHANGED
@@ -377,6 +377,8 @@ $ I18n.with_locale(:'zh-CN') { lon.single_line }
377
377
  => "英国London"
378
378
  ```
379
379
 
380
+ Address format strings are described in detail [here](docs/address_format_strings.md).
381
+
380
382
  #### Validation
381
383
 
382
384
  ```ruby
@@ -24,5 +24,13 @@ languages:
24
24
  format:
25
25
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{zip}{city}_{phone}"
26
26
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city}_{country}_{phone}"
27
+ format_extended:
28
+ edit: "{country}_{firstName}{lastName}_{company}_{streetName}{streetNumber}_{address2}_{zip}{city}_{phone}"
29
+ additional_address_fields:
30
+ address1:
31
+ - key: streetName
32
+ required: true
33
+ - key: streetNumber
34
+ required: false
27
35
  emoji: "\U0001F1E7\U0001F1EA"
28
36
  timezone: Europe/Brussels
@@ -19,6 +19,21 @@ languages:
19
19
  format:
20
20
  edit: "{country}_{firstName}{lastName}_{company}_{zip}_{address1}_{address2}_{city}{province}_{phone}"
21
21
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city} {province}_{country}_{phone}"
22
+ format_extended:
23
+ edit: "{country}_{firstName}{lastName}_{company}_{zip}_{streetName}{streetNumber}_{address2}{neighborhood}_{city}{province}_{phone}"
24
+ additional_address_fields:
25
+ address1:
26
+ - key: streetName
27
+ required: true
28
+ - key: streetNumber
29
+ decorator: ","
30
+ required: true
31
+ address2:
32
+ - key: address2
33
+ required: false
34
+ - key: neighborhood
35
+ decorator: ","
36
+ required: false
22
37
  emoji: "\U0001F1E7\U0001F1F7"
23
38
  localized_data:
24
39
  - name: tax_credential_br
@@ -14,6 +14,7 @@ zip_example: '2544'
14
14
  zip_regex: "^((CH( |-)?)?(([1-8]\\d{3})|(9[012356789]\\d{2})|(94[01234567]\\d)))$"
15
15
  phone_number_prefix: 41
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
  - de
@@ -0,0 +1,25 @@
1
+ ---
2
+ en:
3
+ worldwide:
4
+ CL:
5
+ addresses:
6
+ neighborhood:
7
+ label:
8
+ default: Commune
9
+ optional: Commune (optional)
10
+ errors:
11
+ blank: Enter a commune
12
+ too_long: Commune is too long (maximum is 255 characters)
13
+ contains_emojis: Commune cannot contain emojis
14
+ contains_mathematical_symbols: Commune cannot contain mathematical symbols
15
+ contains_restricted_characters: Commune can only contain letters, numbers,
16
+ local characters, and special characters
17
+ contains_too_many_words: Commune cannot have more than %{word_count}
18
+ words
19
+ contains_html_tags: Commune cannot contain HTML tags.
20
+ contains_url: Commune cannot contain URLs.
21
+ unknown_for_city: Enter a valid commune name for %{city}.
22
+ unknown_for_zip: Enter a valid commune name for %{zip}.
23
+ unknown_for_address: Commune may be incorrect.
24
+ warnings:
25
+ contains_too_many_words: Commune is recommended to have less than %{word_count} words
@@ -14,6 +14,19 @@ week_start_day: sunday
14
14
  format:
15
15
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{zip}{city}_{province}_{phone}"
16
16
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city}_{province}_{country}_{phone}"
17
+ format_extended:
18
+ edit: "{country}_{firstName}{lastName}_{company}_{streetName}{streetNumber}_{address2}{neighborhood}_{zip}{city}_{province}_{phone}"
19
+ additional_address_fields:
20
+ address1:
21
+ - key: streetName
22
+ required: true
23
+ - key: streetNumber
24
+ required: false
25
+ address2:
26
+ - key: address2
27
+ required: false
28
+ - key: neighborhood
29
+ required: false
17
30
  emoji: "\U0001F1E8\U0001F1F1"
18
31
  languages:
19
32
  - es
@@ -15,6 +15,14 @@ week_start_day: sunday
15
15
  format:
16
16
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{city}{province}{zip}_{phone}"
17
17
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city} {province}_{country}_{phone}"
18
+ format_extended:
19
+ edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}{neighborhood}_{city}{province}{zip}_{phone}"
20
+ additional_address_fields:
21
+ address2:
22
+ - key: address2
23
+ required: false
24
+ - key: neighborhood
25
+ required: false
18
26
  emoji: "\U0001F1E8\U0001F1F4"
19
27
  languages:
20
28
  - es
@@ -21,6 +21,14 @@ languages:
21
21
  format:
22
22
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{zip}{city}{province}_{phone}"
23
23
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city}_{province}_{country}_{phone}"
24
+ format_extended:
25
+ edit: "{country}_{firstName}{lastName}_{company}_{streetName}{streetNumber}_{address2}_{zip}{city}{province}_{phone}"
26
+ additional_address_fields:
27
+ address1:
28
+ - key: streetName
29
+ required: true
30
+ - key: streetNumber
31
+ required: false
24
32
  emoji: "\U0001F1EA\U0001F1F8"
25
33
  zones:
26
34
  - name: A Coruña
@@ -17,6 +17,15 @@ languages:
17
17
  format:
18
18
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{city}_{province}{zip}_{phone}"
19
19
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{city}_{province} {zip}_{country}_{phone}"
20
+ format_extended:
21
+ edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}{neighborhood}_{city}_{province}{zip}_{phone}"
22
+ additional_address_fields:
23
+ address2:
24
+ - key: address2
25
+ required: false
26
+ - key: neighborhood
27
+ decorator: ","
28
+ required: false
20
29
  emoji: "\U0001F1EE\U0001F1E9"
21
30
  zones:
22
31
  - name: Aceh
@@ -141,8 +141,8 @@ zones:
141
141
  zip_prefixes:
142
142
  - '49'
143
143
  # Dadra and Nagar Haveli was merged with Daman and Diu in 2020, and uses the new ISO code DH for the combined zone.
144
- # But, we need to upgrade our version of CLDR before shopify-i18n will recognize DH.
145
- # TODO: import new CLDR in shopify-i18n, merge DD and DN into new zone DH
144
+ # But, we need to upgrade our version of CLDR before worldwide will recognize DH.
145
+ # TODO: import new CLDR in worldwide, merge DD and DN into new zone DH
146
146
  - name: Dadra and Nagar Haveli
147
147
  code: DN
148
148
  tax: 0.18
@@ -15,6 +15,19 @@ week_start_day: sunday
15
15
  format:
16
16
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{zip}{city}{province}_{phone}"
17
17
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city} {province}_{country}_{phone}"
18
+ format_extended:
19
+ edit: "{country}_{firstName}{lastName}_{company}_{streetName}{streetNumber}_{address2}{neighborhood}_{zip}{city}{province}_{phone}"
20
+ additional_address_fields:
21
+ address1:
22
+ - key: streetName
23
+ required: true
24
+ - key: streetNumber
25
+ required: false
26
+ address2:
27
+ - key: address2
28
+ required: false
29
+ - key: neighborhood
30
+ required: true
18
31
  emoji: "\U0001F1F2\U0001F1FD"
19
32
  languages:
20
33
  - es
@@ -12,7 +12,7 @@ phone_number_prefix: 672
12
12
  zip_autofill_enabled: true
13
13
  format:
14
14
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{city}_{phone}"
15
- show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city}_{country}_{phone}"
15
+ show: "{firstName} {lastName}_{company}_{address1}_{address2}_{city}_{country} {zip}_{phone}"
16
16
  emoji: 🇳🇫
17
17
  languages:
18
18
  - en
@@ -23,5 +23,13 @@ languages:
23
23
  format:
24
24
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{zip}{city}_{phone}"
25
25
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city}_{country}_{phone}"
26
+ format_extended:
27
+ edit: "{country}_{firstName}{lastName}_{company}_{streetName}{streetNumber}_{address2}_{zip}{city}_{phone}"
28
+ additional_address_fields:
29
+ address1:
30
+ - key: streetName
31
+ required: true
32
+ - key: streetNumber
33
+ required: true
26
34
  emoji: "\U0001F1F3\U0001F1F1"
27
35
  timezone: Europe/Amsterdam
@@ -15,6 +15,15 @@ week_start_day: sunday
15
15
  format:
16
16
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{zip}{city}_{province}_{phone}"
17
17
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city}_{province}_{country}_{phone}"
18
+ format_extended:
19
+ edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}{neighborhood}_{zip}{city}_{province}_{phone}"
20
+ additional_address_fields:
21
+ address2:
22
+ - key: address2
23
+ required: false
24
+ - key: neighborhood
25
+ decorator: "Barangay"
26
+ required: true
18
27
  emoji: "\U0001F1F5\U0001F1ED"
19
28
  languages:
20
29
  - en
@@ -0,0 +1,25 @@
1
+ ---
2
+ en:
3
+ worldwide:
4
+ TR:
5
+ addresses:
6
+ neighborhood:
7
+ label:
8
+ default: District
9
+ optional: District (optional)
10
+ errors:
11
+ blank: Enter a district
12
+ too_long: District is too long (maximum is 255 characters)
13
+ contains_emojis: District cannot contain emojis
14
+ contains_mathematical_symbols: District cannot contain mathematical symbols
15
+ contains_restricted_characters: District can only contain letters, numbers,
16
+ local characters, and special characters
17
+ contains_too_many_words: District cannot have more than %{word_count}
18
+ words
19
+ contains_html_tags: District cannot contain HTML tags.
20
+ contains_url: District cannot contain URLs.
21
+ unknown_for_city: Enter a valid district name for %{city}.
22
+ unknown_for_zip: Enter a valid district name for %{zip}.
23
+ unknown_for_address: District may be incorrect.
24
+ warnings:
25
+ contains_too_many_words: District is recommended to have less than %{word_count} words
@@ -16,6 +16,14 @@ week_start_day: monday
16
16
  format:
17
17
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{zip}{city}_{phone}"
18
18
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city}_{country}_{phone}"
19
+ format_extended:
20
+ edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}{neighborhood}_{zip}{city}_{phone}"
21
+ additional_address_fields:
22
+ address2:
23
+ - key: address2
24
+ required: false
25
+ - key: neighborhood
26
+ required: false
19
27
  emoji: "\U0001F1F9\U0001F1F7"
20
28
  languages:
21
29
  - tr
@@ -0,0 +1,25 @@
1
+ ---
2
+ en:
3
+ worldwide:
4
+ TW:
5
+ addresses:
6
+ neighborhood:
7
+ label:
8
+ default: District
9
+ optional: District (optional)
10
+ errors:
11
+ blank: Enter a district
12
+ too_long: District is too long (maximum is 255 characters)
13
+ contains_emojis: District cannot contain emojis
14
+ contains_mathematical_symbols: District cannot contain mathematical symbols
15
+ contains_restricted_characters: District can only contain letters, numbers,
16
+ local characters, and special characters
17
+ contains_too_many_words: District cannot have more than %{word_count}
18
+ words
19
+ contains_html_tags: District cannot contain HTML tags.
20
+ contains_url: District cannot contain URLs.
21
+ unknown_for_city: Enter a valid district name for %{city}.
22
+ unknown_for_zip: Enter a valid district name for %{zip}.
23
+ unknown_for_address: District may be incorrect.
24
+ warnings:
25
+ contains_too_many_words: District is recommended to have less than %{word_count} words
@@ -17,6 +17,8 @@ week_start_day: sunday
17
17
  format:
18
18
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{city}{zip}_{phone}"
19
19
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{zip} {city}_{country}_{phone}"
20
+ format_extended:
21
+ edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{neighborhood}{city}{zip}_{phone}"
20
22
  emoji: "\U0001F1F9\U0001F1FC"
21
23
  languages:
22
24
  - "zh-TW"
@@ -0,0 +1,25 @@
1
+ ---
2
+ en:
3
+ worldwide:
4
+ VN:
5
+ addresses:
6
+ neighborhood:
7
+ label:
8
+ default: Ward
9
+ optional: Ward (optional)
10
+ errors:
11
+ blank: Enter a ward
12
+ too_long: Ward is too long (maximum is 255 characters)
13
+ contains_emojis: Ward cannot contain emojis
14
+ contains_mathematical_symbols: Ward cannot contain mathematical symbols
15
+ contains_restricted_characters: Ward can only contain letters, numbers,
16
+ local characters, and special characters
17
+ contains_too_many_words: Ward cannot have more than %{word_count}
18
+ words
19
+ contains_html_tags: Ward cannot contain HTML tags.
20
+ contains_url: Ward cannot contain URLs.
21
+ unknown_for_city: Enter a valid ward name for %{city}.
22
+ unknown_for_zip: Enter a valid ward name for %{zip}.
23
+ unknown_for_address: Ward may be incorrect.
24
+ warnings:
25
+ contains_too_many_words: Ward is recommended to have less than %{word_count} words
@@ -13,6 +13,15 @@ week_start_day: monday
13
13
  format:
14
14
  edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{city}{zip}_{phone}"
15
15
  show: "{firstName} {lastName}_{company}_{address1}_{address2}_{city} {zip}_{country}_{phone}"
16
+ format_extended:
17
+ edit: "{country}_{firstName}{lastName}_{company}_{address1}_{address2}_{neighborhood}_{city}{zip}_{phone}"
18
+ additional_address_fields:
19
+ address2:
20
+ - key: address2
21
+ required: false
22
+ - key: neighborhood
23
+ decorator: ", Quận"
24
+ required: false
16
25
  emoji: "\U0001F1FB\U0001F1F3"
17
26
  languages:
18
27
  - fr
@@ -63,6 +63,42 @@ en:
63
63
  unknown_for_address: Address line 1 may be incorrect.
64
64
  warnings:
65
65
  contains_too_many_words: Address line 1 is recommended to have less than %{word_count} words
66
+ street_name:
67
+ label:
68
+ default: Street
69
+ optional: Street (optional)
70
+ errors:
71
+ blank: Enter a street name
72
+ too_long: Street is too long (maximum is 255 characters)
73
+ contains_emojis: Street cannot contain emojis
74
+ contains_mathematical_symbols: Street cannot contain mathematical symbols
75
+ contains_restricted_characters: Street can only contain letters, numbers,
76
+ local characters, and special characters
77
+ contains_too_many_words: Street cannot have more than %{word_count} words
78
+ contains_html_tags: Street cannot contain HTML tags.
79
+ contains_url: Street cannot contain URLs.
80
+ street_unknown_for_zip: Enter a valid street name for %{zip}.
81
+ unknown_for_address: Street may be incorrect.
82
+ warnings:
83
+ contains_too_many_words: Street is recommended to have less than %{word_count} words
84
+ street_number:
85
+ label:
86
+ default: Building number
87
+ optional: Building number (optional)
88
+ errors:
89
+ blank: Enter a building number
90
+ too_long: Building number is too long (maximum is 255 characters)
91
+ contains_emojis: Building number cannot contain emojis
92
+ contains_mathematical_symbols: Building number cannot contain mathematical symbols
93
+ contains_restricted_characters: Building number can only contain letters,
94
+ numbers, local characters, and special characters
95
+ contains_html_tags: Building number cannot contain HTML tags.
96
+ contains_url: Building number cannot contain URLs.
97
+ building_number_invalid: Building number couldn't be located for %{street},
98
+ %{zip}.
99
+ unknown_for_address: Building number may be incorrect.
100
+ warnings:
101
+ contains_too_many_words: Building number is recommended to have less than %{word_count} words
66
102
  address2:
67
103
  label:
68
104
  default: Apartment, suite, etc.
@@ -83,9 +119,28 @@ en:
83
119
  building_number_invalid: Building number couldn't be located for %{street},
84
120
  %{zip}.
85
121
  unknown_for_address: Address line 2 may be incorrect.
86
-
87
122
  warnings:
88
123
  contains_too_many_words: Address line 2 is recommended to have less than %{word_count} words
124
+ neighborhood:
125
+ label:
126
+ default: Neighborhood
127
+ optional: Neighborhood (optional)
128
+ errors:
129
+ blank: Enter a neighborhood
130
+ too_long: Neighborhood is too long (maximum is 255 characters)
131
+ contains_emojis: Neighborhood cannot contain emojis
132
+ contains_mathematical_symbols: Neighborhood cannot contain mathematical symbols
133
+ contains_restricted_characters: Neighborhood can only contain letters, numbers,
134
+ local characters, and special characters
135
+ contains_too_many_words: Neighborhood cannot have more than %{word_count}
136
+ words
137
+ contains_html_tags: Neighborhood cannot contain HTML tags.
138
+ contains_url: Neighborhood cannot contain URLs.
139
+ unknown_for_city: Enter a valid neighborhood name for %{city}.
140
+ unknown_for_zip: Enter a valid neighborhood name for %{zip}.
141
+ unknown_for_address: Neighborhood may be incorrect.
142
+ warnings:
143
+ contains_too_many_words: Neighborhood is recommended to have less than %{word_count} words
89
144
  city:
90
145
  label:
91
146
  default: City
@@ -0,0 +1,111 @@
1
+ # Address format strings
2
+
3
+ ## Introduction <!-- omit in toc -->
4
+
5
+ Worldwide defines different address format strings that control the layout of address elements for each country region.
6
+
7
+ Each format string has a different syntax, and is meant for use in different scenarios.
8
+
9
+ This page aims to document these syntaxes, their usage and limitations for those who need to create/edit them.
10
+
11
+ **⚠️ Warning:** You shouldn't parse these format strings yourself, but instead make use of the higher-level libraries that already consume these strings. This document is meant for those creating the higher-level libraries, or for those who need to make changes to these format strings.
12
+
13
+ ## Table of Contents <!-- omit in toc -->
14
+
15
+ - [Address format strings](#address-format-strings)
16
+ - [`edit`](#edit)
17
+ - [English description](#english-description)
18
+ - [Grammar](#grammar)
19
+ - [`show`](#show)
20
+ - [English description](#english-description-1)
21
+ - [Grammar](#grammar-1)
22
+ - [Limitations](#limitations)
23
+ - [No escaping of special characters](#no-escaping-of-special-characters)
24
+ - [No space-less formats](#no-space-less-formats)
25
+ - [No free-standing prefix/suffix characters](#no-free-standing-prefixsuffix-characters)
26
+ - [No special concatenation characters](#no-special-concatenation-characters)
27
+
28
+ ## `edit`
29
+
30
+ The `edit` address format string controls the layout of elements within an address input form for a country region.
31
+
32
+ e.g., `{company}_{address1}_{address2}_{city}_{country}{province}{zip}_{phone}`
33
+
34
+ ![Example address input form formatted using the `edit` address format](images/edit.png)
35
+
36
+ **⚠️ Warning:** There's a lot more to creating an address form than just the layout of the fields (error messages, optionality, placeholders, etc.) You probably shouldn't parse `edit` yourself; use a pre-existing, higher-level library instead. This document is meant for those creating the higher-level libraries.
37
+
38
+ ### English description
39
+
40
+ 1. Fields are specified by wrapping the field name in curly braces: `{field_name}`
41
+ 2. Lines of fields are separated by an underscore `_`
42
+
43
+ ### Grammar
44
+
45
+ Below is the EBNF ([extended Backus-Naur form](https://en.wikipedia.org/wiki/Extended_Backus-Naur_form)) for `edit` address format strings:
46
+
47
+ ```
48
+ EditFormatString ::= Lines
49
+ Lines ::= Line (LineSeparator Lines)?
50
+ LineSeparator ::= '_'
51
+ Line ::= Field+
52
+ Field ::= '{' Identifier '}'
53
+ Identifier ::= [a-zA-Z0-9_]+
54
+ ```
55
+
56
+ ## `show`
57
+
58
+ The `show` address format string controls how addresses should be rendered as part of a UI.
59
+
60
+ e.g., `{firstName} {lastName}_{company}_{address1}_{address2}_{city} {province} {zip}_{country}_{phone}`
61
+
62
+ ![Example address formatted using the `show` address format](images/show.png)
63
+
64
+ ### English description
65
+
66
+ 1. Fields are specified by wrapping the field name in curly braces: `{field_name}`
67
+ 2. Lines of fields are separated by an underscore `_`
68
+ 3. Fields are separated by an space character
69
+ 4. Other characters are permitted as prefixes/suffixes of a field
70
+ * Note: the prefix of a field is separated from the suffix of a preceding field by the space character separating the fields
71
+
72
+ ### Grammar
73
+
74
+ Below is the EBNF ([extended Backus-Naur form](https://en.wikipedia.org/wiki/Extended_Backus-Naur_form)) for `show` address format strings:
75
+
76
+ ```
77
+ ShowFormatString ::= Lines
78
+ Lines ::= Line (LineSeparator Lines)?
79
+ LineSeparator ::= '_'
80
+ Line ::= PrefixedSuffixedField (FieldSeparator PrefixedSuffixedField)*
81
+ FieldSeparator ::= ' '
82
+ PrefixedSuffixedField ::= (Prefix? Field Suffix?)
83
+ Field ::= '{' Identifier '}'
84
+ Identifier ::= [a-zA-Z0-9_]+
85
+ Prefix ::= Text
86
+ Suffix ::= Text
87
+ Text ::= [^_{} ]+
88
+ ```
89
+
90
+ ### Limitations
91
+
92
+ There are a number of limitations to the `show` syntax that cannot cover the complexity of the world's address formatting.
93
+
94
+ #### No escaping of special characters
95
+
96
+ There is no support for escaping special characters: `{`, `}`, `_`, `<space>`
97
+
98
+ #### No space-less formats
99
+
100
+ Since the fields are space-separated, there is no way to specify a non-separator space character.
101
+ However, many languages (e.g., English) are space-delimited, so libraries using the `show` string end up concatenatiing the fields together using spaces, even if the language doesn't require spaces (e.g., Japanese).
102
+
103
+ #### No free-standing prefix/suffix characters
104
+
105
+ There is no way to specify prefix/suffix characters that will be included regardless of the provided values.
106
+ Any characters besides a field name are either prefixes or suffixes of a field, and therefore if a value for the field is not provided, the associated prefix/suffix characters are also not provided.
107
+
108
+ #### No special concatenation characters
109
+
110
+ There is no way to specify characters other than space characters for concatenating two fields.
111
+ For example, in Brazil, when the `city` and `province` fields are formatted adjacent to one another, instead of a space between the fields, ` - ` should be used. These concatenation characters are neither a prefix nor a suffix of either field, so cannot be specified in this format's syntax.
Binary file
Binary file
@@ -11,7 +11,10 @@ module Worldwide
11
11
  :last_name,
12
12
  :company,
13
13
  :address1,
14
+ :street_name,
15
+ :street_number,
14
16
  :address2,
17
+ :neighborhood,
15
18
  :city,
16
19
  :province,
17
20
  :zip,
@@ -19,6 +19,7 @@ module Worldwide
19
19
  :example_city,
20
20
  :flag,
21
21
  :format,
22
+ :format_extended,
22
23
  :group,
23
24
  :group_name,
24
25
  :cldr_code,
@@ -32,6 +33,7 @@ module Worldwide
32
33
  :zip_example,
33
34
  :zip_regex,
34
35
  :zip_requirement,
36
+ :additional_address_fields,
35
37
  ]
36
38
 
37
39
  # A region may have more than one parent.
@@ -73,9 +75,15 @@ module Worldwide
73
75
  # - show: how to arrange the fields when formatting an address for display
74
76
  attr_accessor :format
75
77
 
78
+ # Hash of strings denoting how to format an address in this region, including substitute and/or additional fields.
79
+ # The format is described in https://shopify.engineering/handling-addresses-from-all-around-the-world
80
+ # - edit: the fields to present on an address input form
81
+ # - show: how to arrange the fields when formatting an address for display
82
+ attr_accessor :format_extended
83
+
76
84
  # The string that results from appending " Countries" to the adjectival form of the {group_name}
77
85
  # @example
78
- # CountryDb.country(code: "CA").group == "North American Countries"
86
+ # Worldwide.region(code: "CA").group == "North American Countries"
79
87
  attr_accessor :group
80
88
 
81
89
  # The continent that this region is part of.
@@ -101,13 +109,11 @@ module Worldwide
101
109
  # The code used by the legacy Shopify ecosystem for this region.
102
110
  # E.g., for MX-CMX it will return "DF".
103
111
  # This code should _never_ be shown in the user interface.
104
- # This is the code that was traditionally returned by "country_db".
105
112
  attr_reader :legacy_code
106
113
 
107
114
  # The name used by the legacy Shopify ecosystem for this region.
108
115
  # E.g., "Sao Tome And[sic] Principe" for "ST".
109
116
  # This name should _never_ be shown in the user interface.
110
- # This name is the name that was traditionally returned by "country_db".
111
117
  attr_reader :legacy_name
112
118
 
113
119
  # Other names that may be used to refer to this region.
@@ -191,6 +197,9 @@ module Worldwide
191
197
  # If true, then the province is optional for addresses in this region.
192
198
  attr_accessor :province_optional
193
199
 
200
+ # A hash of additional address fields and the rules for concatening them into the standard fields
201
+ attr_accessor :additional_address_fields
202
+
194
203
  def initialize(
195
204
  alpha_three: nil,
196
205
  continent: false,
@@ -226,11 +235,13 @@ module Worldwide
226
235
  @tax_rate = tax_rate
227
236
  @use_zone_code_as_short_name = use_zone_code_as_short_name
228
237
 
238
+ @additional_address_fields = {}
229
239
  @building_number_required = false
230
240
  @building_number_may_be_in_address2 = false
231
241
  @currency = nil
232
242
  @flag = nil
233
243
  @format = {}
244
+ @format_extended = {}
234
245
  @group = nil
235
246
  @group_name = nil
236
247
  @languages = []
@@ -95,6 +95,7 @@ module Worldwide
95
95
  end
96
96
 
97
97
  def apply_territory_attributes(region, spec)
98
+ region.additional_address_fields = spec["additional_address_fields"] || {}
98
99
  region.building_number_required = spec["building_number_required"] || false
99
100
  region.building_number_may_be_in_address2 = spec["building_number_may_be_in_address2"] || false
100
101
  currency_code = spec["currency"]
@@ -102,6 +103,7 @@ module Worldwide
102
103
  region.currency = Worldwide.currency(code: currency_code) unless currency_code.nil?
103
104
  region.flag = spec["emoji"]
104
105
  region.format = spec["format"]
106
+ region.format_extended = spec["format_extended"] || {}
105
107
  region.group = spec["group"]
106
108
  region.group_name = spec["group_name"]
107
109
  region.hide_provinces_from_addresses = spec["hide_provinces_from_addresses"] || false
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Worldwide
4
- VERSION = "0.11.0"
4
+ VERSION = "0.12.0"
5
5
  end
data/lib/worldwide/zip.rb CHANGED
@@ -85,7 +85,7 @@ module Worldwide
85
85
  def normalize(country_code:, zip:, allow_autofill: true, strip_extraneous_characters: false)
86
86
  input = zip # preserve the original zip, in case we need to fall back to it
87
87
 
88
- return input if country_code.nil?
88
+ return input if Util.blank?(country_code)
89
89
 
90
90
  country = Worldwide.region(code: country_code)
91
91
  return zip if country.nil? || NORMALIZATION_DISABLED_COUNTRIES.include?(country.iso_code)
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.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-11 00:00:00.000000000 Z
11
+ date: 2024-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -6552,6 +6552,7 @@ files:
6552
6552
  - db/data/regions/CI.yml
6553
6553
  - db/data/regions/CK.yml
6554
6554
  - db/data/regions/CL.yml
6555
+ - db/data/regions/CL/en.yml
6555
6556
  - db/data/regions/CM.yml
6556
6557
  - db/data/regions/CN.yml
6557
6558
  - db/data/regions/CN/bg-BG.yml
@@ -7947,9 +7948,11 @@ files:
7947
7948
  - db/data/regions/TN.yml
7948
7949
  - db/data/regions/TO.yml
7949
7950
  - db/data/regions/TR.yml
7951
+ - db/data/regions/TR/en.yml
7950
7952
  - db/data/regions/TT.yml
7951
7953
  - db/data/regions/TV.yml
7952
7954
  - db/data/regions/TW.yml
7955
+ - db/data/regions/TW/en.yml
7953
7956
  - db/data/regions/TZ.yml
7954
7957
  - db/data/regions/UA.yml
7955
7958
  - db/data/regions/UG.yml
@@ -8061,6 +8064,7 @@ files:
8061
8064
  - db/data/regions/VE.yml
8062
8065
  - db/data/regions/VG.yml
8063
8066
  - db/data/regions/VN.yml
8067
+ - db/data/regions/VN/en.yml
8064
8068
  - db/data/regions/VU.yml
8065
8069
  - db/data/regions/WF.yml
8066
8070
  - db/data/regions/WS.yml
@@ -8171,6 +8175,9 @@ files:
8171
8175
  - db/data/regions/_default/zh-TW.yml
8172
8176
  - db/data/world.yml
8173
8177
  - db/extant_outcodes.yml
8178
+ - docs/address_format_strings.md
8179
+ - docs/images/edit.png
8180
+ - docs/images/show.png
8174
8181
  - formats.md
8175
8182
  - lib/worldwide.rb
8176
8183
  - lib/worldwide/address.rb
@@ -8233,7 +8240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
8233
8240
  - !ruby/object:Gem::Version
8234
8241
  version: '0'
8235
8242
  requirements: []
8236
- rubygems_version: 3.5.7
8243
+ rubygems_version: 3.5.10
8237
8244
  signing_key:
8238
8245
  specification_version: 4
8239
8246
  summary: Internationalization and localization APIs