@@ -18,7 +18,10 @@ export function write_api(config, manifest_data) {
1818 fs . mkdirSync ( types_dir , { recursive : true } ) ;
1919 } catch { }
2020
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+ ] ;
2225
2326 /** @type {string[] } */
2427 const api_declarations = [ ] ;
@@ -35,7 +38,7 @@ export function write_api(config, manifest_data) {
3538 api_declarations . push (
3639 'type ExpandMethods<T> = { [Method in keyof T]: T[Method] extends (...args: any) => any ? GetEndpointType<T[Method]> : never; };'
3740 ) ;
38- api_declarations . push ( 'type optional_trailing = `` | `${string}`;' ) ;
41+ api_declarations . push ( 'type optional_trailing = `` | `? ${string}`;' ) ;
3942 api_declarations . push ( 'type restricted_characters = ` ` | `/` | `\\\\`;' ) ;
4043 api_declarations . push ( 'type restricted_characters_rest = ` ` | `\\\\`;' ) ;
4144 api_declarations . push (
@@ -66,12 +69,23 @@ export function write_api(config, manifest_data) {
6669 true
6770 : false;\n`
6871 ) ;
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+ ) ;
6980 api_declarations . push (
7081 'type UnionAllTrue<B extends boolean> = [B] extends [true] ? true : false;'
7182 ) ;
7283 api_declarations . push (
7384 'type FixDynamicStr<S> = S extends undefined | null ? "" : Kit.Equals<S, string> extends true ? `/${string}` : S;'
7485 ) ;
86+ api_declarations . push (
87+ 'type FixDynamicTrailing<S> = S extends undefined | null ? "" : Kit.Equals<S, string> extends true ? `?${string}` : S;'
88+ ) ;
7589
7690 /** @type {string[] } */
7791 const api_endpoints = [
@@ -87,7 +101,7 @@ export function write_api(config, manifest_data) {
87101 api_endpoints . push ( `\t\t${ index } : { ` ) ;
88102 api_endpoints . push ( `\t\t\tid: \`${ route . id } \`; ` ) ;
89103 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; `
91105 ) ;
92106 if ( route . endpoint ) {
93107 const route_import_path = posixify (
@@ -222,6 +236,10 @@ function parseSlugs(str) {
222236 validators . push ( `ValidateRequired<RequiredSlug${ index ++ } >` ) ;
223237 }
224238 } while ( changed ) ;
239+ if ( ! endsWithSlug ( str ) ) {
240+ str += '${infer Trailing}' ;
241+ validators . push ( 'ValidateTrailing<Trailing>' ) ;
242+ }
225243 const validator_str =
226244 validators . length > 0
227245 ? `UnionAllTrue<${ validators . length > 1 ? validators . join ( ' | ' ) : validators . join ( '' ) } >`
@@ -232,3 +250,11 @@ function parseSlugs(str) {
232250 validator_str
233251 } ;
234252}
253+
254+ /**
255+ *
256+ * @param {string } str
257+ */
258+ function endsWithSlug ( str ) {
259+ return str . endsWith ( '}' ) ;
260+ }
0 commit comments