UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

66 lines (55 loc) 1.58 kB
import { type PathTemplateSegment, parsePathTemplate, } from "./path-template.js"; import type { HttpMethod } from "./types.js"; const methodNameMap: Record<HttpMethod, string> = { GET: "get", POST: "create", PUT: "update", PATCH: "patch", DELETE: "delete", HEAD: "head", OPTIONS: "options", }; function toPascalCase(value: string): string { return value .replace(/([a-z0-9])([A-Z])/g, "$1 $2") .split(/[^a-zA-Z0-9]+/) .filter(Boolean) .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) .join(""); } function getMeaningfulPathSegments(path: string): PathTemplateSegment[] { const segments = parsePathTemplate(path).segments; if ( segments[0]?.kind === "static" && segments[0].value.toLowerCase() === "api" ) { return segments.slice(1); } return segments; } /** * Generate a stable contract name from an HTTP method and path. * * `/api` is ignored as a leading path segment so generated names focus on the * resource shape. */ export function generateContractName(method: HttpMethod, path: string): string { const methodPrefix = methodNameMap[method]; const segments = getMeaningfulPathSegments(path); if (segments.length === 0) { return `${methodPrefix}Root`; } const nameSuffix = segments .map((segment) => { if (segment.kind === "dynamic") { const paramName = toPascalCase(segment.name); return `By${paramName || "Param"}`; } return toPascalCase(segment.value) || "Resource"; }) .join(""); return `${methodPrefix}${nameSuffix}`; }