@mailwoman/codex 4.0.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.
- package/out/ca/index.d.ts +12 -0
- package/out/ca/index.d.ts.map +1 -0
- package/out/ca/index.js +12 -0
- package/out/ca/index.js.map +1 -0
- package/out/ca/postal-code.d.ts +74 -0
- package/out/ca/postal-code.d.ts.map +1 -0
- package/out/ca/postal-code.js +100 -0
- package/out/ca/postal-code.js.map +1 -0
- package/out/ca/province.d.ts +114 -0
- package/out/ca/province.d.ts.map +1 -0
- package/out/ca/province.js +79 -0
- package/out/ca/province.js.map +1 -0
- package/out/ca/street-type.d.ts +57 -0
- package/out/ca/street-type.d.ts.map +1 -0
- package/out/ca/street-type.js +156 -0
- package/out/ca/street-type.js.map +1 -0
- package/out/de/bundesland.d.ts +124 -0
- package/out/de/bundesland.d.ts.map +1 -0
- package/out/de/bundesland.js +81 -0
- package/out/de/bundesland.js.map +1 -0
- package/out/de/index.d.ts +12 -0
- package/out/de/index.d.ts.map +1 -0
- package/out/de/index.js +12 -0
- package/out/de/index.js.map +1 -0
- package/out/de/postleitzahl.d.ts +108 -0
- package/out/de/postleitzahl.d.ts.map +1 -0
- package/out/de/postleitzahl.js +63 -0
- package/out/de/postleitzahl.js.map +1 -0
- package/out/de/street-type.d.ts +58 -0
- package/out/de/street-type.d.ts.map +1 -0
- package/out/de/street-type.js +79 -0
- package/out/de/street-type.js.map +1 -0
- package/out/fr/code-postal.d.ts +68 -0
- package/out/fr/code-postal.d.ts.map +1 -0
- package/out/fr/code-postal.js +84 -0
- package/out/fr/code-postal.js.map +1 -0
- package/out/fr/departement.d.ts +538 -0
- package/out/fr/departement.d.ts.map +1 -0
- package/out/fr/departement.js +127 -0
- package/out/fr/departement.js.map +1 -0
- package/out/fr/index.d.ts +13 -0
- package/out/fr/index.d.ts.map +1 -0
- package/out/fr/index.js +13 -0
- package/out/fr/index.js.map +1 -0
- package/out/fr/region.d.ts +113 -0
- package/out/fr/region.d.ts.map +1 -0
- package/out/fr/region.js +76 -0
- package/out/fr/region.js.map +1 -0
- package/out/fr/voie.d.ts +64 -0
- package/out/fr/voie.d.ts.map +1 -0
- package/out/fr/voie.js +88 -0
- package/out/fr/voie.js.map +1 -0
- package/out/gb/country.d.ts +51 -0
- package/out/gb/country.d.ts.map +1 -0
- package/out/gb/country.js +56 -0
- package/out/gb/country.js.map +1 -0
- package/out/gb/index.d.ts +14 -0
- package/out/gb/index.d.ts.map +1 -0
- package/out/gb/index.js +14 -0
- package/out/gb/index.js.map +1 -0
- package/out/gb/postcode-area.d.ts +46 -0
- package/out/gb/postcode-area.d.ts.map +1 -0
- package/out/gb/postcode-area.js +101 -0
- package/out/gb/postcode-area.js.map +1 -0
- package/out/gb/postcode.d.ts +73 -0
- package/out/gb/postcode.d.ts.map +1 -0
- package/out/gb/postcode.js +88 -0
- package/out/gb/postcode.js.map +1 -0
- package/out/gb/street-type.d.ts +36 -0
- package/out/gb/street-type.d.ts.map +1 -0
- package/out/gb/street-type.js +86 -0
- package/out/gb/street-type.js.map +1 -0
- package/out/index.d.ts +27 -0
- package/out/index.d.ts.map +1 -0
- package/out/index.js +27 -0
- package/out/index.js.map +1 -0
- package/out/jp/address-unit.d.ts +72 -0
- package/out/jp/address-unit.d.ts.map +1 -0
- package/out/jp/address-unit.js +78 -0
- package/out/jp/address-unit.js.map +1 -0
- package/out/jp/index.d.ts +13 -0
- package/out/jp/index.d.ts.map +1 -0
- package/out/jp/index.js +13 -0
- package/out/jp/index.js.map +1 -0
- package/out/jp/postal-code.d.ts +63 -0
- package/out/jp/postal-code.d.ts.map +1 -0
- package/out/jp/postal-code.js +77 -0
- package/out/jp/postal-code.js.map +1 -0
- package/out/jp/prefecture.d.ts +347 -0
- package/out/jp/prefecture.d.ts.map +1 -0
- package/out/jp/prefecture.js +147 -0
- package/out/jp/prefecture.js.map +1 -0
- package/out/postcode-systems.d.ts +31 -0
- package/out/postcode-systems.d.ts.map +1 -0
- package/out/postcode-systems.js +58 -0
- package/out/postcode-systems.js.map +1 -0
- package/out/us/index.d.ts +12 -0
- package/out/us/index.d.ts.map +1 -0
- package/out/us/index.js +12 -0
- package/out/us/index.js.map +1 -0
- package/out/us/state.d.ts +26 -0
- package/out/us/state.d.ts.map +1 -0
- package/out/us/state.js +84 -0
- package/out/us/state.js.map +1 -0
- package/out/us/street-suffix.d.ts +499 -0
- package/out/us/street-suffix.d.ts.map +1 -0
- package/out/us/street-suffix.js +313 -0
- package/out/us/street-suffix.js.map +1 -0
- package/out/us/zipcode.d.ts +184 -0
- package/out/us/zipcode.d.ts.map +1 -0
- package/out/us/zipcode.js +127 -0
- package/out/us/zipcode.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The 16 German federal states (Bundesländer), keyed by their ISO 3166-2:DE subdivision code.
|
|
7
|
+
*
|
|
8
|
+
* The US analog is `us/state.ts`. The informative difference: a US state's two-letter code (`CA`)
|
|
9
|
+
* is the USPS abbreviation people actually write in an address, whereas a German address almost
|
|
10
|
+
* never carries the Bundesland at all — it is `PLZ City`, and the state is inferred. So these
|
|
11
|
+
* codes matter for resolver region-matching and display, not for parsing the surface string.
|
|
12
|
+
*/
|
|
13
|
+
/** Per-state record: ISO 3166-2:DE code, native German name, and the common English exonym. */
|
|
14
|
+
export interface GermanStateInfo {
|
|
15
|
+
/** ISO 3166-2:DE subdivision code without the `DE-` prefix (e.g. `BY` for `DE-BY`). */
|
|
16
|
+
code: string;
|
|
17
|
+
/** Native German name (e.g. `Bayern`). */
|
|
18
|
+
name: string;
|
|
19
|
+
/** Common English name (e.g. `Bavaria`). */
|
|
20
|
+
english: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* ISO 3166-2:DE code → state info, for all 16 Bundesländer. Codes are the official subdivision
|
|
24
|
+
* codes minus the `DE-` prefix.
|
|
25
|
+
*/
|
|
26
|
+
export declare const DE_BUNDESLAENDER: {
|
|
27
|
+
readonly BW: {
|
|
28
|
+
readonly code: "BW";
|
|
29
|
+
readonly name: "Baden-Württemberg";
|
|
30
|
+
readonly english: "Baden-Württemberg";
|
|
31
|
+
};
|
|
32
|
+
readonly BY: {
|
|
33
|
+
readonly code: "BY";
|
|
34
|
+
readonly name: "Bayern";
|
|
35
|
+
readonly english: "Bavaria";
|
|
36
|
+
};
|
|
37
|
+
readonly BE: {
|
|
38
|
+
readonly code: "BE";
|
|
39
|
+
readonly name: "Berlin";
|
|
40
|
+
readonly english: "Berlin";
|
|
41
|
+
};
|
|
42
|
+
readonly BB: {
|
|
43
|
+
readonly code: "BB";
|
|
44
|
+
readonly name: "Brandenburg";
|
|
45
|
+
readonly english: "Brandenburg";
|
|
46
|
+
};
|
|
47
|
+
readonly HB: {
|
|
48
|
+
readonly code: "HB";
|
|
49
|
+
readonly name: "Bremen";
|
|
50
|
+
readonly english: "Bremen";
|
|
51
|
+
};
|
|
52
|
+
readonly HH: {
|
|
53
|
+
readonly code: "HH";
|
|
54
|
+
readonly name: "Hamburg";
|
|
55
|
+
readonly english: "Hamburg";
|
|
56
|
+
};
|
|
57
|
+
readonly HE: {
|
|
58
|
+
readonly code: "HE";
|
|
59
|
+
readonly name: "Hessen";
|
|
60
|
+
readonly english: "Hesse";
|
|
61
|
+
};
|
|
62
|
+
readonly MV: {
|
|
63
|
+
readonly code: "MV";
|
|
64
|
+
readonly name: "Mecklenburg-Vorpommern";
|
|
65
|
+
readonly english: "Mecklenburg-Western Pomerania";
|
|
66
|
+
};
|
|
67
|
+
readonly NI: {
|
|
68
|
+
readonly code: "NI";
|
|
69
|
+
readonly name: "Niedersachsen";
|
|
70
|
+
readonly english: "Lower Saxony";
|
|
71
|
+
};
|
|
72
|
+
readonly NW: {
|
|
73
|
+
readonly code: "NW";
|
|
74
|
+
readonly name: "Nordrhein-Westfalen";
|
|
75
|
+
readonly english: "North Rhine-Westphalia";
|
|
76
|
+
};
|
|
77
|
+
readonly RP: {
|
|
78
|
+
readonly code: "RP";
|
|
79
|
+
readonly name: "Rheinland-Pfalz";
|
|
80
|
+
readonly english: "Rhineland-Palatinate";
|
|
81
|
+
};
|
|
82
|
+
readonly SL: {
|
|
83
|
+
readonly code: "SL";
|
|
84
|
+
readonly name: "Saarland";
|
|
85
|
+
readonly english: "Saarland";
|
|
86
|
+
};
|
|
87
|
+
readonly SN: {
|
|
88
|
+
readonly code: "SN";
|
|
89
|
+
readonly name: "Sachsen";
|
|
90
|
+
readonly english: "Saxony";
|
|
91
|
+
};
|
|
92
|
+
readonly ST: {
|
|
93
|
+
readonly code: "ST";
|
|
94
|
+
readonly name: "Sachsen-Anhalt";
|
|
95
|
+
readonly english: "Saxony-Anhalt";
|
|
96
|
+
};
|
|
97
|
+
readonly SH: {
|
|
98
|
+
readonly code: "SH";
|
|
99
|
+
readonly name: "Schleswig-Holstein";
|
|
100
|
+
readonly english: "Schleswig-Holstein";
|
|
101
|
+
};
|
|
102
|
+
readonly TH: {
|
|
103
|
+
readonly code: "TH";
|
|
104
|
+
readonly name: "Thüringen";
|
|
105
|
+
readonly english: "Thuringia";
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
/** An ISO 3166-2:DE state code (`BW`, `BY`, `BE`, …). */
|
|
109
|
+
export type GermanStateCode = keyof typeof DE_BUNDESLAENDER;
|
|
110
|
+
/** Type-predicate for an ISO 3166-2:DE state code. Case-insensitive. */
|
|
111
|
+
export declare function isGermanStateCode(input: unknown): input is GermanStateCode;
|
|
112
|
+
/**
|
|
113
|
+
* Name (native German, English exonym, or common alias) → ISO 3166-2:DE code, lowercase-keyed.
|
|
114
|
+
* Includes the everyday aliases a parser actually meets: `NRW` for Nordrhein-Westfalen, `Bavaria`
|
|
115
|
+
* for Bayern, `Saxony` for Sachsen. The point is resolver region-matching: a German parse emits a
|
|
116
|
+
* region surface form, and the eval needs to map it to a code without a US-USPS-shaped matcher.
|
|
117
|
+
*/
|
|
118
|
+
export declare const DE_STATE_NAME_TO_CODE: ReadonlyMap<string, GermanStateCode>;
|
|
119
|
+
/**
|
|
120
|
+
* Resolve a German state surface form (code, German name, English name, or common alias) to its ISO
|
|
121
|
+
* 3166-2:DE code. Returns null when unrecognized.
|
|
122
|
+
*/
|
|
123
|
+
export declare function lookupGermanState(input: string | null | undefined): GermanStateCode | null;
|
|
124
|
+
//# sourceMappingURL=bundesland.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundesland.d.ts","sourceRoot":"","sources":["../../de/bundesland.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,+FAA+F;AAC/F,MAAM,WAAW,eAAe;IAC/B,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAA;IACZ,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBuB,CAAA;AAEpD,yDAAyD;AACzD,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,gBAAgB,CAAA;AAI3D,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAqBnE,CAAA;AAEJ;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,eAAe,GAAG,IAAI,CAK1F"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The 16 German federal states (Bundesländer), keyed by their ISO 3166-2:DE subdivision code.
|
|
7
|
+
*
|
|
8
|
+
* The US analog is `us/state.ts`. The informative difference: a US state's two-letter code (`CA`)
|
|
9
|
+
* is the USPS abbreviation people actually write in an address, whereas a German address almost
|
|
10
|
+
* never carries the Bundesland at all — it is `PLZ City`, and the state is inferred. So these
|
|
11
|
+
* codes matter for resolver region-matching and display, not for parsing the surface string.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* ISO 3166-2:DE code → state info, for all 16 Bundesländer. Codes are the official subdivision
|
|
15
|
+
* codes minus the `DE-` prefix.
|
|
16
|
+
*/
|
|
17
|
+
export const DE_BUNDESLAENDER = {
|
|
18
|
+
BW: { code: "BW", name: "Baden-Württemberg", english: "Baden-Württemberg" },
|
|
19
|
+
BY: { code: "BY", name: "Bayern", english: "Bavaria" },
|
|
20
|
+
BE: { code: "BE", name: "Berlin", english: "Berlin" },
|
|
21
|
+
BB: { code: "BB", name: "Brandenburg", english: "Brandenburg" },
|
|
22
|
+
HB: { code: "HB", name: "Bremen", english: "Bremen" },
|
|
23
|
+
HH: { code: "HH", name: "Hamburg", english: "Hamburg" },
|
|
24
|
+
HE: { code: "HE", name: "Hessen", english: "Hesse" },
|
|
25
|
+
MV: { code: "MV", name: "Mecklenburg-Vorpommern", english: "Mecklenburg-Western Pomerania" },
|
|
26
|
+
NI: { code: "NI", name: "Niedersachsen", english: "Lower Saxony" },
|
|
27
|
+
NW: { code: "NW", name: "Nordrhein-Westfalen", english: "North Rhine-Westphalia" },
|
|
28
|
+
RP: { code: "RP", name: "Rheinland-Pfalz", english: "Rhineland-Palatinate" },
|
|
29
|
+
SL: { code: "SL", name: "Saarland", english: "Saarland" },
|
|
30
|
+
SN: { code: "SN", name: "Sachsen", english: "Saxony" },
|
|
31
|
+
ST: { code: "ST", name: "Sachsen-Anhalt", english: "Saxony-Anhalt" },
|
|
32
|
+
SH: { code: "SH", name: "Schleswig-Holstein", english: "Schleswig-Holstein" },
|
|
33
|
+
TH: { code: "TH", name: "Thüringen", english: "Thuringia" },
|
|
34
|
+
};
|
|
35
|
+
const STATE_CODE_SET = new Set(Object.keys(DE_BUNDESLAENDER));
|
|
36
|
+
/** Type-predicate for an ISO 3166-2:DE state code. Case-insensitive. */
|
|
37
|
+
export function isGermanStateCode(input) {
|
|
38
|
+
return typeof input === "string" && STATE_CODE_SET.has(input.toUpperCase());
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Name (native German, English exonym, or common alias) → ISO 3166-2:DE code, lowercase-keyed.
|
|
42
|
+
* Includes the everyday aliases a parser actually meets: `NRW` for Nordrhein-Westfalen, `Bavaria`
|
|
43
|
+
* for Bayern, `Saxony` for Sachsen. The point is resolver region-matching: a German parse emits a
|
|
44
|
+
* region surface form, and the eval needs to map it to a code without a US-USPS-shaped matcher.
|
|
45
|
+
*/
|
|
46
|
+
export const DE_STATE_NAME_TO_CODE = (() => {
|
|
47
|
+
const out = new Map();
|
|
48
|
+
for (const code of Object.keys(DE_BUNDESLAENDER)) {
|
|
49
|
+
const info = DE_BUNDESLAENDER[code];
|
|
50
|
+
out.set(info.name.toLowerCase(), code);
|
|
51
|
+
out.set(info.english.toLowerCase(), code);
|
|
52
|
+
out.set(code.toLowerCase(), code);
|
|
53
|
+
}
|
|
54
|
+
// Everyday aliases that are neither the ISO code nor the canonical name.
|
|
55
|
+
const aliases = {
|
|
56
|
+
nrw: "NW",
|
|
57
|
+
"nordrhein westfalen": "NW",
|
|
58
|
+
"baden wurttemberg": "BW",
|
|
59
|
+
"baden-wuerttemberg": "BW",
|
|
60
|
+
"baden wuerttemberg": "BW",
|
|
61
|
+
thueringen: "TH",
|
|
62
|
+
"freie hansestadt bremen": "HB",
|
|
63
|
+
"freie und hansestadt hamburg": "HH",
|
|
64
|
+
};
|
|
65
|
+
for (const [alias, code] of Object.entries(aliases))
|
|
66
|
+
out.set(alias, code);
|
|
67
|
+
return out;
|
|
68
|
+
})();
|
|
69
|
+
/**
|
|
70
|
+
* Resolve a German state surface form (code, German name, English name, or common alias) to its ISO
|
|
71
|
+
* 3166-2:DE code. Returns null when unrecognized.
|
|
72
|
+
*/
|
|
73
|
+
export function lookupGermanState(input) {
|
|
74
|
+
if (!input || typeof input !== "string")
|
|
75
|
+
return null;
|
|
76
|
+
const key = input.trim().toLowerCase();
|
|
77
|
+
if (STATE_CODE_SET.has(key.toUpperCase()))
|
|
78
|
+
return key.toUpperCase();
|
|
79
|
+
return DE_STATE_NAME_TO_CODE.get(key) ?? null;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=bundesland.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundesland.js","sourceRoot":"","sources":["../../de/bundesland.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The German address system (Deutsche Post / ISO 3166-2:DE): street types, postal codes
|
|
7
|
+
* (Postleitzahl), and the federal states (Bundesländer).
|
|
8
|
+
*/
|
|
9
|
+
export * from "./bundesland.js";
|
|
10
|
+
export * from "./postleitzahl.js";
|
|
11
|
+
export * from "./street-type.js";
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../de/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA"}
|
package/out/de/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The German address system (Deutsche Post / ISO 3166-2:DE): street types, postal codes
|
|
7
|
+
* (Postleitzahl), and the federal states (Bundesländer).
|
|
8
|
+
*/
|
|
9
|
+
export * from "./bundesland.js";
|
|
10
|
+
export * from "./postleitzahl.js";
|
|
11
|
+
export * from "./street-type.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../de/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* German postal codes (Postleitzahl, PLZ): the branded type, the shape, normalization, and the
|
|
7
|
+
* first-digit → Leitzone geographic prior.
|
|
8
|
+
*
|
|
9
|
+
* The US analog is `us/zipcode.ts`, and the contrast is the informative part. A US ZIP's first
|
|
10
|
+
* digit maps cleanly to a band of states (`StateAbbreviationZipCodePrefixRecord`). A German PLZ's
|
|
11
|
+
* first digit maps to a **Leitzone** — a postal routing region that deliberately **crosses
|
|
12
|
+
* Bundesland borders** (Leitzone 6 covers Frankfurt in Hessen, Saarbrücken in Saarland, and Mainz
|
|
13
|
+
* in Rheinland-Pfalz). So the PLZ prior narrows geography, but it does NOT narrow the state the
|
|
14
|
+
* way a US ZIP does — a lesson for any code that tries to derive a German region from a postcode
|
|
15
|
+
* alone.
|
|
16
|
+
*/
|
|
17
|
+
import type { Tagged } from "type-fest";
|
|
18
|
+
/**
|
|
19
|
+
* A German postal code: five digits since the 1993 reform (`12623`). A bare 5-digit string, same
|
|
20
|
+
* shape as a US ZIP or a French code postal — disambiguation is the parser's job, not the shape's.
|
|
21
|
+
*
|
|
22
|
+
* @category Postal
|
|
23
|
+
* @type string
|
|
24
|
+
* @title Postleitzahl
|
|
25
|
+
* @pattern ^\d{5}$
|
|
26
|
+
*/
|
|
27
|
+
export type Postleitzahl = Tagged<string, "Postleitzahl">;
|
|
28
|
+
/** The PLZ shape: exactly five digits. */
|
|
29
|
+
export declare const PLZ_PATTERN: RegExp;
|
|
30
|
+
/**
|
|
31
|
+
* Normalize a PLZ surface form to the bare five digits: strip the `D-` / `DE-` country courtesy
|
|
32
|
+
* prefix and surrounding whitespace (`D-68161` → `68161`). Returns null if the result is not a
|
|
33
|
+
* PLZ.
|
|
34
|
+
*/
|
|
35
|
+
export declare function normalizePLZ(raw: unknown): Postleitzahl | null;
|
|
36
|
+
/** Type-predicate for a (normalized) German postal code. */
|
|
37
|
+
export declare function isPostleitzahl(input: unknown): input is Postleitzahl;
|
|
38
|
+
/** A PLZ Leitzone first digit. */
|
|
39
|
+
export type LeitzoneDigit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
40
|
+
/** Per-Leitzone descriptor: the routing region and a few anchor cities (coarse, postal not admin). */
|
|
41
|
+
export interface LeitzoneInfo {
|
|
42
|
+
digit: LeitzoneDigit;
|
|
43
|
+
/** Coarse routing-region label. */
|
|
44
|
+
region: string;
|
|
45
|
+
/** Well-known anchor cities in the zone (illustrative, not exhaustive). */
|
|
46
|
+
cities: readonly string[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* PLZ first digit → Leitzone. A coarse, postal-routing prior: these zones cross Bundesland borders,
|
|
50
|
+
* so the label is "which corner of Germany", not "which state". Anchor cities are the safe,
|
|
51
|
+
* well-known way to pin a zone without over-claiming a boundary the routing geography does not
|
|
52
|
+
* actually follow.
|
|
53
|
+
*/
|
|
54
|
+
export declare const PLZ_LEITZONEN: {
|
|
55
|
+
readonly 0: {
|
|
56
|
+
readonly digit: 0;
|
|
57
|
+
readonly region: "Sachsen / Ostthüringen";
|
|
58
|
+
readonly cities: readonly ["Leipzig", "Dresden", "Chemnitz"];
|
|
59
|
+
};
|
|
60
|
+
readonly 1: {
|
|
61
|
+
readonly digit: 1;
|
|
62
|
+
readonly region: "Berlin / Brandenburg / Mecklenburg-Vorpommern";
|
|
63
|
+
readonly cities: readonly ["Berlin", "Potsdam", "Rostock"];
|
|
64
|
+
};
|
|
65
|
+
readonly 2: {
|
|
66
|
+
readonly digit: 2;
|
|
67
|
+
readonly region: "Hamburg / Schleswig-Holstein / Bremen";
|
|
68
|
+
readonly cities: readonly ["Hamburg", "Kiel", "Bremen"];
|
|
69
|
+
};
|
|
70
|
+
readonly 3: {
|
|
71
|
+
readonly digit: 3;
|
|
72
|
+
readonly region: "Niedersachsen / Nordhessen";
|
|
73
|
+
readonly cities: readonly ["Hannover", "Braunschweig", "Kassel"];
|
|
74
|
+
};
|
|
75
|
+
readonly 4: {
|
|
76
|
+
readonly digit: 4;
|
|
77
|
+
readonly region: "nördliches Nordrhein-Westfalen";
|
|
78
|
+
readonly cities: readonly ["Düsseldorf", "Dortmund", "Münster"];
|
|
79
|
+
};
|
|
80
|
+
readonly 5: {
|
|
81
|
+
readonly digit: 5;
|
|
82
|
+
readonly region: "südliches NRW / nördliches Rheinland-Pfalz";
|
|
83
|
+
readonly cities: readonly ["Köln", "Bonn", "Aachen"];
|
|
84
|
+
};
|
|
85
|
+
readonly 6: {
|
|
86
|
+
readonly digit: 6;
|
|
87
|
+
readonly region: "Südhessen / Rheinland-Pfalz / Saarland";
|
|
88
|
+
readonly cities: readonly ["Frankfurt am Main", "Mainz", "Saarbrücken"];
|
|
89
|
+
};
|
|
90
|
+
readonly 7: {
|
|
91
|
+
readonly digit: 7;
|
|
92
|
+
readonly region: "Baden-Württemberg";
|
|
93
|
+
readonly cities: readonly ["Stuttgart", "Karlsruhe", "Freiburg"];
|
|
94
|
+
};
|
|
95
|
+
readonly 8: {
|
|
96
|
+
readonly digit: 8;
|
|
97
|
+
readonly region: "südliches Bayern";
|
|
98
|
+
readonly cities: readonly ["München", "Augsburg", "Ingolstadt"];
|
|
99
|
+
};
|
|
100
|
+
readonly 9: {
|
|
101
|
+
readonly digit: 9;
|
|
102
|
+
readonly region: "nördliches Bayern / Oberpfalz";
|
|
103
|
+
readonly cities: readonly ["Nürnberg", "Würzburg", "Regensburg"];
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
/** The Leitzone of a PLZ (its first digit's routing region), or null if the input is not a PLZ. */
|
|
107
|
+
export declare function leitzoneOf(plz: unknown): LeitzoneInfo | null;
|
|
108
|
+
//# sourceMappingURL=postleitzahl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postleitzahl.d.ts","sourceRoot":"","sources":["../../de/postleitzahl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAEvC;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;AAEzD,0CAA0C;AAC1C,eAAO,MAAM,WAAW,QAAY,CAAA;AAEpC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAI9D;AAED,4DAA4D;AAC5D,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED,kCAAkC;AAClC,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAEjE,sGAAsG;AACtG,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,aAAa,CAAA;IACpB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,2EAA2E;IAC3E,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CACzB;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAe8B,CAAA;AAExD,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAI5D"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* German postal codes (Postleitzahl, PLZ): the branded type, the shape, normalization, and the
|
|
7
|
+
* first-digit → Leitzone geographic prior.
|
|
8
|
+
*
|
|
9
|
+
* The US analog is `us/zipcode.ts`, and the contrast is the informative part. A US ZIP's first
|
|
10
|
+
* digit maps cleanly to a band of states (`StateAbbreviationZipCodePrefixRecord`). A German PLZ's
|
|
11
|
+
* first digit maps to a **Leitzone** — a postal routing region that deliberately **crosses
|
|
12
|
+
* Bundesland borders** (Leitzone 6 covers Frankfurt in Hessen, Saarbrücken in Saarland, and Mainz
|
|
13
|
+
* in Rheinland-Pfalz). So the PLZ prior narrows geography, but it does NOT narrow the state the
|
|
14
|
+
* way a US ZIP does — a lesson for any code that tries to derive a German region from a postcode
|
|
15
|
+
* alone.
|
|
16
|
+
*/
|
|
17
|
+
/** The PLZ shape: exactly five digits. */
|
|
18
|
+
export const PLZ_PATTERN = /^\d{5}$/;
|
|
19
|
+
/**
|
|
20
|
+
* Normalize a PLZ surface form to the bare five digits: strip the `D-` / `DE-` country courtesy
|
|
21
|
+
* prefix and surrounding whitespace (`D-68161` → `68161`). Returns null if the result is not a
|
|
22
|
+
* PLZ.
|
|
23
|
+
*/
|
|
24
|
+
export function normalizePLZ(raw) {
|
|
25
|
+
if (typeof raw !== "string")
|
|
26
|
+
return null;
|
|
27
|
+
const s = raw.trim().toUpperCase().replace(/^DE?-/, "");
|
|
28
|
+
return PLZ_PATTERN.test(s) ? s : null;
|
|
29
|
+
}
|
|
30
|
+
/** Type-predicate for a (normalized) German postal code. */
|
|
31
|
+
export function isPostleitzahl(input) {
|
|
32
|
+
return typeof input === "string" && PLZ_PATTERN.test(input);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* PLZ first digit → Leitzone. A coarse, postal-routing prior: these zones cross Bundesland borders,
|
|
36
|
+
* so the label is "which corner of Germany", not "which state". Anchor cities are the safe,
|
|
37
|
+
* well-known way to pin a zone without over-claiming a boundary the routing geography does not
|
|
38
|
+
* actually follow.
|
|
39
|
+
*/
|
|
40
|
+
export const PLZ_LEITZONEN = {
|
|
41
|
+
0: { digit: 0, region: "Sachsen / Ostthüringen", cities: ["Leipzig", "Dresden", "Chemnitz"] },
|
|
42
|
+
1: { digit: 1, region: "Berlin / Brandenburg / Mecklenburg-Vorpommern", cities: ["Berlin", "Potsdam", "Rostock"] },
|
|
43
|
+
2: { digit: 2, region: "Hamburg / Schleswig-Holstein / Bremen", cities: ["Hamburg", "Kiel", "Bremen"] },
|
|
44
|
+
3: { digit: 3, region: "Niedersachsen / Nordhessen", cities: ["Hannover", "Braunschweig", "Kassel"] },
|
|
45
|
+
4: { digit: 4, region: "nördliches Nordrhein-Westfalen", cities: ["Düsseldorf", "Dortmund", "Münster"] },
|
|
46
|
+
5: { digit: 5, region: "südliches NRW / nördliches Rheinland-Pfalz", cities: ["Köln", "Bonn", "Aachen"] },
|
|
47
|
+
6: {
|
|
48
|
+
digit: 6,
|
|
49
|
+
region: "Südhessen / Rheinland-Pfalz / Saarland",
|
|
50
|
+
cities: ["Frankfurt am Main", "Mainz", "Saarbrücken"],
|
|
51
|
+
},
|
|
52
|
+
7: { digit: 7, region: "Baden-Württemberg", cities: ["Stuttgart", "Karlsruhe", "Freiburg"] },
|
|
53
|
+
8: { digit: 8, region: "südliches Bayern", cities: ["München", "Augsburg", "Ingolstadt"] },
|
|
54
|
+
9: { digit: 9, region: "nördliches Bayern / Oberpfalz", cities: ["Nürnberg", "Würzburg", "Regensburg"] },
|
|
55
|
+
};
|
|
56
|
+
/** The Leitzone of a PLZ (its first digit's routing region), or null if the input is not a PLZ. */
|
|
57
|
+
export function leitzoneOf(plz) {
|
|
58
|
+
const normalized = normalizePLZ(plz);
|
|
59
|
+
if (!normalized)
|
|
60
|
+
return null;
|
|
61
|
+
return PLZ_LEITZONEN[Number(normalized[0])];
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=postleitzahl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postleitzahl.js","sourceRoot":"","sources":["../../de/postleitzahl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAeH,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAA;AAEpC;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACxC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IACxC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IACvD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAkB,CAAC,CAAC,CAAC,IAAI,CAAA;AACxD,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,cAAc,CAAC,KAAc;IAC5C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAC5D,CAAC;AAcD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC5B,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE;IAC7F,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,+CAA+C,EAAE,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE;IAClH,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,uCAAuC,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE;IACvG,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,4BAA4B,EAAE,MAAM,EAAE,CAAC,UAAU,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE;IACrG,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,gCAAgC,EAAE,MAAM,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE;IACxG,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,4CAA4C,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE;IACzG,CAAC,EAAE;QACF,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,wCAAwC;QAChD,MAAM,EAAE,CAAC,mBAAmB,EAAE,OAAO,EAAE,aAAa,CAAC;KACrD;IACD,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE;IAC5F,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE;IAC1F,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,+BAA+B,EAAE,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE;CACjD,CAAA;AAExD,mGAAmG;AACnG,MAAM,UAAU,UAAU,CAAC,GAAY;IACtC,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAA;IAC5B,OAAO,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAkB,CAAC,CAAA;AAC7D,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* German street types (Straßentypen).
|
|
7
|
+
*
|
|
8
|
+
* The US analog is `us/street-suffix.ts`, and the structural contrast is the whole lesson of this
|
|
9
|
+
* file. A US street type is a separate trailing word with a USPS-standardized abbreviation (`Main
|
|
10
|
+
* Street` → `ST`). A German street type is overwhelmingly an **agglutinative suffix** fused onto
|
|
11
|
+
* the name (`Straußstraße`, `Karl-Liebknecht-Straße`), with only one abbreviation in real use
|
|
12
|
+
* (`Str.`). So detection is by suffix, not by a trailing token, and there is no Pub-28-style
|
|
13
|
+
* abbreviation table to salvage.
|
|
14
|
+
*
|
|
15
|
+
* The second lesson is the collision, the German cousin of the US `KY` = Key / Kentucky problem.
|
|
16
|
+
* Many German PLACE names end in what look like street suffixes — `-berg` (Nürnberg), `-burg`
|
|
17
|
+
* (Hamburg), `-dorf` (Düsseldorf), `-feld`, `-hof`, `-stadt`. If those counted as street markers,
|
|
18
|
+
* the city token in a `PLZ City` segment would masquerade as a street and wrongly flag the
|
|
19
|
+
* postcode as a house number. {@link DE_STREET_SUFFIXES} is therefore a curated, place-name-SAFE
|
|
20
|
+
* set — the suffixes that are distinctively streets and (almost) never the tail of a city name.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Canonical German street type → recognized written variants (including the `Str.` abbreviation and
|
|
24
|
+
* the `ß`/`ss` spelling split). The full reference table, used for synthesis/expansion. For the "is
|
|
25
|
+
* this token part of a street" test, use {@link DE_STREET_SUFFIXES} / {@link isGermanStreetToken},
|
|
26
|
+
* which exclude the place-name-colliding suffixes.
|
|
27
|
+
*/
|
|
28
|
+
export declare const DE_STREET_TYPE_VARIANTS: {
|
|
29
|
+
readonly Straße: readonly ["Str.", "Str", "Strasse"];
|
|
30
|
+
readonly Weg: readonly [];
|
|
31
|
+
readonly Platz: readonly ["Pl.", "Pl"];
|
|
32
|
+
readonly Gasse: readonly [];
|
|
33
|
+
readonly Allee: readonly [];
|
|
34
|
+
readonly Ring: readonly [];
|
|
35
|
+
readonly Damm: readonly [];
|
|
36
|
+
readonly Ufer: readonly [];
|
|
37
|
+
readonly Steig: readonly [];
|
|
38
|
+
readonly Stieg: readonly [];
|
|
39
|
+
readonly Pfad: readonly [];
|
|
40
|
+
readonly Chaussee: readonly ["Chaussée"];
|
|
41
|
+
readonly Twiete: readonly [];
|
|
42
|
+
};
|
|
43
|
+
/** A canonical German street type (e.g. `Straße`, `Weg`, `Platz`). */
|
|
44
|
+
export type GermanStreetType = keyof typeof DE_STREET_TYPE_VARIANTS;
|
|
45
|
+
/**
|
|
46
|
+
* Place-name-SAFE street suffixes for "is this token part of a street" detection, lowercase, with
|
|
47
|
+
* the `ß`/`ss` split spelled out and `str` for the `Str.` abbreviation. Deliberately EXCLUDES the
|
|
48
|
+
* suffixes that also end German city names — `-berg`, `-burg`, `-dorf`, `-feld`, `-hof`, `-stadt`,
|
|
49
|
+
* `-heim`, `-bach`, `-tal` — so a city token in a `PLZ City` segment is not mistaken for a street.
|
|
50
|
+
*/
|
|
51
|
+
export declare const DE_STREET_SUFFIXES: readonly ["straße", "strasse", "str", "weg", "platz", "gasse", "allee", "ring", "damm", "ufer", "steig", "stieg", "pfad", "chaussee", "twiete"];
|
|
52
|
+
/**
|
|
53
|
+
* True when a token reads as (part of) a German street: it ends with one of the place-name-safe
|
|
54
|
+
* {@link DE_STREET_SUFFIXES}. Handles both the fused compound (`Straußstraße` → ends `straße`) and
|
|
55
|
+
* the standalone type word or `Str.` abbreviation (`Platz`, `Str` → end `platz` / `str`).
|
|
56
|
+
*/
|
|
57
|
+
export declare function isGermanStreetToken(token: unknown): boolean;
|
|
58
|
+
//# sourceMappingURL=street-type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"street-type.d.ts","sourceRoot":"","sources":["../../de/street-type.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;CAckB,CAAA;AAEtD,sEAAsE;AACtE,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,uBAAuB,CAAA;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,iJAgBrB,CAAA;AAEV;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAK3D"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* German street types (Straßentypen).
|
|
7
|
+
*
|
|
8
|
+
* The US analog is `us/street-suffix.ts`, and the structural contrast is the whole lesson of this
|
|
9
|
+
* file. A US street type is a separate trailing word with a USPS-standardized abbreviation (`Main
|
|
10
|
+
* Street` → `ST`). A German street type is overwhelmingly an **agglutinative suffix** fused onto
|
|
11
|
+
* the name (`Straußstraße`, `Karl-Liebknecht-Straße`), with only one abbreviation in real use
|
|
12
|
+
* (`Str.`). So detection is by suffix, not by a trailing token, and there is no Pub-28-style
|
|
13
|
+
* abbreviation table to salvage.
|
|
14
|
+
*
|
|
15
|
+
* The second lesson is the collision, the German cousin of the US `KY` = Key / Kentucky problem.
|
|
16
|
+
* Many German PLACE names end in what look like street suffixes — `-berg` (Nürnberg), `-burg`
|
|
17
|
+
* (Hamburg), `-dorf` (Düsseldorf), `-feld`, `-hof`, `-stadt`. If those counted as street markers,
|
|
18
|
+
* the city token in a `PLZ City` segment would masquerade as a street and wrongly flag the
|
|
19
|
+
* postcode as a house number. {@link DE_STREET_SUFFIXES} is therefore a curated, place-name-SAFE
|
|
20
|
+
* set — the suffixes that are distinctively streets and (almost) never the tail of a city name.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Canonical German street type → recognized written variants (including the `Str.` abbreviation and
|
|
24
|
+
* the `ß`/`ss` spelling split). The full reference table, used for synthesis/expansion. For the "is
|
|
25
|
+
* this token part of a street" test, use {@link DE_STREET_SUFFIXES} / {@link isGermanStreetToken},
|
|
26
|
+
* which exclude the place-name-colliding suffixes.
|
|
27
|
+
*/
|
|
28
|
+
export const DE_STREET_TYPE_VARIANTS = {
|
|
29
|
+
Straße: ["Str.", "Str", "Strasse"],
|
|
30
|
+
Weg: [],
|
|
31
|
+
Platz: ["Pl.", "Pl"],
|
|
32
|
+
Gasse: [],
|
|
33
|
+
Allee: [],
|
|
34
|
+
Ring: [],
|
|
35
|
+
Damm: [],
|
|
36
|
+
Ufer: [],
|
|
37
|
+
Steig: [],
|
|
38
|
+
Stieg: [],
|
|
39
|
+
Pfad: [],
|
|
40
|
+
Chaussee: ["Chaussée"],
|
|
41
|
+
Twiete: [],
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Place-name-SAFE street suffixes for "is this token part of a street" detection, lowercase, with
|
|
45
|
+
* the `ß`/`ss` split spelled out and `str` for the `Str.` abbreviation. Deliberately EXCLUDES the
|
|
46
|
+
* suffixes that also end German city names — `-berg`, `-burg`, `-dorf`, `-feld`, `-hof`, `-stadt`,
|
|
47
|
+
* `-heim`, `-bach`, `-tal` — so a city token in a `PLZ City` segment is not mistaken for a street.
|
|
48
|
+
*/
|
|
49
|
+
export const DE_STREET_SUFFIXES = [
|
|
50
|
+
"straße",
|
|
51
|
+
"strasse",
|
|
52
|
+
"str",
|
|
53
|
+
"weg",
|
|
54
|
+
"platz",
|
|
55
|
+
"gasse",
|
|
56
|
+
"allee",
|
|
57
|
+
"ring",
|
|
58
|
+
"damm",
|
|
59
|
+
"ufer",
|
|
60
|
+
"steig",
|
|
61
|
+
"stieg",
|
|
62
|
+
"pfad",
|
|
63
|
+
"chaussee",
|
|
64
|
+
"twiete",
|
|
65
|
+
];
|
|
66
|
+
/**
|
|
67
|
+
* True when a token reads as (part of) a German street: it ends with one of the place-name-safe
|
|
68
|
+
* {@link DE_STREET_SUFFIXES}. Handles both the fused compound (`Straußstraße` → ends `straße`) and
|
|
69
|
+
* the standalone type word or `Str.` abbreviation (`Platz`, `Str` → end `platz` / `str`).
|
|
70
|
+
*/
|
|
71
|
+
export function isGermanStreetToken(token) {
|
|
72
|
+
if (typeof token !== "string")
|
|
73
|
+
return false;
|
|
74
|
+
const t = token.toLowerCase().replace(/[^a-zà-ÿß]/g, "");
|
|
75
|
+
if (t.length < 3)
|
|
76
|
+
return false;
|
|
77
|
+
return DE_STREET_SUFFIXES.some((s) => t.endsWith(s));
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=street-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"street-type.js","sourceRoot":"","sources":["../../de/street-type.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACtC,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;IAClC,GAAG,EAAE,EAAE;IACP,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;IACpB,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE,CAAC,UAAU,CAAC;IACtB,MAAM,EAAE,EAAE;CAC2C,CAAA;AAKtD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IACjC,QAAQ;IACR,SAAS;IACT,KAAK;IACL,KAAK;IACL,OAAO;IACP,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,UAAU;IACV,QAAQ;CACC,CAAA;AAEV;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;IACxD,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAA;IAC9B,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* French postal codes (code postal): the branded type, the shape, normalization, and the
|
|
7
|
+
* first-two-digits → département mapping — the cleanest postcode→admin prior of the three
|
|
8
|
+
* systems.
|
|
9
|
+
*
|
|
10
|
+
* The informative contrast across `us/zipcode.ts`, `de/postleitzahl.ts`, and here:
|
|
11
|
+
*
|
|
12
|
+
* - A US ZIP's first digit maps to a loose BAND of states.
|
|
13
|
+
* - A German PLZ's first digit maps to a Leitzone that CROSSES Bundesland borders.
|
|
14
|
+
* - A French code postal's first TWO digits ARE the département number directly (`75008` → 75, Paris;
|
|
15
|
+
* `13001` → 13, Bouches-du-Rhône). So the French prefix pins the actual admin unit, and the
|
|
16
|
+
* région follows from the département. It is the tightest of the three.
|
|
17
|
+
*
|
|
18
|
+
* The exceptions are the interesting part: Corsica shares prefix `20` across two départements (`2A`
|
|
19
|
+
* Corse-du-Sud / `2B` Haute-Corse, resolved by the rest of the code), and the overseas DOM use a
|
|
20
|
+
* THREE-digit prefix (`971`–`976`). `departementOfCodePostal` handles both. Two further
|
|
21
|
+
* real-world caveats it does NOT try to model: a handful of communes sit under a neighbouring
|
|
22
|
+
* département's code (e.g. some `05`/`04` border villages), and a CEDEX code can carry a
|
|
23
|
+
* large-volume-mail prefix that differs from the geographic one — both rare enough to leave to
|
|
24
|
+
* the gazetteer.
|
|
25
|
+
*/
|
|
26
|
+
import type { Tagged } from "type-fest";
|
|
27
|
+
import { type DepartementCode, type DepartementInfo } from "./departement.js";
|
|
28
|
+
import { type FrenchRegionInfo } from "./region.js";
|
|
29
|
+
/**
|
|
30
|
+
* A French postal code: five digits (`75008`). Same shape as a US ZIP or a German PLZ — the shape
|
|
31
|
+
* alone does not disambiguate the country.
|
|
32
|
+
*
|
|
33
|
+
* @category Postal
|
|
34
|
+
* @type string
|
|
35
|
+
* @title Code postal
|
|
36
|
+
* @pattern ^\d{5}$
|
|
37
|
+
*/
|
|
38
|
+
export type CodePostal = Tagged<string, "CodePostal">;
|
|
39
|
+
/** The code-postal shape: exactly five digits. */
|
|
40
|
+
export declare const CODE_POSTAL_PATTERN: RegExp;
|
|
41
|
+
/**
|
|
42
|
+
* Normalize a code-postal surface form to the bare five digits: strip an `F-` country courtesy
|
|
43
|
+
* prefix and surrounding whitespace (`F-75008` → `75008`). Returns null if the result is not five
|
|
44
|
+
* digits.
|
|
45
|
+
*/
|
|
46
|
+
export declare function normalizeCodePostal(raw: unknown): CodePostal | null;
|
|
47
|
+
/** Type-predicate for a (normalized) French postal code. */
|
|
48
|
+
export declare function isCodePostal(input: unknown): input is CodePostal;
|
|
49
|
+
/**
|
|
50
|
+
* The département code a postal code belongs to. The clean rule plus its two exceptions:
|
|
51
|
+
*
|
|
52
|
+
* - `20xxx` → Corsica. The split is by the rest of the code: roughly `20000`–`20199` → `2A` (Ajaccio
|
|
53
|
+
* side), `20200`+ → `2B` (Bastia side). Approximate at the boundary, exact for the bulk.
|
|
54
|
+
* - `970`–`976`xx → an overseas DOM, keyed by the three-digit prefix (`971`–`974`, `976`).
|
|
55
|
+
* - Otherwise the first two digits are the département number.
|
|
56
|
+
*
|
|
57
|
+
* Returns null for a prefix with no département (e.g. `975`/`977`/`98x` collectivities, or a
|
|
58
|
+
* malformed code).
|
|
59
|
+
*/
|
|
60
|
+
export declare function departementOfCodePostal(codePostal: unknown): DepartementCode | null;
|
|
61
|
+
/** The full département record a postal code resolves to (name + région), or null. */
|
|
62
|
+
export declare function departementForCodePostal(codePostal: unknown): DepartementInfo | null;
|
|
63
|
+
/**
|
|
64
|
+
* The région a postal code resolves to, via its département; null if the code maps to no
|
|
65
|
+
* département.
|
|
66
|
+
*/
|
|
67
|
+
export declare function regionForCodePostal(codePostal: unknown): FrenchRegionInfo | null;
|
|
68
|
+
//# sourceMappingURL=code-postal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-postal.d.ts","sourceRoot":"","sources":["../../fr/code-postal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAmB,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC9F,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE/D;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;AAErD,kDAAkD;AAClD,eAAO,MAAM,mBAAmB,QAAY,CAAA;AAE5C;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAInE;AAED,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAenF;AAED,sFAAsF;AACtF,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAEpF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAGhF"}
|