soseki 0.0.9 → 0.0.11

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 (39) hide show
  1. package/dist/src/core/_process-routes.d.ts.map +1 -1
  2. package/dist/src/core/_process-routes.js +8 -10
  3. package/dist/src/core/_regexparam.d.ts +37 -0
  4. package/dist/src/core/_regexparam.d.ts.map +1 -0
  5. package/dist/src/core/_regexparam.js +1 -0
  6. package/dist/src/core/errors.d.ts +29 -0
  7. package/dist/src/core/errors.d.ts.map +1 -1
  8. package/dist/src/core/errors.js +20 -1
  9. package/dist/src/core/match-routes.d.ts +2 -2
  10. package/dist/src/core/match-routes.d.ts.map +1 -1
  11. package/dist/src/core/match-routes.js +4 -6
  12. package/dist/src/core/route-pattern-utils.d.ts +163 -0
  13. package/dist/src/core/route-pattern-utils.d.ts.map +1 -0
  14. package/dist/src/core/route-pattern-utils.js +222 -0
  15. package/dist/src/core/route.types.d.ts +27 -65
  16. package/dist/src/core/route.types.d.ts.map +1 -1
  17. package/dist/src/core/start-action.d.ts.map +1 -1
  18. package/dist/src/engines/navigation-api-engine.d.ts.map +1 -1
  19. package/dist/src/engines/navigation-api-engine.js +7 -9
  20. package/dist/src/hooks/use-params.d.ts +2 -2
  21. package/dist/src/hooks/use-params.d.ts.map +1 -1
  22. package/dist/src/soseki.d.ts +2 -0
  23. package/dist/src/soseki.d.ts.map +1 -1
  24. package/dist/src/soseki.js +1 -0
  25. package/package.json +1 -1
  26. package/src/core/_process-routes.ts +7 -12
  27. package/src/core/_regexparam.ts +67 -0
  28. package/src/core/errors.ts +52 -0
  29. package/src/core/match-routes.ts +6 -9
  30. package/src/core/route-pattern-utils.ts +327 -0
  31. package/src/core/route.types.ts +29 -98
  32. package/src/core/start-action.ts +2 -2
  33. package/src/engines/navigation-api-engine.ts +7 -9
  34. package/src/hooks/use-params.ts +3 -3
  35. package/src/soseki.ts +3 -0
  36. package/dist/src/core/_match-route-path.d.ts +0 -22
  37. package/dist/src/core/_match-route-path.d.ts.map +0 -1
  38. package/dist/src/core/_match-route-path.js +0 -26
  39. package/src/core/_match-route-path.ts +0 -45
@@ -0,0 +1,327 @@
1
+ import { inject, parse } from "regexparam";
2
+
3
+ import type { RouteParams } from "./_regexparam.js";
4
+ import { RoutePatternMismatchError } from "./errors.js";
5
+ import RoutePath from "./route-path.js";
6
+
7
+ /**
8
+ * 対象の型プロパティーをすべて任意とし、さらに各プロパティー値に undefined を許容する型です。
9
+ *
10
+ * @template T オブジェクトの型定義です。
11
+ */
12
+ type Optional<T> = {
13
+ readonly [P in keyof T]?: T[P] | undefined;
14
+ };
15
+
16
+ /**
17
+ * ルートパターンの照合処理において、URL の文字列情報を抽出するためのインターフェースです。
18
+ */
19
+ export interface RoutePatternMatchURL {
20
+ /**
21
+ * ホスト名を除いた URL パス全体の文字列を表します。
22
+ */
23
+ readonly pathname: string;
24
+ }
25
+
26
+ /**
27
+ * 引数に渡された対象から URL パスを取得し、一貫した形式に正規化します。
28
+ *
29
+ * @param target 文字列または URL 情報を持つオブジェクトです。
30
+ * @returns 正規化されたパス文字列です。
31
+ */
32
+ function normalizeTarget(target: string | RoutePatternMatchURL): string {
33
+ return new RoutePath(typeof target === "string" ? target : target.pathname).pathname;
34
+ }
35
+
36
+ /**
37
+ * ルートパターンを解析および処理する際の挙動を設定するオプションです。
38
+ */
39
+ export type RoutePatternUtilsOptions = {
40
+ /**
41
+ * 子ディレクトリーへの前方一致を許可するかどうかを制御するフラグです。下位パスが存在する場合にも一致とみなす場合に true を指定します。
42
+ *
43
+ * @default false
44
+ */
45
+ readonly allowChild?: boolean | undefined;
46
+ };
47
+
48
+ /**
49
+ * ルートパターンの解析などを行うユーティリティークラスです。
50
+ *
51
+ * @template TRoutePattern リテラル型で固定されたルートパターンの文字列定義です。
52
+ */
53
+ export default class RoutePatternUtils<const TRoutePattern extends string = string> {
54
+ /**
55
+ * ルートパターンと対象のパスが一致するかどうかを静的に検証します。
56
+ *
57
+ * @template TRoutePattern パターンの文字列型です。
58
+ * @param routePattern 基準となるルートパターン文字列です。
59
+ * @param target 検証対象のパス文字列またはオブジェクトです。
60
+ * @param options 解析時の振る舞いを制御するオプションです。
61
+ * @returns 一致する場合は true、一致しない場合は false です。
62
+ */
63
+ public static match<const TRoutePattern extends string>(
64
+ routePattern: TRoutePattern,
65
+ target: string | RoutePatternMatchURL,
66
+ options: RoutePatternUtilsOptions,
67
+ ): boolean {
68
+ return new RoutePatternUtils(routePattern, options).match(target);
69
+ }
70
+
71
+ /**
72
+ * 静的な解析を行い、対象のパスからパラメーターを抽出します。一致しない場合はエラーを投げます。
73
+ *
74
+ * @template TRoutePattern パターンの文字列型です。
75
+ * @param routePattern 基準となるルートパターン文字列です。
76
+ * @param target 解析対象のパス文字列またはオブジェクトです。
77
+ * @param options 解析時の振る舞いを制御するオプションです。
78
+ * @returns 抽出されたパラメーターオブジェクトです。
79
+ */
80
+ public static parse<const TRoutePattern extends string>(
81
+ routePattern: TRoutePattern,
82
+ target: string | RoutePatternMatchURL,
83
+ options: RoutePatternUtilsOptions,
84
+ ): RouteParams<TRoutePattern> {
85
+ return new RoutePatternUtils(routePattern, options).parse(target);
86
+ }
87
+
88
+ /**
89
+ * 静的な埋め込みを行い、ルートパターンにパラメーターを適用してパスを生成します。
90
+ *
91
+ * @template TRoutePattern パターンの文字列型です。
92
+ * @param routePattern 基準となるルートパターン文字列です。
93
+ * @param params 埋め込むパラメーターのキーと値の組み合わせです。
94
+ * @param options 解析時の振る舞いを制御するオプションです。
95
+ * @returns パラメーターが適用された新しいパス文字列です。
96
+ */
97
+ public static inject<const TRoutePattern extends string>(
98
+ routePattern: TRoutePattern,
99
+ params: Readonly<RouteParams<TRoutePattern>>,
100
+ options: RoutePatternUtilsOptions,
101
+ ): string {
102
+ return new RoutePatternUtils(routePattern, options).inject(params);
103
+ }
104
+
105
+ // public static partialInject<const TRoutePattern extends string>(
106
+ // routePattern: TRoutePattern,
107
+ // params: Optional<RouteParams<TRoutePattern>>,
108
+ // options: RoutePatternUtilsOptions = {},
109
+ // ): string {}
110
+
111
+ /**
112
+ * 対象のパスに含まれるパラメーターの一部を指定された値で置き換えて、新しいパスを静的に生成します。
113
+ *
114
+ * @template TRoutePattern パターンの文字列型です。
115
+ * @param routePattern 基準となるルートパターン文字列です。
116
+ * @param target 既存のパス文字列またはオブジェクトです。
117
+ * @param params 上書きするパラメーターです。
118
+ * @param options 解析時の振る舞いを制御するオプションです。
119
+ * @returns 置き換え後のパス文字列です。
120
+ */
121
+ public static replace<const TRoutePattern extends string>(
122
+ routePattern: TRoutePattern,
123
+ target: string | RoutePatternMatchURL,
124
+ params: Optional<RouteParams<TRoutePattern>>,
125
+ options: RoutePatternUtilsOptions,
126
+ ): string {
127
+ return new RoutePatternUtils(routePattern, options).replace(target, params);
128
+ }
129
+
130
+ /**
131
+ * 静的な解析を行い、対象のパスからパラメーターを安全に抽出します。一致しない場合は null を返します。
132
+ *
133
+ * @template TRoutePattern パターンの文字列型です。
134
+ * @param routePattern 基準となるルートパターン文字列です。
135
+ * @param target 解析対象のパス文字列またはオブジェクトです。
136
+ * @param options 解析時の振る舞いを制御するオプションです。
137
+ * @returns 抽出されたパラメーターオブジェクト、一致しない場合は null です。
138
+ */
139
+ public static parseSafe<const TRoutePattern extends string>(
140
+ routePattern: TRoutePattern,
141
+ target: string | RoutePatternMatchURL,
142
+ options: RoutePatternUtilsOptions,
143
+ ): RouteParams<TRoutePattern> | null {
144
+ return new RoutePatternUtils(routePattern, options).parseSafe(target);
145
+ }
146
+
147
+ // public static injectSafe<const TRoutePattern extends string>(
148
+ // routePattern: TRoutePattern,
149
+ // params: Readonly<RouteParams<TRoutePattern>>,
150
+ // options: RoutePatternUtilsOptions = {},
151
+ // ): string | null {}
152
+
153
+ /**
154
+ * 対象のパスに含まれるパラメーターの一部を指定された値で安全に置き換えます。不一致の場合は null を返します。
155
+ *
156
+ * @template TRoutePattern パターンの文字列型です。
157
+ * @param routePattern 基準となるルートパターン文字列です。
158
+ * @param target 既存のパス文字列またはオブジェクトです。
159
+ * @param params 上書きするパラメーターです。
160
+ * @param options 解析時の振る舞いを制御するオプションです。
161
+ * @returns 置き換え後のパス文字列、不一致の場合は null です。
162
+ */
163
+ public static replaceSafe<const TRoutePattern extends string>(
164
+ routePattern: TRoutePattern,
165
+ target: string | RoutePatternMatchURL,
166
+ params: Optional<RouteParams<TRoutePattern>>,
167
+ options: RoutePatternUtilsOptions,
168
+ ): string | null {
169
+ return new RoutePatternUtils(routePattern, options).replaceSafe(target, params);
170
+ }
171
+
172
+ /**
173
+ * インスタンスに保持されるルートパターン文字列です。
174
+ */
175
+ public readonly route: string;
176
+
177
+ /**
178
+ * ルートパターンのマッチングとパラメーター抽出に使用する正規表現オブジェクトです。
179
+ */
180
+ public readonly pattern: RegExp;
181
+
182
+ /**
183
+ * ルートパターンから抽出されたパラメーター名の配列です。
184
+ */
185
+ public readonly paramKeys: readonly Extract<keyof RouteParams<TRoutePattern>, string>[];
186
+
187
+ /**
188
+ * 新しい `RoutePatternUtils` インスタンスを作成します。
189
+ *
190
+ * @param routePattern 解析基準となるルートパターンです。
191
+ * @param options 前方一致などを制御するオプションです。
192
+ */
193
+ public constructor(routePattern: TRoutePattern, options: RoutePatternUtilsOptions = {}) {
194
+ const { keys, pattern } = parse(routePattern, options.allowChild);
195
+ this.route = routePattern;
196
+ this.pattern = pattern;
197
+ this.paramKeys = keys satisfies string[] as any[];
198
+ }
199
+
200
+ /**
201
+ * パスが構築時のルートパターンに一致するかどうかを評価します。
202
+ *
203
+ * @param target 検証対象のパス文字列またはオブジェクトです。
204
+ * @returns パターンに合致する場合は true、それ以外は false です。
205
+ */
206
+ public match(target: string | RoutePatternMatchURL): boolean {
207
+ target = normalizeTarget(target);
208
+ return this.pattern.test(target);
209
+ }
210
+
211
+ /**
212
+ * インスタンスのルートパターンを基に対象パスからパラメーターを抽出します。解析できない場合は、処理が継続できないため例外を投げます。
213
+ *
214
+ * @param target 解析対象のパス文字列またはオブジェクトです。
215
+ * @returns 抽出したパラメーターオブジェクトです。
216
+ */
217
+ public parse(target: string | RoutePatternMatchURL): RouteParams<TRoutePattern> {
218
+ const params = this.parseSafe(target);
219
+ if (params === null) {
220
+ throw new RoutePatternMismatchError({
221
+ route: this.route,
222
+ target: normalizeTarget(target),
223
+ });
224
+ }
225
+
226
+ return params;
227
+ }
228
+
229
+ /**
230
+ * 指定されたパラメーター群をルートパターンに埋め込んで、具体的なパス文字列を構築します。
231
+ *
232
+ * @param params パラメーターのキーと値のオブジェクトです。
233
+ * @returns 生成されたパス文字列です。
234
+ */
235
+ public inject(params: Readonly<RouteParams<TRoutePattern>>): string {
236
+ return inject(this.route, params);
237
+ }
238
+
239
+ // public partialInject(params: Optional<RouteParams<TRoutePattern>>): string {}
240
+
241
+ /**
242
+ * 現在のパスに含まれるパラメーター値の一部を、指定された値で上書きした新しいパスを構築します。対象パスがルートパターンと一致しない場合は例外を投げます。
243
+ *
244
+ * @param target 基準となる現在のパス文字列またはオブジェクトです。
245
+ * @param params 変更を適用する一部のパラメーターです。
246
+ * @returns 新しく生成されたパス文字列です。
247
+ */
248
+ public replace(
249
+ target: string | RoutePatternMatchURL,
250
+ params: Optional<RouteParams<TRoutePattern>>,
251
+ ): string {
252
+ const replaced = this.replaceSafe(target, params);
253
+ if (replaced === null) {
254
+ throw new RoutePatternMismatchError({
255
+ route: this.route,
256
+ target: normalizeTarget(target),
257
+ });
258
+ }
259
+
260
+ return replaced;
261
+ }
262
+
263
+ /**
264
+ * パターンに基づきパスの解析を行い、プレースホルダーに該当する箇所をオブジェクトとして抽出します。
265
+ *
266
+ * @param target 解析対象のパス文字列またはオブジェクトです。
267
+ * @returns 抽出に成功した場合はパラメーターのオブジェクト、不一致の場合は null です。
268
+ */
269
+ public parseSafe(target: string | RoutePatternMatchURL): RouteParams<TRoutePattern> | null {
270
+ target = normalizeTarget(target);
271
+ const matches = this.pattern.exec(target);
272
+ if (!matches) {
273
+ return null;
274
+ }
275
+
276
+ const params: Record<string, string> = {};
277
+ for (let i = 0, param: string | undefined; i < this.paramKeys.length; i++) {
278
+ // exec メソッドの戻り値のインデックス 0 にはマッチした文字列全体が格納されているため、各パラメーターの値はインデックス 1 以降(i + 1)から取得します。
279
+ param = matches[i + 1];
280
+
281
+ // キャプチャーされたセグメントが存在し、かつ文字列型である場合にのみ、対応するパラメーターキーと値をマッピングします。
282
+ // オプショナルなパラメーターが URL 側で省略されている場合は undefined となるため、この条件節により除外されます。
283
+ if (typeof param === "string") {
284
+ params[this.paramKeys[i]!] = param;
285
+ }
286
+ }
287
+
288
+ return params as RouteParams<TRoutePattern>;
289
+ }
290
+
291
+ // public injectSafe(params: Readonly<RouteParams<TRoutePattern>>): string | null {
292
+ // if (!this.paramKeys.every((key) => key in params && typeof params[key] === "string")) {
293
+ // return null;
294
+ // }
295
+
296
+ // return inject(this.route, params);
297
+ // }
298
+
299
+ /**
300
+ * 既存のパスから抽出されたパラメーター値をベースとして、任意のパラメーターのみを上書きしたパス文字列を再構築します。
301
+ *
302
+ * @param target 基にするパス文字列またはオブジェクトです。
303
+ * @param params 上書き指定するパラメーターオブジェクトです。
304
+ * @returns 再構築されたパス文字列、パスが不一致の場合は null です。
305
+ */
306
+ public replaceSafe(
307
+ target: string | RoutePatternMatchURL,
308
+ params: Optional<RouteParams<TRoutePattern>>,
309
+ ): string | null {
310
+ const defaults = this.parseSafe(target);
311
+ if (defaults === null) {
312
+ return null;
313
+ }
314
+
315
+ const values: Record<string, any> = {};
316
+ for (const key of this.paramKeys) {
317
+ const param = params[key];
318
+ if (typeof param === "string") {
319
+ values[key] = param;
320
+ } else {
321
+ values[key] = defaults[key];
322
+ }
323
+ }
324
+
325
+ return inject(this.route, values);
326
+ }
327
+ }
@@ -1,95 +1,31 @@
1
1
  import type * as React from "react";
2
2
 
3
+ import type { RouteParams as $RouteParams } from "./_regexparam.js";
3
4
  import type { ReadonlyURL } from "./readonly-url.types.js";
5
+ import type RoutePatternUtils from "./route-pattern-utils.js";
4
6
  import type { RouteGetRequest, RoutePostRequest } from "./route-request.js";
5
7
 
6
- /**
7
- * 個別のパスパラメーターを解析し、適切なプロパティーの型オブジェクトへと変換する内部ユーティリティー型です。
8
- *
9
- * パラメーターの末尾の形状を条件付き型により詳細に選別します。
10
- *
11
- * @template Param 解析対象となる単一のパラメーター文字列です。
12
- */
13
- // oxfmt-ignore
14
- type ParamRecord<Param extends string> =
15
- // パラメーター末尾に「?」がある場合、オプショナルなプロパティー型に変換します
16
- Param extends `${infer Name}?`
17
- ? { [K in Name]?: string }
18
-
19
- // パラメーターに拡張子が含まれている場合、拡張子を除いた名前を必須のプロパティー型に変換します。
20
- : Param extends `${infer Name}.${string}`
21
- ? { [K in Name]: string }
22
-
23
- // 上記のいずれのパターンにも該当しない場合は、パラメーター名をそのまま必須のプロパティー型に変換します。
24
- : { [K in Param]: string };
25
-
26
- /**
27
- * パス文字列のセグメントから動的なパラメーターやワイルドカードを再帰的に抽出し、型安全なオブジェクト構造を構築するユーティリティー型です。
28
- *
29
- * 開発者が指定した文字列リテラル型の形状に基づいて、ルーティングに必要なパラメーターの型を静的に決定します。
30
- *
31
- * このユーティリティー型は、ライブラリー `regexparam` の改良版です。
32
- *
33
- * @template T 解析対象となる URL パス全体の文字列リテラル型です。
34
- * @see https://github.com/lukeed/regexparam
35
- * @see https://github.com/lukeed/regexparam/issues/31
36
- * @see https://github.com/lukeed/regexparam/pull/33
37
- */
38
- // oxfmt-ignore
39
- type RouteParams<T extends string> =
40
- // 与えられた型が具体的なリテラルでなく文字列型である場合は、汎用的なレコード型へとフォールバックします。
41
- string extends T
42
- ? { [K in string]?: string }
43
-
44
- // パスの中間にワイルドカードが存在する場合、前後のパラメーターに加えて、必須のワイルドカードプロパティーを結合します。
45
- : T extends `${infer Prev}/*/${infer Rest}`
46
- ? & RouteParams<Prev>
47
- & { wild: string }
48
- & RouteParams<`/${Rest}`>
49
-
50
- // パスの先頭がコロンで開始されている場合、先頭にスラッシュ(/)を補正して再帰的に再評価します。
51
- : T extends `:${infer Rest}`
52
- ? RouteParams<`/:${Rest}`>
53
-
54
- // パスの中間にコロンで始まるパラメーターが含まれている場合、そのセグメントの型情報を抽出し、スラッシュ以降の残りのパスの解析結果と交差型で結合します。
55
- : T extends `${string}:${infer Param}/${infer Rest}`
56
- ? & ParamRecord<Param>
57
- & RouteParams<`/${Rest}`>
58
-
59
- // パスの末尾がコロンで始まるパラメーターで終了している場合、そのセグメントの型情報を判定して抽出を完了します。
60
- : T extends `${string}/:${infer Param}`
61
- ? ParamRecord<Param>
62
-
63
- // パスの末尾がオプショナルワイルドカードで終了している場合、キー名を「"*"」としたオプショナルなプロパティー型を返します。
64
- : T extends `${string}/*?`
65
- ? { "*"?: string }
66
-
67
- // パスの末尾が通常のワイルドカードで終了している場合、キー名を「"*"」とした必須のプロパティー型を返します。
68
- : T extends `${string}/*`
69
- ? { "*": string }
70
-
71
- // 抽出可能なパラメーターやワイルドカードが一切検出されなかった場合は、空のオブジェクト型を返します。
72
- : {};
73
-
74
8
  /**
75
9
  * 文字列リテラルとして定義されたパスの形状から、含まれるパスパラメーターを解析し、静的に型付けされたオブジェクトとして抽出する型定義です。
76
10
  *
77
- * @template TRoutePath パラメーター抽出の対象となるパス文字列リテラル型です。
11
+ * @template TRoutePattern パラメーター抽出の対象となるパス文字列リテラル型です。
78
12
  */
79
- export type RoutePathParams<TRoutePath extends string = string> = Readonly<RouteParams<TRoutePath>>;
13
+ export type RouteParams<TRoutePattern extends string = string> = Readonly<
14
+ $RouteParams<TRoutePattern>
15
+ >;
80
16
 
81
17
  /**
82
18
  * データ更新などのアクション処理を実行する際に、該当する関数へ渡される引数の型定義です。
83
19
  *
84
20
  * 解析済みのパスパラメーターと、HTTP の POST メソッドを抽象化したリクエストオブジェクトを含みます。
85
21
  *
86
- * @template TRoutePath 対象となるルートのパス文字列リテラル型です。
22
+ * @template TRoutePattern 対象となるルートのパス文字列リテラル型です。
87
23
  */
88
- export type ActionFunctionArgs<TRoutePath extends string = string> = {
24
+ export type ActionFunctionArgs<TRoutePattern extends string = string> = {
89
25
  /**
90
26
  * 現在の URL パスから抽出されたパラメーターオブジェクトです。
91
27
  */
92
- params: RoutePathParams<TRoutePath>;
28
+ params: RouteParams<TRoutePattern>;
93
29
 
94
30
  /**
95
31
  * フォームデータなどを内包する、HTTP の POST メソッドに特化したルーティングリクエストオブジェクトです。
@@ -100,11 +36,11 @@ export type ActionFunctionArgs<TRoutePath extends string = string> = {
100
36
  /**
101
37
  * データの登録、更新、削除といった副作用を伴うアクション処理を定義するための関数インターフェースです。
102
38
  *
103
- * @template TRoutePath 対象となるルートのパス文字列リテラル型です。
39
+ * @template TRoutePattern 対象となるルートのパス文字列リテラル型です。
104
40
  * @template TData アクション関数が返す戻り値の型定義です。既定値は `unknown` です。
105
41
  */
106
- export interface ActionFunction<TRoutePath extends string = string, TData = unknown> {
107
- (args: ActionFunctionArgs<TRoutePath>): TData;
42
+ export interface ActionFunction<TRoutePattern extends string = string, TData = unknown> {
43
+ (args: ActionFunctionArgs<TRoutePattern>): TData;
108
44
  }
109
45
 
110
46
  /**
@@ -112,9 +48,9 @@ export interface ActionFunction<TRoutePath extends string = string, TData = unkn
112
48
  *
113
49
  * アクションを実行した契機となる HTTP メソッドの種類(GET / POST)に応じて、含まれるコンテキスト情報が分岐します。
114
50
  *
115
- * @template TRoutePath 対象となるルートのパス文字列リテラル型です。
51
+ * @template TRoutePattern 対象となるルートのパス文字列リテラル型です。
116
52
  */
117
- export type ShouldReloadFunctionArgs<TRoutePath extends string = string> =
53
+ export type ShouldReloadFunctionArgs<TRoutePattern extends string = string> =
118
54
  | {
119
55
  /**
120
56
  * 再読み込みを引き起こした HTTP メソッドの種別です。
@@ -129,7 +65,7 @@ export type ShouldReloadFunctionArgs<TRoutePath extends string = string> =
129
65
  /**
130
66
  * 現在の URL から抽出されたパスパラメーターです。
131
67
  */
132
- currentParams: RoutePathParams<TRoutePath>;
68
+ currentParams: RouteParams<TRoutePattern>;
133
69
 
134
70
  /**
135
71
  * POST リクエストが発生する直前の読み取り専用 URL オブジェクトです。
@@ -139,7 +75,7 @@ export type ShouldReloadFunctionArgs<TRoutePath extends string = string> =
139
75
  /**
140
76
  * POST リクエストが発生する直前の URL から抽出されたパスパラメーターです。
141
77
  */
142
- prevParams: RoutePathParams;
78
+ prevParams: RouteParams;
143
79
 
144
80
  /**
145
81
  * システムが内部ロジックに基づいて判断した、再読み込み実行の既定の判定フラグです。
@@ -160,7 +96,7 @@ export type ShouldReloadFunctionArgs<TRoutePath extends string = string> =
160
96
  /**
161
97
  * 現在の URL から抽出されたパスパラメーターです。
162
98
  */
163
- currentParams: RoutePathParams<TRoutePath>;
99
+ currentParams: RouteParams<TRoutePattern>;
164
100
 
165
101
  /**
166
102
  * POST リクエストが発生する直前の読み取り専用 URL オブジェクトです。
@@ -170,7 +106,7 @@ export type ShouldReloadFunctionArgs<TRoutePath extends string = string> =
170
106
  /**
171
107
  * POST リクエストが発生する直前の URL から抽出されたパスパラメーターです。
172
108
  */
173
- prevParams: RoutePathParams;
109
+ prevParams: RouteParams;
174
110
 
175
111
  /**
176
112
  * POST リクエストと共に送信された標準のフォームデータオブジェクトです。
@@ -191,11 +127,11 @@ export type ShouldReloadFunctionArgs<TRoutePath extends string = string> =
191
127
  /**
192
128
  * ルートデータの再読み込みが不必要な場合に、余分な通信や再取得処理を抑制するための判定関数インターフェースです。
193
129
  *
194
- * @template TRoutePath 対象となるルートのパス文字列リテラル型です。
130
+ * @template TRoutePattern 対象となるルートのパス文字列リテラル型です。
195
131
  * @returns データを再読み込みする場合は `true`、スキップする場合は `false` を返します。
196
132
  */
197
- export interface ShouldReloadFunction<TRoutePath extends string = string> {
198
- (args: ShouldReloadFunctionArgs<TRoutePath>): boolean;
133
+ export interface ShouldReloadFunction<TRoutePattern extends string = string> {
134
+ (args: ShouldReloadFunctionArgs<TRoutePattern>): boolean;
199
135
  }
200
136
 
201
137
  /**
@@ -203,13 +139,13 @@ export interface ShouldReloadFunction<TRoutePath extends string = string> {
203
139
  *
204
140
  * 解析済みのパスパラメーターと、HTTP の GET メソッドを抽象化したリクエストオブジェクトを含みます。
205
141
  *
206
- * @template TRoutePath 対象となるルートのパス文字列リテラル型です。
142
+ * @template TRoutePattern 対象となるルートのパス文字列リテラル型です。
207
143
  */
208
- export type LoaderFunctionArgs<TRoutePath extends string = string> = {
144
+ export type LoaderFunctionArgs<TRoutePattern extends string = string> = {
209
145
  /**
210
146
  * 現在の URL パスから抽出されたパラメーターオブジェクトです。
211
147
  */
212
- params: RoutePathParams<TRoutePath>;
148
+ params: RouteParams<TRoutePattern>;
213
149
 
214
150
  /**
215
151
  * HTTP の GET メソッドに特化したルーティングリクエストオブジェクトです。
@@ -220,11 +156,11 @@ export type LoaderFunctionArgs<TRoutePath extends string = string> = {
220
156
  /**
221
157
  * 画面の初期描画時や遷移時にデータをオンデマンドで取得するための関数インターフェースです。
222
158
  *
223
- * @template TRoutePath 対象となるルートのパス文字列リテラル型です。
159
+ * @template TRoutePattern 対象となるルートのパス文字列リテラル型です。
224
160
  * @template TData ローダー関数が返す戻り値の型定義です。既定値は `unknown` です。
225
161
  */
226
- export interface LoaderFunction<TRoutePath extends string = string, TData = unknown> {
227
- (args: LoaderFunctionArgs<TRoutePath>): TData;
162
+ export interface LoaderFunction<TRoutePattern extends string = string, TData = unknown> {
163
+ (args: LoaderFunctionArgs<TRoutePattern>): TData;
228
164
  }
229
165
 
230
166
  /**
@@ -344,14 +280,9 @@ export type Route = {
344
280
  readonly index: boolean;
345
281
 
346
282
  /**
347
- * 実際の URL パスがこのルートに合致するかを検証するために動的に生成された正規表現オブジェクトです。
348
- */
349
- readonly pathPattern: RegExp;
350
-
351
- /**
352
- * パスパターン内に含まれるパラメーターのキー名を、順番通りに格納した読み取り専用の配列です。
283
+ * ルートパターンの解析などを行うユーティリティーです。
353
284
  */
354
- readonly paramKeys: readonly string[];
285
+ readonly utils: RoutePatternUtils;
355
286
 
356
287
  /**
357
288
  * データ更新用のアクション関数です。未定義の場合は `undefined` となります。
@@ -6,7 +6,7 @@ import type { MatchedRoute } from "./match-routes.js";
6
6
  import type { ReadonlyFormData } from "./readonly-form-data.types.js";
7
7
  import RedirectResponse from "./redirect-response.js";
8
8
  import RouteRequest from "./route-request.js";
9
- import type { ActionFunction, RoutePathParams } from "./route.types.js";
9
+ import type { ActionFunction, RouteParams } from "./route.types.js";
10
10
 
11
11
  /**
12
12
  * アクション処理の実行開始時に必要となる、起点リクエスト情報の型定義です。
@@ -64,7 +64,7 @@ export default function startAction(
64
64
  request: ActionStartRequest,
65
65
  ): StartedAction | null {
66
66
  let action: ActionFunction | undefined;
67
- let params: RoutePathParams;
67
+ let params: RouteParams;
68
68
  let urlPath: string;
69
69
 
70
70
  for ({ action, params, urlPath } of routes) {
@@ -105,8 +105,7 @@ export default class NavigationApiEngine implements IEngine {
105
105
  * ユーザーのアクションによって発生したすべての遷移要求をインターセプトして処理する、ルーティングの中枢ハンドラーです。
106
106
  */
107
107
  const handleNavigate = (event: NavigateEvent): void => {
108
- // 処理すべきでない通常のブラウザー固有のナビゲーション(ハッシュ変更、ファイルのダウンロードなど)は、
109
- // 標準の挙動を妨げないようにインターセプトせず即座にスルーします。
108
+ // 処理すべきでない通常のブラウザー固有のナビゲーション(ハッシュ変更、ファイルのダウンロードなど)は、標準の挙動を妨げないようにインターセプトせず即座にスルーします。
110
109
  // 参照: https://developer.mozilla.org/docs/Web/API/Navigation_API#handling_a_navigation_using_intercept
111
110
  if (
112
111
  !event.isTrusted ||
@@ -187,8 +186,7 @@ export default class NavigationApiEngine implements IEngine {
187
186
  switch (action.data.status) {
188
187
  case "rejected": {
189
188
  // アクションがエラーで失敗した場合は、URL を変更せず現在の元のページに強制リダイレクトさせます。
190
- const { pathname, search, hash } = currentEntry.url;
191
- controller.redirect(pathname + search + hash);
189
+ controller.redirect(RoutePath.encode(currentEntry.url));
192
190
 
193
191
  break;
194
192
  }
@@ -197,12 +195,12 @@ export default class NavigationApiEngine implements IEngine {
197
195
  // アクションが正常終了した場合、返り値にリダイレクト指示が含まれていればその目的地へ遷移させます。
198
196
  // リダイレクトがなければそのまま本来の目的地へとブラウザーのコミット先を書き換えます。
199
197
  const { redirectTo = currentEntry.url } = actionResponse;
200
- const { pathname, search, hash } = redirectTo;
201
- controller.redirect(pathname + search + hash);
198
+ const redirectPath = new RoutePath(redirectTo);
199
+ controller.redirect(redirectPath.toString());
202
200
 
203
- redirectUrl.pathname = pathname;
204
- redirectUrl.search = search;
205
- redirectUrl.hash = hash;
201
+ redirectUrl.pathname = redirectPath.pathname;
202
+ redirectUrl.search = redirectPath.search;
203
+ redirectUrl.hash = redirectPath.hash;
206
204
 
207
205
  break;
208
206
  }
@@ -1,4 +1,4 @@
1
- import type { RoutePathParams } from "../core/route.types.js";
1
+ import type { RouteParams } from "../core/route.types.js";
2
2
  import useRouteContext from "./use-route-context.js";
3
3
 
4
4
  /**
@@ -6,6 +6,6 @@ import useRouteContext from "./use-route-context.js";
6
6
  *
7
7
  * @returns 現在のパスパラメーターを含むオブジェクトを返します。
8
8
  */
9
- export default function useParams<TPath extends string = string>(): RoutePathParams<TPath> {
10
- return useRouteContext().params as RoutePathParams<TPath>;
9
+ export default function useParams<TPath extends string = string>(): RouteParams<TPath> {
10
+ return useRouteContext().params as RouteParams<TPath>;
11
11
  }
package/src/soseki.ts CHANGED
@@ -37,6 +37,9 @@ export type * from "./core/readonly-url.types.js";
37
37
  export type * from "./core/redirect-response.js";
38
38
  export { default as RedirectResponse } from "./core/redirect-response.js";
39
39
 
40
+ export type * from "./core/route-pattern-utils.js";
41
+ export { default as RoutePatternUtils } from "./core/route-pattern-utils.js";
42
+
40
43
  export type * from "./core/route-request.js";
41
44
  export { default as RouteRequest } from "./core/route-request.js";
42
45
 
@@ -1,22 +0,0 @@
1
- import type { ReadonlyURL } from "./readonly-url.types.js";
2
- import type { Route, RoutePathParams } from "./route.types.js";
3
- /**
4
- * パスマッチングの処理結果を表すオブジェクトの型定義です。
5
- */
6
- export type MatchPathResult = {
7
- /**
8
- * マッチした URL パスから抽出されたパラメーターのキーと値のオブジェクトです。
9
- */
10
- params: RoutePathParams;
11
- };
12
- /**
13
- * 指定されたルートの正規表現パターンと URL のパス部分を照合し、マッチング検証およびパラメーター抽出を行う関数です。
14
- *
15
- * ルーティングエンジンが、現在の遷移先 URL に適合するルートを特定し、動的セグメントの値を型安全に回収する目的で使用します。
16
- *
17
- * @param route 検証対象となるルートオブジェクトから、マッチングに必要な `paramKeys` と `pathPattern` を抽出したオブジェクトです。
18
- * @param url マッチングの判定元となる、読み取り専用の URL オブジェクトです。
19
- * @returns マッチした場合は抽出されたパラメーターを含む `MatchPathResult` を返し、マッチしなかった場合は `null` を返します。
20
- */
21
- export default function matchPath(route: Pick<Route, "paramKeys" | "pathPattern">, url: ReadonlyURL): MatchPathResult | null;
22
- //# sourceMappingURL=_match-route-path.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_match-route-path.d.ts","sourceRoot":"","sources":["../../../src/core/_match-route-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAAC,EAC/C,GAAG,EAAE,WAAW,GACf,eAAe,GAAG,IAAI,CAmBxB"}