- 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
43 lines
1.4 KiB
TypeScript
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
|
|
}
|