@0xd33p/vietnam-divisions 0.2.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/README.md +80 -0
- package/dist/__tests__/vn.test.d.ts +2 -0
- package/dist/__tests__/vn.test.d.ts.map +1 -0
- package/dist/__tests__/vn.test.js +1107 -0
- package/dist/__tests__/vn.test.js.map +1 -0
- package/dist/data/legacy/commune.json +11077 -0
- package/dist/data/legacy/district.json +730 -0
- package/dist/data/legacy/province.json +65 -0
- package/dist/data/v3/commune.json +16607 -0
- package/dist/data/v3/province.json +240 -0
- package/dist/data/v3/province_merges.json +256 -0
- package/dist/data/v3/ward_mappings.json +98795 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +332 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/address.d.ts +37 -0
- package/dist/internal/address.d.ts.map +1 -0
- package/dist/internal/address.js +164 -0
- package/dist/internal/address.js.map +1 -0
- package/dist/internal/helpers.d.ts +24 -0
- package/dist/internal/helpers.d.ts.map +1 -0
- package/dist/internal/helpers.js +55 -0
- package/dist/internal/helpers.js.map +1 -0
- package/dist/internal/legacy/index.d.ts +21 -0
- package/dist/internal/legacy/index.d.ts.map +1 -0
- package/dist/internal/legacy/index.js +60 -0
- package/dist/internal/legacy/index.js.map +1 -0
- package/dist/internal/legacy/types.d.ts +18 -0
- package/dist/internal/legacy/types.d.ts.map +1 -0
- package/dist/internal/legacy/types.js +2 -0
- package/dist/internal/legacy/types.js.map +1 -0
- package/dist/internal/v3/index.d.ts +21 -0
- package/dist/internal/v3/index.d.ts.map +1 -0
- package/dist/internal/v3/index.js +55 -0
- package/dist/internal/v3/index.js.map +1 -0
- package/dist/internal/v3/types.d.ts +33 -0
- package/dist/internal/v3/types.d.ts.map +1 -0
- package/dist/internal/v3/types.js +2 -0
- package/dist/internal/v3/types.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +32 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { GeoUnit, GeoResult, GeoErrorResult, AddressLookupResult } from './types.js';
|
|
2
|
+
export type { GeoUnit, GeoError, GeoResult, AddressLookupResult, } from './types.js';
|
|
3
|
+
export declare const vn: {
|
|
4
|
+
/**
|
|
5
|
+
* Get administrative divisions.
|
|
6
|
+
* - No arguments → 34 provinces (v3 system)
|
|
7
|
+
* - With parentId → communes/wards under that province (v3 system)
|
|
8
|
+
*/
|
|
9
|
+
divisions(parentId?: string): GeoResult<GeoUnit[]> | GeoErrorResult;
|
|
10
|
+
/**
|
|
11
|
+
* Look up a single unit by ID, code, or name.
|
|
12
|
+
* Auto-detects: province ID (2-char like "79"), commune ID (5-char like "00004"),
|
|
13
|
+
* province code ("HCM", "HNI"), or full name.
|
|
14
|
+
* Auto-resolves: old province IDs via merge/mapping data.
|
|
15
|
+
*/
|
|
16
|
+
lookup(query: string): GeoResult<GeoUnit & {
|
|
17
|
+
kind: "province" | "ward";
|
|
18
|
+
}> | GeoErrorResult;
|
|
19
|
+
/**
|
|
20
|
+
* Search divisions by name (case-insensitive, partial match).
|
|
21
|
+
* - Without parentId → search in provinces
|
|
22
|
+
* - With parentId → search in communes of that province
|
|
23
|
+
*/
|
|
24
|
+
search(name: string, parentId?: string): GeoResult<GeoUnit[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Look up a full address string in both legacy and v3 systems.
|
|
27
|
+
*
|
|
28
|
+
* Parses a comma-separated address (e.g. "Xã Đông Hòa, TP Thái Bình, Thái Bình"
|
|
29
|
+
* or "Dong Hoa, Thai Binh"), resolves province/district/commune in the legacy
|
|
30
|
+
* system (63 tỉnh), then cross-references to the v3 system (34 tỉnh).
|
|
31
|
+
*
|
|
32
|
+
* **Strict mode (Option B):** Must find exactly one province — fails with
|
|
33
|
+
* `address_missing_province` or `address_ambiguous_province` otherwise.
|
|
34
|
+
*/
|
|
35
|
+
addressLookup(raw: string): GeoResult<AddressLookupResult> | GeoErrorResult;
|
|
36
|
+
/**
|
|
37
|
+
* Legacy system (63 provinces, 3 levels: province → district → commune).
|
|
38
|
+
* Explicit opt-in for backward compatibility.
|
|
39
|
+
*/
|
|
40
|
+
legacy: {
|
|
41
|
+
/**
|
|
42
|
+
* Get legacy divisions.
|
|
43
|
+
* - No arguments → 63 provinces
|
|
44
|
+
* - With parentId → districts under that province
|
|
45
|
+
*/
|
|
46
|
+
divisions(parentId?: string): GeoResult<GeoUnit[]> | GeoErrorResult;
|
|
47
|
+
/**
|
|
48
|
+
* Look up a legacy unit by ID.
|
|
49
|
+
* Auto-detects: province ID (2-char), district ID (3-char), commune ID (5-char).
|
|
50
|
+
*/
|
|
51
|
+
lookup(query: string): GeoResult<GeoUnit & {
|
|
52
|
+
kind: "province" | "district" | "ward";
|
|
53
|
+
}> | GeoErrorResult;
|
|
54
|
+
/**
|
|
55
|
+
* Search legacy divisions by name.
|
|
56
|
+
* - Without parentId → search in provinces
|
|
57
|
+
* - With parentId → search in districts of that province
|
|
58
|
+
*/
|
|
59
|
+
search(name: string, parentId?: string): GeoResult<GeoUnit[]>;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,OAAO,EACP,QAAQ,EACR,SAAS,EACT,mBAAmB,GACpB,MAAM,YAAY,CAAC;AA8CpB,eAAO,MAAM,EAAE;IACb;;;;OAIG;yBACkB,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,cAAc;IAYnE;;;;;OAKG;kBAEM,MAAM,GACZ,SAAS,CAAC,OAAO,GAAG;QAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAAA;KAAE,CAAC,GAAG,cAAc;IA4DtE;;;;OAIG;iBACU,MAAM,aAAa,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;IAU7D;;;;;;;;;OASG;uBAEI,MAAM,GACV,SAAS,CAAC,mBAAmB,CAAC,GAAG,cAAc;IA0JlD;;;OAGG;;QAED;;;;WAIG;6BACkB,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,cAAc;QAYnE;;;WAGG;sBAEM,MAAM,GAEX,SAAS,CAAC,OAAO,GAAG;YAAE,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAA;SAAE,CAAC,GAC/D,cAAc;QAwClB;;;;WAIG;qBACU,MAAM,aAAa,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;;CAehE,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { v3 as v3Internal, provinceMerges, wardMappings, } from './internal/v3/index.js';
|
|
2
|
+
import { legacy as legacyInternal } from './internal/legacy/index.js';
|
|
3
|
+
import { normalizeProvince, normalizeCommune, normalizeDistrict, normalizeName, ok, fail, } from './internal/helpers.js';
|
|
4
|
+
import { parseAddress, fuzzySearchProvinces } from './internal/address.js';
|
|
5
|
+
// ─── Private helpers ────────────────────────────────────
|
|
6
|
+
function resolveOldProvinceId(oldId) {
|
|
7
|
+
const trimmed = oldId.trim();
|
|
8
|
+
for (const merge of provinceMerges) {
|
|
9
|
+
const match = merge.mergedFrom.find((m) => m.oldProvinceId === trimmed);
|
|
10
|
+
if (match) {
|
|
11
|
+
const current = v3Internal.getProvinceById(merge.newProvinceId);
|
|
12
|
+
if (current) {
|
|
13
|
+
return { ...normalizeProvince(current), kind: 'province' };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
function resolveOldCommuneId(oldId) {
|
|
20
|
+
const trimmed = oldId.trim();
|
|
21
|
+
const rawMappings = wardMappings;
|
|
22
|
+
for (const mapping of rawMappings) {
|
|
23
|
+
if (mapping.oldWardCode === trimmed) {
|
|
24
|
+
const c = v3Internal.getCommuneById(mapping.newWardCode);
|
|
25
|
+
if (c) {
|
|
26
|
+
return { ...normalizeCommune(c), kind: 'ward' };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
// ─── Public API ─────────────────────────────────────────
|
|
33
|
+
export const vn = {
|
|
34
|
+
/**
|
|
35
|
+
* Get administrative divisions.
|
|
36
|
+
* - No arguments → 34 provinces (v3 system)
|
|
37
|
+
* - With parentId → communes/wards under that province (v3 system)
|
|
38
|
+
*/
|
|
39
|
+
divisions(parentId) {
|
|
40
|
+
if (parentId === undefined) {
|
|
41
|
+
const list = v3Internal.provinces();
|
|
42
|
+
if (list.length === 0)
|
|
43
|
+
return fail('empty_province_list');
|
|
44
|
+
return ok(list.map(normalizeProvince));
|
|
45
|
+
}
|
|
46
|
+
if (parentId.length === 0)
|
|
47
|
+
return fail('invalid_province_id');
|
|
48
|
+
const list = v3Internal.getCommunesByProvinceId(parentId);
|
|
49
|
+
if (list.length === 0)
|
|
50
|
+
return fail('empty_commune_list');
|
|
51
|
+
return ok(list.map(normalizeCommune));
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* Look up a single unit by ID, code, or name.
|
|
55
|
+
* Auto-detects: province ID (2-char like "79"), commune ID (5-char like "00004"),
|
|
56
|
+
* province code ("HCM", "HNI"), or full name.
|
|
57
|
+
* Auto-resolves: old province IDs via merge/mapping data.
|
|
58
|
+
*/
|
|
59
|
+
lookup(query) {
|
|
60
|
+
if (!query || query.length === 0)
|
|
61
|
+
return fail('invalid_query');
|
|
62
|
+
const trimmed = query.trim();
|
|
63
|
+
// 1. Try as province ID (2 chars)
|
|
64
|
+
if (trimmed.length === 2 && /^\d+$/.test(trimmed)) {
|
|
65
|
+
const p = v3Internal.getProvinceById(trimmed);
|
|
66
|
+
if (p) {
|
|
67
|
+
return ok({ ...normalizeProvince(p), kind: 'province' });
|
|
68
|
+
}
|
|
69
|
+
// Try auto-resolve from old province ID via merge data
|
|
70
|
+
const resolved = resolveOldProvinceId(trimmed);
|
|
71
|
+
if (resolved) {
|
|
72
|
+
return ok(resolved);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// 1.5 Try as old commune ID via ward mappings
|
|
76
|
+
if (trimmed.length === 5) {
|
|
77
|
+
const resolvedCommune = resolveOldCommuneId(trimmed);
|
|
78
|
+
if (resolvedCommune) {
|
|
79
|
+
return ok(resolvedCommune);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// 2. Try as province code (3 uppercase letters)
|
|
83
|
+
if (trimmed.length === 3 && /^[A-Za-z]+$/.test(trimmed)) {
|
|
84
|
+
const p = v3Internal.getProvinceByCode(trimmed.toUpperCase());
|
|
85
|
+
if (p) {
|
|
86
|
+
return ok({ ...normalizeProvince(p), kind: 'province' });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// 3. Try as commune ID (5 chars)
|
|
90
|
+
if (trimmed.length === 5) {
|
|
91
|
+
const c = v3Internal.getCommuneById(trimmed);
|
|
92
|
+
if (c) {
|
|
93
|
+
return ok({ ...normalizeCommune(c), kind: 'ward' });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// 4. Try as full province name (exact match, case-insensitive)
|
|
97
|
+
const provinceByName = v3Internal.searchProvinceByName(trimmed);
|
|
98
|
+
if (provinceByName.length === 1) {
|
|
99
|
+
return ok({
|
|
100
|
+
...normalizeProvince(provinceByName[0]),
|
|
101
|
+
kind: 'province',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// 5. Try auto-resolve old province/commune ID
|
|
105
|
+
const resolvedProv = resolveOldProvinceId(trimmed);
|
|
106
|
+
if (resolvedProv)
|
|
107
|
+
return ok(resolvedProv);
|
|
108
|
+
const resolvedCom = resolveOldCommuneId(trimmed);
|
|
109
|
+
if (resolvedCom)
|
|
110
|
+
return ok(resolvedCom);
|
|
111
|
+
return fail('province_not_found');
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* Search divisions by name (case-insensitive, partial match).
|
|
115
|
+
* - Without parentId → search in provinces
|
|
116
|
+
* - With parentId → search in communes of that province
|
|
117
|
+
*/
|
|
118
|
+
search(name, parentId) {
|
|
119
|
+
if (!name)
|
|
120
|
+
return ok([]);
|
|
121
|
+
if (parentId) {
|
|
122
|
+
return ok(v3Internal.searchCommunesByName(parentId, name).map(normalizeCommune));
|
|
123
|
+
}
|
|
124
|
+
return ok(v3Internal.searchProvinceByName(name).map(normalizeProvince));
|
|
125
|
+
},
|
|
126
|
+
/**
|
|
127
|
+
* Look up a full address string in both legacy and v3 systems.
|
|
128
|
+
*
|
|
129
|
+
* Parses a comma-separated address (e.g. "Xã Đông Hòa, TP Thái Bình, Thái Bình"
|
|
130
|
+
* or "Dong Hoa, Thai Binh"), resolves province/district/commune in the legacy
|
|
131
|
+
* system (63 tỉnh), then cross-references to the v3 system (34 tỉnh).
|
|
132
|
+
*
|
|
133
|
+
* **Strict mode (Option B):** Must find exactly one province — fails with
|
|
134
|
+
* `address_missing_province` or `address_ambiguous_province` otherwise.
|
|
135
|
+
*/
|
|
136
|
+
addressLookup(raw) {
|
|
137
|
+
if (!raw || raw.trim().length === 0)
|
|
138
|
+
return fail('invalid_query');
|
|
139
|
+
// 1. Parse address into parts
|
|
140
|
+
const parsed = parseAddress(raw);
|
|
141
|
+
if (!parsed.province) {
|
|
142
|
+
return fail('address_missing_province');
|
|
143
|
+
}
|
|
144
|
+
// 2. Build searchable lists
|
|
145
|
+
const legacyProvinceList = legacyInternal
|
|
146
|
+
.provinces()
|
|
147
|
+
.map(normalizeProvince);
|
|
148
|
+
const v3ProvinceList = v3Internal.provinces().map(normalizeProvince);
|
|
149
|
+
const nProvinceQuery = normalizeName(parsed.province);
|
|
150
|
+
// 3. Find province in legacy
|
|
151
|
+
const legacyProvinceMatches = fuzzySearchProvinces(parsed.province, legacyProvinceList);
|
|
152
|
+
if (legacyProvinceMatches.length === 0) {
|
|
153
|
+
return fail('address_ambiguous_province');
|
|
154
|
+
}
|
|
155
|
+
if (legacyProvinceMatches.length > 1) {
|
|
156
|
+
return fail('address_ambiguous_province');
|
|
157
|
+
}
|
|
158
|
+
const legacyProvince = legacyProvinceMatches[0];
|
|
159
|
+
// 4. Find province in v3
|
|
160
|
+
let v3Province = null;
|
|
161
|
+
const v3ProvinceMatches = fuzzySearchProvinces(parsed.province, v3ProvinceList);
|
|
162
|
+
if (v3ProvinceMatches.length === 1) {
|
|
163
|
+
v3Province = v3ProvinceMatches[0];
|
|
164
|
+
}
|
|
165
|
+
else if (v3ProvinceMatches.length > 1) {
|
|
166
|
+
return fail('address_ambiguous_province');
|
|
167
|
+
}
|
|
168
|
+
// 4b. Cross-resolve: legacy → v3 via provinceMerges
|
|
169
|
+
if (!v3Province) {
|
|
170
|
+
for (const merge of provinceMerges) {
|
|
171
|
+
const found = merge.mergedFrom.find((m) => m.oldProvinceId === legacyProvince.id);
|
|
172
|
+
if (found) {
|
|
173
|
+
const resolved = v3Internal.getProvinceById(merge.newProvinceId);
|
|
174
|
+
if (resolved) {
|
|
175
|
+
v3Province = normalizeProvince(resolved);
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// 5. Resolve district + commune in legacy
|
|
182
|
+
let legacyDistrict = null;
|
|
183
|
+
let legacyCommune = null;
|
|
184
|
+
const legacyDistricts = legacyInternal.getDistrictsByProvinceId(legacyProvince.id);
|
|
185
|
+
if (parsed.district) {
|
|
186
|
+
const districtMatches = fuzzySearchProvinces(parsed.district, legacyDistricts.map(normalizeDistrict));
|
|
187
|
+
if (districtMatches.length > 0) {
|
|
188
|
+
legacyDistrict = districtMatches[0];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (parsed.commune) {
|
|
192
|
+
// Search within district first (if found), then within whole province
|
|
193
|
+
if (legacyDistrict) {
|
|
194
|
+
const communeMatches = fuzzySearchProvinces(parsed.commune, legacyInternal
|
|
195
|
+
.getCommunesByDistrictId(legacyDistrict.id)
|
|
196
|
+
.map(normalizeCommune));
|
|
197
|
+
if (communeMatches.length > 0) {
|
|
198
|
+
legacyCommune = communeMatches[0];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (!legacyCommune) {
|
|
202
|
+
const communeMatches = fuzzySearchProvinces(parsed.commune, legacyInternal
|
|
203
|
+
.getCommunesByProvinceId(legacyProvince.id)
|
|
204
|
+
.map(normalizeCommune));
|
|
205
|
+
if (communeMatches.length > 0) {
|
|
206
|
+
legacyCommune = communeMatches[0];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// 6. Resolve commune in v3
|
|
211
|
+
let v3Commune = null;
|
|
212
|
+
if (v3Province) {
|
|
213
|
+
// 6a. Try ward_mappings if we have a legacy commune
|
|
214
|
+
if (legacyCommune) {
|
|
215
|
+
const rawMappings = wardMappings;
|
|
216
|
+
const match = rawMappings.find((m) => m.oldWardCode === legacyCommune.id);
|
|
217
|
+
if (match) {
|
|
218
|
+
const resolved = v3Internal.getCommuneById(match.newWardCode);
|
|
219
|
+
if (resolved) {
|
|
220
|
+
v3Commune = normalizeCommune(resolved);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// 6b. Fall back to searching by name in v3 province communes
|
|
225
|
+
if (!v3Commune && parsed.commune) {
|
|
226
|
+
const v3Communes = v3Internal
|
|
227
|
+
.getCommunesByProvinceId(v3Province.id)
|
|
228
|
+
.map(normalizeCommune);
|
|
229
|
+
const communeMatches = fuzzySearchProvinces(parsed.commune, v3Communes);
|
|
230
|
+
if (communeMatches.length > 0) {
|
|
231
|
+
v3Commune = communeMatches[0];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// 7. Build result
|
|
236
|
+
const result = {
|
|
237
|
+
legacy: {
|
|
238
|
+
province: legacyProvince,
|
|
239
|
+
district: legacyDistrict,
|
|
240
|
+
commune: legacyCommune,
|
|
241
|
+
hamlet: parsed.hamlet,
|
|
242
|
+
},
|
|
243
|
+
v3: {
|
|
244
|
+
province: v3Province,
|
|
245
|
+
commune: v3Commune,
|
|
246
|
+
hamlet: parsed.hamlet,
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
return ok(result);
|
|
250
|
+
},
|
|
251
|
+
/**
|
|
252
|
+
* Legacy system (63 provinces, 3 levels: province → district → commune).
|
|
253
|
+
* Explicit opt-in for backward compatibility.
|
|
254
|
+
*/
|
|
255
|
+
legacy: {
|
|
256
|
+
/**
|
|
257
|
+
* Get legacy divisions.
|
|
258
|
+
* - No arguments → 63 provinces
|
|
259
|
+
* - With parentId → districts under that province
|
|
260
|
+
*/
|
|
261
|
+
divisions(parentId) {
|
|
262
|
+
if (parentId === undefined) {
|
|
263
|
+
const list = legacyInternal.provinces();
|
|
264
|
+
if (list.length === 0)
|
|
265
|
+
return fail('empty_province_list');
|
|
266
|
+
return ok(list.map(normalizeProvince));
|
|
267
|
+
}
|
|
268
|
+
if (parentId.length === 0)
|
|
269
|
+
return fail('invalid_province_id');
|
|
270
|
+
const list = legacyInternal.getDistrictsByProvinceId(parentId);
|
|
271
|
+
if (list.length === 0)
|
|
272
|
+
return fail('empty_district_list');
|
|
273
|
+
return ok(list.map(normalizeDistrict));
|
|
274
|
+
},
|
|
275
|
+
/**
|
|
276
|
+
* Look up a legacy unit by ID.
|
|
277
|
+
* Auto-detects: province ID (2-char), district ID (3-char), commune ID (5-char).
|
|
278
|
+
*/
|
|
279
|
+
lookup(query) {
|
|
280
|
+
if (!query || query.length === 0)
|
|
281
|
+
return fail('invalid_query');
|
|
282
|
+
const trimmed = query.trim();
|
|
283
|
+
// Try province ID (2 chars)
|
|
284
|
+
if (trimmed.length === 2) {
|
|
285
|
+
const p = legacyInternal.getProvinceById(trimmed);
|
|
286
|
+
if (p) {
|
|
287
|
+
return ok({ ...normalizeProvince(p), kind: 'province' });
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Try district ID (3 chars)
|
|
291
|
+
if (trimmed.length === 3) {
|
|
292
|
+
const d = legacyInternal.getDistrictById(trimmed);
|
|
293
|
+
if (d) {
|
|
294
|
+
return ok({ ...normalizeDistrict(d), kind: 'district' });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Try commune ID (5 chars)
|
|
298
|
+
if (trimmed.length === 5) {
|
|
299
|
+
const c = legacyInternal.getCommuneById(trimmed);
|
|
300
|
+
if (c) {
|
|
301
|
+
return ok({ ...normalizeCommune(c), kind: 'ward' });
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// Try province by name
|
|
305
|
+
const byName = legacyInternal.searchByName(trimmed);
|
|
306
|
+
if (byName.length === 1) {
|
|
307
|
+
return ok({
|
|
308
|
+
...normalizeProvince(byName[0]),
|
|
309
|
+
kind: 'province',
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
return fail('province_not_found');
|
|
313
|
+
},
|
|
314
|
+
/**
|
|
315
|
+
* Search legacy divisions by name.
|
|
316
|
+
* - Without parentId → search in provinces
|
|
317
|
+
* - With parentId → search in districts of that province
|
|
318
|
+
*/
|
|
319
|
+
search(name, parentId) {
|
|
320
|
+
if (!name)
|
|
321
|
+
return ok([]);
|
|
322
|
+
if (parentId) {
|
|
323
|
+
return ok(legacyInternal
|
|
324
|
+
.getDistrictsByProvinceId(parentId)
|
|
325
|
+
.filter((d) => d.name.toLowerCase().includes(name.toLowerCase().trim()))
|
|
326
|
+
.map(normalizeDistrict));
|
|
327
|
+
}
|
|
328
|
+
return ok(legacyInternal.searchByName(name).map(normalizeProvince));
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { GeoUnit } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detect level of an address part by its prefix.
|
|
4
|
+
* @param provinceFound — if true, treat ambiguous "Thành phố/TP" as district.
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectLevel(part: string, provinceFound?: boolean): 'province' | 'district' | 'commune' | 'hamlet' | 'unknown';
|
|
7
|
+
export interface ParsedAddress {
|
|
8
|
+
/** Deduplicated, trimmed, original-case parts (right-to-left order). */
|
|
9
|
+
parts: string[];
|
|
10
|
+
hamlet: string | null;
|
|
11
|
+
commune: string | null;
|
|
12
|
+
district: string | null;
|
|
13
|
+
province: string | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Split, trim, dedup (by normalized form), then classify each part.
|
|
17
|
+
* Returns structured parts without doing any DB lookup.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseAddress(raw: string): ParsedAddress;
|
|
20
|
+
/**
|
|
21
|
+
* Expand common Vietnamese administrative abbreviations.
|
|
22
|
+
* "TP HCM" → "thành phố hồ chí minh", "TX" → "thị xã", etc.
|
|
23
|
+
*/
|
|
24
|
+
export declare function expandAbbreviations(name: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a query matches a target name.
|
|
27
|
+
* - Exact normalized match
|
|
28
|
+
* - Target contains query (token-level)
|
|
29
|
+
* - Query contains target
|
|
30
|
+
*/
|
|
31
|
+
export declare function fuzzyMatch(query: string, target: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Find best matches in a list of GeoUnits.
|
|
34
|
+
* Returns exact matches first, then partial matches.
|
|
35
|
+
*/
|
|
36
|
+
export declare function fuzzySearchProvinces(query: string, items: GeoUnit[]): GeoUnit[];
|
|
37
|
+
//# sourceMappingURL=address.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../src/internal/address.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAU3C;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,OAAO,GACtB,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CA4B5D;AAED,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CA8DvD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxD;AASD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQjE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,OAAO,EAAE,GACf,OAAO,EAAE,CAkBX"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { normalizeName } from './helpers.js';
|
|
2
|
+
/** Level prefixes ordered from most specific to least. */
|
|
3
|
+
const HAMLET_PREFIXES = ['thôn', 'ấp', 'tổ', 'xóm', 'bản', 'số'];
|
|
4
|
+
const COMMUNE_PREFIXES = ['xã', 'phường', 'thị trấn', 'tt.', 'tt'];
|
|
5
|
+
const DISTRICT_PREFIXES = ['huyện', 'quận', 'thị xã', 'tx.', 'tx'];
|
|
6
|
+
/** "Thành phố" and "tp" are ambiguous — could be province or district. */
|
|
7
|
+
const AMBIGUOUS_PREFIXES = ['thành phố', 'tp.', 'tp'];
|
|
8
|
+
const PROVINCE_PREFIXES = ['tỉnh'];
|
|
9
|
+
/**
|
|
10
|
+
* Detect level of an address part by its prefix.
|
|
11
|
+
* @param provinceFound — if true, treat ambiguous "Thành phố/TP" as district.
|
|
12
|
+
*/
|
|
13
|
+
export function detectLevel(part, provinceFound) {
|
|
14
|
+
const lower = part.toLowerCase().trim();
|
|
15
|
+
// Exclusive province prefix
|
|
16
|
+
for (const prefix of PROVINCE_PREFIXES) {
|
|
17
|
+
if (lower.startsWith(prefix) || lower.endsWith(prefix)) {
|
|
18
|
+
return 'province';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Ambiguous: if province already found, treat as district
|
|
22
|
+
for (const prefix of AMBIGUOUS_PREFIXES) {
|
|
23
|
+
if (lower.startsWith(prefix) || lower.endsWith(prefix)) {
|
|
24
|
+
return provinceFound ? 'district' : 'province';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
for (const prefix of DISTRICT_PREFIXES) {
|
|
28
|
+
if (lower.startsWith(prefix))
|
|
29
|
+
return 'district';
|
|
30
|
+
}
|
|
31
|
+
for (const prefix of COMMUNE_PREFIXES) {
|
|
32
|
+
if (lower.startsWith(prefix))
|
|
33
|
+
return 'commune';
|
|
34
|
+
}
|
|
35
|
+
for (const prefix of HAMLET_PREFIXES) {
|
|
36
|
+
if (lower.startsWith(prefix))
|
|
37
|
+
return 'hamlet';
|
|
38
|
+
}
|
|
39
|
+
return 'unknown';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Split, trim, dedup (by normalized form), then classify each part.
|
|
43
|
+
* Returns structured parts without doing any DB lookup.
|
|
44
|
+
*/
|
|
45
|
+
export function parseAddress(raw) {
|
|
46
|
+
if (!raw) {
|
|
47
|
+
return { parts: [], hamlet: null, commune: null, district: null, province: null };
|
|
48
|
+
}
|
|
49
|
+
// Split by comma, trim, filter empty
|
|
50
|
+
const rawParts = raw.split(',').map((s) => s.trim()).filter(Boolean);
|
|
51
|
+
if (rawParts.length === 0) {
|
|
52
|
+
return { parts: [], hamlet: null, commune: null, district: null, province: null };
|
|
53
|
+
}
|
|
54
|
+
// Dedup by normalized form (keep first occurrence)
|
|
55
|
+
const seen = new Set();
|
|
56
|
+
const deduped = [];
|
|
57
|
+
for (const p of rawParts) {
|
|
58
|
+
const norm = normalizeName(p);
|
|
59
|
+
if (norm && !seen.has(norm)) {
|
|
60
|
+
seen.add(norm);
|
|
61
|
+
deduped.push(p);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Classify right-to-left
|
|
65
|
+
let hamlet = null;
|
|
66
|
+
let commune = null;
|
|
67
|
+
let district = null;
|
|
68
|
+
let province = null;
|
|
69
|
+
// Reverse order: rightmost = province (broadest scope in VN address format)
|
|
70
|
+
const reversed = [...deduped].reverse();
|
|
71
|
+
// Phase 1: rightmost part is ALWAYS the province
|
|
72
|
+
province = reversed[0];
|
|
73
|
+
// Phase 2: classify remaining parts (left of province)
|
|
74
|
+
const remaining = deduped.slice(0, -1); // all except the last (rightmost)
|
|
75
|
+
for (const part of remaining) {
|
|
76
|
+
const level = detectLevel(part, true); // province already found
|
|
77
|
+
if (level === 'hamlet' && !hamlet) {
|
|
78
|
+
hamlet = part;
|
|
79
|
+
}
|
|
80
|
+
else if (level === 'commune' && !commune) {
|
|
81
|
+
commune = part;
|
|
82
|
+
}
|
|
83
|
+
else if (level === 'district' && !district) {
|
|
84
|
+
district = part;
|
|
85
|
+
}
|
|
86
|
+
else if (!commune) {
|
|
87
|
+
// Unknown → treat as commune (most specific known level)
|
|
88
|
+
commune = part;
|
|
89
|
+
}
|
|
90
|
+
else if (!district) {
|
|
91
|
+
district = part;
|
|
92
|
+
}
|
|
93
|
+
else if (!hamlet) {
|
|
94
|
+
hamlet = part;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
parts: deduped,
|
|
99
|
+
hamlet,
|
|
100
|
+
commune,
|
|
101
|
+
district,
|
|
102
|
+
province,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Expand common Vietnamese administrative abbreviations.
|
|
107
|
+
* "TP HCM" → "thành phố hồ chí minh", "TX" → "thị xã", etc.
|
|
108
|
+
*/
|
|
109
|
+
export function expandAbbreviations(name) {
|
|
110
|
+
return name
|
|
111
|
+
.replace(/\btp\.?\b/gi, 'thành phố')
|
|
112
|
+
.replace(/\btx\.?\b/gi, 'thị xã')
|
|
113
|
+
.replace(/\btt\.?\b/gi, 'thị trấn')
|
|
114
|
+
.replace(/\bhcm\b/gi, 'hồ chí minh')
|
|
115
|
+
.replace(/\bhni\b/gi, 'hà nội');
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Normalize for search: expand abbreviations first, THEN remove diacritics.
|
|
119
|
+
*/
|
|
120
|
+
function normalizeForSearch(name) {
|
|
121
|
+
return normalizeName(expandAbbreviations(name));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Check if a query matches a target name.
|
|
125
|
+
* - Exact normalized match
|
|
126
|
+
* - Target contains query (token-level)
|
|
127
|
+
* - Query contains target
|
|
128
|
+
*/
|
|
129
|
+
export function fuzzyMatch(query, target) {
|
|
130
|
+
const nq = normalizeForSearch(query);
|
|
131
|
+
const nt = normalizeForSearch(target);
|
|
132
|
+
if (!nq || !nt)
|
|
133
|
+
return false;
|
|
134
|
+
if (nq === nt)
|
|
135
|
+
return true;
|
|
136
|
+
if (nt.includes(nq))
|
|
137
|
+
return true;
|
|
138
|
+
if (nq.includes(nt))
|
|
139
|
+
return true;
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Find best matches in a list of GeoUnits.
|
|
144
|
+
* Returns exact matches first, then partial matches.
|
|
145
|
+
*/
|
|
146
|
+
export function fuzzySearchProvinces(query, items) {
|
|
147
|
+
const nq = normalizeForSearch(query);
|
|
148
|
+
if (!nq)
|
|
149
|
+
return [];
|
|
150
|
+
const exact = [];
|
|
151
|
+
const partial = [];
|
|
152
|
+
for (const item of items) {
|
|
153
|
+
const ni = normalizeForSearch(item.name);
|
|
154
|
+
if (ni === nq) {
|
|
155
|
+
exact.push(item);
|
|
156
|
+
}
|
|
157
|
+
else if (ni.includes(nq)) {
|
|
158
|
+
partial.push(item);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Exact matches first
|
|
162
|
+
return [...exact, ...partial];
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../src/internal/address.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { GeoUnit, GeoError } from '../types.js';
|
|
2
|
+
/** Remove Vietnamese diacritics, lowercase, collapse whitespace. */
|
|
3
|
+
export declare function normalizeName(name: string): string;
|
|
4
|
+
export declare function normalizeProvince(p: {
|
|
5
|
+
idProvince: string;
|
|
6
|
+
name: string;
|
|
7
|
+
}): GeoUnit;
|
|
8
|
+
export declare function normalizeCommune(c: {
|
|
9
|
+
idCommune: string;
|
|
10
|
+
name: string;
|
|
11
|
+
}): GeoUnit;
|
|
12
|
+
export declare function normalizeDistrict(d: {
|
|
13
|
+
idDistrict: string;
|
|
14
|
+
name: string;
|
|
15
|
+
}): GeoUnit;
|
|
16
|
+
export declare function ok<T>(data: T): {
|
|
17
|
+
data: T;
|
|
18
|
+
error?: undefined;
|
|
19
|
+
};
|
|
20
|
+
export declare function fail(error: GeoError): {
|
|
21
|
+
data: null;
|
|
22
|
+
error: GeoError;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/internal/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAgCrD,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAEV;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAEV;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAEV;AAED,wBAAgB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,CAE7D;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAErE"}
|