@cp949/japanpost-react 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,8 @@
1
- <!-- This file is generated by `pnpm readme:package`. Edit docs/README.en.md and docs/README.ko.md instead. -->
2
-
3
1
  # @cp949/japanpost-react
4
2
 
5
- [English](#english) | [한국어](#한국어)
3
+ [한국어 README](./README.ko.md)
6
4
 
7
- ---
8
-
9
- ## English
5
+ <!-- This file is generated by `pnpm readme:package`. Edit docs/README.en.md and docs/README.ko.md instead. -->
10
6
 
11
7
  React + TypeScript hooks and headless inputs for Japan postal-code and address
12
8
  lookup.
@@ -27,83 +23,112 @@ pnpm add @cp949/japanpost-react
27
23
 
28
24
  ```tsx
29
25
  import { useJapanPostalCode } from "@cp949/japanpost-react";
30
- import type { JapanAddressDataSource } from "@cp949/japanpost-react";
26
+ import type {
27
+ JapanAddressDataSource,
28
+ JapanAddressRequestOptions,
29
+ JapanAddress,
30
+ Page,
31
+ } from "@cp949/japanpost-react";
31
32
  import { createJapanAddressError } from "@cp949/japanpost-react";
32
33
 
33
34
  // The only supported integration model is a real server-backed flow.
34
35
  // Point the data source at your own backend API.
36
+ // On beta-compatible backends, blank addresszip searches and postal-code misses
37
+ // may return HTTP 200 with an empty page. Keep those as successful Page results.
38
+ // The status mapping below applies only to non-OK responses.
39
+ function isAbortError(error: unknown): boolean {
40
+ return error instanceof DOMException && error.name === "AbortError";
41
+ }
42
+
43
+ function resolveErrorCode(path: string, status: number) {
44
+ if (status === 404) {
45
+ return "not_found";
46
+ }
47
+
48
+ if (status === 504) {
49
+ return "timeout";
50
+ }
51
+
52
+ if (status === 400) {
53
+ return path === "/q/japanpost/searchcode"
54
+ ? "invalid_postal_code"
55
+ : "invalid_query";
56
+ }
57
+
58
+ return "data_source_error";
59
+ }
60
+
61
+ async function readPage(
62
+ path: string,
63
+ request: unknown,
64
+ options?: JapanAddressRequestOptions,
65
+ ): Promise<Page<JapanAddress>> {
66
+ let res: Response;
67
+
68
+ try {
69
+ res = await fetch(path, {
70
+ method: "POST",
71
+ headers: {
72
+ "content-type": "application/json",
73
+ },
74
+ body: JSON.stringify(request),
75
+ signal: options?.signal,
76
+ });
77
+ } catch (error) {
78
+ throw createJapanAddressError(
79
+ isAbortError(error) ? "timeout" : "network_error",
80
+ isAbortError(error) ? "Request timed out" : "Network request failed",
81
+ {
82
+ cause: error,
83
+ },
84
+ );
85
+ }
86
+
87
+ if (!res.ok) {
88
+ const message = `Request failed with status ${res.status}`;
89
+
90
+ throw createJapanAddressError(resolveErrorCode(path, res.status), message, {
91
+ status: res.status,
92
+ });
93
+ }
94
+
95
+ let payload: unknown;
96
+
97
+ try {
98
+ payload = await res.json();
99
+ } catch (error) {
100
+ throw createJapanAddressError(
101
+ "bad_response",
102
+ "Response payload was not valid JSON",
103
+ {
104
+ cause: error,
105
+ },
106
+ );
107
+ }
108
+
109
+ if (
110
+ typeof payload !== "object" ||
111
+ payload === null ||
112
+ !Array.isArray((payload as { elements?: unknown }).elements) ||
113
+ typeof (payload as { totalElements?: unknown }).totalElements !== "number" ||
114
+ typeof (payload as { pageNumber?: unknown }).pageNumber !== "number" ||
115
+ typeof (payload as { rowsPerPage?: unknown }).rowsPerPage !== "number"
116
+ ) {
117
+ throw createJapanAddressError(
118
+ "bad_response",
119
+ "Response payload must include a valid page payload",
120
+ );
121
+ }
122
+
123
+ return payload as Page<JapanAddress>;
124
+ }
125
+
35
126
  const dataSource: JapanAddressDataSource = {
36
- async lookupPostalCode(postalCode) {
37
- const res = await fetch(`/searchcode/${postalCode}`);
38
- if (!res.ok) {
39
- const message = `Postal code lookup failed with status ${res.status}`;
40
-
41
- if (res.status === 400) {
42
- throw createJapanAddressError("invalid_postal_code", message, {
43
- status: res.status,
44
- });
45
- }
46
-
47
- if (res.status === 404) {
48
- throw createJapanAddressError("not_found", message, {
49
- status: res.status,
50
- });
51
- }
52
-
53
- if (res.status === 504) {
54
- throw createJapanAddressError("timeout", message, {
55
- status: res.status,
56
- });
57
- }
58
-
59
- throw createJapanAddressError("data_source_error", message, {
60
- status: res.status,
61
- });
62
- }
63
- const payload = await res.json();
64
- if (!Array.isArray(payload.addresses)) {
65
- throw createJapanAddressError(
66
- "bad_response",
67
- "Postal code lookup returned an invalid payload",
68
- );
69
- }
70
- return payload.addresses;
127
+ async lookupPostalCode(request, options) {
128
+ return readPage(`/q/japanpost/searchcode`, request, options);
71
129
  },
72
- async searchAddress(query) {
73
- const res = await fetch(`/addresszip?q=${encodeURIComponent(query)}`);
74
- if (!res.ok) {
75
- const message = `Address search failed with status ${res.status}`;
76
-
77
- if (res.status === 400) {
78
- throw createJapanAddressError("invalid_query", message, {
79
- status: res.status,
80
- });
81
- }
82
-
83
- if (res.status === 404) {
84
- throw createJapanAddressError("not_found", message, {
85
- status: res.status,
86
- });
87
- }
88
-
89
- if (res.status === 504) {
90
- throw createJapanAddressError("timeout", message, {
91
- status: res.status,
92
- });
93
- }
94
-
95
- throw createJapanAddressError("data_source_error", message, {
96
- status: res.status,
97
- });
98
- }
99
- const payload = await res.json();
100
- if (!Array.isArray(payload.addresses)) {
101
- throw createJapanAddressError(
102
- "bad_response",
103
- "Address search returned an invalid payload",
104
- );
105
- }
106
- return payload.addresses;
130
+ async searchAddress(request, options) {
131
+ return readPage(`/q/japanpost/addresszip`, request, options);
107
132
  },
108
133
  };
109
134
 
@@ -119,7 +144,8 @@ export function PostalForm() {
119
144
  {error.code}: {error.message}
120
145
  </p>
121
146
  )}
122
- {data?.addresses.map((addr) => (
147
+ <p>Total results: {data?.totalElements ?? 0}</p>
148
+ {data?.elements.map((addr) => (
123
149
  <p key={addr.postalCode + addr.address}>{addr.address}</p>
124
150
  ))}
125
151
  </div>
@@ -127,6 +153,12 @@ export function PostalForm() {
127
153
  }
128
154
  ```
129
155
 
156
+ The sample `resolveErrorCode()` helper only classifies non-OK responses. In the
157
+ current beta-compatible contract, blank address-search requests and postal-code
158
+ misses may still succeed with `200` plus an empty page, while `404 -> not_found`
159
+ remains a backend-specific choice for servers that intentionally surface misses
160
+ as errors.
161
+
130
162
  ## Exports
131
163
 
132
164
  - `normalizeJapanPostalCode`
@@ -139,7 +171,8 @@ export function PostalForm() {
139
171
  - `useJapanAddress`
140
172
  - `PostalCodeInput`
141
173
  - `AddressSearchInput`
142
- - Public types including `JapanAddress` and `JapanAddressDataSource`
174
+ - Public types including `JapanAddress`, `JapanAddressDataSource`,
175
+ `JapanPostSearchcodeRequest`, `JapanPostAddresszipRequest`, and `Page`
143
176
  - Request options type: `JapanAddressRequestOptions`
144
177
 
145
178
  ## Utility Notes
@@ -152,7 +185,8 @@ without inserting a hyphen.
152
185
 
153
186
  ### useJapanPostalCode
154
187
 
155
- Looks up addresses by postal code.
188
+ Looks up addresses by postal code. The hook accepts `3-7` digits and uses
189
+ prefix search when the input has `3-6` digits.
156
190
 
157
191
  ```tsx
158
192
  const { loading, data, error, search, reset } = useJapanPostalCode({
@@ -171,6 +205,11 @@ const { loading, data, error, search, reset } = useJapanAddressSearch({
171
205
  });
172
206
  ```
173
207
 
208
+ The hook still performs client-side pre-validation for blank queries and
209
+ returns `invalid_query` before sending a request. That validation is a UX
210
+ helper only and does not replace server-side validation or server-side
211
+ contract handling.
212
+
174
213
  ### useJapanAddress
175
214
 
176
215
  Combines postal-code lookup and keyword search into one hook.
@@ -182,10 +221,28 @@ const { loading, data, error, searchByPostalCode, searchByKeyword, reset } =
182
221
 
183
222
  All hooks require `dataSource` at runtime.
184
223
 
224
+ The hook public APIs stay string-based:
225
+
226
+ - `useJapanPostalCode().search(value: string)`
227
+ - `useJapanAddressSearch().search(query: string)`
228
+ - `useJapanAddress().searchByPostalCode(value: string)`
229
+ - `useJapanAddress().searchByKeyword(query: string)`
230
+
231
+ Internally, the hooks build request objects before calling the data source:
232
+
233
+ - postal-code lookup: `{ value, pageNumber: 0, rowsPerPage: 100 }`
234
+ - address search: `{ freeword, pageNumber: 0, rowsPerPage: 100 }`
235
+
236
+ Optional request flags such as `includeCityDetails` and
237
+ `includePrefectureDetails` are omitted unless your own data source
238
+ implementation sets them explicitly.
239
+
185
240
  ## Error Handling Notes
186
241
 
187
- `JapanAddressDataSource` should return `JapanAddress[]` directly from both
188
- methods. The hooks wrap those arrays into lookup/search result objects.
242
+ `JapanAddressDataSource` should return `Page<JapanAddress>` directly from both
243
+ methods. Hooks preserve that page payload as-is, so consumers can read
244
+ `data.elements`, `data.totalElements`, `data.pageNumber`, and
245
+ `data.rowsPerPage` directly.
189
246
 
190
247
  Both methods may also receive an optional second argument:
191
248
 
@@ -203,16 +260,20 @@ Recommended error-code mapping:
203
260
  | Situation | Recommended code |
204
261
  | --- | --- |
205
262
  | Invalid postal code input | `invalid_postal_code` |
206
- | Blank keyword input | `invalid_query` |
263
+ | Blank keyword input in hook-side pre-validation | `invalid_query` |
207
264
  | Network failure | `network_error` |
208
265
  | Request aborted / timeout | `timeout` |
209
- | No matching addresses | `not_found` |
266
+ | No matching addresses on backends that surface misses as errors | `not_found` |
210
267
  | Malformed success payload | `bad_response` |
211
268
  | Other backend failures | `data_source_error` |
212
269
 
213
- In this repository's reference demo flow, the sample `dataSource` maps `400
214
- /searchcode/...` to `invalid_postal_code`, `400 /addresszip?...` to
215
- `invalid_query`, `404` to `not_found`, and `504` to `timeout`.
270
+ In this repository's reference demo flow, the sample `dataSource` classifies
271
+ failed requests by HTTP status code only. Current beta-compatible flows may
272
+ return `200` with an empty page for both blank `addresszip` requests and
273
+ postal-code misses, and those should stay successful page results. Other
274
+ `400` responses can still map to `invalid_query`, `404` remains useful for
275
+ backends that intentionally surface misses as errors, and `504` maps to
276
+ `timeout`.
216
277
 
217
278
  ## Headless Components
218
279
 
@@ -251,250 +312,3 @@ the upstream lookup request timed out. Both cases still map cleanly to the
251
312
  Use your server-side API from the `dataSource` implementation, and keep token
252
313
  exchange plus upstream signing on the server. React hooks and UI components
253
314
  should stay in client components.
254
-
255
- ---
256
-
257
- ## 한국어
258
-
259
- React + TypeScript 기반의 일본 우편번호/주소 검색 훅과 headless 입력
260
- 컴포넌트 라이브러리입니다.
261
-
262
- 이 문서는 배포 패키지 사용 가이드입니다. `pnpm demo:full` 같은 저장소 수준 보조
263
- 스크립트는 현재 Linux/WSL 계열 셸 환경을 전제로 하며, 자세한 내용은 루트 README에서 다룹니다.
264
-
265
- ## 설치
266
-
267
- ```bash
268
- pnpm add @cp949/japanpost-react
269
- ```
270
-
271
- - 지원 React 버전: React 18, React 19
272
-
273
- ## 빠른 시작
274
-
275
- ```tsx
276
- import { useJapanPostalCode } from "@cp949/japanpost-react";
277
- import type { JapanAddressDataSource } from "@cp949/japanpost-react";
278
- import { createJapanAddressError } from "@cp949/japanpost-react";
279
-
280
- // 현재 지원 방식은 실제 서버 연동뿐입니다.
281
- // 앱의 백엔드 API 경로에 맞게 dataSource를 연결하세요.
282
- const dataSource: JapanAddressDataSource = {
283
- async lookupPostalCode(postalCode) {
284
- const res = await fetch(`/searchcode/${postalCode}`);
285
- if (!res.ok) {
286
- const message = `Postal code lookup failed with status ${res.status}`;
287
-
288
- if (res.status === 400) {
289
- throw createJapanAddressError("invalid_postal_code", message, {
290
- status: res.status,
291
- });
292
- }
293
-
294
- if (res.status === 404) {
295
- throw createJapanAddressError("not_found", message, {
296
- status: res.status,
297
- });
298
- }
299
-
300
- if (res.status === 504) {
301
- throw createJapanAddressError("timeout", message, {
302
- status: res.status,
303
- });
304
- }
305
-
306
- throw createJapanAddressError("data_source_error", message, {
307
- status: res.status,
308
- });
309
- }
310
- const payload = await res.json();
311
- if (!Array.isArray(payload.addresses)) {
312
- throw createJapanAddressError(
313
- "bad_response",
314
- "Postal code lookup returned an invalid payload",
315
- );
316
- }
317
- return payload.addresses;
318
- },
319
- async searchAddress(query) {
320
- const res = await fetch(`/addresszip?q=${encodeURIComponent(query)}`);
321
- if (!res.ok) {
322
- const message = `Address search failed with status ${res.status}`;
323
-
324
- if (res.status === 400) {
325
- throw createJapanAddressError("invalid_query", message, {
326
- status: res.status,
327
- });
328
- }
329
-
330
- if (res.status === 404) {
331
- throw createJapanAddressError("not_found", message, {
332
- status: res.status,
333
- });
334
- }
335
-
336
- if (res.status === 504) {
337
- throw createJapanAddressError("timeout", message, {
338
- status: res.status,
339
- });
340
- }
341
-
342
- throw createJapanAddressError("data_source_error", message, {
343
- status: res.status,
344
- });
345
- }
346
- const payload = await res.json();
347
- if (!Array.isArray(payload.addresses)) {
348
- throw createJapanAddressError(
349
- "bad_response",
350
- "Address search returned an invalid payload",
351
- );
352
- }
353
- return payload.addresses;
354
- },
355
- };
356
-
357
- export function PostalForm() {
358
- const { loading, data, error, search } = useJapanPostalCode({ dataSource });
359
-
360
- return (
361
- <div>
362
- <button onClick={() => void search("100-0001")}>조회</button>
363
- {loading && <p>조회 중...</p>}
364
- {error && (
365
- <p>
366
- {error.code}: {error.message}
367
- </p>
368
- )}
369
- {data?.addresses.map((addr) => (
370
- <p key={addr.postalCode + addr.address}>{addr.address}</p>
371
- ))}
372
- </div>
373
- );
374
- }
375
- ```
376
-
377
- ## Exports
378
-
379
- - `normalizeJapanPostalCode`
380
- - `formatJapanPostalCode`
381
- - `normalizeJapanPostAddressRecord`
382
- - `isValidJapanPostalCode`
383
- - `createJapanAddressError`
384
- - `useJapanPostalCode`
385
- - `useJapanAddressSearch`
386
- - `useJapanAddress`
387
- - `PostalCodeInput`
388
- - `AddressSearchInput`
389
- - `JapanAddress`, `JapanAddressDataSource`를 포함한 공개 타입
390
- - 요청 옵션 타입: `JapanAddressRequestOptions`
391
-
392
- ## 유틸리티 메모
393
-
394
- `formatJapanPostalCode()`는 정규화된 값이 정확히 7자리일 때만 하이픈을 넣습니다.
395
- 그 외 길이에서는 하이픈을 추가하지 않고 숫자만 남긴 값을 그대로 반환합니다.
396
-
397
- ## Hooks
398
-
399
- ### useJapanPostalCode
400
-
401
- 우편번호로 주소를 조회합니다.
402
-
403
- ```tsx
404
- const { loading, data, error, search, reset } = useJapanPostalCode({
405
- dataSource,
406
- });
407
- ```
408
-
409
- ### useJapanAddressSearch
410
-
411
- 자유 형식 키워드로 주소를 검색하며 `debounceMs`를 지원합니다.
412
-
413
- ```tsx
414
- const { loading, data, error, search, reset } = useJapanAddressSearch({
415
- dataSource,
416
- debounceMs: 300,
417
- });
418
- ```
419
-
420
- ### useJapanAddress
421
-
422
- 우편번호 조회와 키워드 검색을 하나의 훅으로 합칩니다.
423
-
424
- ```tsx
425
- const { loading, data, error, searchByPostalCode, searchByKeyword, reset } =
426
- useJapanAddress({ dataSource, debounceMs: 300 });
427
- ```
428
-
429
- 모든 훅은 런타임에서 `dataSource`가 필요합니다.
430
-
431
- ## 에러 처리 메모
432
-
433
- `JapanAddressDataSource`의 두 메서드는 모두 `JapanAddress[]`를 직접
434
- 반환해야 합니다. 각 훅은 그 배열을 받아 `{ postalCode, addresses }`,
435
- `{ query, addresses }` 형태의 결과 객체를 조합합니다.
436
-
437
- 두 메서드는 선택적인 두 번째 인자도 받을 수 있습니다.
438
-
439
- ```ts
440
- type JapanAddressRequestOptions = {
441
- signal?: AbortSignal;
442
- };
443
- ```
444
-
445
- 훅은 superseded 요청, `reset()`, unmount 정리 상황에서 이전 요청을 취소할 수
446
- 있도록 `signal`을 전달합니다. 백엔드 레이어가 abort를 지원하면 그대로 활용할 수
447
- 있습니다.
448
-
449
- 권장 에러 코드 매핑:
450
-
451
- | 상황 | 권장 코드 |
452
- | --- | --- |
453
- | 잘못된 우편번호 입력 | `invalid_postal_code` |
454
- | 빈 주소 검색어 | `invalid_query` |
455
- | 네트워크 실패 | `network_error` |
456
- | 요청 중단 / 타임아웃 | `timeout` |
457
- | 검색 결과 없음 | `not_found` |
458
- | 성공 응답 shape 이상 | `bad_response` |
459
- | 그 외 백엔드 오류 | `data_source_error` |
460
-
461
- 이 저장소의 참고 demo 흐름에서는 예시 `dataSource`가 `400 /searchcode/...`를
462
- `invalid_postal_code`, `400 /addresszip?...`를 `invalid_query`, `404`를
463
- `not_found`, `504`를 `timeout`으로 매핑합니다.
464
-
465
- ## Headless 컴포넌트
466
-
467
- `PostalCodeInput`, `AddressSearchInput`은 스타일 없이 동작과 DOM 구조만
468
- 제공하므로, 앱의 디자인 시스템에 맞게 직접 꾸밀 수 있습니다.
469
-
470
- 두 컴포넌트는 네이티브 props 전달도 지원합니다.
471
-
472
- - `inputProps`: 실제 `<input />`에 전달
473
- - `buttonProps`: 실제 `<button />`에 전달
474
-
475
- 따라서 `id`, `name`, `placeholder`, `aria-*`, `autoComplete`, `className`,
476
- 폼 연동용 속성을 직접 넘길 수 있습니다. `PostalCodeInput`은 별도 override가
477
- 없으면 기본적으로 `inputMode="numeric"`를 사용합니다.
478
-
479
- ## Data Source와 서버 연동
480
-
481
- 이 패키지는 자체 백엔드 서버와 함께 사용하는 것을 권장합니다. Japan Post
482
- 공식 연동은 토큰 기반 인증을 사용하므로, 브라우저에서 업스트림 자격증명을
483
- 직접 보관하면 안 됩니다. 현재 지원 방식은 실제 서버 연동뿐입니다.
484
-
485
- 이 저장소의 `apps/minimal-api`는 로컬 기준 참고 서버 구현입니다. Japan Post
486
- API ver 2.0을 감싸며, 로컬 개발과 통합 확인 용도로 쓰는 구성을 목표로
487
- 합니다. demo의 `/minimal-api` 경로는 개발 편의를 위한 로컬 경로 연결입니다.
488
- 업스트림 payload에 구조화된 주소 필드와 원본 전체 주소 문자열인 `address`가 함께
489
- 있더라도, 참고 서버는 둘을 그대로 이어붙이지 않고 중복 없는 표시 주소를
490
- 우선 사용합니다.
491
-
492
- timeout 메시지는 토큰 발급 단계와 실제 조회 단계 중 어느 쪽에서 timeout이
493
- 발생했는지에 따라 달라질 수 있지만, 두 경우 모두 `timeout` 코드로 다루면
494
- 됩니다.
495
-
496
- ## SSR
497
-
498
- `dataSource` 구현에서는 서버 측 API를 사용하고, 토큰 교환과 업스트림 서명은
499
- 서버에서만 처리하세요. React 훅과 UI 컴포넌트는 클라이언트 컴포넌트에서
500
- 사용하는 것이 안전합니다.
@@ -2,6 +2,7 @@ import { AddressSearchInputProps } from '../core/types';
2
2
  /**
3
3
  * 스타일 의존성이 없는 최소한의 주소 키워드 검색 입력 컴포넌트.
4
4
  * value를 전달하면 제어 모드, 전달하지 않으면 비제어 모드로 동작한다.
5
+ * 검색 시 trim 처리를 내부에서 수행해 공백만 다른 입력이 별도 쿼리로 번지지 않게 한다.
5
6
  */
6
7
  export declare function AddressSearchInput({ defaultValue, value, disabled, label, buttonLabel, inputProps, buttonProps, onChange, onSearch, }: AddressSearchInputProps): import("react/jsx-runtime").JSX.Element;
7
8
  //# sourceMappingURL=AddressSearchInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AddressSearchInput.d.ts","sourceRoot":"","sources":["../../src/components/AddressSearchInput.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,YAAiB,EACjB,KAAK,EACL,QAAQ,EACR,KAAyB,EACzB,WAAsB,EACtB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,QAAQ,GACT,EAAE,uBAAuB,2CA4CzB"}
1
+ {"version":3,"file":"AddressSearchInput.d.ts","sourceRoot":"","sources":["../../src/components/AddressSearchInput.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAE7D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,YAAiB,EACjB,KAAK,EACL,QAAQ,EACR,KAAyB,EACzB,WAAsB,EACtB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,QAAQ,GACT,EAAE,uBAAuB,2CA4CzB"}
@@ -2,6 +2,7 @@ import { PostalCodeInputProps } from '../core/types';
2
2
  /**
3
3
  * 스타일 의존성이 없는 최소한의 우편번호 입력 컴포넌트.
4
4
  * value를 전달하면 제어 모드, 전달하지 않으면 비제어 모드로 동작한다.
5
+ * 제출 시에는 표시 형식이 아니라 정규화된 숫자 문자열을 콜백에 넘기는 것이 핵심 계약이다.
5
6
  */
6
7
  export declare function PostalCodeInput({ defaultValue, value, disabled, label, buttonLabel, inputProps, buttonProps, onChange, onSearch, }: PostalCodeInputProps): import("react/jsx-runtime").JSX.Element;
7
8
  //# sourceMappingURL=PostalCodeInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PostalCodeInput.d.ts","sourceRoot":"","sources":["../../src/components/PostalCodeInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,YAAiB,EACjB,KAAK,EACL,QAAQ,EACR,KAAqB,EACrB,WAAsB,EACtB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,QAAQ,GACT,EAAE,oBAAoB,2CA6CtB"}
1
+ {"version":3,"file":"PostalCodeInput.d.ts","sourceRoot":"","sources":["../../src/components/PostalCodeInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,YAAiB,EACjB,KAAK,EACL,QAAQ,EACR,KAAqB,EACrB,WAAsB,EACtB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,QAAQ,GACT,EAAE,oBAAoB,2CA8CtB"}
@@ -1,7 +1,8 @@
1
1
  import { JapanAddressError, JapanAddressErrorCode } from './types';
2
2
  /**
3
- * 라이브러리 전용 에러 객체를 생성한다.
4
- * name과 code를 일관되게 설정해 catch 블록에서 타입 좁히기가 쉽도록 한다.
3
+ * 라이브러리 전반에서 공통으로 쓰는 오류 객체 생성기다.
4
+ * 브라우저 fetch 오류, validation 오류, data source 오류를 모두 같은 표면으로 맞춰
5
+ * 소비자가 code/status만으로 분기할 수 있게 한다.
5
6
  */
6
7
  export declare function createJapanAddressError(code: JapanAddressErrorCode, message: string, options?: {
7
8
  cause?: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAExE;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,iBAAiB,CAQnB"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,iBAAiB,CAQnB"}
@@ -1,7 +1,7 @@
1
1
  import { JapanAddress, NormalizedJapanAddressRecord } from './types';
2
2
  /**
3
3
  * 정규화된 내부 주소 레코드를 라이브러리 공개 JapanAddress 형태로 변환한다.
4
- * address는 도도부현·시구정촌·동·상세주소를 순서대로 이어붙인 문자열이다.
4
+ * address는 표시용 convenience 필드이므로, 구조화된 필드와 같은 순서를 유지해 예측 가능성을 보장한다.
5
5
  */
6
6
  export declare function normalizeJapanPostAddressRecord(record: NormalizedJapanAddressRecord): JapanAddress;
7
7
  //# sourceMappingURL=normalizers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalizers.d.ts","sourceRoot":"","sources":["../../src/core/normalizers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAU1E;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,4BAA4B,GACnC,YAAY,CAoBd"}
1
+ {"version":3,"file":"normalizers.d.ts","sourceRoot":"","sources":["../../src/core/normalizers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAe1E;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,4BAA4B,GACnC,YAAY,CAoBd"}