125 lines
2.9 KiB
TypeScript
125 lines
2.9 KiB
TypeScript
import "../core/metadata.ts";
|
|
import { defineMemberMetadata, getMemberMetadata } from "../core/metadata.ts";
|
|
|
|
export const PARAM_METADATA_KEY = "muddle:params";
|
|
|
|
export type ParamKind =
|
|
| "param"
|
|
| "body"
|
|
| "query"
|
|
| "request"
|
|
| "response"
|
|
| "locals"
|
|
| "form";
|
|
|
|
export interface ParamMetadata {
|
|
index: number;
|
|
kind: ParamKind;
|
|
/** Name of the route parameter or query key. */
|
|
name?: string;
|
|
}
|
|
|
|
/** `@Param('id')`, a route parameter. */
|
|
export function Param(name?: string): ParameterDecorator {
|
|
return (target, _propertyKey, index) => {
|
|
defineMemberMetadata(
|
|
PARAM_METADATA_KEY,
|
|
{ index, kind: "param", name } satisfies ParamMetadata,
|
|
target as object,
|
|
_propertyKey as string,
|
|
);
|
|
};
|
|
}
|
|
|
|
/** `@Body()`, the parsed request body. */
|
|
export function Body(): ParameterDecorator {
|
|
return (target, _propertyKey, index) => {
|
|
defineMemberMetadata(
|
|
PARAM_METADATA_KEY,
|
|
{ index, kind: "body" } satisfies ParamMetadata,
|
|
target as object,
|
|
_propertyKey as string,
|
|
);
|
|
};
|
|
}
|
|
|
|
/** `@Form()`, the submitted form fields. */
|
|
export function Form(): ParameterDecorator {
|
|
return (target, _propertyKey, index) => {
|
|
defineMemberMetadata(
|
|
PARAM_METADATA_KEY,
|
|
{ index, kind: "form" } satisfies ParamMetadata,
|
|
target as object,
|
|
_propertyKey as string,
|
|
);
|
|
};
|
|
}
|
|
|
|
/** `@Query('page')`, a query string entry. */
|
|
export function Query(name?: string): ParameterDecorator {
|
|
return (target, _propertyKey, index) => {
|
|
defineMemberMetadata(
|
|
PARAM_METADATA_KEY,
|
|
{ index, kind: "query", name } satisfies ParamMetadata,
|
|
target as object,
|
|
_propertyKey as string,
|
|
);
|
|
};
|
|
}
|
|
|
|
/** `@Req()`, the full request context. */
|
|
export function Req(): ParameterDecorator {
|
|
return (target, _propertyKey, index) => {
|
|
defineMemberMetadata(
|
|
PARAM_METADATA_KEY,
|
|
{ index, kind: "request" } satisfies ParamMetadata,
|
|
target as object,
|
|
_propertyKey as string,
|
|
);
|
|
};
|
|
}
|
|
|
|
/** `@Res()`, the response builder. */
|
|
export function Res(): ParameterDecorator {
|
|
return (target, _propertyKey, index) => {
|
|
defineMemberMetadata(
|
|
PARAM_METADATA_KEY,
|
|
{ index, kind: "response" } satisfies ParamMetadata,
|
|
target as object,
|
|
_propertyKey as string,
|
|
);
|
|
};
|
|
}
|
|
|
|
/** `@Locals()`, the mutable per request scratch space. */
|
|
export function Locals(): ParameterDecorator {
|
|
return (target, _propertyKey, index) => {
|
|
defineMemberMetadata(
|
|
PARAM_METADATA_KEY,
|
|
{ index, kind: "locals" } satisfies ParamMetadata,
|
|
target as object,
|
|
_propertyKey as string,
|
|
);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Reads the parameter descriptors of a controller method.
|
|
*/
|
|
export function getParamMetadata(
|
|
target: object,
|
|
propertyKey?: string,
|
|
): Map<number, ParamMetadata> {
|
|
const entries = propertyKey
|
|
? (getMemberMetadata(
|
|
PARAM_METADATA_KEY,
|
|
target,
|
|
propertyKey,
|
|
) as ParamMetadata[])
|
|
: [];
|
|
const map = new Map<number, ParamMetadata>();
|
|
for (const entry of entries) {
|
|
map.set(entry.index, entry);
|
|
}
|
|
return map;
|
|
}
|