@mailwoman/codex 7.2.0 → 7.2.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.
Files changed (57) hide show
  1. package/address-system-conventions.ts +68 -0
  2. package/au/delivery-service.ts +179 -0
  3. package/au/index.ts +15 -0
  4. package/au/level-designator.ts +209 -0
  5. package/au/postcode.ts +51 -0
  6. package/au/state.ts +35 -0
  7. package/ca/index.ts +12 -0
  8. package/ca/postal-code.ts +121 -0
  9. package/ca/province.ts +99 -0
  10. package/ca/street-type.ts +167 -0
  11. package/country/codes.ts +534 -0
  12. package/country/country.ts +125 -0
  13. package/country/index.ts +14 -0
  14. package/country/names.ts +274 -0
  15. package/country/official-languages.ts +397 -0
  16. package/country/reference-data.ts +267 -0
  17. package/country/reference.ts +47 -0
  18. package/de/bundesland.ts +102 -0
  19. package/de/index.ts +12 -0
  20. package/de/postleitzahl.ts +91 -0
  21. package/de/street-type.ts +83 -0
  22. package/fr/cedex.ts +56 -0
  23. package/fr/code-postal.ts +105 -0
  24. package/fr/departement.ts +142 -0
  25. package/fr/index.ts +14 -0
  26. package/fr/region.ts +93 -0
  27. package/fr/voie.ts +98 -0
  28. package/gb/country.ts +74 -0
  29. package/gb/index.ts +14 -0
  30. package/gb/postcode-area.ts +107 -0
  31. package/gb/postcode.ts +109 -0
  32. package/gb/street-type.ts +90 -0
  33. package/index.ts +38 -0
  34. package/jp/address-unit.ts +87 -0
  35. package/jp/index.ts +13 -0
  36. package/jp/postal-code.ts +93 -0
  37. package/jp/prefecture.ts +173 -0
  38. package/level-semantics.ts +623 -0
  39. package/nz/delivery-service.ts +211 -0
  40. package/nz/index.ts +12 -0
  41. package/nz/postcode.ts +42 -0
  42. package/package.json +81 -37
  43. package/postcode-systems.ts +68 -0
  44. package/tools/build-country-surface-lexicon.ts +166 -0
  45. package/tools/export-country-surfaces.ts +46 -0
  46. package/tools/generate-country-reference.ts +153 -0
  47. package/tools/generate-official-languages.ts +188 -0
  48. package/tools/index.ts +12 -0
  49. package/us/floor-designator.ts +119 -0
  50. package/us/index.ts +19 -0
  51. package/us/military-address.ts +199 -0
  52. package/us/po-box.ts +82 -0
  53. package/us/state.ts +156 -0
  54. package/us/street-directional.ts +220 -0
  55. package/us/street-suffix.ts +345 -0
  56. package/us/unit-designator.ts +223 -0
  57. package/us/zipcode.ts +212 -0
@@ -0,0 +1,173 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * The 47 Japanese prefectures (都道府県, todōfuken), keyed by their ISO 3166-2:JP code — the two-digit
7
+ * numeric string `"01"`..`"47"` standing in for `JP-01`..`JP-47`.
8
+ *
9
+ * The contrast with `fr/region.ts`, `de/bundesland.ts`, and `us/state.ts` is in the name itself.
10
+ * "都道府県" is four kanji because the top-level admin unit comes in four legally distinct flavours,
11
+ * even though all 47 are peers in practice:
12
+ *
13
+ * - 都 (to, "metropolis") — exactly **1**: Tokyo (東京都). The capital's special form.
14
+ * - 道 (dō, "circuit") — exactly **1**: Hokkaido (北海道). A historical term; the name already ends in 道,
15
+ * so Hokkaido is written and indexed whole, never stripped to "北海".
16
+ * - 府 (fu, "urban prefecture") — exactly **2**: Osaka (大阪府) and Kyoto (京都府). The old imperial capital
17
+ * region.
18
+ * - 県 (ken, "prefecture") — the remaining **43**. The ordinary case.
19
+ *
20
+ * Unlike a French région or a German Bundesland, the prefecture DOES appear on a normal address
21
+ * line: a Japanese address is written largest-to-smallest (prefecture → city → ward → block), so
22
+ * the prefecture is the first thing written, not an inferred-from-postcode afterthought. See
23
+ * `postal-code.ts` for why the postcode is nonetheless the single most reliable anchor.
24
+ */
25
+
26
+ /** A to/dō/fu/ken classification of the top-level admin unit. */
27
+ export type JapanesePrefectureType = "to" | "do" | "fu" | "ken"
28
+
29
+ /** Per-prefecture record: ISO 3166-2:JP numeric code + kanji + romaji + to/dō/fu/ken type. */
30
+ export interface JapanesePrefectureInfo {
31
+ /** ISO 3166-2:JP code without the `JP-` prefix: a two-digit numeric string (`"13"` for `JP-13`). */
32
+ code: string
33
+ /** Kanji name, including its 都/道/府/県 suffix (e.g. `東京都`). */
34
+ kanji: string
35
+ /** Macron-free romaji name, suffix-less (e.g. `Tokyo`). */
36
+ romaji: string
37
+ /** Which of the four flavours of top-level unit this is. */
38
+ type: JapanesePrefectureType
39
+ }
40
+
41
+ /**
42
+ * ISO 3166-2:JP numeric code → info, for all 47 prefectures. Ordered by code, which is also the conventional
43
+ * north-to-south-ish ordering (Hokkaido `01` at the top, Okinawa `47` at the bottom).
44
+ */
45
+ export const JP_PREFECTURES = {
46
+ "01": { code: "01", kanji: "北海道", romaji: "Hokkaido", type: "do" },
47
+ "02": { code: "02", kanji: "青森県", romaji: "Aomori", type: "ken" },
48
+ "03": { code: "03", kanji: "岩手県", romaji: "Iwate", type: "ken" },
49
+ "04": { code: "04", kanji: "宮城県", romaji: "Miyagi", type: "ken" },
50
+ "05": { code: "05", kanji: "秋田県", romaji: "Akita", type: "ken" },
51
+ "06": { code: "06", kanji: "山形県", romaji: "Yamagata", type: "ken" },
52
+ "07": { code: "07", kanji: "福島県", romaji: "Fukushima", type: "ken" },
53
+ "08": { code: "08", kanji: "茨城県", romaji: "Ibaraki", type: "ken" },
54
+ "09": { code: "09", kanji: "栃木県", romaji: "Tochigi", type: "ken" },
55
+ "10": { code: "10", kanji: "群馬県", romaji: "Gunma", type: "ken" },
56
+ "11": { code: "11", kanji: "埼玉県", romaji: "Saitama", type: "ken" },
57
+ "12": { code: "12", kanji: "千葉県", romaji: "Chiba", type: "ken" },
58
+ "13": { code: "13", kanji: "東京都", romaji: "Tokyo", type: "to" },
59
+ "14": { code: "14", kanji: "神奈川県", romaji: "Kanagawa", type: "ken" },
60
+ "15": { code: "15", kanji: "新潟県", romaji: "Niigata", type: "ken" },
61
+ "16": { code: "16", kanji: "富山県", romaji: "Toyama", type: "ken" },
62
+ "17": { code: "17", kanji: "石川県", romaji: "Ishikawa", type: "ken" },
63
+ "18": { code: "18", kanji: "福井県", romaji: "Fukui", type: "ken" },
64
+ "19": { code: "19", kanji: "山梨県", romaji: "Yamanashi", type: "ken" },
65
+ "20": { code: "20", kanji: "長野県", romaji: "Nagano", type: "ken" },
66
+ "21": { code: "21", kanji: "岐阜県", romaji: "Gifu", type: "ken" },
67
+ "22": { code: "22", kanji: "静岡県", romaji: "Shizuoka", type: "ken" },
68
+ "23": { code: "23", kanji: "愛知県", romaji: "Aichi", type: "ken" },
69
+ "24": { code: "24", kanji: "三重県", romaji: "Mie", type: "ken" },
70
+ "25": { code: "25", kanji: "滋賀県", romaji: "Shiga", type: "ken" },
71
+ "26": { code: "26", kanji: "京都府", romaji: "Kyoto", type: "fu" },
72
+ "27": { code: "27", kanji: "大阪府", romaji: "Osaka", type: "fu" },
73
+ "28": { code: "28", kanji: "兵庫県", romaji: "Hyogo", type: "ken" },
74
+ "29": { code: "29", kanji: "奈良県", romaji: "Nara", type: "ken" },
75
+ "30": { code: "30", kanji: "和歌山県", romaji: "Wakayama", type: "ken" },
76
+ "31": { code: "31", kanji: "鳥取県", romaji: "Tottori", type: "ken" },
77
+ "32": { code: "32", kanji: "島根県", romaji: "Shimane", type: "ken" },
78
+ "33": { code: "33", kanji: "岡山県", romaji: "Okayama", type: "ken" },
79
+ "34": { code: "34", kanji: "広島県", romaji: "Hiroshima", type: "ken" },
80
+ "35": { code: "35", kanji: "山口県", romaji: "Yamaguchi", type: "ken" },
81
+ "36": { code: "36", kanji: "徳島県", romaji: "Tokushima", type: "ken" },
82
+ "37": { code: "37", kanji: "香川県", romaji: "Kagawa", type: "ken" },
83
+ "38": { code: "38", kanji: "愛媛県", romaji: "Ehime", type: "ken" },
84
+ "39": { code: "39", kanji: "高知県", romaji: "Kochi", type: "ken" },
85
+ "40": { code: "40", kanji: "福岡県", romaji: "Fukuoka", type: "ken" },
86
+ "41": { code: "41", kanji: "佐賀県", romaji: "Saga", type: "ken" },
87
+ "42": { code: "42", kanji: "長崎県", romaji: "Nagasaki", type: "ken" },
88
+ "43": { code: "43", kanji: "熊本県", romaji: "Kumamoto", type: "ken" },
89
+ "44": { code: "44", kanji: "大分県", romaji: "Oita", type: "ken" },
90
+ "45": { code: "45", kanji: "宮崎県", romaji: "Miyazaki", type: "ken" },
91
+ "46": { code: "46", kanji: "鹿児島県", romaji: "Kagoshima", type: "ken" },
92
+ "47": { code: "47", kanji: "沖縄県", romaji: "Okinawa", type: "ken" },
93
+ } as const satisfies Record<string, JapanesePrefectureInfo>
94
+
95
+ /** An ISO 3166-2:JP prefecture code (`"01"`..`"47"`). */
96
+ export type JapanesePrefectureCode = keyof typeof JP_PREFECTURES
97
+
98
+ const PREFECTURE_CODE_SET: ReadonlySet<string> = new Set(Object.keys(JP_PREFECTURES))
99
+
100
+ /** Type-predicate for an ISO 3166-2:JP prefecture code (`"01"`..`"47"`). */
101
+ export function isJapanesePrefectureCode(input: unknown): input is JapanesePrefectureCode {
102
+ return typeof input === "string" && PREFECTURE_CODE_SET.has(input)
103
+ }
104
+
105
+ /**
106
+ * Fold a romaji surface form so `Tōkyō`, `Tokyo`, and `Tokyo-to` all key alike: strip macrons (NFD
107
+ *
108
+ * - Drop the combining marks), lowercase, peel off an appended `-to`/`-do`/`-fu`/`-ken` type-suffix, then drop everything
109
+ * but `a-z`. `Tōkyō-to` and `tokyo` both → `tokyo`.
110
+ *
111
+ * The suffix is only stripped when it is a genuine appendage — separated by a hyphen/space/middle-dot (`Tokyo-to`,
112
+ * `Osaka fu`) or trailing the macron-bearing long-vowel form. That guard is essential: four bare romaji names already
113
+ * END in a suffix syllable (Kyo**to**, Gi**fu**, Hokkai**do**, Kumamo**to**), and a blind trailing-strip would maim
114
+ * them. We never strip from an unseparated bare name, so `kyoto` stays `kyoto`.
115
+ */
116
+ function foldRomaji(s: string): string {
117
+ const lowered = s
118
+ .toLowerCase()
119
+ .normalize("NFD")
120
+ .replace(/[\u0300-\u036f]/g, "")
121
+ // Strip an appended type-suffix only when a separator (hyphen / space / middle dot) precedes it.
122
+ const desuffixed = lowered.replace(/[-\s·][\s]*(to|do|fu|ken)$/, "")
123
+
124
+ return desuffixed.replace(/[^a-z]/g, "")
125
+ }
126
+
127
+ /**
128
+ * Strip the trailing 都/道/府/県 admin kanji from a prefecture name (`東京都` → `東京`). Hokkaido is the exception: `北海道` ends
129
+ * in 道 but is a single indivisible name, so it is left whole.
130
+ */
131
+ function stripKanjiSuffix(kanji: string): string {
132
+ if (kanji === "北海道") return kanji
133
+
134
+ return kanji.replace(/[都道府県]$/, "")
135
+ }
136
+
137
+ /**
138
+ * Folded romaji / kanji surface form → ISO 3166-2:JP code. Every prefecture contributes several keys: the macron-folded
139
+ * romaji (and the suffixed `name-ken` form folds to the same key), the full kanji (`東京都`), and the suffix-less kanji
140
+ * (`東京`). Hokkaido keeps its 道 in both kanji keys.
141
+ */
142
+ export const JP_PREFECTURE_NAME_TO_CODE: ReadonlyMap<string, JapanesePrefectureCode> = (() => {
143
+ const out = new Map<string, JapanesePrefectureCode>()
144
+
145
+ for (const code of Object.keys(JP_PREFECTURES) as JapanesePrefectureCode[]) {
146
+ const info = JP_PREFECTURES[code]
147
+ out.set(foldRomaji(info.romaji), code)
148
+ out.set(info.kanji, code)
149
+ out.set(stripKanjiSuffix(info.kanji), code)
150
+ }
151
+
152
+ return out
153
+ })()
154
+
155
+ /**
156
+ * Resolve a Japanese prefecture surface form to its ISO 3166-2:JP code, accepting:
157
+ *
158
+ * - A code directly (`"13"` → `"13"`),
159
+ * - A romaji name, case-insensitive, macrons optional, with OR without the romaji type-suffix (`Tōkyō` / `Tokyo` /
160
+ * `tokyo` / `Tokyo-to` → `"13"`),
161
+ * - A kanji name, with or without its 都/道/府/県 suffix (`東京都` / `東京` → `"13"`).
162
+ *
163
+ * Returns null for anything it cannot place.
164
+ */
165
+ export function lookupJapanesePrefecture(input: string | null | undefined): JapanesePrefectureCode | null {
166
+ if (!input || typeof input !== "string") return null
167
+ const trimmed = input.trim()
168
+
169
+ if (PREFECTURE_CODE_SET.has(trimmed)) return trimmed as JapanesePrefectureCode
170
+
171
+ // Try kanji first (exact, then suffix-less), then fall back to the macron-folded romaji.
172
+ return JP_PREFECTURE_NAME_TO_CODE.get(trimmed) ?? JP_PREFECTURE_NAME_TO_CODE.get(foldRomaji(trimmed)) ?? null
173
+ }