@cp949/japanpost-react 1.0.0 → 1.0.2
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.ko.md +349 -0
- package/README.md +249 -419
- package/dist/index.d.ts +1 -11
- package/dist/index.es.js +106 -60
- package/dist/index.umd.cjs +1 -1
- package/dist/{components → src/components}/AddressSearchInput.d.ts +1 -0
- package/dist/src/components/AddressSearchInput.d.ts.map +1 -0
- package/dist/{components → src/components}/PostalCodeInput.d.ts +1 -0
- package/dist/src/components/PostalCodeInput.d.ts.map +1 -0
- package/dist/src/core/errors.d.ts +11 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/formatters.d.ts.map +1 -0
- package/dist/{core → src/core}/normalizers.d.ts +1 -1
- package/dist/src/core/normalizers.d.ts.map +1 -0
- package/dist/src/core/types.d.ts +261 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/validators.d.ts.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/react/toJapanAddressError.d.ts +8 -0
- package/dist/src/react/toJapanAddressError.d.ts.map +1 -0
- package/dist/{react → src/react}/useJapanAddress.d.ts +2 -1
- package/dist/src/react/useJapanAddress.d.ts.map +1 -0
- package/dist/src/react/useJapanAddressSearch.d.ts.map +1 -0
- package/dist/src/react/useJapanPostalCode.d.ts.map +1 -0
- package/dist/{react → src/react}/useLatestRequestState.d.ts +6 -0
- package/dist/src/react/useLatestRequestState.d.ts.map +1 -0
- package/package.json +5 -5
- package/dist/components/AddressSearchInput.d.ts.map +0 -1
- package/dist/components/PostalCodeInput.d.ts.map +0 -1
- package/dist/core/errors.d.ts +0 -10
- package/dist/core/errors.d.ts.map +0 -1
- package/dist/core/formatters.d.ts.map +0 -1
- package/dist/core/normalizers.d.ts.map +0 -1
- package/dist/core/types.d.ts +0 -182
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/validators.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/react/toJapanAddressError.d.ts +0 -7
- package/dist/react/toJapanAddressError.d.ts.map +0 -1
- package/dist/react/useJapanAddress.d.ts.map +0 -1
- package/dist/react/useJapanAddressSearch.d.ts.map +0 -1
- package/dist/react/useJapanPostalCode.d.ts.map +0 -1
- package/dist/react/useLatestRequestState.d.ts.map +0 -1
- /package/dist/{core → src/core}/formatters.d.ts +0 -0
- /package/dist/{core → src/core}/validators.d.ts +0 -0
- /package/dist/{react → src/react}/useJapanAddressSearch.d.ts +0 -0
- /package/dist/{react → src/react}/useJapanPostalCode.d.ts +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1 @@
|
|
|
1
|
-
export {
|
|
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, JapanAddressRequestOptions, JapanAddressSearchResult, JapanPostalCodeLookupResult, NormalizedJapanAddressRecord, 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 {}
|
package/dist/index.es.js
CHANGED
|
@@ -283,31 +283,36 @@ function y() {
|
|
|
283
283
|
let n = r(0), a = r(!0), o = r(null), [s, c] = i(!1), [l, u] = i(null), [d, f] = i(null), p = e((e) => a.current && e === n.current, []), m = e(() => {
|
|
284
284
|
n.current += 1, o.current?.abort(), o.current = null;
|
|
285
285
|
}, []);
|
|
286
|
-
|
|
286
|
+
t(() => (a.current = !0, () => {
|
|
287
287
|
a.current = !1, m();
|
|
288
|
-
}), [m])
|
|
288
|
+
}), [m]);
|
|
289
|
+
let h = e(() => {
|
|
290
|
+
let e = n.current + 1;
|
|
291
|
+
n.current = e, o.current?.abort();
|
|
292
|
+
let t = new AbortController();
|
|
293
|
+
return o.current = t, c(!0), f(null), {
|
|
294
|
+
requestId: e,
|
|
295
|
+
signal: t.signal
|
|
296
|
+
};
|
|
297
|
+
}, []), g = e((e, t) => {
|
|
298
|
+
p(e) && u(t);
|
|
299
|
+
}, [p]), _ = e((e, t) => (p(e) && (f(t), u(null)), null), [p]), v = e(() => {
|
|
300
|
+
m(), c(!1);
|
|
301
|
+
}, [m]);
|
|
302
|
+
return {
|
|
289
303
|
loading: s,
|
|
290
304
|
data: l,
|
|
291
305
|
error: d,
|
|
292
|
-
beginRequest:
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
let t = new AbortController();
|
|
296
|
-
return o.current = t, c(!0), f(null), {
|
|
297
|
-
requestId: e,
|
|
298
|
-
signal: t.signal
|
|
299
|
-
};
|
|
300
|
-
}, []),
|
|
301
|
-
setSuccess: e((e, t) => {
|
|
302
|
-
p(e) && u(t);
|
|
303
|
-
}, [p]),
|
|
304
|
-
setFailure: e((e, t) => (p(e) && (f(t), u(null)), null), [p]),
|
|
306
|
+
beginRequest: h,
|
|
307
|
+
setSuccess: g,
|
|
308
|
+
setFailure: _,
|
|
305
309
|
finishRequest: e((e) => {
|
|
306
310
|
p(e) && (c(!1), o.current = null);
|
|
307
311
|
}, [p]),
|
|
312
|
+
cancel: v,
|
|
308
313
|
reset: e(() => {
|
|
309
|
-
|
|
310
|
-
}, [
|
|
314
|
+
v(), u(null), f(null);
|
|
315
|
+
}, [v])
|
|
311
316
|
};
|
|
312
317
|
}
|
|
313
318
|
//#endregion
|
|
@@ -316,26 +321,55 @@ function b(e) {
|
|
|
316
321
|
if (e) return e;
|
|
317
322
|
throw Error("useJapanAddressSearch requires options.dataSource");
|
|
318
323
|
}
|
|
319
|
-
function x(
|
|
320
|
-
|
|
324
|
+
function x(e) {
|
|
325
|
+
return e?.trim() || void 0;
|
|
326
|
+
}
|
|
327
|
+
function S(e) {
|
|
328
|
+
let t = typeof e == "string" ? { addressQuery: e } : e, n = x(t.addressQuery), r = x(t.prefCode), i = x(t.prefName), a = x(t.prefKana), o = x(t.prefRoma), s = x(t.cityCode), c = x(t.cityName), l = x(t.cityKana), u = x(t.cityRoma), d = x(t.townName), f = x(t.townKana), p = x(t.townRoma);
|
|
329
|
+
return n === void 0 && r === void 0 && i === void 0 && a === void 0 && o === void 0 && s === void 0 && c === void 0 && l === void 0 && u === void 0 && d === void 0 && f === void 0 && p === void 0 ? null : {
|
|
330
|
+
...n === void 0 ? {} : { addressQuery: n },
|
|
331
|
+
...r === void 0 ? {} : { prefCode: r },
|
|
332
|
+
...i === void 0 ? {} : { prefName: i },
|
|
333
|
+
...a === void 0 ? {} : { prefKana: a },
|
|
334
|
+
...o === void 0 ? {} : { prefRoma: o },
|
|
335
|
+
...s === void 0 ? {} : { cityCode: s },
|
|
336
|
+
...c === void 0 ? {} : { cityName: c },
|
|
337
|
+
...l === void 0 ? {} : { cityKana: l },
|
|
338
|
+
...u === void 0 ? {} : { cityRoma: u },
|
|
339
|
+
...d === void 0 ? {} : { townName: d },
|
|
340
|
+
...f === void 0 ? {} : { townKana: f },
|
|
341
|
+
...p === void 0 ? {} : { townRoma: p },
|
|
342
|
+
pageNumber: t.pageNumber ?? 0,
|
|
343
|
+
rowsPerPage: t.rowsPerPage ?? 100,
|
|
344
|
+
...t.includeCityDetails === void 0 ? {} : { includeCityDetails: t.includeCityDetails },
|
|
345
|
+
...t.includePrefectureDetails === void 0 ? {} : { includePrefectureDetails: t.includePrefectureDetails }
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
function C(e) {
|
|
349
|
+
return e.aborted ? Promise.resolve(null) : new Promise((t) => {
|
|
350
|
+
let n = () => {
|
|
351
|
+
e.removeEventListener("abort", n), t(null);
|
|
352
|
+
};
|
|
353
|
+
e.addEventListener("abort", n, { once: !0 });
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
function w(i) {
|
|
357
|
+
let a = n(() => b(i.dataSource), [i.dataSource]), o = i.debounceMs ?? 0, s = r(null), c = r(null), { loading: l, data: u, error: d, beginRequest: f, setSuccess: p, setFailure: h, finishRequest: g, cancel: _, reset: x } = y(), w = e((e) => {
|
|
321
358
|
s.current !== null && (globalThis.clearTimeout(s.current), s.current = null), c.current?.(e), c.current = null;
|
|
322
359
|
}, []);
|
|
323
360
|
t(() => () => {
|
|
324
|
-
|
|
325
|
-
}, [
|
|
326
|
-
let
|
|
327
|
-
|
|
328
|
-
}, [
|
|
361
|
+
w(null);
|
|
362
|
+
}, [w]);
|
|
363
|
+
let T = e(() => {
|
|
364
|
+
w(null), x();
|
|
365
|
+
}, [w, x]), E = e(() => {
|
|
366
|
+
w(null), _();
|
|
367
|
+
}, [w, _]), D = e(async (e, t, n) => {
|
|
329
368
|
try {
|
|
330
|
-
let r = n.
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
addresses: await a.searchAddress(r, i)
|
|
335
|
-
};
|
|
336
|
-
return p(e, o), o;
|
|
337
|
-
} catch (t) {
|
|
338
|
-
return h(e, v(t));
|
|
369
|
+
let r = { signal: t }, i = a.searchAddress(n, r), o = await Promise.race([i, C(t)]);
|
|
370
|
+
return t.aborted || o === null ? null : (p(e, o), o);
|
|
371
|
+
} catch (n) {
|
|
372
|
+
return t.aborted ? null : h(e, v(n));
|
|
339
373
|
} finally {
|
|
340
374
|
g(e);
|
|
341
375
|
}
|
|
@@ -349,51 +383,63 @@ function x(i) {
|
|
|
349
383
|
loading: l,
|
|
350
384
|
data: u,
|
|
351
385
|
error: d,
|
|
352
|
-
|
|
386
|
+
cancel: E,
|
|
387
|
+
reset: T,
|
|
353
388
|
search: e((e) => {
|
|
354
|
-
let { requestId:
|
|
355
|
-
|
|
356
|
-
|
|
389
|
+
let t = S(e), { requestId: n, signal: r } = f();
|
|
390
|
+
if (w(null), t === null) {
|
|
391
|
+
let e = h(n, m("invalid_query", "Address query is required"));
|
|
392
|
+
return g(n), Promise.resolve(e);
|
|
393
|
+
}
|
|
394
|
+
return o <= 0 ? new Promise((e) => {
|
|
395
|
+
c.current = e, D(n, r, t).then((t) => {
|
|
396
|
+
e(t), c.current === e && (c.current = null);
|
|
397
|
+
});
|
|
398
|
+
}) : new Promise((e) => {
|
|
399
|
+
c.current = e, s.current = globalThis.setTimeout(() => {
|
|
357
400
|
s.current = null;
|
|
358
|
-
let
|
|
359
|
-
c.current = null,
|
|
360
|
-
|
|
401
|
+
let e = c.current;
|
|
402
|
+
c.current = null, D(n, r, t).then((t) => {
|
|
403
|
+
e?.(t);
|
|
361
404
|
});
|
|
362
405
|
}, o);
|
|
363
406
|
});
|
|
364
407
|
}, [
|
|
365
408
|
f,
|
|
366
|
-
|
|
409
|
+
w,
|
|
367
410
|
o,
|
|
368
|
-
|
|
411
|
+
D
|
|
369
412
|
])
|
|
370
413
|
};
|
|
371
414
|
}
|
|
372
415
|
//#endregion
|
|
373
416
|
//#region src/react/useJapanPostalCode.ts
|
|
374
|
-
function
|
|
417
|
+
function T(e) {
|
|
375
418
|
if (e) return e;
|
|
376
419
|
throw Error("useJapanPostalCode requires options.dataSource");
|
|
377
420
|
}
|
|
378
|
-
function
|
|
379
|
-
let r = n(() =>
|
|
421
|
+
function E(t) {
|
|
422
|
+
let r = n(() => T(t.dataSource), [t.dataSource]), { loading: i, data: a, error: o, beginRequest: s, setSuccess: c, setFailure: l, finishRequest: u, cancel: f, reset: p } = y();
|
|
380
423
|
return {
|
|
381
424
|
loading: i,
|
|
382
425
|
data: a,
|
|
383
426
|
error: o,
|
|
384
|
-
|
|
427
|
+
cancel: f,
|
|
428
|
+
reset: p,
|
|
385
429
|
search: e(async (e) => {
|
|
386
430
|
let { requestId: t, signal: n } = s();
|
|
387
431
|
try {
|
|
388
|
-
let i = d(
|
|
389
|
-
if (!/^\d{7}$/.test(
|
|
390
|
-
let
|
|
391
|
-
postalCode:
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
432
|
+
let i = typeof e == "string" ? { postalCode: e } : e, a = d(i.postalCode);
|
|
433
|
+
if (!/^\d{3,7}$/.test(a)) throw m("invalid_postal_code", "Postal code must contain between 3 and 7 digits");
|
|
434
|
+
let o = { signal: n }, s = {
|
|
435
|
+
postalCode: a,
|
|
436
|
+
pageNumber: i.pageNumber ?? 0,
|
|
437
|
+
rowsPerPage: i.rowsPerPage ?? 100,
|
|
438
|
+
...i.includeParenthesesTown === void 0 ? {} : { includeParenthesesTown: i.includeParenthesesTown }
|
|
439
|
+
}, l = await r.lookupPostalCode(s, o);
|
|
440
|
+
return n.aborted ? null : (c(t, l), l);
|
|
395
441
|
} catch (e) {
|
|
396
|
-
return l(t, v(e));
|
|
442
|
+
return n.aborted ? null : l(t, v(e));
|
|
397
443
|
} finally {
|
|
398
444
|
u(t);
|
|
399
445
|
}
|
|
@@ -408,24 +454,24 @@ function C(t) {
|
|
|
408
454
|
}
|
|
409
455
|
//#endregion
|
|
410
456
|
//#region src/react/useJapanAddress.ts
|
|
411
|
-
function
|
|
457
|
+
function D(t) {
|
|
412
458
|
let r = n(() => {
|
|
413
459
|
if (t.dataSource) return t.dataSource;
|
|
414
460
|
throw Error("useJapanAddress requires options.dataSource");
|
|
415
|
-
}, [t.dataSource]), a =
|
|
461
|
+
}, [t.dataSource]), a = E({ dataSource: r }), o = w({
|
|
416
462
|
dataSource: r,
|
|
417
463
|
debounceMs: t.debounceMs
|
|
418
|
-
}), s = a.reset, c = a.search, l = o.reset, u = o.search, [d, f] = i(null), p = e(async (e) => (l(), f("postalCode"), c(e)), [l, c]), m = e(async (e) => (s(), f("
|
|
464
|
+
}), s = a.reset, c = a.search, l = o.reset, u = o.search, [d, f] = i(null), p = e(async (e) => (l(), f("postalCode"), c(e)), [l, c]), m = e(async (e) => (s(), f("addressQuery"), u(e)), [s, u]), h = e(() => {
|
|
419
465
|
s(), l(), f(null);
|
|
420
|
-
}, [l, s]), g = d === "postalCode" ? a.data : d === "
|
|
466
|
+
}, [l, s]), g = d === "postalCode" ? a.data : d === "addressQuery" ? o.data : null, _ = d === "postalCode" ? a.error : d === "addressQuery" ? o.error : null;
|
|
421
467
|
return {
|
|
422
468
|
loading: a.loading || o.loading,
|
|
423
469
|
data: g,
|
|
424
470
|
error: _,
|
|
425
471
|
reset: h,
|
|
426
472
|
searchByPostalCode: p,
|
|
427
|
-
|
|
473
|
+
searchByAddressQuery: m
|
|
428
474
|
};
|
|
429
475
|
}
|
|
430
476
|
//#endregion
|
|
431
|
-
export { u as AddressSearchInput, p as PostalCodeInput, m as createJapanAddressError, f as formatJapanPostalCode, _ as isValidJapanPostalCode, g as normalizeJapanPostAddressRecord, d as normalizeJapanPostalCode,
|
|
477
|
+
export { u as AddressSearchInput, p as PostalCodeInput, m as createJapanAddressError, f as formatJapanPostalCode, _ as isValidJapanPostalCode, g as normalizeJapanPostAddressRecord, d as normalizeJapanPostalCode, D as useJapanAddress, w as useJapanAddressSearch, E as useJapanPostalCode };
|
package/dist/index.umd.cjs
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
<%s {...props} />
|
|
4
4
|
React keys must be passed directly to JSX without using spread:
|
|
5
5
|
let props = %s;
|
|
6
|
-
<%s key={someKey} {...props} />`,o,p,m,p),L[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require(`react`),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.client.reference`),k=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,A=Object.prototype.hasOwnProperty,j=Array.isArray,M=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var N,P={},F=m.react_stack_bottom_frame.bind(m,o)(),I=M(i(o)),L={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)},e.jsxs=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)}})()})),a=n(((e,t)=>{process.env.NODE_ENV===`production`?t.exports=r():t.exports=i()}))();function o({defaultValue:e=``,value:n,disabled:r,label:i=`Address keyword`,buttonLabel:o=`Search`,inputProps:s,buttonProps:c,onChange:l,onSearch:u}){let[d,f]=(0,t.useState)(e),p=n??d;function m(e){e.preventDefault(),u(p.trim())}function h(e){n===void 0&&f(e),l?.(e)}return(0,a.jsxs)(`form`,{onSubmit:m,children:[(0,a.jsxs)(`label`,{children:[i,(0,a.jsx)(`input`,{...s,disabled:r,value:p,onChange:e=>h(e.target.value)})]}),(0,a.jsx)(`button`,{...c,disabled:r,type:`submit`,children:o})]})}function s(e){return e.replace(/[^\d]/g,``)}function c(e){let t=s(e);return t.length===7?`${t.slice(0,3)}-${t.slice(3)}`:t}function l({defaultValue:e=``,value:n,disabled:r,label:i=`Postal code`,buttonLabel:o=`Search`,inputProps:c,buttonProps:l,onChange:u,onSearch:d}){let[f,p]=(0,t.useState)(e),m=n??f;function h(e){e.preventDefault(),d(s(m))}function g(e){n===void 0&&p(e),u?.(e)}return(0,a.jsxs)(`form`,{onSubmit:h,children:[(0,a.jsxs)(`label`,{children:[i,(0,a.jsx)(`input`,{...c,disabled:r,inputMode:c?.inputMode??`numeric`,value:m,onChange:e=>g(e.target.value)})]}),(0,a.jsx)(`button`,{...l,disabled:r,type:`submit`,children:o})]})}function u(e,t,n){let r=Error(t);return r.name=`JapanAddressError`,r.code=e,r.cause=n?.cause,r.status=n?.status,r}function d(e){return e.filter(Boolean).join(` `).trim()}function f(e){let t=d([e.prefecture,e.city,e.town,e.detail??``]);return{postalCode:e.postalCode,prefecture:e.prefecture,prefectureKana:e.prefectureKana,city:e.city,cityKana:e.cityKana,town:e.town,townKana:e.townKana,address:t,provider:`japan-post`}}function p(e){return/^\d{7}$/.test(s(e))}function m(e){return typeof e==`object`&&e&&`code`in e&&typeof e.code==`string`?e:u(`data_source_error`,e instanceof Error?e.message:`Unknown error`,{cause:e})}function h(){let e=(0,t.useRef)(0),n=(0,t.useRef)(!0),r=(0,t.useRef)(null),[i,a]=(0,t.useState)(!1),[o,s]=(0,t.useState)(null),[c,l]=(0,t.useState)(null),u=(0,t.useCallback)(t=>n.current&&t===e.current,[]),d=(0,t.useCallback)(()=>{e.current+=1,r.current?.abort(),r.current=null},[]);
|
|
6
|
+
<%s key={someKey} {...props} />`,o,p,m,p),L[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require(`react`),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.client.reference`),k=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,A=Object.prototype.hasOwnProperty,j=Array.isArray,M=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var N,P={},F=m.react_stack_bottom_frame.bind(m,o)(),I=M(i(o)),L={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)},e.jsxs=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)}})()})),a=n(((e,t)=>{process.env.NODE_ENV===`production`?t.exports=r():t.exports=i()}))();function o({defaultValue:e=``,value:n,disabled:r,label:i=`Address keyword`,buttonLabel:o=`Search`,inputProps:s,buttonProps:c,onChange:l,onSearch:u}){let[d,f]=(0,t.useState)(e),p=n??d;function m(e){e.preventDefault(),u(p.trim())}function h(e){n===void 0&&f(e),l?.(e)}return(0,a.jsxs)(`form`,{onSubmit:m,children:[(0,a.jsxs)(`label`,{children:[i,(0,a.jsx)(`input`,{...s,disabled:r,value:p,onChange:e=>h(e.target.value)})]}),(0,a.jsx)(`button`,{...c,disabled:r,type:`submit`,children:o})]})}function s(e){return e.replace(/[^\d]/g,``)}function c(e){let t=s(e);return t.length===7?`${t.slice(0,3)}-${t.slice(3)}`:t}function l({defaultValue:e=``,value:n,disabled:r,label:i=`Postal code`,buttonLabel:o=`Search`,inputProps:c,buttonProps:l,onChange:u,onSearch:d}){let[f,p]=(0,t.useState)(e),m=n??f;function h(e){e.preventDefault(),d(s(m))}function g(e){n===void 0&&p(e),u?.(e)}return(0,a.jsxs)(`form`,{onSubmit:h,children:[(0,a.jsxs)(`label`,{children:[i,(0,a.jsx)(`input`,{...c,disabled:r,inputMode:c?.inputMode??`numeric`,value:m,onChange:e=>g(e.target.value)})]}),(0,a.jsx)(`button`,{...l,disabled:r,type:`submit`,children:o})]})}function u(e,t,n){let r=Error(t);return r.name=`JapanAddressError`,r.code=e,r.cause=n?.cause,r.status=n?.status,r}function d(e){return e.filter(Boolean).join(` `).trim()}function f(e){let t=d([e.prefecture,e.city,e.town,e.detail??``]);return{postalCode:e.postalCode,prefecture:e.prefecture,prefectureKana:e.prefectureKana,city:e.city,cityKana:e.cityKana,town:e.town,townKana:e.townKana,address:t,provider:`japan-post`}}function p(e){return/^\d{7}$/.test(s(e))}function m(e){return typeof e==`object`&&e&&`code`in e&&typeof e.code==`string`?e:u(`data_source_error`,e instanceof Error?e.message:`Unknown error`,{cause:e})}function h(){let e=(0,t.useRef)(0),n=(0,t.useRef)(!0),r=(0,t.useRef)(null),[i,a]=(0,t.useState)(!1),[o,s]=(0,t.useState)(null),[c,l]=(0,t.useState)(null),u=(0,t.useCallback)(t=>n.current&&t===e.current,[]),d=(0,t.useCallback)(()=>{e.current+=1,r.current?.abort(),r.current=null},[]);(0,t.useEffect)(()=>(n.current=!0,()=>{n.current=!1,d()}),[d]);let f=(0,t.useCallback)(()=>{let t=e.current+1;e.current=t,r.current?.abort();let n=new AbortController;return r.current=n,a(!0),l(null),{requestId:t,signal:n.signal}},[]),p=(0,t.useCallback)((e,t)=>{u(e)&&s(t)},[u]),m=(0,t.useCallback)((e,t)=>(u(e)&&(l(t),s(null)),null),[u]),h=(0,t.useCallback)(()=>{d(),a(!1)},[d]);return{loading:i,data:o,error:c,beginRequest:f,setSuccess:p,setFailure:m,finishRequest:(0,t.useCallback)(e=>{u(e)&&(a(!1),r.current=null)},[u]),cancel:h,reset:(0,t.useCallback)(()=>{h(),s(null),l(null)},[h])}}function g(e){if(e)return e;throw Error(`useJapanAddressSearch requires options.dataSource`)}function _(e){return e?.trim()||void 0}function v(e){let t=typeof e==`string`?{addressQuery:e}:e,n=_(t.addressQuery),r=_(t.prefCode),i=_(t.prefName),a=_(t.prefKana),o=_(t.prefRoma),s=_(t.cityCode),c=_(t.cityName),l=_(t.cityKana),u=_(t.cityRoma),d=_(t.townName),f=_(t.townKana),p=_(t.townRoma);return n===void 0&&r===void 0&&i===void 0&&a===void 0&&o===void 0&&s===void 0&&c===void 0&&l===void 0&&u===void 0&&d===void 0&&f===void 0&&p===void 0?null:{...n===void 0?{}:{addressQuery:n},...r===void 0?{}:{prefCode:r},...i===void 0?{}:{prefName:i},...a===void 0?{}:{prefKana:a},...o===void 0?{}:{prefRoma:o},...s===void 0?{}:{cityCode:s},...c===void 0?{}:{cityName:c},...l===void 0?{}:{cityKana:l},...u===void 0?{}:{cityRoma:u},...d===void 0?{}:{townName:d},...f===void 0?{}:{townKana:f},...p===void 0?{}:{townRoma:p},pageNumber:t.pageNumber??0,rowsPerPage:t.rowsPerPage??100,...t.includeCityDetails===void 0?{}:{includeCityDetails:t.includeCityDetails},...t.includePrefectureDetails===void 0?{}:{includePrefectureDetails:t.includePrefectureDetails}}}function y(e){return e.aborted?Promise.resolve(null):new Promise(t=>{let n=()=>{e.removeEventListener(`abort`,n),t(null)};e.addEventListener(`abort`,n,{once:!0})})}function b(e){let n=(0,t.useMemo)(()=>g(e.dataSource),[e.dataSource]),r=e.debounceMs??0,i=(0,t.useRef)(null),a=(0,t.useRef)(null),{loading:o,data:s,error:c,beginRequest:l,setSuccess:d,setFailure:f,finishRequest:p,cancel:_,reset:b}=h(),x=(0,t.useCallback)(e=>{i.current!==null&&(globalThis.clearTimeout(i.current),i.current=null),a.current?.(e),a.current=null},[]);(0,t.useEffect)(()=>()=>{x(null)},[x]);let S=(0,t.useCallback)(()=>{x(null),b()},[x,b]),C=(0,t.useCallback)(()=>{x(null),_()},[x,_]),w=(0,t.useCallback)(async(e,t,r)=>{try{let i={signal:t},a=n.searchAddress(r,i),o=await Promise.race([a,y(t)]);return t.aborted||o===null?null:(d(e,o),o)}catch(n){return t.aborted?null:f(e,m(n))}finally{p(e)}},[n,p,f,d]);return{loading:o,data:s,error:c,cancel:C,reset:S,search:(0,t.useCallback)(e=>{let t=v(e),{requestId:n,signal:o}=l();if(x(null),t===null){let e=f(n,u(`invalid_query`,`Address query is required`));return p(n),Promise.resolve(e)}return r<=0?new Promise(e=>{a.current=e,w(n,o,t).then(t=>{e(t),a.current===e&&(a.current=null)})}):new Promise(e=>{a.current=e,i.current=globalThis.setTimeout(()=>{i.current=null;let e=a.current;a.current=null,w(n,o,t).then(t=>{e?.(t)})},r)})},[l,x,r,w])}}function x(e){if(e)return e;throw Error(`useJapanPostalCode requires options.dataSource`)}function S(e){let n=(0,t.useMemo)(()=>x(e.dataSource),[e.dataSource]),{loading:r,data:i,error:a,beginRequest:o,setSuccess:c,setFailure:l,finishRequest:d,cancel:f,reset:p}=h();return{loading:r,data:i,error:a,cancel:f,reset:p,search:(0,t.useCallback)(async e=>{let{requestId:t,signal:r}=o();try{let i=typeof e==`string`?{postalCode:e}:e,a=s(i.postalCode);if(!/^\d{3,7}$/.test(a))throw u(`invalid_postal_code`,`Postal code must contain between 3 and 7 digits`);let o={signal:r},l={postalCode:a,pageNumber:i.pageNumber??0,rowsPerPage:i.rowsPerPage??100,...i.includeParenthesesTown===void 0?{}:{includeParenthesesTown:i.includeParenthesesTown}},d=await n.lookupPostalCode(l,o);return r.aborted?null:(c(t,d),d)}catch(e){return r.aborted?null:l(t,m(e))}finally{d(t)}},[o,n,d,l,c])}}function C(e){let n=(0,t.useMemo)(()=>{if(e.dataSource)return e.dataSource;throw Error(`useJapanAddress requires options.dataSource`)},[e.dataSource]),r=S({dataSource:n}),i=b({dataSource:n,debounceMs:e.debounceMs}),a=r.reset,o=r.search,s=i.reset,c=i.search,[l,u]=(0,t.useState)(null),d=(0,t.useCallback)(async e=>(s(),u(`postalCode`),o(e)),[s,o]),f=(0,t.useCallback)(async e=>(a(),u(`addressQuery`),c(e)),[a,c]),p=(0,t.useCallback)(()=>{a(),s(),u(null)},[s,a]),m=l===`postalCode`?r.data:l===`addressQuery`?i.data:null,h=l===`postalCode`?r.error:l===`addressQuery`?i.error:null;return{loading:r.loading||i.loading,data:m,error:h,reset:p,searchByPostalCode:d,searchByAddressQuery:f}}e.AddressSearchInput=o,e.PostalCodeInput=l,e.createJapanAddressError=u,e.formatJapanPostalCode=c,e.isValidJapanPostalCode=p,e.normalizeJapanPostAddressRecord=f,e.normalizeJapanPostalCode=s,e.useJapanAddress=C,e.useJapanAddressSearch=b,e.useJapanPostalCode=S});
|
|
@@ -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
|
|
@@ -0,0 +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;;;;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
|
|
@@ -0,0 +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;;;;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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { JapanAddressError, JapanAddressErrorCode } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 라이브러리 전반에서 공통으로 쓰는 오류 객체 생성기다.
|
|
4
|
+
* 브라우저 fetch 오류, validation 오류, data source 오류를 모두 같은 표면으로 맞춰
|
|
5
|
+
* 소비자가 code/status만으로 분기할 수 있게 한다.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createJapanAddressError(code: JapanAddressErrorCode, message: string, options?: {
|
|
8
|
+
cause?: unknown;
|
|
9
|
+
status?: number;
|
|
10
|
+
}): JapanAddressError;
|
|
11
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +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;;;;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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../../src/core/formatters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW3D"}
|
|
@@ -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
|
|
@@ -0,0 +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;AAe1E;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,4BAA4B,GACnC,YAAY,CAoBd"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* `japanpost-react`의 공개 계약과 내부 정규화 계약을 한 곳에 모아 둔 타입 모음이다.
|
|
4
|
+
* 훅, 입력 컴포넌트, data source, minimal-api 연동 예제가 모두 이 정의를 기준으로 맞물리므로
|
|
5
|
+
* 필드 의미를 바꿀 때는 런타임 동작뿐 아니라 외부 사용자의 기대 계약도 함께 고려해야 한다.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 일본우정 API에서 반환되는 원본 주소 레코드 형태.
|
|
9
|
+
* 공개 API 표면에는 직접 노출하지 않고 내부에서만 사용한다.
|
|
10
|
+
*/
|
|
11
|
+
export type JapanPostApiAddressRecord = {
|
|
12
|
+
zip_code?: string | number | null;
|
|
13
|
+
pref_code?: string | number | null;
|
|
14
|
+
pref_name?: string | null;
|
|
15
|
+
pref_kana?: string | null;
|
|
16
|
+
city_name?: string | null;
|
|
17
|
+
city_kana?: string | null;
|
|
18
|
+
town_name?: string | null;
|
|
19
|
+
town_kana?: string | null;
|
|
20
|
+
block_name?: string | null;
|
|
21
|
+
other_name?: string | null;
|
|
22
|
+
address?: string | null;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* 우편번호로 주소를 검색할 때(searchcode) API 응답 형태.
|
|
26
|
+
*/
|
|
27
|
+
export type JapanPostSearchCodeResponse = {
|
|
28
|
+
addresses?: JapanPostApiAddressRecord[] | null;
|
|
29
|
+
message?: string | null;
|
|
30
|
+
status?: number;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* 주소 키워드로 검색할 때(addresszip) API 응답 형태.
|
|
34
|
+
*/
|
|
35
|
+
export type JapanPostAddressZipResponse = {
|
|
36
|
+
addresses?: JapanPostApiAddressRecord[] | null;
|
|
37
|
+
message?: string | null;
|
|
38
|
+
status?: number;
|
|
39
|
+
};
|
|
40
|
+
export type JapanPostApiResponse = JapanPostSearchCodeResponse | JapanPostAddressZipResponse;
|
|
41
|
+
/**
|
|
42
|
+
* minimal-api가 그대로 받는 공개 searchcode 요청 타입이다.
|
|
43
|
+
* pageNumber/rowsPerPage를 노출하는 이유는 라이브러리와 API 예제가 같은 pager 의미 체계를 공유하기 위해서다.
|
|
44
|
+
*/
|
|
45
|
+
export type JapanPostSearchcodeRequest = {
|
|
46
|
+
postalCode: string;
|
|
47
|
+
pageNumber: number;
|
|
48
|
+
rowsPerPage: number;
|
|
49
|
+
includeParenthesesTown?: boolean | null;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* useJapanPostalCode의 공개 검색 입력 타입.
|
|
53
|
+
* 문자열 입력은 기존 호환성을 유지하고, 객체 입력은 pager 옵션을 함께 전달할 수 있게 한다.
|
|
54
|
+
*/
|
|
55
|
+
export type JapanPostalCodeSearchInput = string | {
|
|
56
|
+
postalCode: string;
|
|
57
|
+
pageNumber?: number;
|
|
58
|
+
rowsPerPage?: number;
|
|
59
|
+
includeParenthesesTown?: boolean | null;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* useJapanAddressSearch의 공개 검색 입력 타입.
|
|
63
|
+
* 문자열 입력은 키워드 검색 호환성을 유지하고, 객체 입력은 자유 검색과 구조화 검색 필드를 함께 전달할 수 있게 한다.
|
|
64
|
+
*/
|
|
65
|
+
export type JapanAddressSearchInput = string | (Omit<JapanPostAddresszipRequest, "pageNumber" | "rowsPerPage"> & {
|
|
66
|
+
pageNumber?: number;
|
|
67
|
+
rowsPerPage?: number;
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* minimal-api가 그대로 받는 공개 addresszip 요청 타입이다.
|
|
71
|
+
* 자유 검색(addressQuery)뿐 아니라 구조화 검색 필드도 함께 열어 두어
|
|
72
|
+
* 상위 UI가 필요한 만큼만 업스트림 검색 축을 선택적으로 노출할 수 있게 한다.
|
|
73
|
+
*/
|
|
74
|
+
export type JapanPostAddresszipRequest = {
|
|
75
|
+
addressQuery?: string | null;
|
|
76
|
+
prefCode?: string | null;
|
|
77
|
+
prefName?: string | null;
|
|
78
|
+
prefKana?: string | null;
|
|
79
|
+
prefRoma?: string | null;
|
|
80
|
+
cityCode?: string | null;
|
|
81
|
+
cityName?: string | null;
|
|
82
|
+
cityKana?: string | null;
|
|
83
|
+
cityRoma?: string | null;
|
|
84
|
+
townName?: string | null;
|
|
85
|
+
townKana?: string | null;
|
|
86
|
+
townRoma?: string | null;
|
|
87
|
+
pageNumber: number;
|
|
88
|
+
rowsPerPage: number;
|
|
89
|
+
includeCityDetails?: boolean | null;
|
|
90
|
+
includePrefectureDetails?: boolean | null;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* API 응답을 정규화한 후의 중간 주소 레코드 형태.
|
|
94
|
+
* 내부 data source 처리 후 공개 JapanAddress 타입으로 변환되기 전에 사용된다.
|
|
95
|
+
*/
|
|
96
|
+
export type NormalizedJapanAddressRecord = {
|
|
97
|
+
postalCode: string;
|
|
98
|
+
prefecture: string;
|
|
99
|
+
prefectureKana?: string;
|
|
100
|
+
city: string;
|
|
101
|
+
cityKana?: string;
|
|
102
|
+
town: string;
|
|
103
|
+
townKana?: string;
|
|
104
|
+
detail?: string;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* 라이브러리 공개 주소 타입. 훅과 클라이언트가 외부로 반환하는 최종 형태.
|
|
108
|
+
* `address`는 표시 편의를 위한 결합 문자열이고, 나머지 필드는 후처리/재조합이 가능한 구조화 값이다.
|
|
109
|
+
*/
|
|
110
|
+
export type JapanAddress = {
|
|
111
|
+
postalCode: string;
|
|
112
|
+
prefecture: string;
|
|
113
|
+
prefectureKana?: string;
|
|
114
|
+
city: string;
|
|
115
|
+
cityKana?: string;
|
|
116
|
+
town: string;
|
|
117
|
+
townKana?: string;
|
|
118
|
+
address: string;
|
|
119
|
+
provider: "japan-post";
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* minimal-api와 라이브러리가 공통으로 사용하는 pager 응답 계약이다.
|
|
123
|
+
* 페이지 기반 UI가 아니더라도 total/page 정보를 유지해 "결과 없음"과 "일부만 조회됨"을 구분할 수 있다.
|
|
124
|
+
*/
|
|
125
|
+
export type Page<T> = {
|
|
126
|
+
elements: T[];
|
|
127
|
+
totalElements: number;
|
|
128
|
+
pageNumber: number;
|
|
129
|
+
rowsPerPage: number;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* 우편번호 조회 결과.
|
|
133
|
+
* 단일 주소만 기대하는 소비자도 있을 수 있지만, 업스트림 계약이 목록 + 페이징이므로 그대로 보존한다.
|
|
134
|
+
*/
|
|
135
|
+
export type JapanPostalCodeLookupResult = Page<JapanAddress>;
|
|
136
|
+
/**
|
|
137
|
+
* 키워드 주소 검색 결과.
|
|
138
|
+
* postal code 조회와 동일한 pager 형태를 사용해 두 검색 모드를 같은 UI로 렌더링할 수 있게 한다.
|
|
139
|
+
*/
|
|
140
|
+
export type JapanAddressSearchResult = Page<JapanAddress>;
|
|
141
|
+
/**
|
|
142
|
+
* 라이브러리 전용 오류 코드 목록.
|
|
143
|
+
* 소비자는 message 문자열보다 code를 기준으로 UX를 분기하는 것이 안전하다.
|
|
144
|
+
*/
|
|
145
|
+
export type JapanAddressErrorCode = "invalid_postal_code" | "invalid_query" | "network_error" | "timeout" | "not_found" | "bad_response" | "data_source_error";
|
|
146
|
+
/**
|
|
147
|
+
* 라이브러리 전용 에러 타입. 훅과 data source 전반에서 일관되게 사용된다.
|
|
148
|
+
* 브라우저/서버/사용자 입력 오류를 모두 같은 형태로 감싸 public contract를 단순화한다.
|
|
149
|
+
*/
|
|
150
|
+
export type JapanAddressError = Error & {
|
|
151
|
+
name: "JapanAddressError";
|
|
152
|
+
code: JapanAddressErrorCode;
|
|
153
|
+
cause?: unknown;
|
|
154
|
+
status?: number;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* data source 요청에 전달할 선택 옵션.
|
|
158
|
+
* 현재는 AbortSignal만 쓰지만, 추후 timeout/metadata가 필요해져도 호출부 시그니처를 크게 흔들지 않기 위한 확장 지점이다.
|
|
159
|
+
*/
|
|
160
|
+
export type JapanAddressRequestOptions = {
|
|
161
|
+
signal?: AbortSignal;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* 주소 데이터를 제공하는 data source 인터페이스.
|
|
165
|
+
* 커스텀 구현체로 교체할 수 있도록 추상화되어 있다.
|
|
166
|
+
* 즉, 훅은 fetch 구현을 모르고 pager 계약과 에러 계약만 신뢰한다.
|
|
167
|
+
*/
|
|
168
|
+
export type JapanAddressDataSource = {
|
|
169
|
+
lookupPostalCode: (request: JapanPostSearchcodeRequest, options?: JapanAddressRequestOptions) => Promise<Page<JapanAddress>>;
|
|
170
|
+
searchAddress: (request: JapanPostAddresszipRequest, options?: JapanAddressRequestOptions) => Promise<Page<JapanAddress>>;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* useJapanPostalCode 훅 옵션.
|
|
174
|
+
* data source 주입 방식으로 브라우저 직접 호출, BFF, mock을 모두 같은 훅으로 다룬다.
|
|
175
|
+
*/
|
|
176
|
+
export type UseJapanPostalCodeOptions = {
|
|
177
|
+
dataSource: JapanAddressDataSource;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* useJapanAddressSearch 훅 옵션.
|
|
181
|
+
* debounce는 UI 입력 빈도를 제어하기 위한 것이며 data source 계약을 바꾸지 않는다.
|
|
182
|
+
*/
|
|
183
|
+
export type UseJapanAddressSearchOptions = {
|
|
184
|
+
dataSource: JapanAddressDataSource;
|
|
185
|
+
debounceMs?: number;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* useJapanAddress 훅 옵션.
|
|
189
|
+
* 통합 훅도 내부적으로는 두 검색 훅을 조합하므로 필요한 옵션만 얇게 위임한다.
|
|
190
|
+
*/
|
|
191
|
+
export type UseJapanAddressOptions = {
|
|
192
|
+
dataSource: JapanAddressDataSource;
|
|
193
|
+
debounceMs?: number;
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* 비동기 데이터 로딩 상태를 표현하는 제네릭 타입.
|
|
197
|
+
* 모든 훅이 같은 상태 모양을 공유하면 소비자 컴포넌트가 검색 종류와 무관하게 공통 렌더링 로직을 가질 수 있다.
|
|
198
|
+
*/
|
|
199
|
+
export type UseAsyncState<T> = {
|
|
200
|
+
loading: boolean;
|
|
201
|
+
data: T | null;
|
|
202
|
+
error: JapanAddressError | null;
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* useJapanPostalCode 훅의 반환 타입.
|
|
206
|
+
* search는 실패나 취소 시 null을 반환해 UI가 try/catch 없이도 분기할 수 있게 한다.
|
|
207
|
+
*/
|
|
208
|
+
export type UseJapanPostalCodeResult = UseAsyncState<JapanPostalCodeLookupResult> & {
|
|
209
|
+
cancel: () => void;
|
|
210
|
+
reset: () => void;
|
|
211
|
+
search: (input: JapanPostalCodeSearchInput) => Promise<JapanPostalCodeLookupResult | null>;
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* useJapanAddressSearch 훅의 반환 타입.
|
|
215
|
+
* debounce 취소와 오류 모두 Promise 결과 관점에서는 null로 귀결될 수 있으므로 호출부는 state와 함께 해석해야 한다.
|
|
216
|
+
*/
|
|
217
|
+
export type UseJapanAddressSearchResult = UseAsyncState<JapanAddressSearchResult> & {
|
|
218
|
+
cancel: () => void;
|
|
219
|
+
reset: () => void;
|
|
220
|
+
search: (input: JapanAddressSearchInput) => Promise<JapanAddressSearchResult | null>;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* useJapanAddress 훅의 반환 타입.
|
|
224
|
+
* data/error는 "현재 활성 검색 모드" 기준 값이며, 두 내부 훅의 상태 전체를 그대로 노출하지는 않는다.
|
|
225
|
+
*/
|
|
226
|
+
export type UseJapanAddressResult = UseAsyncState<Page<JapanAddress>> & {
|
|
227
|
+
reset: () => void;
|
|
228
|
+
searchByPostalCode: (input: JapanPostalCodeSearchInput) => Promise<JapanPostalCodeLookupResult | null>;
|
|
229
|
+
searchByAddressQuery: (input: JapanAddressSearchInput) => Promise<JapanAddressSearchResult | null>;
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* 검색 입력 컴포넌트들이 공유하는 공통 props.
|
|
233
|
+
* 제어/비제어 모드를 모두 지원해 폼 라이브러리와 단순 데모 예제를 같은 컴포넌트로 소화한다.
|
|
234
|
+
*/
|
|
235
|
+
type BaseTextSearchInputProps = {
|
|
236
|
+
defaultValue?: string;
|
|
237
|
+
value?: string;
|
|
238
|
+
disabled?: boolean;
|
|
239
|
+
label?: ReactNode;
|
|
240
|
+
buttonLabel?: ReactNode;
|
|
241
|
+
inputProps?: Omit<ComponentPropsWithoutRef<"input">, "defaultValue" | "disabled" | "onChange" | "value">;
|
|
242
|
+
buttonProps?: Omit<ComponentPropsWithoutRef<"button">, "children" | "disabled" | "onClick" | "type">;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* PostalCodeInput 컴포넌트 props.
|
|
246
|
+
* onSearch는 표시 문자열이 아니라 정규화된 우편번호를 받는다는 점이 핵심 계약이다.
|
|
247
|
+
*/
|
|
248
|
+
export type PostalCodeInputProps = BaseTextSearchInputProps & {
|
|
249
|
+
onChange?: (postalCode: string) => void;
|
|
250
|
+
onSearch: (postalCode: string) => void;
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* AddressSearchInput 컴포넌트 props.
|
|
254
|
+
* onSearch에는 trim 처리된 검색어가 전달되어 공백만 다른 입력이 별도 쿼리로 취급되지 않게 한다.
|
|
255
|
+
*/
|
|
256
|
+
export type AddressSearchInputProps = BaseTextSearchInputProps & {
|
|
257
|
+
onChange?: (query: string) => void;
|
|
258
|
+
onSearch: (query: string) => void;
|
|
259
|
+
};
|
|
260
|
+
export {};
|
|
261
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../../src/core/validators.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG7D"}
|