@damarkuncoro/posindonesia 1.0.5 → 1.0.6
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 +15 -12
- package/lib/cjs/cli.js +10 -4
- package/lib/cjs/cli.js.map +1 -1
- package/lib/cjs/infrastructure/repositories/RemotePostalCodeRepository.d.ts +24 -0
- package/lib/cjs/infrastructure/repositories/RemotePostalCodeRepository.d.ts.map +1 -0
- package/lib/cjs/infrastructure/repositories/RemotePostalCodeRepository.js +56 -0
- package/lib/cjs/infrastructure/repositories/RemotePostalCodeRepository.js.map +1 -0
- package/lib/cjs/main.d.ts +22 -4
- package/lib/cjs/main.d.ts.map +1 -1
- package/lib/cjs/main.js +47 -16
- package/lib/cjs/main.js.map +1 -1
- package/lib/esm/cli.js +10 -4
- package/lib/esm/cli.js.map +1 -1
- package/lib/esm/infrastructure/repositories/RemotePostalCodeRepository.d.ts +24 -0
- package/lib/esm/infrastructure/repositories/RemotePostalCodeRepository.d.ts.map +1 -0
- package/lib/esm/infrastructure/repositories/RemotePostalCodeRepository.js +52 -0
- package/lib/esm/infrastructure/repositories/RemotePostalCodeRepository.js.map +1 -0
- package/lib/esm/main.d.ts +22 -4
- package/lib/esm/main.d.ts.map +1 -1
- package/lib/esm/main.js +46 -15
- package/lib/esm/main.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,12 +7,13 @@ Library TypeScript berperforma tinggi untuk mencari Kodepos Indonesia berdasarka
|
|
|
7
7
|
|
|
8
8
|
## Fitur Utama 🚀
|
|
9
9
|
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
10
|
+
- **Hybrid Search**: Pilih antara pencarian **Local** (offline & super cepat) atau **Remote** (real-time dari situs resmi).
|
|
11
|
+
- **Offline-First**: Tidak memerlukan koneksi internet untuk pencarian data lokal (~80.000+ data).
|
|
12
|
+
- **Fuzzy Search**: Cerdas menangani typo menggunakan Fuse.js (Mode Local).
|
|
13
|
+
- **Inverted Index**: Pencarian kata kunci instan dengan performa tinggi.
|
|
12
14
|
- **Lazy Loading**: Hanya memuat data provinsi yang dibutuhkan untuk menghemat RAM.
|
|
13
15
|
- **Structured Search**: Pencarian spesifik berdasarkan Provinsi, Kota, Kecamatan, atau Desa.
|
|
14
16
|
- **CLI Tool**: Cari kodepos langsung dari terminal.
|
|
15
|
-
- **High Performance**: Indexing internal untuk pencarian kodepos instan.
|
|
16
17
|
|
|
17
18
|
## Instalasi
|
|
18
19
|
|
|
@@ -29,8 +30,11 @@ Gunakan fungsi `search` global yang sudah dioptimalkan dengan cache internal.
|
|
|
29
30
|
```typescript
|
|
30
31
|
import { search, searchByCode } from '@damarkuncoro/posindonesia';
|
|
31
32
|
|
|
32
|
-
// 🔍 Pencarian
|
|
33
|
-
const
|
|
33
|
+
// 🔍 Pencarian Lokal (Default, Offline, Super Cepat)
|
|
34
|
+
const localResults = await search(['Gambir', 'Jakarta Pusat']);
|
|
35
|
+
|
|
36
|
+
// 🌐 Pencarian Remote (Real-time dari situs Pos Indonesia)
|
|
37
|
+
const remoteResults = await search('Gambir', { source: 'remote' });
|
|
34
38
|
|
|
35
39
|
// 🧠 Pencarian Fuzzy (menangani typo: 'Gmbir' -> 'Gambir')
|
|
36
40
|
const fuzzy = await search('Gmbir', { useFuzzy: true });
|
|
@@ -41,9 +45,8 @@ const structured = await search({
|
|
|
41
45
|
city: 'Jakarta Pusat'
|
|
42
46
|
});
|
|
43
47
|
|
|
44
|
-
// ⚡ Pencarian Spesifik Provinsi (
|
|
45
|
-
|
|
46
|
-
const dki = await search('Gambir', { provinceCode: '31' });
|
|
48
|
+
// ⚡ Pencarian Spesifik Provinsi (Nama atau Kode)
|
|
49
|
+
const byProvince = await search('Bandung', { province: 'Jawa Barat' });
|
|
47
50
|
|
|
48
51
|
// 🔢 Pencarian berdasarkan Kodepos (Instan/Indexed)
|
|
49
52
|
const byCode = await searchByCode('10110');
|
|
@@ -86,14 +89,14 @@ const results = await searchUseCase.execute(['Bandung']);
|
|
|
86
89
|
Anda dapat menggunakan library ini langsung dari terminal tanpa menulis kode.
|
|
87
90
|
|
|
88
91
|
```bash
|
|
89
|
-
# Mencari berdasarkan kata kunci
|
|
92
|
+
# Mencari berdasarkan kata kunci (Mode Lokal)
|
|
90
93
|
npx posindonesia search Gambir Jakarta
|
|
91
94
|
|
|
95
|
+
# Mencari secara real-time dari situs resmi
|
|
96
|
+
npx posindonesia search Gambir --remote
|
|
97
|
+
|
|
92
98
|
# Mencari dengan filter provinsi dan mode fuzzy
|
|
93
99
|
npx posindonesia search Gmbir -p 31 --fuzzy
|
|
94
|
-
|
|
95
|
-
# Mencari berdasarkan kodepos
|
|
96
|
-
npx posindonesia code 10110
|
|
97
100
|
```
|
|
98
101
|
|
|
99
102
|
## Skema Data
|
package/lib/cjs/cli.js
CHANGED
|
@@ -18,12 +18,14 @@ program
|
|
|
18
18
|
.argument('<keywords...>', 'Keywords to search (e.g. Gambir Jakarta)')
|
|
19
19
|
.option('-p, --province <code2>', 'Limit search to specific province code (e.g. 31)')
|
|
20
20
|
.option('-f, --fuzzy', 'Enable fuzzy search')
|
|
21
|
+
.option('-r, --remote', 'Fetch real-time data from Pos Indonesia')
|
|
21
22
|
.action(async (keywords, options) => {
|
|
22
23
|
try {
|
|
23
|
-
console.log(chalk_1.default.blue(`Searching for: ${keywords.join(', ')}...`));
|
|
24
|
+
console.log(chalk_1.default.blue(`Searching for: ${keywords.join(', ')} (${options.remote ? 'Remote' : 'Local'})...`));
|
|
24
25
|
const results = await (0, main_js_1.search)(keywords, {
|
|
25
26
|
provinceCode: options.province,
|
|
26
|
-
useFuzzy: options.fuzzy
|
|
27
|
+
useFuzzy: options.fuzzy,
|
|
28
|
+
source: options.remote ? 'remote' : 'local'
|
|
27
29
|
});
|
|
28
30
|
if (results.length === 0) {
|
|
29
31
|
console.log(chalk_1.default.yellow('No results found.'));
|
|
@@ -44,10 +46,14 @@ program
|
|
|
44
46
|
.description('Search by specific postal code or administrative code')
|
|
45
47
|
.argument('<code>', 'The code to search for')
|
|
46
48
|
.option('-p, --province <code2>', 'Limit search to specific province code')
|
|
49
|
+
.option('-r, --remote', 'Fetch real-time data from Pos Indonesia')
|
|
47
50
|
.action(async (code, options) => {
|
|
48
51
|
try {
|
|
49
|
-
console.log(chalk_1.default.blue(`Searching for code: ${code}...`));
|
|
50
|
-
const results = await (0, main_js_1.searchByCode)(code,
|
|
52
|
+
console.log(chalk_1.default.blue(`Searching for code: ${code} (${options.remote ? 'Remote' : 'Local'})...`));
|
|
53
|
+
const results = await (0, main_js_1.searchByCode)(code, {
|
|
54
|
+
provinceCode: options.province,
|
|
55
|
+
source: options.remote ? 'remote' : 'local'
|
|
56
|
+
});
|
|
51
57
|
if (results.length === 0) {
|
|
52
58
|
console.log(chalk_1.default.yellow('No results found.'));
|
|
53
59
|
return;
|
package/lib/cjs/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";;;;;;AACA,yCAAoC;AACpC,uCAAiD;AACjD,kDAA0B;AAE1B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,4CAA4C,CAAC;KACzD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,QAAQ,CAAC,eAAe,EAAE,0CAA0C,CAAC;KACrE,MAAM,CAAC,wBAAwB,EAAE,kDAAkD,CAAC;KACpF,MAAM,CAAC,aAAa,EAAE,qBAAqB,CAAC;KAC5C,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IAClC,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,kBAAkB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PostalCode } from '../../domain/models/PostalCode.js';
|
|
2
|
+
import { SearchableRepository, PostalCodeFilter } from '../../domain/repositories/PostalCodeRepository.js';
|
|
3
|
+
import { ApiConfig } from '../external/PosIndonesiaApi.js';
|
|
4
|
+
/**
|
|
5
|
+
* Implementation of SearchableRepository that fetches data directly from Pos Indonesia website.
|
|
6
|
+
* This is useful for real-time data but requires an internet connection.
|
|
7
|
+
*/
|
|
8
|
+
export declare class RemotePostalCodeRepository implements SearchableRepository {
|
|
9
|
+
private readonly apiConfig;
|
|
10
|
+
constructor(apiConfig?: ApiConfig);
|
|
11
|
+
/**
|
|
12
|
+
* Search by keywords via remote scraping.
|
|
13
|
+
*/
|
|
14
|
+
findByKeywords(keywords: string[], _provinceCode?: string): Promise<PostalCode[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Search by specific code via remote scraping.
|
|
17
|
+
*/
|
|
18
|
+
findByCode(code: string, provinceCode?: string): Promise<PostalCode[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Filtered search via remote scraping (approximated by keywords).
|
|
21
|
+
*/
|
|
22
|
+
findByFilter(filter: PostalCodeFilter, provinceCode?: string): Promise<PostalCode[]>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=RemotePostalCodeRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemotePostalCodeRepository.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/repositories/RemotePostalCodeRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AAC3G,OAAO,EAAuB,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAGhF;;;GAGG;AACH,qBAAa,0BAA2B,YAAW,oBAAoB;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,SAAS,GAAE,SAAc;IAIrC;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAmBvF;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAI5E;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAW3F"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RemotePostalCodeRepository = void 0;
|
|
4
|
+
const PostalCode_js_1 = require("../../domain/models/PostalCode.js");
|
|
5
|
+
const PosIndonesiaApi_js_1 = require("../external/PosIndonesiaApi.js");
|
|
6
|
+
const HtmlParser_js_1 = require("../parsers/HtmlParser.js");
|
|
7
|
+
/**
|
|
8
|
+
* Implementation of SearchableRepository that fetches data directly from Pos Indonesia website.
|
|
9
|
+
* This is useful for real-time data but requires an internet connection.
|
|
10
|
+
*/
|
|
11
|
+
class RemotePostalCodeRepository {
|
|
12
|
+
constructor(apiConfig = {}) {
|
|
13
|
+
this.apiConfig = apiConfig;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Search by keywords via remote scraping.
|
|
17
|
+
*/
|
|
18
|
+
async findByKeywords(keywords, _provinceCode) {
|
|
19
|
+
// Pos Indonesia API takes a single keyword string
|
|
20
|
+
const searchString = keywords.join(' ');
|
|
21
|
+
const html = await (0, PosIndonesiaApi_js_1.fetchPostalCodeHtml)(searchString, undefined, this.apiConfig);
|
|
22
|
+
const rawData = (0, HtmlParser_js_1.parsePostalCodeTable)(html);
|
|
23
|
+
return rawData.map(item => new PostalCode_js_1.PostalCode({
|
|
24
|
+
postalCode: item.kodepos,
|
|
25
|
+
province: item.provinsi,
|
|
26
|
+
provinceCode: '', // Remote doesn't provide Kemendagri codes easily
|
|
27
|
+
city: item.kabupaten_kota,
|
|
28
|
+
cityCode: '',
|
|
29
|
+
district: item.kecamatan,
|
|
30
|
+
districtCode: '',
|
|
31
|
+
village: item.desa_kelurahan,
|
|
32
|
+
villageCode: ''
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Search by specific code via remote scraping.
|
|
37
|
+
*/
|
|
38
|
+
async findByCode(code, provinceCode) {
|
|
39
|
+
return this.findByKeywords([code], provinceCode);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Filtered search via remote scraping (approximated by keywords).
|
|
43
|
+
*/
|
|
44
|
+
async findByFilter(filter, provinceCode) {
|
|
45
|
+
const keywords = [
|
|
46
|
+
filter.postalCode,
|
|
47
|
+
filter.village,
|
|
48
|
+
filter.district,
|
|
49
|
+
filter.city,
|
|
50
|
+
filter.province
|
|
51
|
+
].filter(Boolean);
|
|
52
|
+
return this.findByKeywords(keywords, provinceCode);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.RemotePostalCodeRepository = RemotePostalCodeRepository;
|
|
56
|
+
//# sourceMappingURL=RemotePostalCodeRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemotePostalCodeRepository.js","sourceRoot":"","sources":["../../../../src/infrastructure/repositories/RemotePostalCodeRepository.ts"],"names":[],"mappings":";;;AAAA,qEAA+D;AAE/D,uEAAgF;AAChF,4DAAgE;AAEhE;;;GAGG;AACH,MAAa,0BAA0B;IAGrC,YAAY,YAAuB,EAAE;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,QAAkB,EAAE,aAAsB;QAC7D,kDAAkD;QAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,IAAA,wCAAmB,EAAC,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,IAAA,oCAAoB,EAAC,IAAI,CAAC,CAAC;QAE3C,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,0BAAU,CAAC;YACxC,UAAU,EAAE,IAAI,CAAC,OAAO;YACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,YAAY,EAAE,EAAE,EAAE,iDAAiD;YACnE,IAAI,EAAE,IAAI,CAAC,cAAc;YACzB,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,YAAY,EAAE,EAAE;YAChB,OAAO,EAAE,IAAI,CAAC,cAAc;YAC5B,WAAW,EAAE,EAAE;SAChB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,YAAqB;QAClD,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,MAAwB,EAAE,YAAqB;QAChE,MAAM,QAAQ,GAAG;YACf,MAAM,CAAC,UAAU;YACjB,MAAM,CAAC,OAAO;YACd,MAAM,CAAC,QAAQ;YACf,MAAM,CAAC,IAAI;YACX,MAAM,CAAC,QAAQ;SAChB,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;QAE9B,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACrD,CAAC;CACF;AAlDD,gEAkDC"}
|
package/lib/cjs/main.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TsPostalCodeRepository, TsRepoConfig } from './infrastructure/repositories/TsPostalCodeRepository.js';
|
|
2
|
+
import { RemotePostalCodeRepository } from './infrastructure/repositories/RemotePostalCodeRepository.js';
|
|
2
3
|
import { PostalCode } from './domain/models/PostalCode.js';
|
|
3
4
|
import { PostalCodeFilter } from './domain/repositories/PostalCodeRepository.js';
|
|
4
5
|
export * from './domain/models/PostalCode.js';
|
|
@@ -8,22 +9,34 @@ export * from './domain/services/Logger.js';
|
|
|
8
9
|
export * from './domain/errors/PostalCodeError.js';
|
|
9
10
|
export * from './application/use-cases/SearchPostalCode.js';
|
|
10
11
|
export { TsPostalCodeRepository, type TsRepoConfig };
|
|
12
|
+
export { RemotePostalCodeRepository };
|
|
11
13
|
export { TsDataProvider } from './infrastructure/data-providers/TsDataProvider.js';
|
|
12
14
|
export * from './types.js';
|
|
13
15
|
export interface SearchOptions {
|
|
14
16
|
province?: string;
|
|
15
17
|
provinceCode?: string;
|
|
16
18
|
useFuzzy?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Data source to use for searching.
|
|
21
|
+
* - 'local': Fast, offline search using static data (Default).
|
|
22
|
+
* - 'remote': Real-time search by scraping Pos Indonesia website (Requires internet).
|
|
23
|
+
* @default 'local'
|
|
24
|
+
*/
|
|
25
|
+
source?: 'local' | 'remote';
|
|
17
26
|
}
|
|
18
27
|
/**
|
|
19
28
|
* Searches for postal codes based on various criteria.
|
|
20
29
|
* This is the primary, recommended function for all search operations.
|
|
21
30
|
*
|
|
22
31
|
* @example
|
|
23
|
-
* // Search by keywords
|
|
32
|
+
* // Search by keywords (Local)
|
|
24
33
|
* await search(['Gambir', 'Jakarta Pusat']);
|
|
25
34
|
*
|
|
26
35
|
* @example
|
|
36
|
+
* // Real-time search from Pos Indonesia (Remote)
|
|
37
|
+
* await search('Gambir', { source: 'remote' });
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
27
40
|
* // Fuzzy search for a typo
|
|
28
41
|
* await search('Gmbir', { useFuzzy: true });
|
|
29
42
|
*
|
|
@@ -36,7 +49,7 @@ export interface SearchOptions {
|
|
|
36
49
|
* await search('Bandung', { province: 'Jawa Barat' });
|
|
37
50
|
*
|
|
38
51
|
* @param keywords - A search term, an array of terms, or a structured filter object.
|
|
39
|
-
* @param options - Configuration for the search, such as province filter
|
|
52
|
+
* @param options - Configuration for the search, such as province filter, fuzzy mode, or source.
|
|
40
53
|
* @returns A promise that resolves to an array of `PostalCode` instances.
|
|
41
54
|
*/
|
|
42
55
|
export declare function search(keywords: string | string[] | PostalCodeFilter, options?: SearchOptions): Promise<PostalCode[]>;
|
|
@@ -45,19 +58,24 @@ export declare function search(keywords: string | string[] | PostalCodeFilter, o
|
|
|
45
58
|
* This is optimized for searching by a 5-digit postal code or administrative codes.
|
|
46
59
|
*
|
|
47
60
|
* @example
|
|
48
|
-
* // Find by postal code
|
|
61
|
+
* // Find by postal code (Local)
|
|
49
62
|
* await searchByCode('10110');
|
|
50
63
|
*
|
|
51
64
|
* @example
|
|
65
|
+
* // Find by postal code (Remote)
|
|
66
|
+
* await searchByCode('10110', { source: 'remote' });
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
52
69
|
* // Find by village code within a specific province
|
|
53
70
|
* await searchByCode('3171010001', { province: 'DKI Jakarta' });
|
|
54
71
|
*
|
|
55
72
|
* @param code - The code to search for (e.g., '10110').
|
|
56
|
-
* @param options - Optional configuration to narrow down the search by province.
|
|
73
|
+
* @param options - Optional configuration to narrow down the search by province or specify source.
|
|
57
74
|
* @returns A promise that resolves to an array of `PostalCode` instances.
|
|
58
75
|
*/
|
|
59
76
|
export declare function searchByCode(code: string, options?: {
|
|
60
77
|
province?: string;
|
|
61
78
|
provinceCode?: string;
|
|
79
|
+
source?: 'local' | 'remote';
|
|
62
80
|
}): Promise<PostalCode[]>;
|
|
63
81
|
//# sourceMappingURL=main.d.ts.map
|
package/lib/cjs/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,yDAAyD,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,yDAAyD,CAAC;AAC/G,OAAO,EAAE,0BAA0B,EAAE,MAAM,6DAA6D,CAAC;AAEzG,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAwB,MAAM,+CAA+C,CAAC;AAGvG,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACtB,MAAM,+CAA+C,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oCAAoC,CAAC;AACnD,cAAc,6CAA6C,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,KAAK,YAAY,EAAE,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,cAAc,YAAY,CAAC;AAY3B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,gBAAgB,EAC9C,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,UAAU,EAAE,CAAC,CAwCvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CAAO,GACtF,OAAO,CAAC,UAAU,EAAE,CAAC,CAyBvB"}
|
package/lib/cjs/main.js
CHANGED
|
@@ -14,11 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.TsDataProvider = exports.TsPostalCodeRepository = void 0;
|
|
17
|
+
exports.TsDataProvider = exports.RemotePostalCodeRepository = exports.TsPostalCodeRepository = void 0;
|
|
18
18
|
exports.search = search;
|
|
19
19
|
exports.searchByCode = searchByCode;
|
|
20
20
|
const TsPostalCodeRepository_js_1 = require("./infrastructure/repositories/TsPostalCodeRepository.js");
|
|
21
21
|
Object.defineProperty(exports, "TsPostalCodeRepository", { enumerable: true, get: function () { return TsPostalCodeRepository_js_1.TsPostalCodeRepository; } });
|
|
22
|
+
const RemotePostalCodeRepository_js_1 = require("./infrastructure/repositories/RemotePostalCodeRepository.js");
|
|
23
|
+
Object.defineProperty(exports, "RemotePostalCodeRepository", { enumerable: true, get: function () { return RemotePostalCodeRepository_js_1.RemotePostalCodeRepository; } });
|
|
22
24
|
const SearchPostalCode_js_1 = require("./application/use-cases/SearchPostalCode.js");
|
|
23
25
|
// Re-export core components
|
|
24
26
|
__exportStar(require("./domain/models/PostalCode.js"), exports);
|
|
@@ -36,15 +38,20 @@ const index_js_1 = require("./data/index.js");
|
|
|
36
38
|
*/
|
|
37
39
|
let globalStandardRepo = null;
|
|
38
40
|
let globalFuzzyRepo = null;
|
|
41
|
+
let globalRemoteRepo = null;
|
|
39
42
|
/**
|
|
40
43
|
* Searches for postal codes based on various criteria.
|
|
41
44
|
* This is the primary, recommended function for all search operations.
|
|
42
45
|
*
|
|
43
46
|
* @example
|
|
44
|
-
* // Search by keywords
|
|
47
|
+
* // Search by keywords (Local)
|
|
45
48
|
* await search(['Gambir', 'Jakarta Pusat']);
|
|
46
49
|
*
|
|
47
50
|
* @example
|
|
51
|
+
* // Real-time search from Pos Indonesia (Remote)
|
|
52
|
+
* await search('Gambir', { source: 'remote' });
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
48
55
|
* // Fuzzy search for a typo
|
|
49
56
|
* await search('Gmbir', { useFuzzy: true });
|
|
50
57
|
*
|
|
@@ -57,23 +64,32 @@ let globalFuzzyRepo = null;
|
|
|
57
64
|
* await search('Bandung', { province: 'Jawa Barat' });
|
|
58
65
|
*
|
|
59
66
|
* @param keywords - A search term, an array of terms, or a structured filter object.
|
|
60
|
-
* @param options - Configuration for the search, such as province filter
|
|
67
|
+
* @param options - Configuration for the search, such as province filter, fuzzy mode, or source.
|
|
61
68
|
* @returns A promise that resolves to an array of `PostalCode` instances.
|
|
62
69
|
*/
|
|
63
70
|
async function search(keywords, options = {}) {
|
|
64
|
-
const
|
|
71
|
+
const source = options.source ?? 'local';
|
|
65
72
|
let repo;
|
|
66
|
-
if (
|
|
67
|
-
if (!
|
|
68
|
-
|
|
73
|
+
if (source === 'remote') {
|
|
74
|
+
if (!globalRemoteRepo) {
|
|
75
|
+
globalRemoteRepo = new RemotePostalCodeRepository_js_1.RemotePostalCodeRepository();
|
|
69
76
|
}
|
|
70
|
-
repo =
|
|
77
|
+
repo = globalRemoteRepo;
|
|
71
78
|
}
|
|
72
79
|
else {
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
const isFuzzy = !!options.useFuzzy;
|
|
81
|
+
if (isFuzzy) {
|
|
82
|
+
if (!globalFuzzyRepo) {
|
|
83
|
+
globalFuzzyRepo = new TsPostalCodeRepository_js_1.TsPostalCodeRepository({ useFuzzy: true });
|
|
84
|
+
}
|
|
85
|
+
repo = globalFuzzyRepo;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
if (!globalStandardRepo) {
|
|
89
|
+
globalStandardRepo = new TsPostalCodeRepository_js_1.TsPostalCodeRepository({ useFuzzy: false });
|
|
90
|
+
}
|
|
91
|
+
repo = globalStandardRepo;
|
|
75
92
|
}
|
|
76
|
-
repo = globalStandardRepo;
|
|
77
93
|
}
|
|
78
94
|
const useCase = new SearchPostalCode_js_1.SearchPostalCode(repo);
|
|
79
95
|
// Resolve province name to code
|
|
@@ -93,22 +109,37 @@ async function search(keywords, options = {}) {
|
|
|
93
109
|
* This is optimized for searching by a 5-digit postal code or administrative codes.
|
|
94
110
|
*
|
|
95
111
|
* @example
|
|
96
|
-
* // Find by postal code
|
|
112
|
+
* // Find by postal code (Local)
|
|
97
113
|
* await searchByCode('10110');
|
|
98
114
|
*
|
|
99
115
|
* @example
|
|
116
|
+
* // Find by postal code (Remote)
|
|
117
|
+
* await searchByCode('10110', { source: 'remote' });
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
100
120
|
* // Find by village code within a specific province
|
|
101
121
|
* await searchByCode('3171010001', { province: 'DKI Jakarta' });
|
|
102
122
|
*
|
|
103
123
|
* @param code - The code to search for (e.g., '10110').
|
|
104
|
-
* @param options - Optional configuration to narrow down the search by province.
|
|
124
|
+
* @param options - Optional configuration to narrow down the search by province or specify source.
|
|
105
125
|
* @returns A promise that resolves to an array of `PostalCode` instances.
|
|
106
126
|
*/
|
|
107
127
|
async function searchByCode(code, options = {}) {
|
|
108
|
-
|
|
109
|
-
|
|
128
|
+
const source = options.source ?? 'local';
|
|
129
|
+
let repo;
|
|
130
|
+
if (source === 'remote') {
|
|
131
|
+
if (!globalRemoteRepo) {
|
|
132
|
+
globalRemoteRepo = new RemotePostalCodeRepository_js_1.RemotePostalCodeRepository();
|
|
133
|
+
}
|
|
134
|
+
repo = globalRemoteRepo;
|
|
110
135
|
}
|
|
111
|
-
|
|
136
|
+
else {
|
|
137
|
+
if (!globalStandardRepo) {
|
|
138
|
+
globalStandardRepo = new TsPostalCodeRepository_js_1.TsPostalCodeRepository();
|
|
139
|
+
}
|
|
140
|
+
repo = globalStandardRepo;
|
|
141
|
+
}
|
|
142
|
+
const useCase = new SearchPostalCode_js_1.SearchPostalCode(repo);
|
|
112
143
|
let resolvedProvinceCode = options.provinceCode;
|
|
113
144
|
if (options.province && !resolvedProvinceCode) {
|
|
114
145
|
const upperProvince = options.province.toUpperCase().replace(/\s+/g, '_');
|
package/lib/cjs/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/cli.js
CHANGED
|
@@ -13,12 +13,14 @@ program
|
|
|
13
13
|
.argument('<keywords...>', 'Keywords to search (e.g. Gambir Jakarta)')
|
|
14
14
|
.option('-p, --province <code2>', 'Limit search to specific province code (e.g. 31)')
|
|
15
15
|
.option('-f, --fuzzy', 'Enable fuzzy search')
|
|
16
|
+
.option('-r, --remote', 'Fetch real-time data from Pos Indonesia')
|
|
16
17
|
.action(async (keywords, options) => {
|
|
17
18
|
try {
|
|
18
|
-
console.log(chalk.blue(`Searching for: ${keywords.join(', ')}...`));
|
|
19
|
+
console.log(chalk.blue(`Searching for: ${keywords.join(', ')} (${options.remote ? 'Remote' : 'Local'})...`));
|
|
19
20
|
const results = await search(keywords, {
|
|
20
21
|
provinceCode: options.province,
|
|
21
|
-
useFuzzy: options.fuzzy
|
|
22
|
+
useFuzzy: options.fuzzy,
|
|
23
|
+
source: options.remote ? 'remote' : 'local'
|
|
22
24
|
});
|
|
23
25
|
if (results.length === 0) {
|
|
24
26
|
console.log(chalk.yellow('No results found.'));
|
|
@@ -39,10 +41,14 @@ program
|
|
|
39
41
|
.description('Search by specific postal code or administrative code')
|
|
40
42
|
.argument('<code>', 'The code to search for')
|
|
41
43
|
.option('-p, --province <code2>', 'Limit search to specific province code')
|
|
44
|
+
.option('-r, --remote', 'Fetch real-time data from Pos Indonesia')
|
|
42
45
|
.action(async (code, options) => {
|
|
43
46
|
try {
|
|
44
|
-
console.log(chalk.blue(`Searching for code: ${code}...`));
|
|
45
|
-
const results = await searchByCode(code,
|
|
47
|
+
console.log(chalk.blue(`Searching for code: ${code} (${options.remote ? 'Remote' : 'Local'})...`));
|
|
48
|
+
const results = await searchByCode(code, {
|
|
49
|
+
provinceCode: options.province,
|
|
50
|
+
source: options.remote ? 'remote' : 'local'
|
|
51
|
+
});
|
|
46
52
|
if (results.length === 0) {
|
|
47
53
|
console.log(chalk.yellow('No results found.'));
|
|
48
54
|
return;
|
package/lib/esm/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,4CAA4C,CAAC;KACzD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,QAAQ,CAAC,eAAe,EAAE,0CAA0C,CAAC;KACrE,MAAM,CAAC,wBAAwB,EAAE,kDAAkD,CAAC;KACpF,MAAM,CAAC,aAAa,EAAE,qBAAqB,CAAC;KAC5C,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IAClC,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PostalCode } from '../../domain/models/PostalCode.js';
|
|
2
|
+
import { SearchableRepository, PostalCodeFilter } from '../../domain/repositories/PostalCodeRepository.js';
|
|
3
|
+
import { ApiConfig } from '../external/PosIndonesiaApi.js';
|
|
4
|
+
/**
|
|
5
|
+
* Implementation of SearchableRepository that fetches data directly from Pos Indonesia website.
|
|
6
|
+
* This is useful for real-time data but requires an internet connection.
|
|
7
|
+
*/
|
|
8
|
+
export declare class RemotePostalCodeRepository implements SearchableRepository {
|
|
9
|
+
private readonly apiConfig;
|
|
10
|
+
constructor(apiConfig?: ApiConfig);
|
|
11
|
+
/**
|
|
12
|
+
* Search by keywords via remote scraping.
|
|
13
|
+
*/
|
|
14
|
+
findByKeywords(keywords: string[], _provinceCode?: string): Promise<PostalCode[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Search by specific code via remote scraping.
|
|
17
|
+
*/
|
|
18
|
+
findByCode(code: string, provinceCode?: string): Promise<PostalCode[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Filtered search via remote scraping (approximated by keywords).
|
|
21
|
+
*/
|
|
22
|
+
findByFilter(filter: PostalCodeFilter, provinceCode?: string): Promise<PostalCode[]>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=RemotePostalCodeRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemotePostalCodeRepository.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/repositories/RemotePostalCodeRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AAC3G,OAAO,EAAuB,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAGhF;;;GAGG;AACH,qBAAa,0BAA2B,YAAW,oBAAoB;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,SAAS,GAAE,SAAc;IAIrC;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAmBvF;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAI5E;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAW3F"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { PostalCode } from '../../domain/models/PostalCode.js';
|
|
2
|
+
import { fetchPostalCodeHtml } from '../external/PosIndonesiaApi.js';
|
|
3
|
+
import { parsePostalCodeTable } from '../parsers/HtmlParser.js';
|
|
4
|
+
/**
|
|
5
|
+
* Implementation of SearchableRepository that fetches data directly from Pos Indonesia website.
|
|
6
|
+
* This is useful for real-time data but requires an internet connection.
|
|
7
|
+
*/
|
|
8
|
+
export class RemotePostalCodeRepository {
|
|
9
|
+
constructor(apiConfig = {}) {
|
|
10
|
+
this.apiConfig = apiConfig;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Search by keywords via remote scraping.
|
|
14
|
+
*/
|
|
15
|
+
async findByKeywords(keywords, _provinceCode) {
|
|
16
|
+
// Pos Indonesia API takes a single keyword string
|
|
17
|
+
const searchString = keywords.join(' ');
|
|
18
|
+
const html = await fetchPostalCodeHtml(searchString, undefined, this.apiConfig);
|
|
19
|
+
const rawData = parsePostalCodeTable(html);
|
|
20
|
+
return rawData.map(item => new PostalCode({
|
|
21
|
+
postalCode: item.kodepos,
|
|
22
|
+
province: item.provinsi,
|
|
23
|
+
provinceCode: '', // Remote doesn't provide Kemendagri codes easily
|
|
24
|
+
city: item.kabupaten_kota,
|
|
25
|
+
cityCode: '',
|
|
26
|
+
district: item.kecamatan,
|
|
27
|
+
districtCode: '',
|
|
28
|
+
village: item.desa_kelurahan,
|
|
29
|
+
villageCode: ''
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Search by specific code via remote scraping.
|
|
34
|
+
*/
|
|
35
|
+
async findByCode(code, provinceCode) {
|
|
36
|
+
return this.findByKeywords([code], provinceCode);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Filtered search via remote scraping (approximated by keywords).
|
|
40
|
+
*/
|
|
41
|
+
async findByFilter(filter, provinceCode) {
|
|
42
|
+
const keywords = [
|
|
43
|
+
filter.postalCode,
|
|
44
|
+
filter.village,
|
|
45
|
+
filter.district,
|
|
46
|
+
filter.city,
|
|
47
|
+
filter.province
|
|
48
|
+
].filter(Boolean);
|
|
49
|
+
return this.findByKeywords(keywords, provinceCode);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=RemotePostalCodeRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemotePostalCodeRepository.js","sourceRoot":"","sources":["../../../../src/infrastructure/repositories/RemotePostalCodeRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAa,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE;;;GAGG;AACH,MAAM,OAAO,0BAA0B;IAGrC,YAAY,YAAuB,EAAE;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,QAAkB,EAAE,aAAsB;QAC7D,kDAAkD;QAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAE3C,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC;YACxC,UAAU,EAAE,IAAI,CAAC,OAAO;YACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,YAAY,EAAE,EAAE,EAAE,iDAAiD;YACnE,IAAI,EAAE,IAAI,CAAC,cAAc;YACzB,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,YAAY,EAAE,EAAE;YAChB,OAAO,EAAE,IAAI,CAAC,cAAc;YAC5B,WAAW,EAAE,EAAE;SAChB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,YAAqB;QAClD,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,MAAwB,EAAE,YAAqB;QAChE,MAAM,QAAQ,GAAG;YACf,MAAM,CAAC,UAAU;YACjB,MAAM,CAAC,OAAO;YACd,MAAM,CAAC,QAAQ;YACf,MAAM,CAAC,IAAI;YACX,MAAM,CAAC,QAAQ;SAChB,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;QAE9B,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACrD,CAAC;CACF"}
|
package/lib/esm/main.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TsPostalCodeRepository, TsRepoConfig } from './infrastructure/repositories/TsPostalCodeRepository.js';
|
|
2
|
+
import { RemotePostalCodeRepository } from './infrastructure/repositories/RemotePostalCodeRepository.js';
|
|
2
3
|
import { PostalCode } from './domain/models/PostalCode.js';
|
|
3
4
|
import { PostalCodeFilter } from './domain/repositories/PostalCodeRepository.js';
|
|
4
5
|
export * from './domain/models/PostalCode.js';
|
|
@@ -8,22 +9,34 @@ export * from './domain/services/Logger.js';
|
|
|
8
9
|
export * from './domain/errors/PostalCodeError.js';
|
|
9
10
|
export * from './application/use-cases/SearchPostalCode.js';
|
|
10
11
|
export { TsPostalCodeRepository, type TsRepoConfig };
|
|
12
|
+
export { RemotePostalCodeRepository };
|
|
11
13
|
export { TsDataProvider } from './infrastructure/data-providers/TsDataProvider.js';
|
|
12
14
|
export * from './types.js';
|
|
13
15
|
export interface SearchOptions {
|
|
14
16
|
province?: string;
|
|
15
17
|
provinceCode?: string;
|
|
16
18
|
useFuzzy?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Data source to use for searching.
|
|
21
|
+
* - 'local': Fast, offline search using static data (Default).
|
|
22
|
+
* - 'remote': Real-time search by scraping Pos Indonesia website (Requires internet).
|
|
23
|
+
* @default 'local'
|
|
24
|
+
*/
|
|
25
|
+
source?: 'local' | 'remote';
|
|
17
26
|
}
|
|
18
27
|
/**
|
|
19
28
|
* Searches for postal codes based on various criteria.
|
|
20
29
|
* This is the primary, recommended function for all search operations.
|
|
21
30
|
*
|
|
22
31
|
* @example
|
|
23
|
-
* // Search by keywords
|
|
32
|
+
* // Search by keywords (Local)
|
|
24
33
|
* await search(['Gambir', 'Jakarta Pusat']);
|
|
25
34
|
*
|
|
26
35
|
* @example
|
|
36
|
+
* // Real-time search from Pos Indonesia (Remote)
|
|
37
|
+
* await search('Gambir', { source: 'remote' });
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
27
40
|
* // Fuzzy search for a typo
|
|
28
41
|
* await search('Gmbir', { useFuzzy: true });
|
|
29
42
|
*
|
|
@@ -36,7 +49,7 @@ export interface SearchOptions {
|
|
|
36
49
|
* await search('Bandung', { province: 'Jawa Barat' });
|
|
37
50
|
*
|
|
38
51
|
* @param keywords - A search term, an array of terms, or a structured filter object.
|
|
39
|
-
* @param options - Configuration for the search, such as province filter
|
|
52
|
+
* @param options - Configuration for the search, such as province filter, fuzzy mode, or source.
|
|
40
53
|
* @returns A promise that resolves to an array of `PostalCode` instances.
|
|
41
54
|
*/
|
|
42
55
|
export declare function search(keywords: string | string[] | PostalCodeFilter, options?: SearchOptions): Promise<PostalCode[]>;
|
|
@@ -45,19 +58,24 @@ export declare function search(keywords: string | string[] | PostalCodeFilter, o
|
|
|
45
58
|
* This is optimized for searching by a 5-digit postal code or administrative codes.
|
|
46
59
|
*
|
|
47
60
|
* @example
|
|
48
|
-
* // Find by postal code
|
|
61
|
+
* // Find by postal code (Local)
|
|
49
62
|
* await searchByCode('10110');
|
|
50
63
|
*
|
|
51
64
|
* @example
|
|
65
|
+
* // Find by postal code (Remote)
|
|
66
|
+
* await searchByCode('10110', { source: 'remote' });
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
52
69
|
* // Find by village code within a specific province
|
|
53
70
|
* await searchByCode('3171010001', { province: 'DKI Jakarta' });
|
|
54
71
|
*
|
|
55
72
|
* @param code - The code to search for (e.g., '10110').
|
|
56
|
-
* @param options - Optional configuration to narrow down the search by province.
|
|
73
|
+
* @param options - Optional configuration to narrow down the search by province or specify source.
|
|
57
74
|
* @returns A promise that resolves to an array of `PostalCode` instances.
|
|
58
75
|
*/
|
|
59
76
|
export declare function searchByCode(code: string, options?: {
|
|
60
77
|
province?: string;
|
|
61
78
|
provinceCode?: string;
|
|
79
|
+
source?: 'local' | 'remote';
|
|
62
80
|
}): Promise<PostalCode[]>;
|
|
63
81
|
//# sourceMappingURL=main.d.ts.map
|
package/lib/esm/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,yDAAyD,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,yDAAyD,CAAC;AAC/G,OAAO,EAAE,0BAA0B,EAAE,MAAM,6DAA6D,CAAC;AAEzG,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAwB,MAAM,+CAA+C,CAAC;AAGvG,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACtB,MAAM,+CAA+C,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oCAAoC,CAAC;AACnD,cAAc,6CAA6C,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,KAAK,YAAY,EAAE,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,cAAc,YAAY,CAAC;AAY3B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,gBAAgB,EAC9C,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,UAAU,EAAE,CAAC,CAwCvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CAAO,GACtF,OAAO,CAAC,UAAU,EAAE,CAAC,CAyBvB"}
|
package/lib/esm/main.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TsPostalCodeRepository } from './infrastructure/repositories/TsPostalCodeRepository.js';
|
|
2
|
+
import { RemotePostalCodeRepository } from './infrastructure/repositories/RemotePostalCodeRepository.js';
|
|
2
3
|
import { SearchPostalCode } from './application/use-cases/SearchPostalCode.js';
|
|
3
4
|
// Re-export core components
|
|
4
5
|
export * from './domain/models/PostalCode.js';
|
|
@@ -7,6 +8,7 @@ export * from './domain/services/Logger.js';
|
|
|
7
8
|
export * from './domain/errors/PostalCodeError.js';
|
|
8
9
|
export * from './application/use-cases/SearchPostalCode.js';
|
|
9
10
|
export { TsPostalCodeRepository };
|
|
11
|
+
export { RemotePostalCodeRepository };
|
|
10
12
|
export { TsDataProvider } from './infrastructure/data-providers/TsDataProvider.js';
|
|
11
13
|
export * from './types.js';
|
|
12
14
|
import { PROVINCE_ALIAS_MAP } from './data/index.js';
|
|
@@ -16,15 +18,20 @@ import { PROVINCE_ALIAS_MAP } from './data/index.js';
|
|
|
16
18
|
*/
|
|
17
19
|
let globalStandardRepo = null;
|
|
18
20
|
let globalFuzzyRepo = null;
|
|
21
|
+
let globalRemoteRepo = null;
|
|
19
22
|
/**
|
|
20
23
|
* Searches for postal codes based on various criteria.
|
|
21
24
|
* This is the primary, recommended function for all search operations.
|
|
22
25
|
*
|
|
23
26
|
* @example
|
|
24
|
-
* // Search by keywords
|
|
27
|
+
* // Search by keywords (Local)
|
|
25
28
|
* await search(['Gambir', 'Jakarta Pusat']);
|
|
26
29
|
*
|
|
27
30
|
* @example
|
|
31
|
+
* // Real-time search from Pos Indonesia (Remote)
|
|
32
|
+
* await search('Gambir', { source: 'remote' });
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
28
35
|
* // Fuzzy search for a typo
|
|
29
36
|
* await search('Gmbir', { useFuzzy: true });
|
|
30
37
|
*
|
|
@@ -37,23 +44,32 @@ let globalFuzzyRepo = null;
|
|
|
37
44
|
* await search('Bandung', { province: 'Jawa Barat' });
|
|
38
45
|
*
|
|
39
46
|
* @param keywords - A search term, an array of terms, or a structured filter object.
|
|
40
|
-
* @param options - Configuration for the search, such as province filter
|
|
47
|
+
* @param options - Configuration for the search, such as province filter, fuzzy mode, or source.
|
|
41
48
|
* @returns A promise that resolves to an array of `PostalCode` instances.
|
|
42
49
|
*/
|
|
43
50
|
export async function search(keywords, options = {}) {
|
|
44
|
-
const
|
|
51
|
+
const source = options.source ?? 'local';
|
|
45
52
|
let repo;
|
|
46
|
-
if (
|
|
47
|
-
if (!
|
|
48
|
-
|
|
53
|
+
if (source === 'remote') {
|
|
54
|
+
if (!globalRemoteRepo) {
|
|
55
|
+
globalRemoteRepo = new RemotePostalCodeRepository();
|
|
49
56
|
}
|
|
50
|
-
repo =
|
|
57
|
+
repo = globalRemoteRepo;
|
|
51
58
|
}
|
|
52
59
|
else {
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
const isFuzzy = !!options.useFuzzy;
|
|
61
|
+
if (isFuzzy) {
|
|
62
|
+
if (!globalFuzzyRepo) {
|
|
63
|
+
globalFuzzyRepo = new TsPostalCodeRepository({ useFuzzy: true });
|
|
64
|
+
}
|
|
65
|
+
repo = globalFuzzyRepo;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
if (!globalStandardRepo) {
|
|
69
|
+
globalStandardRepo = new TsPostalCodeRepository({ useFuzzy: false });
|
|
70
|
+
}
|
|
71
|
+
repo = globalStandardRepo;
|
|
55
72
|
}
|
|
56
|
-
repo = globalStandardRepo;
|
|
57
73
|
}
|
|
58
74
|
const useCase = new SearchPostalCode(repo);
|
|
59
75
|
// Resolve province name to code
|
|
@@ -73,22 +89,37 @@ export async function search(keywords, options = {}) {
|
|
|
73
89
|
* This is optimized for searching by a 5-digit postal code or administrative codes.
|
|
74
90
|
*
|
|
75
91
|
* @example
|
|
76
|
-
* // Find by postal code
|
|
92
|
+
* // Find by postal code (Local)
|
|
77
93
|
* await searchByCode('10110');
|
|
78
94
|
*
|
|
79
95
|
* @example
|
|
96
|
+
* // Find by postal code (Remote)
|
|
97
|
+
* await searchByCode('10110', { source: 'remote' });
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
80
100
|
* // Find by village code within a specific province
|
|
81
101
|
* await searchByCode('3171010001', { province: 'DKI Jakarta' });
|
|
82
102
|
*
|
|
83
103
|
* @param code - The code to search for (e.g., '10110').
|
|
84
|
-
* @param options - Optional configuration to narrow down the search by province.
|
|
104
|
+
* @param options - Optional configuration to narrow down the search by province or specify source.
|
|
85
105
|
* @returns A promise that resolves to an array of `PostalCode` instances.
|
|
86
106
|
*/
|
|
87
107
|
export async function searchByCode(code, options = {}) {
|
|
88
|
-
|
|
89
|
-
|
|
108
|
+
const source = options.source ?? 'local';
|
|
109
|
+
let repo;
|
|
110
|
+
if (source === 'remote') {
|
|
111
|
+
if (!globalRemoteRepo) {
|
|
112
|
+
globalRemoteRepo = new RemotePostalCodeRepository();
|
|
113
|
+
}
|
|
114
|
+
repo = globalRemoteRepo;
|
|
90
115
|
}
|
|
91
|
-
|
|
116
|
+
else {
|
|
117
|
+
if (!globalStandardRepo) {
|
|
118
|
+
globalStandardRepo = new TsPostalCodeRepository();
|
|
119
|
+
}
|
|
120
|
+
repo = globalStandardRepo;
|
|
121
|
+
}
|
|
122
|
+
const useCase = new SearchPostalCode(repo);
|
|
92
123
|
let resolvedProvinceCode = options.provinceCode;
|
|
93
124
|
if (options.province && !resolvedProvinceCode) {
|
|
94
125
|
const upperProvince = options.province.toUpperCase().replace(/\s+/g, '_');
|
package/lib/esm/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAgB,MAAM,yDAAyD,CAAC;AAC/G,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAI/E,4BAA4B;AAC5B,cAAc,+BAA+B,CAAC;AAO9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oCAAoC,CAAC;AACnD,cAAc,6CAA6C,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;GAGG;AACH,IAAI,kBAAkB,GAAkC,IAAI,CAAC;AAC7D,IAAI,eAAe,GAAkC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"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"}
|