@@ -18,7 +18,10 @@ export function write_api(config, manifest_data) {
18
18
fs . mkdirSync ( types_dir , { recursive : true } ) ;
19
19
} catch { }
20
20
21
- const api_imports = [ 'import type * as Kit from "@sveltejs/kit";' ] ;
21
+ const api_imports = [
22
+ 'import type * as Kit from "@sveltejs/kit";' ,
23
+ 'import type { base } from "$app/paths";'
24
+ ] ;
22
25
23
26
/** @type {string[] } */
24
27
const api_declarations = [ ] ;
@@ -35,7 +38,7 @@ export function write_api(config, manifest_data) {
35
38
api_declarations . push (
36
39
'type ExpandMethods<T> = { [Method in keyof T]: T[Method] extends (...args: any) => any ? GetEndpointType<T[Method]> : never; };'
37
40
) ;
38
- api_declarations . push ( 'type optional_trailing = `` | `${string}`;' ) ;
41
+ api_declarations . push ( 'type optional_trailing = `` | `? ${string}`;' ) ;
39
42
api_declarations . push ( 'type restricted_characters = ` ` | `/` | `\\\\`;' ) ;
40
43
api_declarations . push ( 'type restricted_characters_rest = ` ` | `\\\\`;' ) ;
41
44
api_declarations . push (
@@ -66,12 +69,23 @@ export function write_api(config, manifest_data) {
66
69
true
67
70
: false;\n`
68
71
) ;
72
+
73
+ api_declarations . push (
74
+ `\n/** Check if is empty or starts with '#' or '?' and does not contain restricted characters */ \ntype ValidateTrailing<S extends string> = FixDynamicTrailing<S> extends '' | \`?\${infer Slug}\` | \`#\${infer Slug}\` ?
75
+ Slug extends (\`\${string}\${restricted_characters}\${string}\`) ?
76
+ false
77
+ : true
78
+ : false;\n`
79
+ ) ;
69
80
api_declarations . push (
70
81
'type UnionAllTrue<B extends boolean> = [B] extends [true] ? true : false;'
71
82
) ;
72
83
api_declarations . push (
73
84
'type FixDynamicStr<S> = S extends undefined | null ? "" : Kit.Equals<S, string> extends true ? `/${string}` : S;'
74
85
) ;
86
+ api_declarations . push (
87
+ 'type FixDynamicTrailing<S> = S extends undefined | null ? "" : Kit.Equals<S, string> extends true ? `?${string}` : S;'
88
+ ) ;
75
89
76
90
/** @type {string[] } */
77
91
const api_endpoints = [
@@ -87,7 +101,7 @@ export function write_api(config, manifest_data) {
87
101
api_endpoints . push ( `\t\t${ index } : { ` ) ;
88
102
api_endpoints . push ( `\t\t\tid: \`${ route . id } \`; ` ) ;
89
103
api_endpoints . push (
90
- `\t\t\tdoes_match: RemoveTrailingSlash<ToCheck> extends \`${ matcher_str } \${optional_trailing }\` ? ${ validator_str } : false; `
104
+ `\t\t\tdoes_match: RemoveTrailingSlash<ToCheck> extends \`\${typeof base} ${ matcher_str } \` ? ${ validator_str } : false; `
91
105
) ;
92
106
if ( route . endpoint ) {
93
107
const route_import_path = posixify (
@@ -222,6 +236,10 @@ function parseSlugs(str) {
222
236
validators . push ( `ValidateRequired<RequiredSlug${ index ++ } >` ) ;
223
237
}
224
238
} while ( changed ) ;
239
+ if ( ! endsWithSlug ( str ) ) {
240
+ str += '${infer Trailing}' ;
241
+ validators . push ( 'ValidateTrailing<Trailing>' ) ;
242
+ }
225
243
const validator_str =
226
244
validators . length > 0
227
245
? `UnionAllTrue<${ validators . length > 1 ? validators . join ( ' | ' ) : validators . join ( '' ) } >`
@@ -232,3 +250,11 @@ function parseSlugs(str) {
232
250
validator_str
233
251
} ;
234
252
}
253
+
254
+ /**
255
+ *
256
+ * @param {string } str
257
+ */
258
+ function endsWithSlug ( str ) {
259
+ return str . endsWith ( '}' ) ;
260
+ }
0 commit comments