@cp949/japanpost-react 1.0.1 → 1.0.3

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 (49) hide show
  1. package/README.ko.md +89 -23
  2. package/README.md +231 -191
  3. package/dist/client.d.ts +1 -0
  4. package/dist/client.es.js +3 -0
  5. package/dist/index.d.ts +1 -11
  6. package/dist/index.es.js +156 -290
  7. package/dist/src/client.d.ts +7 -0
  8. package/dist/src/client.d.ts.map +1 -0
  9. package/dist/src/components/AddressSearchInput.d.ts.map +1 -0
  10. package/dist/src/components/PostalCodeInput.d.ts.map +1 -0
  11. package/dist/src/core/errors.d.ts.map +1 -0
  12. package/dist/src/core/formatters.d.ts.map +1 -0
  13. package/dist/src/core/normalizers.d.ts.map +1 -0
  14. package/dist/{core → src/core}/types.d.ts +27 -7
  15. package/dist/src/core/types.d.ts.map +1 -0
  16. package/dist/src/core/validators.d.ts.map +1 -0
  17. package/dist/src/index.d.ts +11 -0
  18. package/dist/src/index.d.ts.map +1 -0
  19. package/dist/src/react/toJapanAddressError.d.ts.map +1 -0
  20. package/dist/src/react/useJapanAddress.d.ts.map +1 -0
  21. package/dist/src/react/useJapanAddressSearch.d.ts.map +1 -0
  22. package/dist/src/react/useJapanPostalCode.d.ts.map +1 -0
  23. package/dist/{react → src/react}/useLatestRequestState.d.ts +1 -0
  24. package/dist/src/react/useLatestRequestState.d.ts.map +1 -0
  25. package/package.json +11 -8
  26. package/dist/components/AddressSearchInput.d.ts.map +0 -1
  27. package/dist/components/PostalCodeInput.d.ts.map +0 -1
  28. package/dist/core/errors.d.ts.map +0 -1
  29. package/dist/core/formatters.d.ts.map +0 -1
  30. package/dist/core/normalizers.d.ts.map +0 -1
  31. package/dist/core/types.d.ts.map +0 -1
  32. package/dist/core/validators.d.ts.map +0 -1
  33. package/dist/index.d.ts.map +0 -1
  34. package/dist/index.umd.cjs +0 -6
  35. package/dist/react/toJapanAddressError.d.ts.map +0 -1
  36. package/dist/react/useJapanAddress.d.ts.map +0 -1
  37. package/dist/react/useJapanAddressSearch.d.ts.map +0 -1
  38. package/dist/react/useJapanPostalCode.d.ts.map +0 -1
  39. package/dist/react/useLatestRequestState.d.ts.map +0 -1
  40. /package/dist/{components → src/components}/AddressSearchInput.d.ts +0 -0
  41. /package/dist/{components → src/components}/PostalCodeInput.d.ts +0 -0
  42. /package/dist/{core → src/core}/errors.d.ts +0 -0
  43. /package/dist/{core → src/core}/formatters.d.ts +0 -0
  44. /package/dist/{core → src/core}/normalizers.d.ts +0 -0
  45. /package/dist/{core → src/core}/validators.d.ts +0 -0
  46. /package/dist/{react → src/react}/toJapanAddressError.d.ts +0 -0
  47. /package/dist/{react → src/react}/useJapanAddress.d.ts +0 -0
  48. /package/dist/{react → src/react}/useJapanAddressSearch.d.ts +0 -0
  49. /package/dist/{react → src/react}/useJapanPostalCode.d.ts +0 -0
package/README.md CHANGED
@@ -4,12 +4,11 @@
4
4
 
5
5
  <!-- This file is generated by `pnpm readme:package`. Edit docs/README.en.md and docs/README.ko.md instead. -->
6
6
 
7
- React + TypeScript hooks and headless inputs for Japan postal-code and address
8
- lookup.
7
+ React hooks, headless input components, and utilities for Japan postal-code
8
+ and address lookup.
9
9
 
10
- This package guide covers the published library. Repository-level demo scripts
11
- such as `pnpm demo:full` currently target Linux/WSL-style shell environments
12
- and are documented in the root README.
10
+ This package does not call Japan Post directly. You provide a
11
+ `JapanAddressDataSource` that talks to your own backend API.
13
12
 
14
13
  ## Install
15
14
 
@@ -17,45 +16,76 @@ and are documented in the root README.
17
16
  pnpm add @cp949/japanpost-react
18
17
  ```
19
18
 
20
- - Supported React versions: React 18 and React 19
19
+ - Peer dependencies: React 18 or React 19
20
+ - Package source in this repository:
21
+ `packages/japanpost-react`
22
+ - Demo app in this repository: `apps/demo`
23
+
24
+ This package is published as ESM. Keep server utilities and shared types on
25
+ `@cp949/japanpost-react`, and import hooks or headless input components for the
26
+ Next.js App Router from `@cp949/japanpost-react/client`. CommonJS consumers
27
+ must use ESM interop. `require("@cp949/japanpost-react")` and
28
+ `require("@cp949/japanpost-react/client")` are not supported. In CommonJS, use
29
+ ESM interop such as `const pkg = await import("@cp949/japanpost-react");`.
30
+
31
+ ## Next.js
32
+
33
+ When you use hooks or headless input components in the Next.js App Router,
34
+ import them from `@cp949/japanpost-react/client` inside a Client Component.
35
+ Keep utility functions and shared types on the root entry.
36
+
37
+ ```tsx
38
+ "use client";
39
+
40
+ import { PostalCodeInput, useJapanPostalCode } from "@cp949/japanpost-react/client";
41
+ import { normalizeJapanPostalCode, type JapanAddressDataSource } from "@cp949/japanpost-react";
42
+ ```
43
+
44
+ ## What The Package Provides
45
+
46
+ - Hooks for postal-code lookup and address search:
47
+ `useJapanPostalCode`, `useJapanAddressSearch`, `useJapanAddress`
48
+ - Headless form components:
49
+ `PostalCodeInput`, `AddressSearchInput`
50
+ - Utilities:
51
+ `normalizeJapanPostalCode`, `formatJapanPostalCode`,
52
+ `isValidJapanPostalCode`, `normalizeJapanPostAddressRecord`,
53
+ `createJapanAddressError`
54
+ - Public types for the request, response, error, and data-source contracts
21
55
 
22
56
  ## Quick Start
23
57
 
58
+ The package expects a `JapanAddressDataSource` with two methods:
59
+
60
+ - `lookupPostalCode(request, options?)`
61
+ - `searchAddress(request, options?)`
62
+
63
+ Both methods return `Promise<Page<JapanAddress>>`.
64
+
24
65
  ```tsx
25
- import { useJapanPostalCode } from "@cp949/japanpost-react";
26
- import type {
27
- JapanAddressDataSource,
28
- JapanAddressRequestOptions,
29
- JapanAddress,
30
- Page,
66
+ import {
67
+ PostalCodeInput,
68
+ createJapanAddressError,
69
+ useJapanPostalCode,
70
+ type JapanAddress,
71
+ type JapanAddressDataSource,
72
+ type JapanAddressRequestOptions,
73
+ type Page,
31
74
  } from "@cp949/japanpost-react";
32
- import { createJapanAddressError } from "@cp949/japanpost-react";
33
75
 
34
- // The only supported integration model is a real server-backed flow.
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
76
  function isAbortError(error: unknown): boolean {
40
77
  return error instanceof DOMException && error.name === "AbortError";
41
78
  }
42
79
 
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";
80
+ function isPagePayload(payload: unknown): payload is Page<JapanAddress> {
81
+ return (
82
+ typeof payload === "object" &&
83
+ payload !== null &&
84
+ Array.isArray((payload as { elements?: unknown }).elements) &&
85
+ typeof (payload as { totalElements?: unknown }).totalElements === "number" &&
86
+ typeof (payload as { pageNumber?: unknown }).pageNumber === "number" &&
87
+ typeof (payload as { rowsPerPage?: unknown }).rowsPerPage === "number"
88
+ );
59
89
  }
60
90
 
61
91
  async function readPage(
@@ -63,10 +93,10 @@ async function readPage(
63
93
  request: unknown,
64
94
  options?: JapanAddressRequestOptions,
65
95
  ): Promise<Page<JapanAddress>> {
66
- let res: Response;
96
+ let response: Response;
67
97
 
68
98
  try {
69
- res = await fetch(path, {
99
+ response = await fetch(path, {
70
100
  method: "POST",
71
101
  headers: {
72
102
  "content-type": "application/json",
@@ -78,173 +108,217 @@ async function readPage(
78
108
  throw createJapanAddressError(
79
109
  isAbortError(error) ? "timeout" : "network_error",
80
110
  isAbortError(error) ? "Request timed out" : "Network request failed",
81
- {
82
- cause: error,
83
- },
111
+ { cause: error },
84
112
  );
85
113
  }
86
114
 
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
- });
115
+ if (!response.ok) {
116
+ throw createJapanAddressError(
117
+ "data_source_error",
118
+ `Request failed with status ${response.status}`,
119
+ { status: response.status },
120
+ );
93
121
  }
94
122
 
95
123
  let payload: unknown;
96
124
 
97
125
  try {
98
- payload = await res.json();
126
+ payload = await response.json();
99
127
  } catch (error) {
100
128
  throw createJapanAddressError(
101
129
  "bad_response",
102
130
  "Response payload was not valid JSON",
103
- {
104
- cause: error,
105
- },
131
+ { cause: error },
106
132
  );
107
133
  }
108
134
 
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
- ) {
135
+ if (!isPagePayload(payload)) {
117
136
  throw createJapanAddressError(
118
137
  "bad_response",
119
138
  "Response payload must include a valid page payload",
120
139
  );
121
140
  }
122
141
 
123
- return payload as Page<JapanAddress>;
142
+ return payload;
124
143
  }
125
144
 
126
145
  const dataSource: JapanAddressDataSource = {
127
- async lookupPostalCode(request, options) {
128
- return readPage(`/q/japanpost/searchcode`, request, options);
146
+ lookupPostalCode(request, options) {
147
+ return readPage("/q/japanpost/searchcode", request, options);
129
148
  },
130
- async searchAddress(request, options) {
131
- return readPage(`/q/japanpost/addresszip`, request, options);
149
+ searchAddress(request, options) {
150
+ return readPage("/q/japanpost/addresszip", request, options);
132
151
  },
133
152
  };
134
153
 
135
- export function PostalForm() {
154
+ export function PostalCodeLookupExample() {
136
155
  const { loading, data, error, search } = useJapanPostalCode({ dataSource });
137
156
 
138
157
  return (
139
158
  <div>
140
- <button onClick={() => void search("100-0001")}>Search</button>
141
- {loading && <p>Loading...</p>}
142
- {error && (
143
- <p>
144
- {error.code}: {error.message}
145
- </p>
146
- )}
147
- <p>Total results: {data?.totalElements ?? 0}</p>
148
- {data?.elements.map((addr) => (
149
- <p key={addr.postalCode + addr.address}>{addr.address}</p>
150
- ))}
159
+ <PostalCodeInput
160
+ buttonLabel="Search"
161
+ label="Postal code"
162
+ onSearch={(postalCode) => {
163
+ void search({ postalCode });
164
+ }}
165
+ />
166
+
167
+ {loading ? <p>Loading...</p> : null}
168
+ {error ? <p>{error.message}</p> : null}
169
+
170
+ <ul>
171
+ {(data?.elements ?? []).map((address) => (
172
+ <li key={`${address.postalCode}-${address.address}`}>
173
+ {address.address}
174
+ </li>
175
+ ))}
176
+ </ul>
151
177
  </div>
152
178
  );
153
179
  }
154
180
  ```
155
181
 
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
-
162
- ## Exports
163
-
164
- - `normalizeJapanPostalCode`
165
- - `formatJapanPostalCode`
166
- - `normalizeJapanPostAddressRecord`
167
- - `isValidJapanPostalCode`
168
- - `createJapanAddressError`
169
- - `useJapanPostalCode`
170
- - `useJapanAddressSearch`
171
- - `useJapanAddress`
172
- - `PostalCodeInput`
173
- - `AddressSearchInput`
174
- - Public types including `JapanAddress`, `JapanAddressDataSource`,
175
- `JapanPostSearchcodeRequest`, `JapanPostAddresszipRequest`, and `Page`
176
- - Request options type: `JapanAddressRequestOptions`
177
-
178
- ## Utility Notes
179
-
180
- `formatJapanPostalCode()` inserts a hyphen only when the normalized value is
181
- exactly 7 digits. For any other length, it returns the normalized digits
182
- without inserting a hyphen.
182
+ The example paths above match this repository's reference backend. In your own
183
+ app, the backend routes can be different as long as your `dataSource`
184
+ implementation returns the same public types.
185
+
186
+ In Next.js, keep the `dataSource` implementation pointed at your own server-side
187
+ API routes. Do not expose Japan Post credentials or token exchange logic to the
188
+ browser.
189
+
190
+ ## Core Contract
191
+
192
+ `Page<T>` is the result shape shared by the hooks and the reference backend:
193
+
194
+ ```ts
195
+ type Page<T> = {
196
+ elements: T[];
197
+ totalElements: number;
198
+ pageNumber: number;
199
+ rowsPerPage: number;
200
+ };
201
+ ```
202
+
203
+ `JapanAddress` is the normalized address shape returned by the package:
204
+
205
+ ```ts
206
+ type JapanAddress = {
207
+ postalCode: string;
208
+ prefecture: string;
209
+ prefectureKana?: string;
210
+ city: string;
211
+ cityKana?: string;
212
+ town: string;
213
+ townKana?: string;
214
+ address: string;
215
+ provider: "japan-post";
216
+ };
217
+ ```
218
+
219
+ The hooks keep this page payload as-is, so consumers read
220
+ `data?.elements`, `data?.totalElements`, `data?.pageNumber`, and
221
+ `data?.rowsPerPage` directly.
183
222
 
184
223
  ## Hooks
185
224
 
186
- ### useJapanPostalCode
225
+ ### `useJapanPostalCode`
187
226
 
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.
227
+ - Accepts `string` or `JapanPostalCodeSearchInput`
228
+ - Normalizes the input to digits before calling the data source
229
+ - Allows `3-7` digits, so prefix lookup is possible
230
+ - Builds `{ postalCode, pageNumber: 0, rowsPerPage: 100 }` by default
231
+ - Exposes `loading`, `data`, `error`, `search`, `cancel`, and `reset`
190
232
 
191
233
  ```tsx
192
- const { loading, data, error, search, reset } = useJapanPostalCode({
193
- dataSource,
234
+ const postalCode = useJapanPostalCode({ dataSource });
235
+
236
+ void postalCode.search("100-0001");
237
+ void postalCode.search({
238
+ postalCode: "1000001",
239
+ pageNumber: 1,
240
+ rowsPerPage: 10,
241
+ includeParenthesesTown: true,
194
242
  });
195
243
  ```
196
244
 
197
- ### useJapanAddressSearch
245
+ ### `useJapanAddressSearch`
198
246
 
199
- Searches addresses by free-form keyword and supports debouncing.
247
+ - Accepts `string` or `JapanAddressSearchInput`
248
+ - Supports free-form search and structured fields in the same request type
249
+ - Rejects a fully blank query before calling the data source
250
+ - Omits `includeCityDetails` and `includePrefectureDetails` unless you set them
251
+ - Supports `debounceMs`
252
+ - Exposes `loading`, `data`, `error`, `search`, `cancel`, and `reset`
200
253
 
201
254
  ```tsx
202
- const { loading, data, error, search, reset } = useJapanAddressSearch({
255
+ const addressSearch = useJapanAddressSearch({
203
256
  dataSource,
204
257
  debounceMs: 300,
205
258
  });
206
- ```
207
259
 
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.
260
+ void addressSearch.search("千代田");
261
+ void addressSearch.search({
262
+ prefName: "東京都",
263
+ cityName: "千代田区",
264
+ pageNumber: 0,
265
+ rowsPerPage: 10,
266
+ });
267
+ ```
212
268
 
213
- ### useJapanAddress
269
+ ### `useJapanAddress`
214
270
 
215
- Combines postal-code lookup and keyword search into one hook.
271
+ - Combines postal-code lookup and address search in one hook
272
+ - Reuses the same `dataSource`
273
+ - Exposes `searchByPostalCode`, `searchByAddressQuery`, and `reset`
274
+ - Returns `data` and `error` for the currently active search mode only
216
275
 
217
276
  ```tsx
218
- const { loading, data, error, searchByPostalCode, searchByKeyword, reset } =
219
- useJapanAddress({ dataSource, debounceMs: 300 });
277
+ const address = useJapanAddress({
278
+ dataSource,
279
+ debounceMs: 300,
280
+ });
281
+
282
+ void address.searchByPostalCode("1000001");
283
+ void address.searchByAddressQuery({
284
+ addressQuery: "千代田",
285
+ pageNumber: 0,
286
+ rowsPerPage: 10,
287
+ });
220
288
  ```
221
289
 
222
- All hooks require `dataSource` at runtime.
290
+ ## Headless Components
291
+
292
+ ### `PostalCodeInput`
293
+
294
+ - Renders a `<form>` with `<label>`, `<input>`, and `<button>`
295
+ - Supports controlled and uncontrolled usage
296
+ - Calls `onSearch` with a normalized digits-only postal code
297
+ - Defaults `inputMode="numeric"` unless overridden with `inputProps`
223
298
 
224
- The hook public APIs stay string-based:
299
+ ### `AddressSearchInput`
225
300
 
226
- - `useJapanPostalCode().search(value: string)`
227
- - `useJapanAddressSearch().search(query: string)`
228
- - `useJapanAddress().searchByPostalCode(value: string)`
229
- - `useJapanAddress().searchByKeyword(query: string)`
301
+ - Renders the same minimal form structure
302
+ - Supports controlled and uncontrolled usage
303
+ - Calls `onSearch` with a trimmed query string
230
304
 
231
- Internally, the hooks build request objects before calling the data source:
305
+ Both components accept:
232
306
 
233
- - postal-code lookup: `{ value, pageNumber: 0, rowsPerPage: 100 }`
234
- - address search: `{ freeword, pageNumber: 0, rowsPerPage: 100 }`
307
+ - `inputProps` for the rendered `<input>`
308
+ - `buttonProps` for the rendered `<button>`
235
309
 
236
- Optional request flags such as `includeCityDetails` and
237
- `includePrefectureDetails` are omitted unless your own data source
238
- implementation sets them explicitly.
310
+ ## Data Source Integration
239
311
 
240
- ## Error Handling Notes
312
+ The package exports types for both sides of the integration:
241
313
 
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.
314
+ - `JapanAddressDataSource`
315
+ - `JapanPostSearchcodeRequest`
316
+ - `JapanPostAddresszipRequest`
317
+ - `JapanPostalCodeSearchInput`
318
+ - `JapanAddressSearchInput`
319
+ - `JapanAddressRequestOptions`
246
320
 
247
- Both methods may also receive an optional second argument:
321
+ The optional second argument to each data-source method is:
248
322
 
249
323
  ```ts
250
324
  type JapanAddressRequestOptions = {
@@ -252,63 +326,29 @@ type JapanAddressRequestOptions = {
252
326
  };
253
327
  ```
254
328
 
255
- Hooks pass `signal` so your data source can cancel superseded requests,
256
- `reset()` calls, and unmount cleanup when your backend layer supports aborts.
257
-
258
- Recommended error-code mapping:
259
-
260
- | Situation | Recommended code |
261
- | --- | --- |
262
- | Invalid postal code input | `invalid_postal_code` |
263
- | Blank keyword input in hook-side pre-validation | `invalid_query` |
264
- | Network failure | `network_error` |
265
- | Request aborted / timeout | `timeout` |
266
- | No matching addresses on backends that surface misses as errors | `not_found` |
267
- | Malformed success payload | `bad_response` |
268
- | Other backend failures | `data_source_error` |
269
-
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`.
277
-
278
- ## Headless Components
279
-
280
- `PostalCodeInput` and `AddressSearchInput` provide behavior and DOM structure
281
- without bundled styles, so you can plug them into your own design system.
282
-
283
- Both components also support native prop passthrough:
284
-
285
- - `inputProps`: forwarded to the rendered `<input />`
286
- - `buttonProps`: forwarded to the rendered `<button />`
287
-
288
- Use these for `id`, `name`, `placeholder`, `aria-*`, `autoComplete`,
289
- `className`, and form integration. `PostalCodeInput` defaults to
290
- `inputMode="numeric"` unless you override it through `inputProps`.
291
-
292
- ## Data Source and Server Integration
329
+ The hooks pass `signal` so your data source can cancel superseded requests,
330
+ `cancel()` calls, `reset()` calls, and unmount cleanup.
293
331
 
294
- Use this package with your own backend server. The official Japan Post flow
295
- uses token-based authentication, so browser apps should not hold upstream
296
- credentials directly. The supported integration model is a real server-backed
297
- flow.
332
+ This repository's reference backend uses these routes:
298
333
 
299
- This repository includes `apps/minimal-api` as the reference local server. It
300
- wraps Japan Post API ver 2.0 and is intended for local development and
301
- integration testing. The demo's `/minimal-api` path is only a development-time
302
- route to that local server. When the upstream payload includes both structured
303
- address parts and a free-form `address` string, the reference server keeps the
304
- display address non-duplicated instead of concatenating both blindly.
334
+ - `POST /q/japanpost/searchcode`
335
+ - `POST /q/japanpost/addresszip`
305
336
 
306
- Timeout messages can differ depending on whether the token exchange timed out or
307
- the upstream lookup request timed out. Both cases still map cleanly to the
308
- `timeout` error code.
337
+ But those route names are not part of the package API. They are just the
338
+ example used by `apps/demo` and `apps/minimal-api`.
309
339
 
310
- ## SSR
340
+ ## Constraints And Notes
311
341
 
312
- Use your server-side API from the `dataSource` implementation, and keep token
313
- exchange plus upstream signing on the server. React hooks and UI components
314
- should stay in client components.
342
+ - `dataSource` is required at runtime for all hooks.
343
+ - `isValidJapanPostalCode()` checks for an exact 7-digit postal code after
344
+ normalization. `useJapanPostalCode()` is less strict and accepts `3-7`
345
+ digits for prefix lookup.
346
+ - `formatJapanPostalCode()` inserts a hyphen only when the normalized value is
347
+ exactly 7 digits.
348
+ - `cancel()` on `useJapanPostalCode()` and `useJapanAddressSearch()` aborts the
349
+ in-flight request but keeps the latest settled `data` and `error`.
350
+ - `reset()` clears both `data` and `error`.
351
+ - The package does not require a backend to return `404` for misses. Returning
352
+ `200` with an empty page is also compatible with the hook contract.
353
+ - Use your own server-side API in the `dataSource` implementation. Keep Japan
354
+ Post credentials and token exchange on the server side.
@@ -0,0 +1 @@
1
+ export * from "./index";
@@ -0,0 +1,3 @@
1
+ "use client";
2
+
3
+ export * from "./index.es.js";
package/dist/index.d.ts CHANGED
@@ -1,11 +1 @@
1
- export { AddressSearchInput } from './components/AddressSearchInput';
2
- export { PostalCodeInput } from './components/PostalCodeInput';
3
- export { createJapanAddressError } from './core/errors';
4
- export { formatJapanPostalCode, normalizeJapanPostalCode, } from './core/formatters';
5
- export { normalizeJapanPostAddressRecord } from './core/normalizers';
6
- export type { AddressSearchInputProps, JapanAddress, JapanAddressDataSource, JapanAddressError, JapanAddressErrorCode, JapanPostAddresszipRequest, JapanPostSearchcodeRequest, JapanAddressRequestOptions, JapanAddressSearchResult, JapanPostalCodeLookupResult, NormalizedJapanAddressRecord, Page, PostalCodeInputProps, UseJapanAddressOptions, UseJapanAddressResult, UseJapanAddressSearchOptions, UseJapanAddressSearchResult, UseJapanPostalCodeOptions, UseJapanPostalCodeResult, } from './core/types';
7
- export { isValidJapanPostalCode } from './core/validators';
8
- export { useJapanAddress } from './react/useJapanAddress';
9
- export { useJapanAddressSearch } from './react/useJapanAddressSearch';
10
- export { useJapanPostalCode } from './react/useJapanPostalCode';
11
- //# sourceMappingURL=index.d.ts.map
1
+ export {}