diff --git a/src/core/create_app.ts b/src/core/create_app.ts index 983b03b..2606365 100644 --- a/src/core/create_app.ts +++ b/src/core/create_app.ts @@ -70,6 +70,12 @@ export function create_serviceworker_manifest({ manifest_data, output, client_fi write_if_changed(`${output}/service-worker.js`, code); } +function create_param_match(param: string, i: number) { + return /^\.{3}.+$/.test(param) + ? `${param.replace(/.{3}/, '')}: d(match[${i + 1}]).split('/')` + : `${param}: d(match[${i + 1}])` +} + function generate_client_manifest( manifest_data: ManifestData, path_to_routes: string, @@ -114,7 +120,7 @@ function generate_client_manifest( if (part.params.length > 0) { needs_decode = true; - const props = part.params.map((param, i) => `${param}: d(match[${i + 1}])`); + const props = part.params.map(create_param_match); return `{ i: ${component_indexes[part.component.name]}, params: match => ({ ${props.join(', ')} }) }`; } @@ -189,7 +195,7 @@ function generate_server_manifest( pattern: ${route.pattern}, handlers: route_${i}, params: ${route.params.length > 0 - ? `match => ({ ${route.params.map((param, i) => `${param}: d(match[${i + 1}])`).join(', ')} })` + ? `match => ({ ${route.params.map(create_param_match).join(', ')} })` : `() => ({})`} }`).join(',\n\n\t\t\t\t')} ], @@ -210,7 +216,7 @@ function generate_server_manifest( ].filter(Boolean); if (part.params.length > 0) { - const params = part.params.map((param, i) => `${param}: d(match[${i + 1}])`); + const params = part.params.map(create_param_match); props.push(`params: match => ({ ${params.join(', ')} })`); } diff --git a/src/core/create_manifest_data.ts b/src/core/create_manifest_data.ts index 6324733..4f0e423 100644 --- a/src/core/create_manifest_data.ts +++ b/src/core/create_manifest_data.ts @@ -246,13 +246,17 @@ type Part = { content: string; dynamic: boolean; qualifier?: string; + spread?: boolean; }; function comparator( a: { basename: string, parts: Part[], file: string, is_index: boolean }, b: { basename: string, parts: Part[], file: string, is_index: boolean } ) { - if (a.is_index !== b.is_index) return a.is_index ? -1 : 1; + if (a.is_index !== b.is_index) { + const spread_pattern = /\[\.{3}/g; + return a.is_index && spread_pattern.test(a.file) ? 1 : -1; + } const max = Math.max(a.parts.length, b.parts.length); @@ -263,6 +267,14 @@ function comparator( if (!a_sub_part) return 1; // b is more specific, so goes first if (!b_sub_part) return -1; + // if spread && index, order later + if (a_sub_part.spread && b_sub_part.spread) { + return a.is_index ? 1 : -1 + } + + // If one is ...spread order it later + if (a_sub_part.spread !== b_sub_part.spread) return a_sub_part.spread ? 1 : -1; + if (a_sub_part.dynamic !== b_sub_part.dynamic) { return a_sub_part.dynamic ? 1 : -1; } @@ -306,6 +318,7 @@ function get_parts(part: string): Part[] { return { content, dynamic, + spread: /^\.{3}.+$/.test(content), qualifier }; }) @@ -333,7 +346,7 @@ function get_pattern(segments: Part[][], add_trailing_slash: boolean) { segments.map(segment => { return '\\/' + segment.map(part => { return part.dynamic - ? part.qualifier || '([^\\/]+?)' + ? part.qualifier || part.spread ? '(.+)' : '([^\\/]+?)' : encodeURI(part.content.normalize()) .replace(/\?/g, '%3F') .replace(/#/g, '%23') diff --git a/test/apps/basics/src/routes/[...rest]/deep.json.js b/test/apps/basics/src/routes/[...rest]/deep.json.js new file mode 100644 index 0000000..a01a608 --- /dev/null +++ b/test/apps/basics/src/routes/[...rest]/deep.json.js @@ -0,0 +1,3 @@ +export function get(req, res) { + res.end(req.params.rest.join(',')); +} diff --git a/test/apps/basics/src/routes/[...rest]/deep.svelte b/test/apps/basics/src/routes/[...rest]/deep.svelte new file mode 100644 index 0000000..4dfeb44 --- /dev/null +++ b/test/apps/basics/src/routes/[...rest]/deep.svelte @@ -0,0 +1,7 @@ + + +

{$page.params.rest.join(',')}

+ +deep diff --git a/test/apps/basics/src/routes/[...rest]/index.svelte b/test/apps/basics/src/routes/[...rest]/index.svelte new file mode 100644 index 0000000..edd2d8e --- /dev/null +++ b/test/apps/basics/src/routes/[...rest]/index.svelte @@ -0,0 +1,7 @@ + + +

{$page.params.rest.join(',')}

+ +deep diff --git a/test/apps/basics/test.ts b/test/apps/basics/test.ts index 1247bfc..6fe167b 100644 --- a/test/apps/basics/test.ts +++ b/test/apps/basics/test.ts @@ -275,4 +275,22 @@ describe('basics', function() { await wait(50); assert.equal(await title(), 'bar'); }); -}); \ No newline at end of file + + it('navigates to ...rest', async () => { + await page.goto(`${base}/abc/xyz`); + await start(); + + assert.equal(await title(), 'abc,xyz'); + + await page.click('[href="xyz/abc/deep"]'); + await wait(50); + assert.equal(await title(), 'xyz,abc'); + + await page.click(`[href="xyz/abc/qwe/deep.json"]`); + await wait(50); + assert.equal( + await page.evaluate(() => document.body.textContent), + 'xyz,abc,qwe' + ); + }); +});