worldwide 0.11.0 → 0.12.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: 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