@arkyn/server 2.0.1-beta.0 → 2.0.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/http/badResponses/badGateway.d.ts +11 -0
- package/dist/http/badResponses/badGateway.d.ts.map +1 -0
- package/dist/http/badResponses/badGateway.js +29 -0
- package/dist/http/badResponses/badRequest.d.ts +11 -0
- package/dist/http/badResponses/badRequest.d.ts.map +1 -0
- package/dist/http/badResponses/badRequest.js +29 -0
- package/dist/http/badResponses/conflict.d.ts +11 -0
- package/dist/http/badResponses/conflict.d.ts.map +1 -0
- package/dist/http/badResponses/conflict.js +29 -0
- package/dist/http/badResponses/forbidden.d.ts +11 -0
- package/dist/http/badResponses/forbidden.d.ts.map +1 -0
- package/dist/http/badResponses/forbidden.js +29 -0
- package/dist/http/badResponses/notFound.d.ts +11 -0
- package/dist/http/badResponses/notFound.d.ts.map +1 -0
- package/dist/http/badResponses/notFound.js +29 -0
- package/dist/http/badResponses/notImplemented.d.ts +11 -0
- package/dist/http/badResponses/notImplemented.d.ts.map +1 -0
- package/dist/http/badResponses/notImplemented.js +29 -0
- package/dist/http/badResponses/serverError.d.ts +11 -0
- package/dist/http/badResponses/serverError.d.ts.map +1 -0
- package/dist/http/badResponses/serverError.js +29 -0
- package/dist/http/badResponses/unauthorized.d.ts +11 -0
- package/dist/http/badResponses/unauthorized.d.ts.map +1 -0
- package/dist/http/badResponses/unauthorized.js +29 -0
- package/dist/http/badResponses/unprocessableEntity.d.ts +16 -0
- package/dist/http/badResponses/unprocessableEntity.d.ts.map +1 -0
- package/dist/http/badResponses/unprocessableEntity.js +33 -0
- package/dist/http/httpDebug.d.ts +3 -0
- package/dist/http/httpDebug.d.ts.map +1 -0
- package/dist/http/httpDebug.js +15 -0
- package/dist/http/successResponses/created.d.ts +11 -0
- package/dist/http/successResponses/created.d.ts.map +1 -0
- package/dist/http/successResponses/created.js +29 -0
- package/dist/http/successResponses/found.d.ts +11 -0
- package/dist/http/successResponses/found.d.ts.map +1 -0
- package/dist/http/successResponses/found.js +29 -0
- package/dist/http/successResponses/noContent.d.ts +10 -0
- package/dist/http/successResponses/noContent.d.ts.map +1 -0
- package/dist/http/successResponses/noContent.js +27 -0
- package/dist/http/successResponses/success.d.ts +11 -0
- package/dist/http/successResponses/success.d.ts.map +1 -0
- package/dist/http/successResponses/success.js +29 -0
- package/dist/http/successResponses/updated.d.ts +11 -0
- package/dist/http/successResponses/updated.d.ts.map +1 -0
- package/dist/http/successResponses/updated.js +29 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/services/decodeRequestBody.d.ts +17 -0
- package/dist/services/decodeRequestBody.d.ts.map +1 -0
- package/dist/services/decodeRequestBody.js +42 -0
- package/dist/services/errorHandler.d.ts +3 -0
- package/dist/services/errorHandler.d.ts.map +1 -0
- package/dist/services/errorHandler.js +51 -0
- package/dist/services/formParse.d.ts +42 -0
- package/dist/services/formParse.d.ts.map +1 -0
- package/dist/services/formParse.js +54 -0
- package/dist/services/getScopedParams.d.ts +28 -0
- package/dist/services/getScopedParams.d.ts.map +1 -0
- package/dist/services/getScopedParams.js +34 -0
- package/dist/services/sendFileToS3.d.ts +52 -0
- package/dist/services/sendFileToS3.d.ts.map +1 -0
- package/dist/services/sendFileToS3.js +143 -0
- package/package.json +2 -1
- package/src/http/badResponses/badGateway.ts +36 -0
- package/src/http/badResponses/badRequest.ts +36 -0
- package/src/http/badResponses/conflict.ts +36 -0
- package/src/http/badResponses/forbidden.ts +36 -0
- package/src/http/badResponses/notFound.ts +36 -0
- package/src/http/badResponses/notImplemented.ts +36 -0
- package/src/http/badResponses/serverError.ts +36 -0
- package/src/http/badResponses/unauthorized.ts +36 -0
- package/src/http/badResponses/unprocessableEntity.ts +48 -0
- package/src/http/httpDebug.ts +18 -0
- package/src/http/successResponses/created.ts +35 -0
- package/src/http/successResponses/found.ts +35 -0
- package/src/http/successResponses/noContent.ts +33 -0
- package/src/http/successResponses/success.ts +35 -0
- package/src/http/successResponses/updated.ts +35 -0
- package/src/index.ts +16 -18
- package/src/services/decodeRequestBody.ts +46 -0
- package/src/services/errorHandler.ts +55 -0
- package/src/services/formParse.ts +42 -1
- package/src/services/getScopedParams.ts +29 -2
- package/src/services/sendFileToS3.ts +81 -56
- package/src/helpers/globalErrorHandler.ts +0 -64
- package/src/httpBadResponses/badRequest.ts +0 -29
- package/src/httpBadResponses/conflict.ts +0 -29
- package/src/httpBadResponses/forbidden.ts +0 -29
- package/src/httpBadResponses/notFound.ts +0 -29
- package/src/httpBadResponses/serverError.ts +0 -29
- package/src/httpBadResponses/unauthorized.ts +0 -29
- package/src/httpBadResponses/unprocessableEntity.ts +0 -43
- package/src/httpResponses/created.ts +0 -35
- package/src/httpResponses/noContent.ts +0 -33
- package/src/httpResponses/success.ts +0 -35
- package/src/httpResponses/updated.ts +0 -35
- package/src/services/extractJsonFromRequest.ts +0 -30
|
@@ -1,4 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
import type { GetScopedParamsFunction } from "@arkyn/types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extracts and returns scoped query parameters from a request URL.
|
|
5
|
+
*
|
|
6
|
+
* @param request - The incoming request object containing the URL.
|
|
7
|
+
* @param scope - An optional string representing the scope prefix for filtering query parameters.
|
|
8
|
+
* If no scope is provided, all query parameters are returned.
|
|
9
|
+
*
|
|
10
|
+
* @returns A `URLSearchParams` object containing the scoped query parameters.
|
|
11
|
+
* If a scope is provided, only parameters with keys starting with the scope
|
|
12
|
+
* (e.g., `scope:key`) are included, and the scope prefix is removed from the keys.
|
|
13
|
+
* If no scope is provided, all query parameters are returned as-is.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Example 1: No scope provided
|
|
17
|
+
* const request = { url: "https://example.com?key1=value1&key2=value2" };
|
|
18
|
+
* const params = getScopedParams(request);
|
|
19
|
+
* console.log(params.toString()); // Output: "key1=value1&key2=value2"
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Example 2: Scope provided
|
|
23
|
+
* const request = { url: "https://example.com?scope:key1=value1&scope:key2=value2&key3=value3" };
|
|
24
|
+
* const params = getScopedParams(request, "scope");
|
|
25
|
+
* console.log(params.toString()); // Output: "key1=value1&key2=value2"
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const getScopedParams: GetScopedParamsFunction = (request, scope = "") => {
|
|
2
29
|
const url = new URL(request.url);
|
|
3
30
|
if (scope === "") return url.searchParams;
|
|
4
31
|
|
|
@@ -9,6 +36,6 @@ function getScopedParams(request: Request, scope: string = "") {
|
|
|
9
36
|
.map(([key, value]) => [key.replace(`${scope}:`, ""), value]);
|
|
10
37
|
|
|
11
38
|
return new URLSearchParams(scopedSearchParams);
|
|
12
|
-
}
|
|
39
|
+
};
|
|
13
40
|
|
|
14
41
|
export { getScopedParams };
|
|
@@ -1,62 +1,34 @@
|
|
|
1
|
+
import { generateId } from "@arkyn/shared";
|
|
2
|
+
import type { AwsConfig, SendFileToS3Function } from "@arkyn/types";
|
|
1
3
|
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
2
4
|
import {
|
|
3
5
|
unstable_composeUploadHandlers as composeUploadHandlers,
|
|
4
6
|
unstable_createFileUploadHandler as createFileUploadHandler,
|
|
5
7
|
unstable_parseMultipartFormData as parseMultipartFormData,
|
|
6
|
-
type ActionFunctionArgs,
|
|
7
8
|
type NodeOnDiskFile,
|
|
8
9
|
} from "@remix-run/node";
|
|
9
|
-
import { randomUUID } from "crypto";
|
|
10
10
|
import fs from "fs";
|
|
11
11
|
import sharp from "sharp";
|
|
12
|
-
import {
|
|
12
|
+
import { BadRequest } from "../http/badResponses/badRequest";
|
|
13
13
|
import { getScopedParams } from "./getScopedParams";
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
AWS_REGION: string;
|
|
17
|
-
AWS_ACCESS_KEY_ID: string;
|
|
18
|
-
AWS_SECRET_ACCESS_KEY: string;
|
|
19
|
-
AWS_S3_BUCKET: string;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
type Config = {
|
|
23
|
-
maxPartSize?: number;
|
|
24
|
-
fileName?: string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
async function s3_upload(
|
|
15
|
+
async function s3Upload(
|
|
28
16
|
fileStream: fs.ReadStream,
|
|
29
17
|
contentType: string,
|
|
30
|
-
|
|
18
|
+
awsConfig: AwsConfig
|
|
31
19
|
) {
|
|
32
|
-
const {
|
|
33
|
-
AWS_ACCESS_KEY_ID,
|
|
34
|
-
AWS_REGION,
|
|
35
|
-
AWS_S3_BUCKET,
|
|
36
|
-
AWS_SECRET_ACCESS_KEY,
|
|
37
|
-
} = awsS3Config;
|
|
38
|
-
|
|
39
|
-
const filePath = fileStream.path;
|
|
40
|
-
let fileName = "";
|
|
41
|
-
|
|
42
|
-
if (typeof filePath === "string") {
|
|
43
|
-
fileName = filePath.split("/").pop() || "";
|
|
44
|
-
} else {
|
|
45
|
-
fileName = randomUUID();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
20
|
const uploadParams = {
|
|
49
|
-
Bucket: AWS_S3_BUCKET,
|
|
50
|
-
Key: `uploads/${
|
|
21
|
+
Bucket: awsConfig.AWS_S3_BUCKET,
|
|
22
|
+
Key: `uploads/${generateId("text", "v4")}`,
|
|
51
23
|
Body: fileStream,
|
|
52
24
|
ContentType: contentType,
|
|
53
25
|
};
|
|
54
26
|
|
|
55
27
|
const s3Client = new S3Client({
|
|
56
|
-
region: AWS_REGION,
|
|
28
|
+
region: awsConfig.AWS_REGION,
|
|
57
29
|
credentials: {
|
|
58
|
-
accessKeyId: AWS_ACCESS_KEY_ID,
|
|
59
|
-
secretAccessKey: AWS_SECRET_ACCESS_KEY,
|
|
30
|
+
accessKeyId: awsConfig.AWS_ACCESS_KEY_ID,
|
|
31
|
+
secretAccessKey: awsConfig.AWS_SECRET_ACCESS_KEY,
|
|
60
32
|
},
|
|
61
33
|
});
|
|
62
34
|
|
|
@@ -69,20 +41,71 @@ async function s3_upload(
|
|
|
69
41
|
}
|
|
70
42
|
|
|
71
43
|
return {
|
|
72
|
-
location: `https://${AWS_S3_BUCKET}.s3.amazonaws.com/${uploadParams.Key}`,
|
|
44
|
+
location: `https://${awsConfig.AWS_S3_BUCKET}.s3.amazonaws.com/${uploadParams.Key}`,
|
|
73
45
|
};
|
|
74
46
|
}
|
|
75
47
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Handles file uploads to an AWS S3 bucket. This function processes a file
|
|
50
|
+
* from a multipart form request, validates and optionally compresses the file,
|
|
51
|
+
* and uploads it to S3. It supports image-specific operations such as resizing
|
|
52
|
+
* validation and quality reduction.
|
|
53
|
+
*
|
|
54
|
+
* @param request - The HTTP request containing the multipart form data.
|
|
55
|
+
* @param awsS3Config - Configuration object for AWS S3, including bucket name,
|
|
56
|
+
* region, and credentials.
|
|
57
|
+
* @param config - Optional configuration object for file handling.
|
|
58
|
+
*
|
|
59
|
+
* @param config.fileName - The name of the form field containing the file. Defaults to `"file"`.
|
|
60
|
+
* @param config.maxPartSize - The maximum size (in bytes) for each part of the file. Defaults to `5_000_000`.
|
|
61
|
+
* @param config.reduceImageQuality - The quality percentage for image compression. Defaults to `100`.
|
|
62
|
+
* @param config.validateImageSize - Whether to validate the image dimensions. Defaults to `false`.
|
|
63
|
+
* @param config.validateImageMessage - The error message template for invalid image dimensions.
|
|
64
|
+
* Defaults to `"Invalid dimensions {{width}}px x {{height}}px"`.
|
|
65
|
+
*
|
|
66
|
+
* @returns A promise that resolves to an object containing the uploaded file's URL
|
|
67
|
+
* or an error message if validation fails.
|
|
68
|
+
*
|
|
69
|
+
* @throws {BadRequest} If no file is uploaded.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const awsS3Config = {
|
|
74
|
+
* AWS_S3_BUCKET: "my-bucket",
|
|
75
|
+
* AWS_REGION: "us-east-1",
|
|
76
|
+
* AWS_ACCESS_KEY_ID: "my-access-key",
|
|
77
|
+
* AWS_SECRET_ACCESS_KEY: "my-secret-key",
|
|
78
|
+
* };
|
|
79
|
+
*
|
|
80
|
+
* const config = {
|
|
81
|
+
* fileName: "upload",
|
|
82
|
+
* maxPartSize: 10_000_000,
|
|
83
|
+
* reduceImageQuality: 80,
|
|
84
|
+
* validateImageSize: true,
|
|
85
|
+
* validateImageMessage: "Invalid dimensions {{width}}px x {{height}}px",
|
|
86
|
+
* };
|
|
87
|
+
*
|
|
88
|
+
* const response = await sendFileToS3(request, awsS3Config, config);
|
|
89
|
+
* if (response.error) {
|
|
90
|
+
* console.error(response.error);
|
|
91
|
+
* } else {
|
|
92
|
+
* console.log("File uploaded to:", response.url);
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
const sendFileToS3: SendFileToS3Function = async (
|
|
98
|
+
request,
|
|
99
|
+
awsS3Config,
|
|
100
|
+
config
|
|
101
|
+
) => {
|
|
102
|
+
const fileName = config?.fileName || "file";
|
|
103
|
+
const maxPartSize = config?.maxPartSize || 5_000_000;
|
|
104
|
+
const reduceImageQuality = config?.reduceImageQuality || 100;
|
|
105
|
+
const validateImageSize = config?.validateImageSize || false;
|
|
106
|
+
const validateImageMessage =
|
|
107
|
+
config?.validateImageMessage ||
|
|
108
|
+
"Invalid dimensions {{width}}px x {{height}}px";
|
|
86
109
|
|
|
87
110
|
const uploadHandler = composeUploadHandlers(
|
|
88
111
|
createFileUploadHandler({
|
|
@@ -94,18 +117,18 @@ async function sendFileToS3(
|
|
|
94
117
|
const formData = await parseMultipartFormData(request, uploadHandler);
|
|
95
118
|
const file = formData.get(fileName) as unknown as NodeOnDiskFile;
|
|
96
119
|
|
|
97
|
-
if (!file) throw new
|
|
120
|
+
if (!file) throw new BadRequest("No file uploaded");
|
|
98
121
|
|
|
99
122
|
const filterParams = getScopedParams(request);
|
|
100
123
|
const width = filterParams.get("w");
|
|
101
124
|
const height = filterParams.get("h");
|
|
102
125
|
|
|
103
126
|
const reduceQuality = filterParams.get("reduceQuality");
|
|
104
|
-
const quality = reduceQuality ? +reduceQuality :
|
|
127
|
+
const quality = reduceQuality ? +reduceQuality : reduceImageQuality;
|
|
105
128
|
|
|
106
129
|
const isImage = file.type.startsWith("image");
|
|
107
130
|
|
|
108
|
-
if (isImage && width && height) {
|
|
131
|
+
if (isImage && width && height && validateImageSize) {
|
|
109
132
|
const image = sharp(file.getFilePath());
|
|
110
133
|
const metadata = await image.metadata();
|
|
111
134
|
|
|
@@ -115,7 +138,9 @@ async function sendFileToS3(
|
|
|
115
138
|
|
|
116
139
|
if (widthDiff > 10 || heightDiff > 10) {
|
|
117
140
|
return {
|
|
118
|
-
error:
|
|
141
|
+
error: validateImageMessage
|
|
142
|
+
.replace("{{width}}", width)
|
|
143
|
+
.replace("{{height}}", height),
|
|
119
144
|
};
|
|
120
145
|
}
|
|
121
146
|
}
|
|
@@ -138,7 +163,7 @@ async function sendFileToS3(
|
|
|
138
163
|
file.getFilePath = () => compressedFilePath;
|
|
139
164
|
|
|
140
165
|
const streamFile = fs.createReadStream(file.getFilePath());
|
|
141
|
-
const apiResponse = await
|
|
166
|
+
const apiResponse = await s3Upload(streamFile, file.type, awsS3Config);
|
|
142
167
|
|
|
143
168
|
fs.unlink(compressedFilePath, (err) => {
|
|
144
169
|
if (err) console.error(`Delete image error: ${err}`);
|
|
@@ -148,9 +173,9 @@ async function sendFileToS3(
|
|
|
148
173
|
}
|
|
149
174
|
|
|
150
175
|
const streamFile = fs.createReadStream(file.getFilePath());
|
|
151
|
-
const apiResponse = await
|
|
176
|
+
const apiResponse = await s3Upload(streamFile, file.type, awsS3Config);
|
|
152
177
|
|
|
153
178
|
return { url: apiResponse.location };
|
|
154
|
-
}
|
|
179
|
+
};
|
|
155
180
|
|
|
156
181
|
export { sendFileToS3 };
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { badRequest, BadRequestError } from "../httpBadResponses/badRequest";
|
|
2
|
-
import { conflict, ConflictError } from "../httpBadResponses/conflict";
|
|
3
|
-
import { forbidden, ForbiddenError } from "../httpBadResponses/forbidden";
|
|
4
|
-
import { notFound, NotFoundError } from "../httpBadResponses/notFound";
|
|
5
|
-
import { serverError } from "../httpBadResponses/serverError";
|
|
6
|
-
import {
|
|
7
|
-
unauthorized,
|
|
8
|
-
UnauthorizedError,
|
|
9
|
-
} from "../httpBadResponses/unauthorized";
|
|
10
|
-
import {
|
|
11
|
-
unprocessableEntity,
|
|
12
|
-
UnprocessableEntityError,
|
|
13
|
-
} from "../httpBadResponses/unprocessableEntity";
|
|
14
|
-
import { created, Created } from "../httpResponses/created";
|
|
15
|
-
import { noContent, NoContent } from "../httpResponses/noContent";
|
|
16
|
-
import { success, Success } from "../httpResponses/success";
|
|
17
|
-
import { updated, Updated } from "../httpResponses/updated";
|
|
18
|
-
|
|
19
|
-
const globalErrorHandler = (error: any) => {
|
|
20
|
-
// If the error is not an instance of Error, return the response
|
|
21
|
-
switch (true) {
|
|
22
|
-
case error instanceof Response:
|
|
23
|
-
return error;
|
|
24
|
-
case error instanceof Created:
|
|
25
|
-
return created(error.body, error.init);
|
|
26
|
-
case error instanceof Updated:
|
|
27
|
-
return updated(error.body, error.init);
|
|
28
|
-
case error instanceof Success:
|
|
29
|
-
return success(error.body, error.init);
|
|
30
|
-
case error instanceof NoContent:
|
|
31
|
-
return noContent(error.init);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const showConsoleError =
|
|
35
|
-
process.env.NODE_ENV === "development" ||
|
|
36
|
-
process.env?.SHOW_ERRORS_IN_CONSOLE === "true";
|
|
37
|
-
|
|
38
|
-
// If showConsoleError is true, log the error to the console
|
|
39
|
-
if (showConsoleError) console.error(error);
|
|
40
|
-
|
|
41
|
-
// If the error is an instance of BadRequestError, ForbiddenError, ConflictError, UnauthorizedError, NotFoundError, or UnprocessableEntityError, return the error
|
|
42
|
-
switch (true) {
|
|
43
|
-
case error instanceof BadRequestError:
|
|
44
|
-
return badRequest(error);
|
|
45
|
-
case error instanceof ForbiddenError:
|
|
46
|
-
return forbidden(error);
|
|
47
|
-
case error instanceof ConflictError:
|
|
48
|
-
return conflict(error);
|
|
49
|
-
case error instanceof UnauthorizedError:
|
|
50
|
-
return unauthorized(error);
|
|
51
|
-
case error instanceof NotFoundError:
|
|
52
|
-
return notFound(error);
|
|
53
|
-
case error instanceof UnprocessableEntityError:
|
|
54
|
-
return unprocessableEntity(error);
|
|
55
|
-
default:
|
|
56
|
-
return serverError({
|
|
57
|
-
message: error?.message || "Server error | Message not found",
|
|
58
|
-
name: "Server Error",
|
|
59
|
-
cause: error.cause || "Unknown",
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export { globalErrorHandler };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
function badRequest(error: BadRequestError) {
|
|
2
|
-
return new Response(
|
|
3
|
-
JSON.stringify({
|
|
4
|
-
status: 400,
|
|
5
|
-
success: false,
|
|
6
|
-
name: error.name,
|
|
7
|
-
message: error.message,
|
|
8
|
-
}),
|
|
9
|
-
{
|
|
10
|
-
status: 400,
|
|
11
|
-
statusText: "Bad Request",
|
|
12
|
-
headers: { "Content-Type": "application/json" },
|
|
13
|
-
}
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class BadRequestError {
|
|
18
|
-
name: string;
|
|
19
|
-
message: string;
|
|
20
|
-
cause?: any;
|
|
21
|
-
|
|
22
|
-
constructor(message: string, cause?: any) {
|
|
23
|
-
this.name = "BadRequestError";
|
|
24
|
-
this.message = message;
|
|
25
|
-
this.cause = cause ? JSON.stringify(cause) : undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { badRequest, BadRequestError };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
function conflict(error: ConflictError) {
|
|
2
|
-
return new Response(
|
|
3
|
-
JSON.stringify({
|
|
4
|
-
status: 409,
|
|
5
|
-
success: false,
|
|
6
|
-
name: error.name,
|
|
7
|
-
message: error.message,
|
|
8
|
-
}),
|
|
9
|
-
{
|
|
10
|
-
status: 409,
|
|
11
|
-
statusText: "Bad Request",
|
|
12
|
-
headers: { "Content-Type": "application/json" },
|
|
13
|
-
}
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class ConflictError {
|
|
18
|
-
name: string;
|
|
19
|
-
message: string;
|
|
20
|
-
cause?: any;
|
|
21
|
-
|
|
22
|
-
constructor(message: string, cause?: any) {
|
|
23
|
-
this.name = "ConflictError";
|
|
24
|
-
this.message = message;
|
|
25
|
-
this.cause = cause ? JSON.stringify(cause) : undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { conflict, ConflictError };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
function forbidden(error: ForbiddenError) {
|
|
2
|
-
return new Response(
|
|
3
|
-
JSON.stringify({
|
|
4
|
-
status: 403,
|
|
5
|
-
success: false,
|
|
6
|
-
name: error.name,
|
|
7
|
-
message: error.message,
|
|
8
|
-
}),
|
|
9
|
-
{
|
|
10
|
-
status: 403,
|
|
11
|
-
statusText: "Bad Request",
|
|
12
|
-
headers: { "Content-Type": "application/json" },
|
|
13
|
-
}
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class ForbiddenError {
|
|
18
|
-
name: string;
|
|
19
|
-
message: string;
|
|
20
|
-
cause?: any;
|
|
21
|
-
|
|
22
|
-
constructor(message: string, cause?: any) {
|
|
23
|
-
this.name = "ForbiddenError";
|
|
24
|
-
this.message = message;
|
|
25
|
-
this.cause = cause ? JSON.stringify(cause) : undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { forbidden, ForbiddenError };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
function notFound(error: NotFoundError) {
|
|
2
|
-
return new Response(
|
|
3
|
-
JSON.stringify({
|
|
4
|
-
status: 404,
|
|
5
|
-
success: false,
|
|
6
|
-
name: error.name,
|
|
7
|
-
message: error.message,
|
|
8
|
-
}),
|
|
9
|
-
{
|
|
10
|
-
status: 404,
|
|
11
|
-
statusText: "Bad Request",
|
|
12
|
-
headers: { "Content-Type": "application/json" },
|
|
13
|
-
}
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class NotFoundError {
|
|
18
|
-
name: string;
|
|
19
|
-
message: string;
|
|
20
|
-
cause?: any;
|
|
21
|
-
|
|
22
|
-
constructor(message: string, cause?: any) {
|
|
23
|
-
this.name = "NotFoundError";
|
|
24
|
-
this.message = message;
|
|
25
|
-
this.cause = cause ? JSON.stringify(cause) : undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { notFound, NotFoundError };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
function serverError(error: ServerError) {
|
|
2
|
-
return new Response(
|
|
3
|
-
JSON.stringify({
|
|
4
|
-
status: 500,
|
|
5
|
-
success: false,
|
|
6
|
-
name: error.name,
|
|
7
|
-
message: error.message,
|
|
8
|
-
}),
|
|
9
|
-
{
|
|
10
|
-
status: 500,
|
|
11
|
-
statusText: "Bad Request",
|
|
12
|
-
headers: { "Content-Type": "application/json" },
|
|
13
|
-
}
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class ServerError {
|
|
18
|
-
name: string;
|
|
19
|
-
message: string;
|
|
20
|
-
cause?: any;
|
|
21
|
-
|
|
22
|
-
constructor(message: string, cause?: any) {
|
|
23
|
-
this.name = "ServerError";
|
|
24
|
-
this.message = message;
|
|
25
|
-
this.cause = cause ? JSON.stringify(cause) : undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { serverError, ServerError };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
function unauthorized(error: UnauthorizedError) {
|
|
2
|
-
return new Response(
|
|
3
|
-
JSON.stringify({
|
|
4
|
-
status: 401,
|
|
5
|
-
success: false,
|
|
6
|
-
name: error.name,
|
|
7
|
-
message: error.message,
|
|
8
|
-
}),
|
|
9
|
-
{
|
|
10
|
-
status: 401,
|
|
11
|
-
statusText: "Bad Request",
|
|
12
|
-
headers: { "Content-Type": "application/json" },
|
|
13
|
-
}
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class UnauthorizedError {
|
|
18
|
-
name: string;
|
|
19
|
-
message: string;
|
|
20
|
-
cause?: any;
|
|
21
|
-
|
|
22
|
-
constructor(message: string, cause?: any) {
|
|
23
|
-
this.name = "UnauthorizedError";
|
|
24
|
-
this.message = message;
|
|
25
|
-
this.cause = cause ? JSON.stringify(cause) : undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { unauthorized, UnauthorizedError };
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
type UnprocessableEntityErrorProps = {
|
|
2
|
-
data?: any;
|
|
3
|
-
fieldErrors?: Record<string, string>;
|
|
4
|
-
fields?: Record<string, string>;
|
|
5
|
-
message?: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
function unprocessableEntity(error: UnprocessableEntityError) {
|
|
9
|
-
return new Response(
|
|
10
|
-
JSON.stringify({
|
|
11
|
-
status: 433,
|
|
12
|
-
success: false,
|
|
13
|
-
name: error.name,
|
|
14
|
-
message: error.message,
|
|
15
|
-
data: error.data || null,
|
|
16
|
-
fieldErrors: error.fieldErrors || null,
|
|
17
|
-
fields: error.fields || null,
|
|
18
|
-
}),
|
|
19
|
-
{
|
|
20
|
-
status: 433,
|
|
21
|
-
statusText: "Bad Request",
|
|
22
|
-
headers: { "Content-Type": "application/json" },
|
|
23
|
-
}
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
class UnprocessableEntityError {
|
|
28
|
-
name: string;
|
|
29
|
-
message?: string;
|
|
30
|
-
fieldErrors: any;
|
|
31
|
-
fields: any;
|
|
32
|
-
data: any;
|
|
33
|
-
|
|
34
|
-
constructor(data: UnprocessableEntityErrorProps) {
|
|
35
|
-
this.data = data?.data || null;
|
|
36
|
-
this.fieldErrors = data?.fieldErrors || null;
|
|
37
|
-
this.fields = data?.fields || null;
|
|
38
|
-
this.name = "UnprocessableEntity";
|
|
39
|
-
this.message = data?.message;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export { unprocessableEntity, UnprocessableEntityError };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
function created(body: any, init?: ResponseInit): Response {
|
|
2
|
-
return new Response(JSON.stringify(body), {
|
|
3
|
-
...init,
|
|
4
|
-
status: 201,
|
|
5
|
-
headers: { "Content-Type": "application/json", ...init?.headers },
|
|
6
|
-
});
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
class Created<T> {
|
|
10
|
-
body: T;
|
|
11
|
-
init: ResponseInit;
|
|
12
|
-
|
|
13
|
-
constructor(body: T, init?: ResponseInit) {
|
|
14
|
-
this.body = body;
|
|
15
|
-
this.init = init || {};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
response() {
|
|
19
|
-
return new Response(JSON.stringify(this.body), {
|
|
20
|
-
...this.init,
|
|
21
|
-
status: 201,
|
|
22
|
-
headers: { "Content-Type": "application/json", ...this.init.headers },
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
json() {
|
|
27
|
-
return new Response(JSON.stringify(this.body), {
|
|
28
|
-
...this.init,
|
|
29
|
-
status: 201,
|
|
30
|
-
headers: { "Content-Type": "application/json", ...this.init.headers },
|
|
31
|
-
}).json();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { created, Created };
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
function noContent(init?: ResponseInit): Response {
|
|
2
|
-
return new Response(null, {
|
|
3
|
-
...init,
|
|
4
|
-
status: 200,
|
|
5
|
-
headers: { "Content-Type": "application/json", ...init?.headers },
|
|
6
|
-
});
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
class NoContent {
|
|
10
|
-
init: ResponseInit;
|
|
11
|
-
|
|
12
|
-
constructor(init?: ResponseInit) {
|
|
13
|
-
this.init = init || {};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
response() {
|
|
17
|
-
return new Response(null, {
|
|
18
|
-
...this.init,
|
|
19
|
-
status: 200,
|
|
20
|
-
headers: { "Content-Type": "application/json", ...this.init.headers },
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
json() {
|
|
25
|
-
return new Response(null, {
|
|
26
|
-
...this.init,
|
|
27
|
-
status: 200,
|
|
28
|
-
headers: { "Content-Type": "application/json", ...this.init.headers },
|
|
29
|
-
}).json();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export { noContent, NoContent };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
function success(body: any, init?: ResponseInit): Response {
|
|
2
|
-
return new Response(JSON.stringify(body), {
|
|
3
|
-
...init,
|
|
4
|
-
status: 200,
|
|
5
|
-
headers: { "Content-Type": "application/json", ...init?.headers },
|
|
6
|
-
});
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
class Success<T> {
|
|
10
|
-
body: T;
|
|
11
|
-
init: ResponseInit;
|
|
12
|
-
|
|
13
|
-
constructor(body: T, init?: ResponseInit) {
|
|
14
|
-
this.body = body;
|
|
15
|
-
this.init = init || {};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
response() {
|
|
19
|
-
return new Response(JSON.stringify(this.body), {
|
|
20
|
-
...this.init,
|
|
21
|
-
status: 200,
|
|
22
|
-
headers: { "Content-Type": "application/json", ...this.init.headers },
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
json() {
|
|
27
|
-
return new Response(JSON.stringify(this.body), {
|
|
28
|
-
...this.init,
|
|
29
|
-
status: 200,
|
|
30
|
-
headers: { "Content-Type": "application/json", ...this.init.headers },
|
|
31
|
-
}).json();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { success, Success };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
function updated(body: any, init?: ResponseInit): Response {
|
|
2
|
-
return new Response(JSON.stringify(body), {
|
|
3
|
-
...init,
|
|
4
|
-
status: 200,
|
|
5
|
-
headers: { "Content-Type": "application/json", ...init?.headers },
|
|
6
|
-
});
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
class Updated<T> {
|
|
10
|
-
body: T;
|
|
11
|
-
init: ResponseInit;
|
|
12
|
-
|
|
13
|
-
constructor(body: T, init?: ResponseInit) {
|
|
14
|
-
this.body = body;
|
|
15
|
-
this.init = init || {};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
response() {
|
|
19
|
-
return new Response(JSON.stringify(this.body), {
|
|
20
|
-
...this.init,
|
|
21
|
-
status: 200,
|
|
22
|
-
headers: { "Content-Type": "application/json", ...this.init.headers },
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
json() {
|
|
27
|
-
return new Response(JSON.stringify(this.body), {
|
|
28
|
-
...this.init,
|
|
29
|
-
status: 200,
|
|
30
|
-
headers: { "Content-Type": "application/json", ...this.init.headers },
|
|
31
|
-
}).json();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { updated, Updated };
|