mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-18 05:25:08 +00:00
Regularize page and server routes
Treats both page and server routes similarly in regards to indexes. It's a (somewhat) breaking change: server routes will accept trailing slashes to match page routes behavior, but only if there's no extension. We still need a stronger support for dealing with different clean urls rules.
This commit is contained in:
@@ -101,7 +101,11 @@ export function select_target(url: URL): Target {
|
|||||||
if (url.origin !== location.origin) return null;
|
if (url.origin !== location.origin) return null;
|
||||||
if (!url.pathname.startsWith(initial_data.baseUrl)) return null;
|
if (!url.pathname.startsWith(initial_data.baseUrl)) return null;
|
||||||
|
|
||||||
const path = url.pathname.slice(initial_data.baseUrl.length);
|
let path = url.pathname.slice(initial_data.baseUrl.length);
|
||||||
|
|
||||||
|
if (path === '') {
|
||||||
|
path = '/';
|
||||||
|
}
|
||||||
|
|
||||||
// avoid accidental clashes between server routes and page routes
|
// avoid accidental clashes between server routes and page routes
|
||||||
if (ignore.some(pattern => pattern.test(path))) return;
|
if (ignore.some(pattern => pattern.test(path))) return;
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ export default function create_manifest_data(cwd: string): ManifestData {
|
|||||||
const parts = get_parts(segment);
|
const parts = get_parts(segment);
|
||||||
const is_index = is_dir ? false : basename.startsWith('index.');
|
const is_index = is_dir ? false : basename.startsWith('index.');
|
||||||
const is_page = component_extensions.indexOf(ext) !== -1;
|
const is_page = component_extensions.indexOf(ext) !== -1;
|
||||||
|
const route_suffix = basename.slice(basename.indexOf('.'), -ext.length);
|
||||||
|
|
||||||
parts.forEach(part => {
|
parts.forEach(part => {
|
||||||
if (/\]\[/.test(part.content)) {
|
if (/\]\[/.test(part.content)) {
|
||||||
@@ -104,7 +105,8 @@ export default function create_manifest_data(cwd: string): ManifestData {
|
|||||||
file: posixify(file),
|
file: posixify(file),
|
||||||
is_dir,
|
is_dir,
|
||||||
is_index,
|
is_index,
|
||||||
is_page
|
is_page,
|
||||||
|
route_suffix
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
@@ -113,25 +115,25 @@ export default function create_manifest_data(cwd: string): ManifestData {
|
|||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
const segments = parent_segments.slice();
|
const segments = parent_segments.slice();
|
||||||
|
|
||||||
if (item.is_index && segments.length > 0) {
|
if (item.is_index) {
|
||||||
const suffix = item.basename
|
if (item.route_suffix) {
|
||||||
.slice(0, -item.ext.length)
|
if (segments.length > 0) {
|
||||||
.replace('index', '');
|
const last_segment = segments[segments.length - 1].slice();
|
||||||
|
const last_part = last_segment[last_segment.length - 1];
|
||||||
|
|
||||||
if (suffix) {
|
if (last_part.dynamic) {
|
||||||
const last_segment = segments[segments.length - 1].slice();
|
last_segment.push({ dynamic: false, content: item.route_suffix });
|
||||||
const last_part = last_segment[last_segment.length - 1];
|
} else {
|
||||||
|
last_segment[last_segment.length - 1] = {
|
||||||
|
dynamic: false,
|
||||||
|
content: `${last_part.content}${item.route_suffix}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (last_part.dynamic) {
|
segments[segments.length - 1] = last_segment;
|
||||||
last_segment.push({ dynamic: false, content: suffix });
|
|
||||||
} else {
|
} else {
|
||||||
last_segment[last_segment.length - 1] = {
|
segments.push(item.parts);
|
||||||
dynamic: false,
|
|
||||||
content: `${last_part.content}${suffix}`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
segments[segments.length - 1] = last_segment;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
segments.push(item.parts);
|
segments.push(item.parts);
|
||||||
@@ -156,8 +158,6 @@ export default function create_manifest_data(cwd: string): ManifestData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (item.is_page) {
|
else if (item.is_page) {
|
||||||
const is_index = item.basename === `index${item.ext}`;
|
|
||||||
|
|
||||||
const component = {
|
const component = {
|
||||||
name: get_slug(item.file),
|
name: get_slug(item.file),
|
||||||
file: item.file,
|
file: item.file,
|
||||||
@@ -166,22 +166,20 @@ export default function create_manifest_data(cwd: string): ManifestData {
|
|||||||
|
|
||||||
components.push(component);
|
components.push(component);
|
||||||
|
|
||||||
const parts = (is_index && stack[stack.length - 1] === null)
|
const parts = (item.is_index && stack[stack.length - 1] === null)
|
||||||
? stack.slice(0, -1).concat({ component, params })
|
? stack.slice(0, -1).concat({ component, params })
|
||||||
: stack.concat({ component, params })
|
: stack.concat({ component, params })
|
||||||
|
|
||||||
const page = {
|
pages.push({
|
||||||
pattern: get_pattern(is_index ? parent_segments : segments, true),
|
pattern: get_pattern(segments, true),
|
||||||
parts
|
parts
|
||||||
};
|
});
|
||||||
|
|
||||||
pages.push(page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
server_routes.push({
|
server_routes.push({
|
||||||
name: `route_${get_slug(item.file)}`,
|
name: `route_${get_slug(item.file)}`,
|
||||||
pattern: get_pattern(segments, false),
|
pattern: get_pattern(segments, !item.route_suffix),
|
||||||
file: item.file,
|
file: item.file,
|
||||||
params: params
|
params: params
|
||||||
});
|
});
|
||||||
@@ -321,7 +319,6 @@ function get_parts(part: string): Part[] {
|
|||||||
function get_slug(file: string) {
|
function get_slug(file: string) {
|
||||||
let name = file
|
let name = file
|
||||||
.replace(/[\\\/]index/, '')
|
.replace(/[\\\/]index/, '')
|
||||||
.replace(/_default([\/\\index])?\.html$/, 'index')
|
|
||||||
.replace(/[\/\\]/g, '_')
|
.replace(/[\/\\]/g, '_')
|
||||||
.replace(/\.\w+$/, '')
|
.replace(/\.\w+$/, '')
|
||||||
.replace(/\[([^(]+)(?:\([^(]+\))?\]/, '$$$1')
|
.replace(/\[([^(]+)(?:\([^(]+\))?\]/, '$$$1')
|
||||||
@@ -334,19 +331,19 @@ function get_slug(file: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function get_pattern(segments: Part[][], add_trailing_slash: boolean) {
|
function get_pattern(segments: Part[][], add_trailing_slash: boolean) {
|
||||||
return new RegExp(
|
const path = segments.map(segment => {
|
||||||
`^` +
|
return segment.map(part => {
|
||||||
segments.map(segment => {
|
return part.dynamic
|
||||||
return '\\/' + segment.map(part => {
|
? part.qualifier || part.spread ? '(.+)' : '([^\\/]+?)'
|
||||||
return part.dynamic
|
: encodeURI(part.content.normalize())
|
||||||
? part.qualifier || part.spread ? '(.+)' : '([^\\/]+?)'
|
.replace(/\?/g, '%3F')
|
||||||
: encodeURI(part.content.normalize())
|
.replace(/#/g, '%23')
|
||||||
.replace(/\?/g, '%3F')
|
.replace(/%5B/g, '[')
|
||||||
.replace(/#/g, '%23')
|
.replace(/%5D/g, ']');
|
||||||
.replace(/%5B/g, '[')
|
}).join('');
|
||||||
.replace(/%5D/g, ']');
|
}).join('\\/');
|
||||||
}).join('');
|
|
||||||
}).join('') +
|
const trailing = add_trailing_slash && segments.length ? '\\/?$' : '$';
|
||||||
(add_trailing_slash ? '\\\/?$' : '$')
|
|
||||||
);
|
return new RegExp(`^\\/${path}${trailing}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ describe('manifest_data', () => {
|
|||||||
|
|
||||||
assert.deepEqual(pages, [
|
assert.deepEqual(pages, [
|
||||||
{
|
{
|
||||||
pattern: /^\/?$/,
|
pattern: /^\/$/,
|
||||||
parts: [
|
parts: [
|
||||||
{ component: index, params: [] }
|
{ component: index, params: [] }
|
||||||
]
|
]
|
||||||
@@ -50,6 +50,13 @@ describe('manifest_data', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
assert.deepEqual(server_routes, [
|
assert.deepEqual(server_routes, [
|
||||||
|
{
|
||||||
|
name: 'route_index',
|
||||||
|
pattern: /^\/$/,
|
||||||
|
file: 'index.js',
|
||||||
|
params: []
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'route_blog_json',
|
name: 'route_blog_json',
|
||||||
pattern: /^\/blog.json$/,
|
pattern: /^\/blog.json$/,
|
||||||
@@ -167,7 +174,7 @@ describe('manifest_data', () => {
|
|||||||
file: 'foo.js',
|
file: 'foo.js',
|
||||||
name: 'route_foo',
|
name: 'route_foo',
|
||||||
params: [],
|
params: [],
|
||||||
pattern: /^\/foo$/
|
pattern: /^\/foo\/?$/
|
||||||
}]);
|
}]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user