Skip to content

Commit d9f8ea3

Browse files
committed
feat: Redirection feature using .location method on response object
1 parent 099f067 commit d9f8ea3

3 files changed

Lines changed: 53 additions & 5 deletions

File tree

src/core/response.ts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,26 @@ import { ServerResponse } from "node:http";
22
import Jrror, { JoorError } from "@/core/error";
33
import { HeaderSent } from "@/core/error/response";
44
import logger from '@/helpers/joorLogger';
5+
import Response, {RESPONSE_LOCATION_STATUS} from "@/types/response";
56

6-
const response = ServerResponse.prototype;
7-
response.status = function (this: ServerResponse, status: number) {
7+
const response = ServerResponse.prototype as Response;
8+
9+
/**
10+
* Sets the HTTP status code for the response.
11+
*
12+
* @param {number} status - The HTTP status code to set.
13+
*
14+
* @returns {Response} The response object for chaining.
15+
*
16+
* @example
17+
* ```typescript
18+
* response.status(200);
19+
* ```
20+
*/
21+
response.status = function (this: ServerResponse, status: number): Response {
822
try {
923
if (this.headersSent) {
10-
throw HeaderSent;
24+
throw HeaderSent; // Headers have already been sent
1125
}
1226
if (!Number.isInteger(status)) {
1327
throw new Jrror({
@@ -40,4 +54,35 @@ response.status = function (this: ServerResponse, status: number) {
4054
return this;
4155
}
4256

57+
}
58+
59+
/**
60+
Sets a location header for the response. Used for redirection.
61+
62+
@param {string} location - The URL to redirect to.
63+
@param {RESPONSE_LOCATION_STATUS} [status=301] - The HTTP status code for the redirection (default is 301).
64+
65+
example
66+
```typescript
67+
response.location('https://example.com', 302);
68+
```
69+
For more information, see the [HTTP/1.1 RFC](https://datatracker.ietf.org/doc/html/rfc7231#section-6.4).
70+
*/
71+
response.location = function (this: ServerResponse, location: string, status: RESPONSE_LOCATION_STATUS = 301): void {
72+
try {
73+
if (this.headersSent) {
74+
throw HeaderSent; // Headers have already been sent
75+
}
76+
this.setHeader("Location", location);
77+
this.status(status);
78+
}
79+
catch (error: unknown) {
80+
81+
if (error instanceof Jrror || error instanceof JoorError) {
82+
error.handle();
83+
}
84+
else {
85+
logger.error(error);
86+
}
87+
}
4388
}

src/packages/vary/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Jrror from '@/core/error';
22
import Response from '@/types/response';
33

4-
const FIEL_NAME_REGEX = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
4+
const FIELD_NAME_REGEX = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
55

66
const parse = (field: string) => {
77
if (!field) return [];
@@ -50,7 +50,7 @@ const append = (header: string, field: unknown): string => {
5050
const fields = Array.isArray(field) ? field : parse(String(field));
5151

5252
for (let i = 0; i < fields.length; i++) {
53-
if (!FIEL_NAME_REGEX.test(fields[i])) {
53+
if (!FIELD_NAME_REGEX.test(fields[i])) {
5454
throw new Jrror({
5555
code: 'vary-field-invalid',
5656
message: `Field name "${fields[i]}" contains invalid characters.`,

src/types/response.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ type RESPONSE_MESSAGE = string;
77

88
type RESPONSE_DATA = unknown;
99

10+
type RESPONSE_LOCATION_STATUS = 301 | 302 | 303 | 307 | 308;
11+
1012
// Interface for response cookies
1113
interface RESPONSE_COOKIES {
1214
[key: string]: {
@@ -61,4 +63,5 @@ export {
6163
RESPONSE_DATA,
6264
RESPONSE_COOKIES,
6365
RESPONSE_HEADERS,
66+
RESPONSE_LOCATION_STATUS,
6467
};

0 commit comments

Comments
 (0)