UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

56 lines 2.56 kB
const PARAM_NAME = "[A-Za-z0-9_-]+"; const COLON_PARAM = new RegExp(`^:(${PARAM_NAME})$`); const BRACKET_PARAM = new RegExp(`^\\[(${PARAM_NAME})\\]$`); function createPathTemplateError(path, segment) { return new Error(`Unsupported path template segment "${segment}" in "${path}". ` + "Use single-segment params like :id or [id]. Contract catch-all params such as [...path] and partial-segment params are not supported. Expose a platform catch-all route to the Beignet server, but keep individual contracts on concrete paths."); } function parsePathSegment(path, segment) { const colonMatch = segment.match(COLON_PARAM); if (colonMatch) { return { kind: "dynamic", name: colonMatch[1], raw: segment }; } const bracketMatch = segment.match(BRACKET_PARAM); if (bracketMatch) { return { kind: "dynamic", name: bracketMatch[1], raw: segment }; } if (segment.startsWith(":") || segment.startsWith("[") || segment.endsWith("]")) { throw createPathTemplateError(path, segment); } return { kind: "static", value: segment }; } /** * Parse a Beignet route path template. * * Paths must start with `/`. Dynamic segments may use `:id` or `[id]`. * Contract catch-all segments and partial dynamic segments are intentionally rejected. */ export function parsePathTemplate(path) { if (!path.startsWith("/")) { throw new Error(`Invalid path template "${path}". Paths must start with "/".`); } const segments = path .split("/") .filter(Boolean) .map((segment) => parsePathSegment(path, segment)); const keys = segments .filter((segment) => segment.kind === "dynamic") .map((segment) => segment.name); const duplicateKeys = keys.filter((key, index) => keys.indexOf(key) !== index); if (duplicateKeys.length) { throw new Error(`Invalid path template "${path}". Path parameter names must be unique; duplicate parameter "${duplicateKeys[0]}" was found.`); } const normalizedPath = `/${segments .map((segment) => segment.kind === "static" ? segment.value : `:${segment.name}`) .join("/")}`; const shapeKey = `/${segments .map((segment) => (segment.kind === "static" ? segment.value : ":")) .join("/")}`; const openApiPath = `/${segments .map((segment) => segment.kind === "static" ? segment.value : `{${segment.name}}`) .join("/")}`; return { keys, segments, normalizedPath, shapeKey, openApiPath }; } //# sourceMappingURL=path-template.js.map