11import { RoutePattern } from '@remix-run/route-pattern'
2+ import {
3+ getRouteMetadata ,
4+ stripRouteMetadata ,
5+ type RouteMetadata ,
6+ type RouteMetadataMarker ,
7+ } from './metadata.js'
28import type { RawBodySchema , RouteSchema } from './types/schema.js'
39
410/** HTTP methods supported by Rouzer action declarations. */
@@ -23,6 +29,8 @@ export type HttpAction<
2329 method : M
2430 /** Request validation and optional response type schema. */
2531 schema : T
32+ /** Optional runtime metadata for generated tooling. */
33+ metadata ?: RouteMetadata
2634}
2735
2836/**
@@ -41,6 +49,8 @@ export type HttpResource<
4149 path : RoutePattern < P >
4250 /** Child resources and actions exposed below this resource. */
4351 children : TChildren
52+ /** Optional runtime metadata for generated tooling. */
53+ metadata ?: RouteMetadata
4454}
4555
4656/** Node type accepted inside an HTTP route tree. */
@@ -49,6 +59,10 @@ export type HttpNode = HttpAction | HttpResource
4959/** Route tree accepted by HTTP clients and routers. */
5060export type HttpRouteTree = { [ key : string ] : HttpNode }
5161
62+ type RouteDeclaration < T extends object > = T & Partial < RouteMetadataMarker >
63+
64+ type StringKeys < T > = Pick < T , Extract < keyof T , string > >
65+
5266/**
5367 * Declare an HTTP resource namespace.
5468 *
@@ -59,85 +73,90 @@ export type HttpRouteTree = { [key: string]: HttpNode }
5973export function resource <
6074 const P extends string ,
6175 const TChildren extends HttpRouteTree ,
62- > ( path : P , children : TChildren ) : HttpResource < P , TChildren > {
76+ > (
77+ path : P ,
78+ children : RouteDeclaration < TChildren >
79+ ) : HttpResource < P , StringKeys < TChildren > > {
80+ const metadata = getRouteMetadata ( children )
6381 return {
6482 kind : 'resource' ,
6583 path : RoutePattern . parse ( path ) ,
66- children,
84+ children : stripRouteMetadata ( children ) as unknown as StringKeys < TChildren > ,
85+ metadata,
6786 }
6887}
6988
7089/** Declare a GET action, optionally with an action-local path segment. */
7190export function get < const P extends string , const T extends RouteSchema > (
7291 path : P ,
73- schema : T
92+ schema : RouteDeclaration < T >
7493) : HttpAction < P , T , 'GET' >
7594export function get < const T extends RouteSchema > (
76- schema : T
95+ schema : RouteDeclaration < T >
7796) : HttpAction < '' , T , 'GET' >
7897export function get (
79- pathOrSchema : string | RouteSchema ,
80- schema ?: RouteSchema
98+ pathOrSchema : string | RouteDeclaration < RouteSchema > ,
99+ schema ?: RouteDeclaration < RouteSchema >
81100) : any {
82101 return action ( 'GET' , pathOrSchema , schema )
83102}
84103
85104/** Declare a POST action, optionally with an action-local path segment. */
86105export function post < const P extends string , const T extends RouteSchema > (
87106 path : P ,
88- schema : T
107+ schema : RouteDeclaration < T >
89108) : HttpAction < P , T , 'POST' >
90109export function post < const T extends RouteSchema > (
91- schema : T
110+ schema : RouteDeclaration < T >
92111) : HttpAction < '' , T , 'POST' >
93112export function post (
94- pathOrSchema : string | RouteSchema ,
95- schema ?: RouteSchema
113+ pathOrSchema : string | RouteDeclaration < RouteSchema > ,
114+ schema ?: RouteDeclaration < RouteSchema >
96115) : any {
97116 return action ( 'POST' , pathOrSchema , schema )
98117}
99118
100119/** Declare a PUT action, optionally with an action-local path segment. */
101120export function put < const P extends string , const T extends RouteSchema > (
102121 path : P ,
103- schema : T
122+ schema : RouteDeclaration < T >
104123) : HttpAction < P , T , 'PUT' >
105124export function put < const T extends RouteSchema > (
106- schema : T
125+ schema : RouteDeclaration < T >
107126) : HttpAction < '' , T , 'PUT' >
108127export function put (
109- pathOrSchema : string | RouteSchema ,
110- schema ?: RouteSchema
128+ pathOrSchema : string | RouteDeclaration < RouteSchema > ,
129+ schema ?: RouteDeclaration < RouteSchema >
111130) : any {
112131 return action ( 'PUT' , pathOrSchema , schema )
113132}
114133
115134/** Declare a PATCH action, optionally with an action-local path segment. */
116135export function patch < const P extends string , const T extends RouteSchema > (
117136 path : P ,
118- schema : T
137+ schema : RouteDeclaration < T >
119138) : HttpAction < P , T , 'PATCH' >
120139export function patch < const T extends RouteSchema > (
121- schema : T
140+ schema : RouteDeclaration < T >
122141) : HttpAction < '' , T , 'PATCH' >
123142export function patch (
124- pathOrSchema : string | RouteSchema ,
125- schema ?: RouteSchema
143+ pathOrSchema : string | RouteDeclaration < RouteSchema > ,
144+ schema ?: RouteDeclaration < RouteSchema >
126145) : any {
127146 return action ( 'PATCH' , pathOrSchema , schema )
128147}
129148
130149/** Declare a DELETE action, optionally with an action-local path segment. */
131150function deleteAction < const P extends string , const T extends RouteSchema > (
132151 path : P ,
133- schema : T
152+ schema : RouteDeclaration < T >
134153) : HttpAction < P , T , 'DELETE' >
135154function deleteAction < const T extends RouteSchema > (
136- schema : T
155+ schema : RouteDeclaration < T >
137156) : HttpAction < '' , T , 'DELETE' >
138157function deleteAction (
139- pathOrSchema : string | RouteSchema ,
140- schema ?: RouteSchema
158+ pathOrSchema : string | RouteDeclaration < RouteSchema > ,
159+ schema ?: RouteDeclaration < RouteSchema >
141160) : any {
142161 return action ( 'DELETE' , pathOrSchema , schema )
143162}
@@ -163,13 +182,20 @@ export function isRawBodySchema(schema: unknown): schema is RawBodySchema {
163182
164183function action (
165184 method : HttpMethod ,
166- pathOrSchema : string | RouteSchema ,
167- schema ?: RouteSchema
185+ pathOrSchema : string | RouteDeclaration < RouteSchema > ,
186+ schema ?: RouteDeclaration < RouteSchema >
168187) {
169188 const path =
170189 typeof pathOrSchema === 'string'
171190 ? RoutePattern . parse ( pathOrSchema )
172191 : undefined
173192 schema ??= typeof pathOrSchema === 'string' ? { } : pathOrSchema
174- return { kind : 'action' , path, method, schema }
193+ const metadata = getRouteMetadata ( schema )
194+ return {
195+ kind : 'action' ,
196+ path,
197+ method,
198+ schema : stripRouteMetadata ( schema ) ,
199+ metadata,
200+ }
175201}
0 commit comments