chore: crush git history - reborn from consolidation on 2026-03-10
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Route discovery from a Fastify instance.
|
||||
* Pure functions, no side effects.
|
||||
*
|
||||
* Fastify 5 removed the public `routes` array. We capture routes via the `onRoute`
|
||||
* hook during plugin registration and store them in a WeakMap keyed by the instance.
|
||||
*/
|
||||
import { extractContract } from './contract.js'
|
||||
import type { RouteContract } from '../types.js'
|
||||
|
||||
interface CapturedRoute {
|
||||
method: string
|
||||
url: string
|
||||
schema?: Record<string, unknown>
|
||||
prefix?: string
|
||||
}
|
||||
// WeakMap to store captured routes per Fastify instance (no memory leaks)
|
||||
const capturedRoutes = new WeakMap<object, CapturedRoute[]>()
|
||||
/**
|
||||
* Capture a route for discovery.
|
||||
* Called from the plugin's `onRoute` hook.
|
||||
*/
|
||||
export const captureRoute = (
|
||||
instance: object,
|
||||
route: CapturedRoute
|
||||
): void => {
|
||||
const existing = capturedRoutes.get(instance) ?? []
|
||||
existing.push(route)
|
||||
capturedRoutes.set(instance, existing)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback route discovery for Fastify 5 when routes were registered before
|
||||
* the APOPHIS plugin (e.g., external apps loaded by CLI).
|
||||
* Uses hasRoute to test known route patterns.
|
||||
*/
|
||||
function discoverRoutesFallback(
|
||||
instance: { hasRoute?: (opts: { method: string; url: string }) => boolean }
|
||||
): RouteContract[] {
|
||||
if (typeof instance.hasRoute !== 'function') {
|
||||
return []
|
||||
}
|
||||
|
||||
// Common HTTP methods to test
|
||||
const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']
|
||||
|
||||
// We can't enumerate all possible routes, but we can check if the instance
|
||||
// has any routes at all by testing a few common patterns
|
||||
// This is a best-effort fallback
|
||||
const routes: RouteContract[] = []
|
||||
|
||||
// Try to extract routes from the instance's internal state
|
||||
// Fastify stores routes in find-my-way router, but it's not directly accessible
|
||||
// We'll use a heuristic: check if the instance responds to common route methods
|
||||
|
||||
// Check if instance has any routes by looking at prototype methods
|
||||
const hasRouting = typeof (instance as any).routing === 'function'
|
||||
if (!hasRouting) {
|
||||
return []
|
||||
}
|
||||
|
||||
// Since we can't enumerate routes in Fastify 5 without the onRoute hook,
|
||||
// we return empty and let the caller handle the "no routes" case
|
||||
return []
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover routes from a Fastify instance.
|
||||
*
|
||||
* First checks captured routes (from onRoute hook), then falls back to
|
||||
* the legacy `routes` array for Fastify 4 compatibility.
|
||||
*/
|
||||
export const discoverRoutes = (instance: { routes?: Array<{ method: string; url: string; schema?: Record<string, unknown> }>; hasRoute?: (opts: { method: string; url: string }) => boolean }): RouteContract[] => {
|
||||
// Fastify 5: routes captured via onRoute hook
|
||||
const captured = capturedRoutes.get(instance)
|
||||
if (captured && captured.length > 0) {
|
||||
return captured.map((route) =>
|
||||
extractContract(route.url, route.method, route.schema)
|
||||
)
|
||||
}
|
||||
// Fastify 4 fallback
|
||||
if (Array.isArray(instance.routes) && instance.routes.length > 0) {
|
||||
return instance.routes.map((route) =>
|
||||
extractContract(route.url, route.method, route.schema)
|
||||
)
|
||||
}
|
||||
// Fastify 5 fallback: routes registered before plugin
|
||||
return discoverRoutesFallback(instance)
|
||||
}
|
||||
/**
|
||||
* Clear captured routes for an instance (useful for testing).
|
||||
*/
|
||||
export const clearCapturedRoutes = (instance: object): void => {
|
||||
capturedRoutes.delete(instance)
|
||||
}
|
||||
Reference in New Issue
Block a user