UNPKG

next-page-tester

Version:
102 lines (101 loc) 4.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeParamsObject = exports.pagePathToRouteRegex = exports.encodeCaptureGroupName = exports.ROUTE_PARAMS_TYPES = void 0; var ROUTE_PARAMS_TYPES; (function (ROUTE_PARAMS_TYPES) { ROUTE_PARAMS_TYPES["DYNAMIC"] = "dynamic"; ROUTE_PARAMS_TYPES["CATCH_ALL"] = "catch_all"; ROUTE_PARAMS_TYPES["OPTIONAL_CATCH_ALL"] = "optional_catch_all"; })(ROUTE_PARAMS_TYPES = exports.ROUTE_PARAMS_TYPES || (exports.ROUTE_PARAMS_TYPES = {})); // [param] const DYNAMIC_ROUTE_SEGMENT_REGEX = /\[([^./[\]]*)\]/g; const DYNAMIC_PATH_SEGMENT_REGEX_STRING = '[^/?]*'; // [...slug] const CATCH_ALL_ROUTE_SEGMENT_REGEX = /\[\.{3}([^/[\]]*)\]/; const CATCH_ALL_PATH_SEGMENT_REGEX_STRING = '.*?'; // [[...slug]] const OPTIONAL_CATCH_ALL_ROUTE_SEGMENT_REGEX = /\/?\[\[\.{3}([^/[\]]*)\]\]/; const OPTIONAL_CATCH_ALL_PATH_SEGMENT_REGEX_STRING = '.*?'; const TRAILING_INDEX_REGEX = /\/index$/; const OPTIONAL_TRAILING_INDEX_REGEX_STRING = '(?:/index)?'; function encodeCaptureGroupName(string) { return '__encodedCaptureGroupName' + Buffer.from(string).toString('hex'); } exports.encodeCaptureGroupName = encodeCaptureGroupName; function decodeCaptureGroupName(string) { return Buffer.from(string.replace(/^__encodedCaptureGroupName/, ''), 'hex').toString(); } function makeNamedCaptureGroup({ name, regex }) { // We need to encode capture group names to support special characters like "-" const encodedName = encodeCaptureGroupName(name); return `(?<${encodedName}>${regex})`; } function makeOptionalNamedCapturingGroup({ name, regex }) { const captureGroup = makeNamedCaptureGroup({ name, regex }); return `${captureGroup}?`; } /** * Build a regex from a page path to catch its matching routes * @returns a regex and the map of the types of params found */ function pagePathToRouteRegex(pagePath) { // Store found route param names by type const paramTypes = {}; // Special case for /index page which should match both "/" and "/index" pathnames if (pagePath === '/index') { return { regex: /^\/(?:index)?$/, paramTypes, }; } const regex = pagePath .replace(TRAILING_INDEX_REGEX, OPTIONAL_TRAILING_INDEX_REGEX_STRING) .replace(OPTIONAL_CATCH_ALL_ROUTE_SEGMENT_REGEX, (match, paramName) => { paramTypes[paramName] = ROUTE_PARAMS_TYPES.OPTIONAL_CATCH_ALL; const captureGroup = makeOptionalNamedCapturingGroup({ name: paramName, regex: OPTIONAL_CATCH_ALL_PATH_SEGMENT_REGEX_STRING, }); return `(?:/)?${captureGroup}`; }) .replace(CATCH_ALL_ROUTE_SEGMENT_REGEX, (match, paramName) => { paramTypes[paramName] = ROUTE_PARAMS_TYPES.CATCH_ALL; return makeNamedCaptureGroup({ name: paramName, regex: CATCH_ALL_PATH_SEGMENT_REGEX_STRING, }); }) .replace(DYNAMIC_ROUTE_SEGMENT_REGEX, (match, paramName) => { paramTypes[paramName] = ROUTE_PARAMS_TYPES.DYNAMIC; return makeNamedCaptureGroup({ name: paramName, regex: DYNAMIC_PATH_SEGMENT_REGEX_STRING, }); }); // Add route's trailing slash return { regex: new RegExp(`^${regex}$`), paramTypes, }; } exports.pagePathToRouteRegex = pagePathToRouteRegex; function makeParamsObject({ routeRegexCaptureGroups, paramTypes, }) { const params = {}; for (const name in routeRegexCaptureGroups) { const value = routeRegexCaptureGroups[name]; if (value !== undefined) { // Capture group names are encoded const paramName = decodeCaptureGroupName(name); const paramType = paramTypes[paramName]; if (paramType === ROUTE_PARAMS_TYPES.CATCH_ALL || paramType === ROUTE_PARAMS_TYPES.OPTIONAL_CATCH_ALL) { params[paramName] = value.split('/'); } else { params[paramName] = value; } } } return params; } exports.makeParamsObject = makeParamsObject;