@iyulab/router 0.9.3 → 0.10.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/CHANGELOG.md +13 -0
- package/dist/Router.d.ts +38 -0
- package/dist/components/UErrorPage.d.ts +16 -0
- package/dist/components/ULink.d.ts +57 -0
- package/dist/components/UOutlet.d.ts +30 -0
- package/dist/index.d.ts +9 -514
- package/dist/index.js +7 -6
- package/dist/internals/RouteTracker.d.ts +22 -0
- package/dist/internals/crypto-helpers.d.ts +8 -0
- package/dist/internals/element-helpers.d.ts +36 -0
- package/dist/internals/route-helpers.d.ts +21 -0
- package/dist/internals/url-helpers.d.ts +38 -0
- package/dist/react.d.ts +10 -100
- package/dist/react.js +1 -1
- package/dist/{share-DC0R4F2d.js → share-C2LbLiIW.js} +2 -2
- package/dist/types/NavigateOptions.d.ts +25 -0
- package/dist/types/RouteConfig.d.ts +133 -0
- package/dist/types/RouteContext.d.ts +85 -0
- package/dist/types/RouteError.d.ts +52 -0
- package/dist/types/RouteEvent.d.ts +43 -0
- package/dist/types/RouterConfig.d.ts +52 -0
- package/package.json +11 -8
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as isExternalUrl, i as absolutePath, n as __decorate, o as parseUrl, r as __decorateMetadata, s as UOutlet, t as ULink } from "./share-
|
|
1
|
+
import { a as isExternalUrl, i as absolutePath, n as __decorate, o as parseUrl, r as __decorateMetadata, s as UOutlet, t as ULink } from "./share-C2LbLiIW.js";
|
|
2
2
|
import { LitElement, css, html } from "lit";
|
|
3
3
|
import { customElement, property } from "lit/decorators.js";
|
|
4
4
|
//#region src/types/RouteError.ts
|
|
@@ -113,7 +113,6 @@ var RouteErrorEvent = class extends RouteEvent {
|
|
|
113
113
|
};
|
|
114
114
|
//#endregion
|
|
115
115
|
//#region src/components/UErrorPage.ts
|
|
116
|
-
var _ref, _ref2;
|
|
117
116
|
var UErrorPage = class UErrorPage extends LitElement {
|
|
118
117
|
constructor(error) {
|
|
119
118
|
super();
|
|
@@ -205,8 +204,8 @@ var UErrorPage = class UErrorPage extends LitElement {
|
|
|
205
204
|
`;
|
|
206
205
|
}
|
|
207
206
|
};
|
|
208
|
-
__decorate([property({ type: Object }), __decorateMetadata("design:type", typeof
|
|
209
|
-
UErrorPage = __decorate([customElement("u-error-page"), __decorateMetadata("design:paramtypes", [typeof
|
|
207
|
+
__decorate([property({ type: Object }), __decorateMetadata("design:type", typeof RouteError === "undefined" ? Object : RouteError)], UErrorPage.prototype, "error", void 0);
|
|
208
|
+
UErrorPage = __decorate([customElement("u-error-page"), __decorateMetadata("design:paramtypes", [typeof RouteError === "undefined" ? Object : RouteError])], UErrorPage);
|
|
210
209
|
//#endregion
|
|
211
210
|
//#region src/internals/crypto-helpers.ts
|
|
212
211
|
/**
|
|
@@ -217,7 +216,7 @@ UErrorPage = __decorate([customElement("u-error-page"), __decorateMetadata("desi
|
|
|
217
216
|
* @return 랜덤한 ID 문자열
|
|
218
217
|
*/
|
|
219
218
|
function getRandomID() {
|
|
220
|
-
return window.isSecureContext ? window.crypto.randomUUID() : window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16);
|
|
219
|
+
return window.isSecureContext ? window.crypto.randomUUID() : window.crypto.getRandomValues(/* @__PURE__ */ new Uint32Array(1))[0].toString(16);
|
|
221
220
|
}
|
|
222
221
|
//#endregion
|
|
223
222
|
//#region src/internals/element-helpers.ts
|
|
@@ -402,7 +401,9 @@ var Router = class {
|
|
|
402
401
|
if (anchor.hasAttribute("download")) return;
|
|
403
402
|
if (anchor.getAttribute("rel") === "external") return;
|
|
404
403
|
if (anchor.target && anchor.target !== "") return;
|
|
405
|
-
|
|
404
|
+
const pathname = new URL(anchor.href).pathname;
|
|
405
|
+
if (this._basepath !== "/" && !pathname.startsWith(this._basepath)) return;
|
|
406
|
+
if (getRoutes(this._routes, pathname).length === 0) return;
|
|
406
407
|
e.preventDefault();
|
|
407
408
|
await this.go(anchor.href);
|
|
408
409
|
} catch {}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RouteConfig } from '../types/RouteConfig.js';
|
|
2
|
+
/**
|
|
3
|
+
* 라우팅 체인 상태를 추적합니다.
|
|
4
|
+
* - 방문한 href를 기록하여 리다이렉트 사이클을 감지합니다.
|
|
5
|
+
* - 이미 실행된 route enter를 기록하여 중복 실행을 방지합니다.
|
|
6
|
+
*/
|
|
7
|
+
export declare class RouteTracker {
|
|
8
|
+
private readonly _history;
|
|
9
|
+
private readonly _processed;
|
|
10
|
+
/** 새 네비게이션 시작 시 상태를 초기화합니다. */
|
|
11
|
+
reset(): void;
|
|
12
|
+
/**
|
|
13
|
+
* href 방문을 기록하고 사이클 여부를 반환합니다.
|
|
14
|
+
* @returns 사이클이 감지되면 true
|
|
15
|
+
*/
|
|
16
|
+
visit(href: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* route enter를 아직 실행하지 않았다면 키를 등록하고 true를 반환합니다.
|
|
19
|
+
* 이미 실행된 route라면 false를 반환합니다 (중첩 라우트 redirect 체인에서 중복 방지).
|
|
20
|
+
*/
|
|
21
|
+
enter(route: RouteConfig): boolean;
|
|
22
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { UOutlet } from '../components/UOutlet';
|
|
2
|
+
/**
|
|
3
|
+
* `u-outlet` 엘리먼트를 찾아 반환합니다.
|
|
4
|
+
*
|
|
5
|
+
* @param element 검색을 시작할 HTMLElement
|
|
6
|
+
* @param skip element 자신을 검사에서 제외할지 여부 (기본값: false)
|
|
7
|
+
* @returns 찾은 UOutlet 엘리먼트 또는 undefined
|
|
8
|
+
*/
|
|
9
|
+
export declare function findOutlet(element: HTMLElement, skip?: boolean): UOutlet | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* `u-outlet` 엘리먼트를 찾아 반환합니다. 없으면 에러를 던집니다.
|
|
12
|
+
*
|
|
13
|
+
* @param element 검색을 시작할 HTMLElement
|
|
14
|
+
* @param skip element 자신을 검사에서 제외할지 여부 (기본값: false)
|
|
15
|
+
*
|
|
16
|
+
* @returns 찾은 UOutlet 엘리먼트
|
|
17
|
+
* @throws OutletMissingError `u-outlet` 엘리먼트를 찾지 못한 경우
|
|
18
|
+
*/
|
|
19
|
+
export declare function findOutletOrThrow(element: HTMLElement, skip?: boolean): UOutlet;
|
|
20
|
+
/**
|
|
21
|
+
* 주어진 엘리먼트 내에서 `u-outlet`이 준비될 때까지 대기합니다.
|
|
22
|
+
*
|
|
23
|
+
* @param element 대기할 엘리먼트
|
|
24
|
+
* @param timeout 타임아웃 시간(밀리초, 기본값: 10_000ms)
|
|
25
|
+
* @param skip element 자신을 검사에서 제외할지 여부 (기본값: false)
|
|
26
|
+
*
|
|
27
|
+
* @returns 준비된 `u-outlet` 엘리먼트
|
|
28
|
+
*/
|
|
29
|
+
export declare function waitOutlet(element: HTMLElement, timeout?: number, skip?: boolean): Promise<UOutlet>;
|
|
30
|
+
/**
|
|
31
|
+
* 이벤트에서 composedPath()/closest를 사용하여 A 태그를 찾아 반환합니다.
|
|
32
|
+
*
|
|
33
|
+
* @param event 이벤트 객체
|
|
34
|
+
* @returns 찾은 A 태그 엘리먼트 또는 null
|
|
35
|
+
*/
|
|
36
|
+
export declare function findAnchorFrom(event: Event): HTMLAnchorElement | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RouteConfig } from '../types/RouteConfig';
|
|
2
|
+
/**
|
|
3
|
+
* 라우트들을 다음 사항에 따라 재귀적으로 재설정합니다.
|
|
4
|
+
* - 각 라우트에 고유 `id`를 랜덤하게 부여합니다.
|
|
5
|
+
* - `path`를 URLPattern 객체로 변환합니다.
|
|
6
|
+
* - 자식 라우트가 있으면 재귀적으로 재설정합니다.
|
|
7
|
+
*
|
|
8
|
+
* @param routes 설정할 라우트 배열
|
|
9
|
+
* @param basepath 기준이 되는 basepath 문자열
|
|
10
|
+
* @returns 재설정된 라우트 배열
|
|
11
|
+
*/
|
|
12
|
+
export declare function setRoutes(routes: RouteConfig[], basepath: string): RouteConfig[];
|
|
13
|
+
/**
|
|
14
|
+
* URLPattern을 사용하여 경로와 일치하는 라우트들을 자식 라우트까지 포함하여 반환합니다.
|
|
15
|
+
* 반환된 배열은 상위 라우트부터 하위 라우트 순서로 정렬됩니다.
|
|
16
|
+
*
|
|
17
|
+
* @param routes 검사할 라우트 배열
|
|
18
|
+
* @param pathname 검사할 경로 이름
|
|
19
|
+
* @returns 일치하는 라우트 배열
|
|
20
|
+
*/
|
|
21
|
+
export declare function getRoutes(routes: RouteConfig[], pathname: string): RouteConfig[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { RouteContext } from '../types/RouteContext';
|
|
2
|
+
/**
|
|
3
|
+
* 주어진 URL이 외부 링크인지 확인합니다.
|
|
4
|
+
*
|
|
5
|
+
* @param url 확인할 URL 문자열
|
|
6
|
+
* @return 외부 링크인 경우 true, 내부 링크인 경우 false
|
|
7
|
+
*/
|
|
8
|
+
export declare function isExternalUrl(url: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* URL 문자열을 파싱하여 RouteContext 객체로 반환합니다.
|
|
11
|
+
* - http(s)로 시작하는 절대 URL은 외부 링크로 간주됩니다.
|
|
12
|
+
* - 절대경로(/...)는 그대로 사용됩니다.
|
|
13
|
+
* - 상대경로는 basepath를 기준으로 절대경로로 변환됩니다.
|
|
14
|
+
* - 쿼리스트링(?)로 시작하는 쿼리는 현재 경로와 추가됩니다.
|
|
15
|
+
* - 해시(#)로 시작하는 해시는 현재 경로와 추가됩니다.
|
|
16
|
+
*
|
|
17
|
+
* @param url 파싱할 URL 문자열
|
|
18
|
+
* @param basepath 기준이 되는 basepath 문자열
|
|
19
|
+
* @returns 파싱된 RouteContext 객체
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseUrl(url: string, basepath: string): RouteContext;
|
|
22
|
+
/**
|
|
23
|
+
* pathname 경로를 조합하여 절대경로를 반환합니다.
|
|
24
|
+
*
|
|
25
|
+
* @param paths 조합할 경로 문자열들
|
|
26
|
+
* @returns 조합된 절대경로 문자열
|
|
27
|
+
*/
|
|
28
|
+
export declare function absolutePath(...paths: string[]): string;
|
|
29
|
+
/**
|
|
30
|
+
* basepath가 동적 패턴일 경우(RouteConfig에서 basepath가 :id 등으로 정의된 경우),
|
|
31
|
+
* 현재 경로에서 해당되는 패턴의 basepath를 추출하여 반환합니다.
|
|
32
|
+
*
|
|
33
|
+
* @param basepath 동적 패턴이 포함된 basepath 문자열
|
|
34
|
+
* @return 현재 경로에 매칭되는 basepath 문자열
|
|
35
|
+
* @example
|
|
36
|
+
* catchBasePath('/app/:id') => '/app/123'
|
|
37
|
+
*/
|
|
38
|
+
export declare function catchBasepath(basepath: string): string;
|
package/dist/react.d.ts
CHANGED
|
@@ -1,100 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/** 강제 렌더링 여부 */
|
|
12
|
-
force?: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* `u-link` 웹 컴포넌트를 React에서 사용할 수 있도록 래핑한 컴포넌트입니다.
|
|
17
|
-
*/
|
|
18
|
-
export declare const ULink: ReactWebComponent<ULink_2, {}>;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* - 클라이언트 라우팅을 지원하는 링크 엘리먼트입니다.
|
|
22
|
-
* - 내부 링크는 클라이언트 라우팅을 수행하고, 외부 링크는 브라우저 기본 네비게이션을 사용합니다.
|
|
23
|
-
* - Ctrl/Meta/Shift/Alt, 중클릭/우클릭 등은 브라우저 기본 동작(새 탭, 컨텍스트 메뉴 등)을 그대로 유지합니다.
|
|
24
|
-
*/
|
|
25
|
-
declare class ULink_2 extends LitElement {
|
|
26
|
-
/** 외부 링크 여부 */
|
|
27
|
-
private isExternal;
|
|
28
|
-
/**
|
|
29
|
-
* 링크 대상 target 속성
|
|
30
|
-
*
|
|
31
|
-
* - `_self`: 현재 창에서 링크 열기 (기본값)
|
|
32
|
-
* - `_blank`: 새 탭/창에서 링크 열기
|
|
33
|
-
* - `_parent`: 부모 프레임에서 링크 열기
|
|
34
|
-
* - `_top`: 최상위 프레임에서 링크 열기
|
|
35
|
-
*/
|
|
36
|
-
target?: string;
|
|
37
|
-
/**
|
|
38
|
-
* 링크 관계 rel 속성
|
|
39
|
-
*
|
|
40
|
-
* - `noopener`: target이 _blank인 경우 보안 강화 (window.opener 차단)
|
|
41
|
-
* - `noreferrer`: target이 _blank인 경우 보안 강화 + Referer 헤더 제거
|
|
42
|
-
* - `external`: 외부 링크임을 명시 (SEO/접근성에 도움)
|
|
43
|
-
* - `nofollow`: 검색 엔진이 링크를 따라가지 않도록 지시 (SEO에 영향)
|
|
44
|
-
* - 그 외 rel 값도 그대로 전달됩니다.
|
|
45
|
-
*/
|
|
46
|
-
rel?: string;
|
|
47
|
-
/**
|
|
48
|
-
* 링크 대상 URL, 다음 사항에 따라 SPA 라우팅 또는 브라우저 네비게이션이 결정됩니다.
|
|
49
|
-
*
|
|
50
|
-
* - 속성을 정의하지 않으면 설정에서 지정한 `basepath`로 SPA 라우팅합니다.
|
|
51
|
-
* - http(s)로 시작하면 외부 링크로 간주하고 브라우저 네비게이션을 사용합니다.
|
|
52
|
-
* - 절대경로(/...)의 경우 `basepath`로 시작하면 SPA 라우팅합니다, 이외 브라우저 네비게이션을 사용합니다.
|
|
53
|
-
* - 상대경로는 (basepath + 상대경로)로 결합하여 SPA 라우팅합니다.
|
|
54
|
-
* - ?로 시작하면 현재 경로에 쿼리스트링을 추가하여 SPA 라우팅합니다.
|
|
55
|
-
* - #으로 시작하면 브라우저 기본 동작을 사용합니다.
|
|
56
|
-
*/
|
|
57
|
-
href?: string;
|
|
58
|
-
connectedCallback(): void;
|
|
59
|
-
disconnectedCallback(): void;
|
|
60
|
-
protected willUpdate(changedProperties: PropertyValues): void;
|
|
61
|
-
render(): TemplateResult<1>;
|
|
62
|
-
/** a 태그에 주입할 href 값을 계산합니다. */
|
|
63
|
-
private compute;
|
|
64
|
-
/**
|
|
65
|
-
* 클릭 가로채기 핸들러
|
|
66
|
-
* - 좌클릭(0) + 보조키 없음(ctrl/meta/shift/alt 없음) + target이 _self일 때만 SPA 라우팅 고려
|
|
67
|
-
* - 그 외(중클릭/우클릭/보조키/target=_blank 등)는 브라우저 기본 동작 유지
|
|
68
|
-
*/
|
|
69
|
-
private handleClick;
|
|
70
|
-
/** 클라이언트 라우팅을 위해 popstate 이벤트를 발생시킵니다. */
|
|
71
|
-
private dispatchPopstate;
|
|
72
|
-
/** basepath를 state에서 꺼내는 헬퍼 */
|
|
73
|
-
private getBasepath;
|
|
74
|
-
static styles: CSSResult;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* `u-outlet` 웹 컴포넌트를 React에서 사용할 수 있도록 래핑한 컴포넌트입니다.
|
|
79
|
-
*/
|
|
80
|
-
export declare const UOutlet: ReactWebComponent<UOutlet_2, {}>;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* LitElement 또는 React 컴포넌트를 렌더링해주는 웹컴포넌트 입니다.
|
|
84
|
-
*/
|
|
85
|
-
declare class UOutlet_2 extends HTMLElement {
|
|
86
|
-
/** 교차 렌더링 방지 id */
|
|
87
|
-
private routeId?;
|
|
88
|
-
/** 실제 렌더링 컨텐츠 */
|
|
89
|
-
private root?;
|
|
90
|
-
/**
|
|
91
|
-
* 주어진 렌더링 옵션에 따라 컨텐츠를 렌더링합니다.
|
|
92
|
-
*/
|
|
93
|
-
render(value: unknown, options?: RenderOption): Promise<void>;
|
|
94
|
-
/**
|
|
95
|
-
* 기존 DOM을 삭제하여, 초기 상태로 되돌립니다.
|
|
96
|
-
*/
|
|
97
|
-
reset(): void;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export { }
|
|
1
|
+
import { ULink as ULinkElement } from './components/ULink.js';
|
|
2
|
+
import { UOutlet as UOutletElement } from './components/UOutlet.js';
|
|
3
|
+
/**
|
|
4
|
+
* `u-link` 웹 컴포넌트를 React에서 사용할 수 있도록 래핑한 컴포넌트입니다.
|
|
5
|
+
*/
|
|
6
|
+
export declare const ULink: import('@lit/react').ReactWebComponent<ULinkElement, {}>;
|
|
7
|
+
/**
|
|
8
|
+
* `u-outlet` 웹 컴포넌트를 React에서 사용할 수 있도록 래핑한 컴포넌트입니다.
|
|
9
|
+
*/
|
|
10
|
+
export declare const UOutlet: import('@lit/react').ReactWebComponent<UOutletElement, {}>;
|
package/dist/react.js
CHANGED
|
@@ -126,12 +126,12 @@ function catchBasepath(basepath) {
|
|
|
126
126
|
return basepath;
|
|
127
127
|
}
|
|
128
128
|
//#endregion
|
|
129
|
-
//#region \0@oxc-project+runtime@0.
|
|
129
|
+
//#region \0@oxc-project+runtime@0.138.0/helpers/esm/decorateMetadata.js
|
|
130
130
|
function __decorateMetadata(k, v) {
|
|
131
131
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
132
132
|
}
|
|
133
133
|
//#endregion
|
|
134
|
-
//#region \0@oxc-project+runtime@0.
|
|
134
|
+
//#region \0@oxc-project+runtime@0.138.0/helpers/esm/decorate.js
|
|
135
135
|
function __decorate(decorators, target, key, desc) {
|
|
136
136
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
137
137
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* go() 메서드에 전달할 네비게이션 옵션
|
|
3
|
+
*/
|
|
4
|
+
export interface NavigateOptions {
|
|
5
|
+
/**
|
|
6
|
+
* 리다이렉트로 인한 네비게이션 여부.
|
|
7
|
+
* - `true`이면 히스토리에 새 항목을 추가하지 않고 현재 항목을 교체합니다(replaceState).
|
|
8
|
+
* - 뒤로가기 버튼이 리다이렉트 경유지를 건너뛰게 됩니다.
|
|
9
|
+
* - 리다이렉트 사이클 감지에 사용됩니다.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
isRedirect?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* 히스토리에 새 항목을 추가하지 않고 현재 항목을 교체합니다(replaceState).
|
|
15
|
+
* - `isRedirect`와 달리 리다이렉트 체인 추적에는 영향을 주지 않습니다.
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
replace?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* pushState / replaceState 호출 시 함께 저장할 커스텀 상태 객체.
|
|
21
|
+
* - `history.state`로 다시 읽을 수 있습니다.
|
|
22
|
+
* @example { from: '/login', referrer: 'email-link' }
|
|
23
|
+
*/
|
|
24
|
+
state?: Record<string, unknown>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { RouteContext, FallbackRouteContext } from './RouteContext';
|
|
2
|
+
/**
|
|
3
|
+
* 공통 라우트 속성
|
|
4
|
+
*/
|
|
5
|
+
interface BaseRouteConfig {
|
|
6
|
+
/**
|
|
7
|
+
* 라우터에서 사용하는 식별자
|
|
8
|
+
*/
|
|
9
|
+
id?: string;
|
|
10
|
+
/**
|
|
11
|
+
* 브라우저의 타이틀이 설정에 따라 변경됩니다.
|
|
12
|
+
*/
|
|
13
|
+
title?: string;
|
|
14
|
+
/**
|
|
15
|
+
* 라우터 경로는 string 또는 URLPattern을 사용할 수 있습니다.
|
|
16
|
+
* string일 경우 자동으로 URLPattern으로 변환됩니다.
|
|
17
|
+
* @default '/'
|
|
18
|
+
* @example
|
|
19
|
+
* - "/user/:id/:name"
|
|
20
|
+
* - "/user/:id/:name?"
|
|
21
|
+
* - "/user/:id/:name*"
|
|
22
|
+
* - "/user/:id/:name+"
|
|
23
|
+
* @link
|
|
24
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/URLPattern
|
|
25
|
+
*/
|
|
26
|
+
path?: string | URLPattern;
|
|
27
|
+
/**
|
|
28
|
+
* 라우트 정보를 받아 렌더링 결과를 반환합니다.
|
|
29
|
+
* @param ctx 현재 라우팅 정보 및, 진행 상태 콜백을 포함하는 Context 객체가 인자로 전달됩니다.
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const route = {
|
|
33
|
+
* path: '/user:id',
|
|
34
|
+
* render: async (ctx) => {
|
|
35
|
+
* // 사용자 정보를 비동기로 가져오는 예시
|
|
36
|
+
* const userId = ctx.params.id;
|
|
37
|
+
* ctx.progress(30);
|
|
38
|
+
* const userData = await fetchUserData(userId);
|
|
39
|
+
* ctx.progress(70);
|
|
40
|
+
* return html`<user-profile .data=${userData}></user-profile>`;
|
|
41
|
+
* }
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
* @remarks
|
|
45
|
+
* `render`는 Lit `TemplateResult`, `HTMLElement`, **또는 React 엘리먼트**를 반환할 수 있습니다.
|
|
46
|
+
* React 엘리먼트를 직접 반환하면 내부 `<u-outlet>`이 `createRoot`/`root.unmount()`를
|
|
47
|
+
* 자동으로 관리합니다 — React 루트를 직접 만들어 컨테이너 `HTMLElement`로 감싸 반환하면
|
|
48
|
+
* 이 자동 해제 지점을 우회하게 되어 라우트 전환마다 unmount가 호출되지 않는 누수가 생깁니다.
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* const route = {
|
|
52
|
+
* path: '/users/:id',
|
|
53
|
+
* render: (ctx) => <UserProfilePage userId={ctx.params.id} />, // React 엘리먼트를 직접 반환
|
|
54
|
+
* };
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
render?: (ctx: RouteContext) => Promise<unknown> | unknown;
|
|
58
|
+
/**
|
|
59
|
+
* 이 라우트 진입 전에 호출되는 enter 함수입니다.
|
|
60
|
+
* - `string` 반환: 해당 경로로 redirect
|
|
61
|
+
* - `false` 반환: 네비게이션 취소
|
|
62
|
+
* - `true` 반환: 통과
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* { path: '/admin', enter: (ctx) => ctx.metadata.role === 'admin' || '/forbidden' }
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
enter?: (ctx: RouteContext) => Promise<string | boolean> | string | boolean;
|
|
69
|
+
/**
|
|
70
|
+
* 라우터 URL 변경시 렌더링을 강제할지 여부
|
|
71
|
+
* - 기본값으로 children을 가질때 false로 설정되며, children이 없을 경우 true로 설정됩니다.
|
|
72
|
+
* - true로 설정하면 기존 렌더링을 무시하고 새로 렌더링합니다.
|
|
73
|
+
*/
|
|
74
|
+
force?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* 경로 매칭시 대소문자 구분 여부
|
|
77
|
+
* @default false
|
|
78
|
+
*/
|
|
79
|
+
ignoreCase?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* 라우트에 연결할 메타데이터
|
|
82
|
+
* - 인증, SEO, 분석 등의 용도로 사용할 수 있습니다.
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* { path: '/admin', metadata: { requiresAuth: true, role: 'admin' } }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
metadata?: Record<string, unknown>;
|
|
89
|
+
}
|
|
90
|
+
interface IndexRouteConfig extends BaseRouteConfig {
|
|
91
|
+
/**
|
|
92
|
+
* 현재 경로의 인덱스 라우트임을 나타냅니다.
|
|
93
|
+
* - 인덱스 라우트는 부모 경로와 동일한 경로를 가지며, path는 자동으로 설정됩니다.
|
|
94
|
+
*/
|
|
95
|
+
index: true;
|
|
96
|
+
}
|
|
97
|
+
interface NonIndexRouteConfig extends BaseRouteConfig {
|
|
98
|
+
/**
|
|
99
|
+
* 인덱스 라우트가 아님을 나타냅니다.
|
|
100
|
+
*/
|
|
101
|
+
index?: false;
|
|
102
|
+
/**
|
|
103
|
+
* 하위 라우트 설정, 재귀적으로 RouteConfig 배열을 가질 수 있습니다.
|
|
104
|
+
* - 하위 라우트가 있는 경우, 부모 라우트의 경로를 기준으로 매칭됩니다.
|
|
105
|
+
*/
|
|
106
|
+
children?: RouteConfig[];
|
|
107
|
+
}
|
|
108
|
+
export type RouteConfig = IndexRouteConfig | NonIndexRouteConfig;
|
|
109
|
+
export interface FallbackRouteConfig {
|
|
110
|
+
/**
|
|
111
|
+
* 브라우저의 타이틀이 설정에 따라 변경됩니다.
|
|
112
|
+
*/
|
|
113
|
+
title?: string;
|
|
114
|
+
/**
|
|
115
|
+
* 라우팅 실패 시 표시할 렌더링 결과를 반환합니다.
|
|
116
|
+
* - 오류가 발생할 경우 또는 렌더링 결과가 false일 경우 호출됩니다.
|
|
117
|
+
* @param ctx 현재 라우팅 정보 및 오류 정보를 포함하는 Context 객체가 인자로 전달됩니다.
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* const fallbackRoute = {
|
|
121
|
+
* title: 'Not Found',
|
|
122
|
+
* render: (ctx) => {
|
|
123
|
+
* if (ctx.error) {
|
|
124
|
+
* return html`<error-page .error=${ctx.error}></error-page>`;
|
|
125
|
+
* }
|
|
126
|
+
* return html`<not-found-page></not-found-page>`;
|
|
127
|
+
* }
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
render?: (ctx: FallbackRouteContext) => Promise<unknown> | unknown;
|
|
132
|
+
}
|
|
133
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { RouteError } from './RouteError';
|
|
2
|
+
/**
|
|
3
|
+
* 라우터 정보
|
|
4
|
+
*/
|
|
5
|
+
export interface RouteContext {
|
|
6
|
+
/**
|
|
7
|
+
* 전체 URL 정보
|
|
8
|
+
* - 도메인 이름을 포함한 URL의 전체 경로입니다.
|
|
9
|
+
* @example https://www.iyulab.com/home/user/1?name=iyu#profile
|
|
10
|
+
*/
|
|
11
|
+
href: string;
|
|
12
|
+
/**
|
|
13
|
+
* URL 도메인 이름
|
|
14
|
+
* - URL의 도메인 이름입니다.
|
|
15
|
+
* @example https://www.iyulab.com
|
|
16
|
+
*/
|
|
17
|
+
origin: string;
|
|
18
|
+
/**
|
|
19
|
+
* 라우터 URL 기본 경로
|
|
20
|
+
* - 라우터의 현재 basepath입니다.
|
|
21
|
+
* @example
|
|
22
|
+
* if basepath is /app/:id
|
|
23
|
+
* set basepath to /app/123
|
|
24
|
+
*/
|
|
25
|
+
basepath: string;
|
|
26
|
+
/**
|
|
27
|
+
* 라우터 URL 전체 경로
|
|
28
|
+
* - 도메인 이름을 제외한 URL의 전체 경로입니다.
|
|
29
|
+
* @example /home/user/1?name=iyu#profile
|
|
30
|
+
*/
|
|
31
|
+
path: string;
|
|
32
|
+
/**
|
|
33
|
+
* 라우터 URL 절대 경로
|
|
34
|
+
* - 쿼리스트링과 해시를 제외한 URL 경로입니다.
|
|
35
|
+
* @example /home/user/1
|
|
36
|
+
*/
|
|
37
|
+
pathname: string;
|
|
38
|
+
/**
|
|
39
|
+
* 라우터 URL 파라미터
|
|
40
|
+
* - URLPattern을 사용하여 파싱된 파라미터입니다.
|
|
41
|
+
* @example 만약 URL이 /user/:id/:name 일경우
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const id = params.id;
|
|
44
|
+
* const name = params.name;
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
params: {
|
|
48
|
+
[key: string]: string | undefined;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* 라우터 URL 쿼리스트링
|
|
52
|
+
* - URLSearchParams를 사용하여 파싱된 쿼리스트링입니다.
|
|
53
|
+
* @example 만약 URL이 ?page=1&size=10 일경우
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const page = query.get('page');
|
|
56
|
+
* const size = query.get('size');
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
query: URLSearchParams;
|
|
60
|
+
/**
|
|
61
|
+
* 라우터 URL 해시
|
|
62
|
+
* - URL의 해시값입니다. 해시값은 하나만 사용할 수 있습니다.
|
|
63
|
+
* - #profile#user 두개 이상의 해시값은 하나로 취급합니다.
|
|
64
|
+
* @example #profile
|
|
65
|
+
*/
|
|
66
|
+
hash?: string;
|
|
67
|
+
/**
|
|
68
|
+
* 현재 라우팅의 진행 상태를 업데이트하여, window 객체의 'route-progress' 이벤트를 트리거합니다.
|
|
69
|
+
* 여러 라우팅이 호출되는 경우, 가장 최근의 라우팅의 진행 상태만 반영되며, 나머지는 무시됩니다.
|
|
70
|
+
* @param value 진행 상태 값 (0~100)
|
|
71
|
+
*/
|
|
72
|
+
progress: (value: number) => void;
|
|
73
|
+
/**
|
|
74
|
+
* 매칭된 라우트 체인의 병합된 메타데이터
|
|
75
|
+
* - 부모 라우트에서 자식 라우트 순서로 병합됩니다.
|
|
76
|
+
*/
|
|
77
|
+
metadata: Record<string, unknown>;
|
|
78
|
+
}
|
|
79
|
+
export interface FallbackRouteContext extends RouteContext {
|
|
80
|
+
/**
|
|
81
|
+
* 라우팅 에러 정보
|
|
82
|
+
* - 라우팅 중 발생한 에러 정보를 포함합니다.
|
|
83
|
+
*/
|
|
84
|
+
error: RouteError;
|
|
85
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 라우팅 에러 정보
|
|
3
|
+
*/
|
|
4
|
+
export declare class RouteError extends Error {
|
|
5
|
+
/**
|
|
6
|
+
* 에러 코드
|
|
7
|
+
* - HTTP 상태 코드 또는 커스텀 에러 코드
|
|
8
|
+
* @example 404, 500, 'ROUTE_NOT_FOUND'
|
|
9
|
+
*/
|
|
10
|
+
code: number | string;
|
|
11
|
+
/**
|
|
12
|
+
* 원본 에러 객체
|
|
13
|
+
* - 원본 Error 객체 또는 예외 정보
|
|
14
|
+
*/
|
|
15
|
+
original?: Error | any;
|
|
16
|
+
/**
|
|
17
|
+
* 에러 발생 시간
|
|
18
|
+
* - 에러가 발생한 시간 (ISO 8601 형식)
|
|
19
|
+
*/
|
|
20
|
+
timestamp: string;
|
|
21
|
+
constructor(code: number | string, message: string, original?: Error | any);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 페이지를 찾을 수 없을 때 발생하는 에러
|
|
25
|
+
*/
|
|
26
|
+
export declare class NotFoundError extends RouteError {
|
|
27
|
+
constructor(path: string, original?: Error | any);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* enter 가드가 false를 반환하여 접근이 거부되었을 때 발생하는 에러
|
|
31
|
+
*/
|
|
32
|
+
export declare class AccessDeniedError extends RouteError {
|
|
33
|
+
constructor(path: string);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* u-outlet 요소를 찾을 수 없을 때 발생하는 에러
|
|
37
|
+
*/
|
|
38
|
+
export declare class OutletMissingError extends RouteError {
|
|
39
|
+
constructor();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 컨텐츠 로드시 나타나는 에러
|
|
43
|
+
*/
|
|
44
|
+
export declare class ContentLoadError extends RouteError {
|
|
45
|
+
constructor(original?: Error | any);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 컨텐츠 렌더링시 발생하는 에러
|
|
49
|
+
*/
|
|
50
|
+
export declare class ContentRenderError extends RouteError {
|
|
51
|
+
constructor(original?: Error | any);
|
|
52
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { RouteContext } from './RouteContext';
|
|
2
|
+
import { RouteError } from './RouteError';
|
|
3
|
+
/** 라우터 이벤트 기본 클래스 */
|
|
4
|
+
declare abstract class RouteEvent extends Event {
|
|
5
|
+
/** 라우팅 정보 */
|
|
6
|
+
readonly context: RouteContext;
|
|
7
|
+
/** 이벤트 발생 시간 */
|
|
8
|
+
readonly timestamp: string;
|
|
9
|
+
constructor(type: string, context: RouteContext, cancelable?: boolean);
|
|
10
|
+
/** 이벤트가 취소되었는지 확인 */
|
|
11
|
+
get cancelled(): boolean;
|
|
12
|
+
/** 이벤트 취소 */
|
|
13
|
+
cancel(): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 라우트 시작 이벤트
|
|
17
|
+
*/
|
|
18
|
+
export declare class RouteBeginEvent extends RouteEvent {
|
|
19
|
+
constructor(context: RouteContext);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 라우트 진행 이벤트
|
|
23
|
+
*/
|
|
24
|
+
export declare class RouteProgressEvent extends RouteEvent {
|
|
25
|
+
/** 진행 상태 값 (0~100) */
|
|
26
|
+
readonly progress: number;
|
|
27
|
+
constructor(context: RouteContext, progress: number);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 라우트 완료 이벤트
|
|
31
|
+
*/
|
|
32
|
+
export declare class RouteDoneEvent extends RouteEvent {
|
|
33
|
+
constructor(context: RouteContext);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 라우트 에러 이벤트
|
|
37
|
+
*/
|
|
38
|
+
export declare class RouteErrorEvent extends RouteEvent {
|
|
39
|
+
/** 에러 정보 */
|
|
40
|
+
readonly error: RouteError;
|
|
41
|
+
constructor(context: RouteContext, error: RouteError);
|
|
42
|
+
}
|
|
43
|
+
export {};
|