Files
summercms/admin/src/app/controllerRoutes.ts
Jakub Zych 5f9353841b feat(10-01): serve the embedded admin SPA at backend.uri with cookie login
- backend.uri prefix (default /backend) mounts the admin API at {prefix}/api/v1
  and the embedded SPA shell at {prefix} with an api/ JSON 404 fallback
- cookie transport: an X-Requested-With login sets the HttpOnly summer_admin
  cookie and returns no token; the backend guard reads the cookie after Bearer
- CSRF wrapper refuses cookie-only POST/PUT/DELETE without X-Requested-With
- boardwalk package embeds boardwalk/dist, rewrites index.html once per prefix
  and sets cache and security headers
- framework admin OpenAPI pipeline (swag, swagger2openapi, openapi-typescript)
  with prefix-relative paths and typed envelopes for the tracer routes
- admin/ Vite SPA: login, plugin rail, section panel and read-only list
  through the openapi-fetch client typed by the generated schema
2026-09-27 15:21:48 +02:00

43 lines
1.4 KiB
TypeScript

// Controller IDs map one to one onto SPA paths (D-10):
// vendor.plugin.controller <-> /vendor/plugin/controller.
export interface ControllerParams {
vendor: string
plugin: string
controller: string
}
const SEGMENT = /^[A-Za-z0-9_-]+$/
export function parseControllerId(id: string): ControllerParams | null {
const parts = id.split('.')
if (parts.length !== 3 || !parts.every((part) => SEGMENT.test(part))) {
return null
}
const [vendor, plugin, controller] = parts as [string, string, string]
return { vendor, plugin, controller }
}
export function controllerPath(id: string): string | null {
const params = parseControllerId(id)
return params ? `/${params.vendor}/${params.plugin}/${params.controller}` : null
}
export function controllerIdFromParams(params: ControllerParams): string {
return `${params.vendor}.${params.plugin}.${params.controller}`
}
export function controllerIdFromPath(path: string): string | null {
const parts = path.replace(/^\/+|\/+$/g, '').split('/')
if (parts.length < 3) {
return null
}
const id = parts.slice(0, 3).join('.')
return parseControllerId(id) ? id : null
}
/** vendor.plugin prefix of a controller ID, used to find the owning plugin. */
export function pluginKey(id: string): string | null {
const params = parseControllerId(id)
return params ? `${params.vendor}.${params.plugin}` : null
}