24 lines
1.2 KiB
JavaScript
24 lines
1.2 KiB
JavaScript
/** Extract literal Minimal API routes and their receiver-specific MapGroup prefix. */
|
|
export function extractRoutesFromSource(source, file) {
|
|
const prefixes = new Map([["app", ""]]);
|
|
const groupPattern = /\b(?:var|const|RouteGroupBuilder)\s+(\w+)\s*=\s*(\w+)\.MapGroup\(\s*"([^"]+)"\s*\)/g;
|
|
for (const match of source.matchAll(groupPattern)) {
|
|
const parent = prefixes.get(match[2]);
|
|
if (parent === undefined) throw new Error(`Unknown MapGroup receiver ${match[2]} in ${file}`);
|
|
prefixes.set(match[1], parent + match[3]);
|
|
}
|
|
const routes = [];
|
|
const mapPattern = /\b(\w+)\.Map(Get|Post|Put|Delete|Patch)\(\s*"([^"]*)"/g;
|
|
for (const match of source.matchAll(mapPattern)) {
|
|
const prefix = prefixes.get(match[1]);
|
|
if (prefix === undefined) throw new Error(`Unknown route receiver ${match[1]} in ${file}`);
|
|
const path = (prefix + match[3]).replace(/\{([a-zA-Z0-9_]+)(:[a-zA-Z]+)?\}/g, "{$1}");
|
|
if (!path.startsWith("/api/v1")) {
|
|
if (!path.startsWith("/health")) throw new Error(`Unexpected non-API route ${path} in ${file}`);
|
|
continue;
|
|
}
|
|
routes.push({ method: match[2].toUpperCase(), path: path.slice("/api/v1".length) || "/", file });
|
|
}
|
|
return routes;
|
|
}
|