in packages/web-components/fast-router/src/recognizer.ts [401:484]
private $add(route: Route, settings?: TSettings): void {
const path = route.path;
const $route = new ConfigurableRoute(
route.path,
route.name || "",
route.caseSensitive === true
);
// Normalize leading, trailing and double slashes by ignoring empty segments
const parts = path === "" ? [""] : path.split("/").filter(isNotEmpty);
const paramNames: string[] = [];
const paramTypes: string[] = [];
let state = this.rootState as AnyState<TSettings>;
const segments: AnySegment<any>[] = [];
for (const part of parts) {
// Each segment always begins with a slash, so we represent this with a non-segment state
state = state.append(null, "/");
switch (part.charAt(0)) {
case "{": {
// route parameter
const nameAndType = part
.slice(1, -1)
.split(":")
.map(x => x.trim());
if (nameAndType.length === 2) {
paramTypes.push(nameAndType[1]);
} else {
paramTypes.push("string");
}
const isOptional = nameAndType[0].endsWith("?");
const name = isOptional
? nameAndType[0].slice(0, -1)
: nameAndType[0];
paramNames.push(name);
const segment = new DynamicSegment<TSettings>(name, isOptional);
segments.push(segment);
state = segment.appendTo(state);
break;
}
case "*": {
// dynamic route
const name = part.slice(1);
paramNames.push(name);
paramTypes.push("string");
const segment = new StarSegment<TSettings>(name);
segments.push(segment);
state = segment.appendTo(state);
break;
}
default: {
// standard path route
const segment = new StaticSegment<TSettings>(
part,
$route.caseSensitive
);
segments.push(segment);
state = segment.appendTo(state);
break;
}
}
}
const endpoint = new Endpoint<TSettings>(
$route,
paramNames,
paramTypes,
settings || null
);
state.setEndpoint(endpoint);
this.paths.set(path, segments);
if (route.name) {
this.names.set(route.name, segments);
}
}