Skip to content

Commit 4c1d4a9

Browse files
jbl428imdudu1
andcommitted
feat: add http exchange decorator
Co-authored-by: imdudu1 <[email protected]>
1 parent df4d092 commit 4c1d4a9

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

lib/decorators/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export const HTTP_INTERFACE_METADATA = Symbol("HTTP_INTERFACE_METADATA");
2+
export const HTTP_EXCHANGE_METADATA = Symbol("HTTP_EXCHANGE_METADATA");
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { describe, test, expect } from "vitest";
2+
import { HTTP_EXCHANGE_METADATA } from "./constants";
3+
import {
4+
type HttpExchangeMetadata,
5+
GetExchange,
6+
PostExchange,
7+
PutExchange,
8+
DeleteExchange,
9+
OptionsExchange,
10+
PatchExchange,
11+
HeadExchange,
12+
} from "./http-exchange.decorator";
13+
14+
describe("HttpExchange", () => {
15+
test.each([
16+
["GET", GetExchange],
17+
["POST", PostExchange],
18+
["PUT", PutExchange],
19+
["DELETE", DeleteExchange],
20+
["PATCH", PatchExchange],
21+
["HEAD", HeadExchange],
22+
["OPTIONS", OptionsExchange],
23+
])("should set %s method metadata", (method, decorator) => {
24+
// given
25+
class TestService {
26+
@decorator("/api/v1/sample")
27+
async request(): Promise<string> {
28+
return "";
29+
}
30+
}
31+
32+
// when
33+
const result: HttpExchangeMetadata = Reflect.getMetadata(
34+
HTTP_EXCHANGE_METADATA,
35+
TestService.prototype,
36+
"request"
37+
);
38+
39+
// then
40+
expect(result.method).toBe(method);
41+
expect(result.url).toBe("/api/v1/sample");
42+
});
43+
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { HTTP_EXCHANGE_METADATA } from "./constants";
2+
3+
type HttpMethod =
4+
| "GET"
5+
| "POST"
6+
| "PUT"
7+
| "DELETE"
8+
| "PATCH"
9+
| "HEAD"
10+
| "OPTIONS";
11+
12+
export interface HttpExchangeMetadata {
13+
method: HttpMethod;
14+
url: string;
15+
}
16+
17+
type AsyncFunction = (...args: unknown[]) => Promise<unknown>;
18+
19+
export function HttpExchange(method: HttpMethod, url: string) {
20+
return function <P extends string>(
21+
target: Record<P, AsyncFunction>,
22+
propertyKey: P
23+
) {
24+
Reflect.defineMetadata(
25+
HTTP_EXCHANGE_METADATA,
26+
{ method, url },
27+
target,
28+
propertyKey
29+
);
30+
};
31+
}
32+
33+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
34+
export const GetExchange = (url = "") => HttpExchange("GET", url);
35+
export const PostExchange = (url = "") => HttpExchange("POST", url);
36+
export const PutExchange = (url = "") => HttpExchange("PUT", url);
37+
export const DeleteExchange = (url = "") => HttpExchange("DELETE", url);
38+
export const PatchExchange = (url = "") => HttpExchange("PATCH", url);
39+
export const HeadExchange = (url = "") => HttpExchange("HEAD", url);
40+
export const OptionsExchange = (url = "") => HttpExchange("OPTIONS", url);

lib/decorators/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./http-interface.decorator";
2+
export * from "./http-exchange.decorator";
23
export * from "./constants";

0 commit comments

Comments
 (0)