@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.
Files changed (45) hide show
  1. package/README.md +80 -0
  2. package/dist/__tests__/vn.test.d.ts +2 -0
  3. package/dist/__tests__/vn.test.d.ts.map +1 -0
  4. package/dist/__tests__/vn.test.js +1107 -0
  5. package/dist/__tests__/vn.test.js.map +1 -0
  6. package/dist/data/legacy/commune.json +11077 -0
  7. package/dist/data/legacy/district.json +730 -0
  8. package/dist/data/legacy/province.json +65 -0
  9. package/dist/data/v3/commune.json +16607 -0
  10. package/dist/data/v3/province.json +240 -0
  11. package/dist/data/v3/province_merges.json +256 -0
  12. package/dist/data/v3/ward_mappings.json +98795 -0
  13. package/dist/index.d.ts +62 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +332 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/internal/address.d.ts +37 -0
  18. package/dist/internal/address.d.ts.map +1 -0
  19. package/dist/internal/address.js +164 -0
  20. package/dist/internal/address.js.map +1 -0
  21. package/dist/internal/helpers.d.ts +24 -0
  22. package/dist/internal/helpers.d.ts.map +1 -0
  23. package/dist/internal/helpers.js +55 -0
  24. package/dist/internal/helpers.js.map +1 -0
  25. package/dist/internal/legacy/index.d.ts +21 -0
  26. package/dist/internal/legacy/index.d.ts.map +1 -0
  27. package/dist/internal/legacy/index.js +60 -0
  28. package/dist/internal/legacy/index.js.map +1 -0
  29. package/dist/internal/legacy/types.d.ts +18 -0
  30. package/dist/internal/legacy/types.d.ts.map +1 -0
  31. package/dist/internal/legacy/types.js +2 -0
  32. package/dist/internal/legacy/types.js.map +1 -0
  33. package/dist/internal/v3/index.d.ts +21 -0
  34. package/dist/internal/v3/index.d.ts.map +1 -0
  35. package/dist/internal/v3/index.js +55 -0
  36. package/dist/internal/v3/index.js.map +1 -0
  37. package/dist/internal/v3/types.d.ts +33 -0
  38. package/dist/internal/v3/types.d.ts.map +1 -0
  39. package/dist/internal/v3/types.js +2 -0
  40. package/dist/internal/v3/types.js.map +1 -0
  41. package/dist/types.d.ts +37 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +2 -0
  44. package/dist/types.js.map +1 -0
  45. package/package.json +32 -0
@@ -0,0 +1,55 @@
1
+ const DIACRITIC_MAP = {
2
+ a: 'a', à: 'a', á: 'a', ả: 'a', ã: 'a', ạ: 'a',
3
+ ă: 'a', ằ: 'a', ắ: 'a', ẳ: 'a', ẵ: 'a', ặ: 'a',
4
+ â: 'a', ầ: 'a', ấ: 'a', ẩ: 'a', ẫ: 'a', ậ: 'a',
5
+ e: 'e', è: 'e', é: 'e', ẻ: 'e', ẽ: 'e', ẹ: 'e',
6
+ ê: 'e', ề: 'e', ế: 'e', ể: 'e', ễ: 'e', ệ: 'e',
7
+ i: 'i', ì: 'i', í: 'i', ỉ: 'i', ĩ: 'i', ị: 'i',
8
+ o: 'o', ò: 'o', ó: 'o', ỏ: 'o', õ: 'o', ọ: 'o',
9
+ ô: 'o', ồ: 'o', ố: 'o', ổ: 'o', ỗ: 'o', ộ: 'o',
10
+ ơ: 'o', ờ: 'o', ớ: 'o', ở: 'o', ỡ: 'o', ợ: 'o',
11
+ u: 'u', ù: 'u', ú: 'u', ủ: 'u', ũ: 'u', ụ: 'u',
12
+ ư: 'u', ừ: 'u', ứ: 'u', ử: 'u', ữ: 'u', ự: 'u',
13
+ y: 'y', ỳ: 'y', ý: 'y', ỷ: 'y', ỹ: 'y', ỵ: 'y',
14
+ đ: 'd',
15
+ // uppercase
16
+ A: 'a', À: 'a', Á: 'a', Ả: 'a', Ã: 'a', Ạ: 'a',
17
+ Ă: 'a', Ằ: 'a', Ắ: 'a', Ẳ: 'a', Ẵ: 'a', Ặ: 'a',
18
+ Â: 'a', Ầ: 'a', Ấ: 'a', Ẩ: 'a', Ẫ: 'a', Ậ: 'a',
19
+ E: 'e', È: 'e', É: 'e', Ẻ: 'e', Ẽ: 'e', Ẹ: 'e',
20
+ Ê: 'e', Ề: 'e', Ế: 'e', Ể: 'e', Ễ: 'e', Ệ: 'e',
21
+ I: 'i', Ì: 'i', Í: 'i', Ỉ: 'i', Ĩ: 'i', Ị: 'i',
22
+ O: 'o', Ò: 'o', Ó: 'o', Ỏ: 'o', Õ: 'o', Ọ: 'o',
23
+ Ô: 'o', Ồ: 'o', Ố: 'o', Ổ: 'o', Ỗ: 'o', Ộ: 'o',
24
+ Ơ: 'o', Ờ: 'o', Ớ: 'o', Ở: 'o', Ỡ: 'o', Ợ: 'o',
25
+ U: 'u', Ù: 'u', Ú: 'u', Ủ: 'u', Ũ: 'u', Ụ: 'u',
26
+ Ư: 'u', Ừ: 'u', Ứ: 'u', Ử: 'u', Ữ: 'u', Ự: 'u',
27
+ Y: 'y', Ỳ: 'y', Ý: 'y', Ỷ: 'y', Ỹ: 'y', Ỵ: 'y',
28
+ Đ: 'd',
29
+ };
30
+ /** Remove Vietnamese diacritics, lowercase, collapse whitespace. */
31
+ export function normalizeName(name) {
32
+ return name
33
+ .split('')
34
+ .map((ch) => DIACRITIC_MAP[ch] ?? ch)
35
+ .join('')
36
+ .toLowerCase()
37
+ .replace(/\s+/g, ' ')
38
+ .trim();
39
+ }
40
+ export function normalizeProvince(p) {
41
+ return { id: p.idProvince, name: p.name };
42
+ }
43
+ export function normalizeCommune(c) {
44
+ return { id: c.idCommune, name: c.name };
45
+ }
46
+ export function normalizeDistrict(d) {
47
+ return { id: d.idDistrict, name: d.name };
48
+ }
49
+ export function ok(data) {
50
+ return { data };
51
+ }
52
+ export function fail(error) {
53
+ return { data: null, error };
54
+ }
55
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/internal/helpers.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAA2B;IAC5C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG;IACN,YAAY;IACZ,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAC9C,CAAC,EAAE,GAAG;CACP,CAAC;AAEF,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI;SACR,KAAK,CAAC,EAAE,CAAC;SACT,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;SACpC,IAAI,CAAC,EAAE,CAAC;SACR,WAAW,EAAE;SACb,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,CAGjC;IACC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAGhC;IACC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,CAGjC;IACC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,EAAE,CAAI,IAAO;IAC3B,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAe;IAClC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { LegacyProvince, LegacyDistrict, LegacyCommune } from './types.js';
2
+ export type { LegacyProvince, LegacyDistrict, LegacyCommune };
3
+ declare function getProvinceById(id: string): LegacyProvince | undefined;
4
+ declare function searchByName(name: string): LegacyProvince[];
5
+ declare function getDistrictsByProvinceId(provinceId: string): LegacyDistrict[];
6
+ declare function getCommunesByDistrictId(districtId: string): LegacyCommune[];
7
+ declare function getCommunesByProvinceId(provinceId: string): LegacyCommune[];
8
+ declare function getDistrictById(id: string): LegacyDistrict | undefined;
9
+ declare function getCommuneById(id: string): LegacyCommune | undefined;
10
+ /** Internal legacy API — consumed by `vn.legacy`. */
11
+ export declare const legacy: {
12
+ provinces: () => LegacyProvince[];
13
+ getProvinceById: typeof getProvinceById;
14
+ searchByName: typeof searchByName;
15
+ getDistrictsByProvinceId: typeof getDistrictsByProvinceId;
16
+ getCommunesByDistrictId: typeof getCommunesByDistrictId;
17
+ getCommunesByProvinceId: typeof getCommunesByProvinceId;
18
+ getDistrictById: typeof getDistrictById;
19
+ getCommuneById: typeof getCommuneById;
20
+ };
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/internal/legacy/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhF,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AAM9D,iBAAS,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAG/D;AAED,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAKpD;AAED,iBAAS,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE,CAGtE;AAED,iBAAS,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,EAAE,CAGpE;AAED,iBAAS,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,EAAE,CAMpE;AAED,iBAAS,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAG/D;AAED,iBAAS,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAG7D;AAED,qDAAqD;AACrD,eAAO,MAAM,MAAM;;;;;;;;;CASlB,CAAC"}
@@ -0,0 +1,60 @@
1
+ import provinceData from '../../data/legacy/province.json' with { type: 'json' };
2
+ import districtData from '../../data/legacy/district.json' with { type: 'json' };
3
+ import communeData from '../../data/legacy/commune.json' with { type: 'json' };
4
+ const provinces = provinceData;
5
+ const districts = districtData;
6
+ const communes = communeData;
7
+ function getProvinceById(id) {
8
+ if (!id)
9
+ return undefined;
10
+ return provinces.find((p) => p.idProvince === id);
11
+ }
12
+ function searchByName(name) {
13
+ if (!name)
14
+ return [];
15
+ const q = name.toLowerCase().trim();
16
+ if (!q)
17
+ return [];
18
+ return provinces.filter((p) => p.name.toLowerCase().includes(q));
19
+ }
20
+ function getDistrictsByProvinceId(provinceId) {
21
+ if (!provinceId)
22
+ return [];
23
+ return districts.filter((d) => d.idProvince === provinceId);
24
+ }
25
+ function getCommunesByDistrictId(districtId) {
26
+ if (!districtId)
27
+ return [];
28
+ return communes.filter((c) => c.idDistrict === districtId);
29
+ }
30
+ function getCommunesByProvinceId(provinceId) {
31
+ if (!provinceId)
32
+ return [];
33
+ const ds = getDistrictsByProvinceId(provinceId);
34
+ if (ds.length === 0)
35
+ return [];
36
+ const districtIds = new Set(ds.map((d) => d.idDistrict));
37
+ return communes.filter((c) => districtIds.has(c.idDistrict));
38
+ }
39
+ function getDistrictById(id) {
40
+ if (!id)
41
+ return undefined;
42
+ return districts.find((d) => d.idDistrict === id);
43
+ }
44
+ function getCommuneById(id) {
45
+ if (!id)
46
+ return undefined;
47
+ return communes.find((c) => c.idCommune === id);
48
+ }
49
+ /** Internal legacy API — consumed by `vn.legacy`. */
50
+ export const legacy = {
51
+ provinces: () => provinces,
52
+ getProvinceById,
53
+ searchByName,
54
+ getDistrictsByProvinceId,
55
+ getCommunesByDistrictId,
56
+ getCommunesByProvinceId,
57
+ getDistrictById,
58
+ getCommuneById,
59
+ };
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/internal/legacy/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /** A province in the legacy system (63 provinces, 3 levels: Province → District → Commune). */
2
+ export interface LegacyProvince {
3
+ idProvince: string;
4
+ name: string;
5
+ }
6
+ /** A district in the legacy system (696 districts). */
7
+ export interface LegacyDistrict {
8
+ idProvince: string;
9
+ idDistrict: string;
10
+ name: string;
11
+ }
12
+ /** A commune in the legacy system (10,051 communes). */
13
+ export interface LegacyCommune {
14
+ idDistrict: string;
15
+ idCommune: string;
16
+ name: string;
17
+ }
18
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/internal/legacy/types.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/internal/legacy/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import type { Province, Commune, ProvinceMerge, WardMapping } from './types.js';
2
+ export type { Province, Commune, ProvinceMerge, WardMapping };
3
+ export declare const provinceMerges: ProvinceMerge[];
4
+ export declare const wardMappings: WardMapping[];
5
+ declare function getProvinceById(id: string): Province | undefined;
6
+ declare function getProvinceByCode(code: string): Province | undefined;
7
+ declare function searchProvinceByName(name: string): Province[];
8
+ declare function getCommunesByProvinceId(provinceId: string): Commune[];
9
+ declare function searchCommunesByName(provinceId: string, name: string): Commune[];
10
+ declare function getCommuneById(id: string): Commune | undefined;
11
+ /** Internal v3 API — consumed by the public `vn` interface. */
12
+ export declare const v3: {
13
+ provinces: () => Province[];
14
+ getProvinceById: typeof getProvinceById;
15
+ getProvinceByCode: typeof getProvinceByCode;
16
+ searchProvinceByName: typeof searchProvinceByName;
17
+ getCommunesByProvinceId: typeof getCommunesByProvinceId;
18
+ searchCommunesByName: typeof searchCommunesByName;
19
+ getCommuneById: typeof getCommuneById;
20
+ };
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/internal/v3/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMhF,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;AAI9D,eAAO,MAAM,cAAc,EAAyB,aAAa,EAAE,CAAC;AACpE,eAAO,MAAM,YAAY,EAAuB,WAAW,EAAE,CAAC;AAE9D,iBAAS,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAGzD;AAED,iBAAS,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAG7D;AAED,iBAAS,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CAQtD;AAED,iBAAS,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,EAAE,CAG9D;AAED,iBAAS,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAOzE;AAED,iBAAS,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAGvD;AAED,+DAA+D;AAC/D,eAAO,MAAM,EAAE;;;;;;;;CAQd,CAAC"}
@@ -0,0 +1,55 @@
1
+ import provinceData from '../../data/v3/province.json' with { type: 'json' };
2
+ import communeData from '../../data/v3/commune.json' with { type: 'json' };
3
+ import provinceMergesData from '../../data/v3/province_merges.json' with { type: 'json' };
4
+ import wardMappingsData from '../../data/v3/ward_mappings.json' with { type: 'json' };
5
+ const provinces = provinceData;
6
+ const communes = communeData;
7
+ export const provinceMerges = provinceMergesData;
8
+ export const wardMappings = wardMappingsData;
9
+ function getProvinceById(id) {
10
+ if (!id || id.length === 0)
11
+ return undefined;
12
+ return provinces.find((p) => p.idProvince === id);
13
+ }
14
+ function getProvinceByCode(code) {
15
+ if (!code || code.length === 0)
16
+ return undefined;
17
+ return provinces.find((p) => p.code === code);
18
+ }
19
+ function searchProvinceByName(name) {
20
+ if (!name || name.length === 0)
21
+ return [];
22
+ const q = name.toLowerCase().trim();
23
+ if (q.length === 0)
24
+ return [];
25
+ return provinces.filter((p) => p.name.toLowerCase().includes(q) || p.shortName.toLowerCase().includes(q));
26
+ }
27
+ function getCommunesByProvinceId(provinceId) {
28
+ if (!provinceId || provinceId.length === 0)
29
+ return [];
30
+ return communes.filter((c) => c.idProvince === provinceId);
31
+ }
32
+ function searchCommunesByName(provinceId, name) {
33
+ if (!provinceId || !name)
34
+ return [];
35
+ const q = name.toLowerCase().trim();
36
+ if (q.length === 0)
37
+ return [];
38
+ return communes.filter((c) => c.idProvince === provinceId && c.name.toLowerCase().includes(q));
39
+ }
40
+ function getCommuneById(id) {
41
+ if (!id || id.length === 0)
42
+ return undefined;
43
+ return communes.find((c) => c.idCommune === id);
44
+ }
45
+ /** Internal v3 API — consumed by the public `vn` interface. */
46
+ export const v3 = {
47
+ provinces: () => provinces,
48
+ getProvinceById,
49
+ getProvinceByCode,
50
+ searchProvinceByName,
51
+ getCommunesByProvinceId,
52
+ searchCommunesByName,
53
+ getCommuneById,
54
+ };
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/internal/v3/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /** A province/city in the new system (34 provinces, Resolution 202/2025/QH15). */
2
+ export interface Province {
3
+ idProvince: string;
4
+ name: string;
5
+ shortName: string;
6
+ code: string;
7
+ placeType: string;
8
+ }
9
+ /** A commune/ward in the new system (3,321 communes). */
10
+ export interface Commune {
11
+ idProvince: string;
12
+ idCommune: string;
13
+ name: string;
14
+ }
15
+ /** Old-to-new province merge mapping. */
16
+ export interface ProvinceMergeItem {
17
+ oldProvinceId: string;
18
+ oldProvinceName: string;
19
+ }
20
+ export interface ProvinceMerge {
21
+ newProvinceId: string;
22
+ newProvinceName: string;
23
+ mergedFrom: ProvinceMergeItem[];
24
+ }
25
+ /** Old-to-new ward code mapping. */
26
+ export interface WardMapping {
27
+ oldIdCommune: string;
28
+ oldCommuneName: string;
29
+ newIdCommune: string;
30
+ newCommuneName: string;
31
+ newIdProvince: string;
32
+ }
33
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/internal/v3/types.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,yDAAyD;AACzD,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,yCAAyC;AACzC,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/internal/v3/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ /** A geographical unit with id + name. */
2
+ export interface GeoUnit {
3
+ id: string;
4
+ name: string;
5
+ }
6
+ /** Self-descriptive error strings. */
7
+ export type GeoError = 'province_not_found' | 'commune_not_found' | 'district_not_found' | 'empty_province_list' | 'empty_commune_list' | 'empty_district_list' | 'invalid_province_id' | 'invalid_commune_id' | 'invalid_query' | 'address_missing_province' | 'address_ambiguous_province';
8
+ /** Result wrapper — discriminated union. */
9
+ export interface GeoResult<T> {
10
+ data: T;
11
+ error?: undefined;
12
+ }
13
+ export interface GeoErrorResult {
14
+ data: null;
15
+ error: GeoError;
16
+ }
17
+ /** A resolved component in an address lookup. */
18
+ export interface AddressComponent {
19
+ id: string | null;
20
+ name: string | null;
21
+ type: 'province' | 'district' | 'commune' | 'hamlet';
22
+ }
23
+ /** Result of addressLookup() — shows both legacy (63 tỉnh) and v3 (34 tỉnh) paths. */
24
+ export interface AddressLookupResult {
25
+ legacy: {
26
+ province: GeoUnit | null;
27
+ district: GeoUnit | null;
28
+ commune: GeoUnit | null;
29
+ hamlet: string | null;
30
+ };
31
+ v3: {
32
+ province: GeoUnit | null;
33
+ commune: GeoUnit | null;
34
+ hamlet: string | null;
35
+ };
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,sCAAsC;AACtC,MAAM,MAAM,QAAQ,GAChB,oBAAoB,GACpB,mBAAmB,GACnB,oBAAoB,GACpB,qBAAqB,GACrB,oBAAoB,GACpB,qBAAqB,GACrB,qBAAqB,GACrB,oBAAoB,GACpB,eAAe,GACf,0BAA0B,GAC1B,4BAA4B,CAAC;AAEjC,4CAA4C;AAC5C,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;CACtD;AAED,sFAAsF;AACtF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE;QACN,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;QACzB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;QACzB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,EAAE,EAAE;QACF,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;QACzB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;CACH"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@0xd33p/vietnam-divisions",
3
+ "version": "0.2.0",
4
+ "files": ["dist"],
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "description": "Vietnam administrative divisions — raw seed data + sync helpers (34 provinces, 3,321 communes, v3)",
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "dev": "tsx --watch src/index.ts",
21
+ "build": "tsc",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest",
24
+ "test:coverage": "vitest run --coverage"
25
+ },
26
+ "devDependencies": {
27
+ "@vitest/coverage-v8": "catalog:",
28
+ "tsx": "^4.22.4",
29
+ "typescript": "catalog:",
30
+ "vitest": "catalog:"
31
+ }
32
+ }