codeweaver 1.1.0 → 2.1.0
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/.vscode/settings.json +3 -0
- package/README.md +114 -181
- package/package.json +12 -7
- package/src/app.ts +2 -112
- package/src/config.ts +33 -64
- package/src/constants.ts +7 -0
- package/src/db.ts +183 -0
- package/src/entities/order.entity.ts +68 -0
- package/src/entities/product.entity.ts +75 -0
- package/src/entities/user.entity.ts +38 -0
- package/src/main.ts +85 -0
- package/src/routers/orders/dto/order.dto.ts +54 -29
- package/src/routers/orders/{index.ts → index.router.ts} +13 -13
- package/src/routers/orders/order.controller.ts +118 -120
- package/src/routers/products/dto/product.dto.ts +86 -30
- package/src/routers/products/{index.ts → index.router.ts} +14 -15
- package/src/routers/products/product.controller.ts +136 -161
- package/src/routers/users/dto/user.dto.ts +14 -18
- package/src/routers/users/{index.ts → index.router.ts} +6 -7
- package/src/routers/users/user.controller.ts +87 -118
- package/src/swagger-options.ts +39 -0
- package/src/utilities/assign.ts +66 -0
- package/src/utilities/cache/memory-cache.ts +74 -0
- package/src/utilities/cache/redis-cache.ts +111 -0
- package/src/utilities/conversion.ts +158 -0
- package/src/utilities/error-handling.ts +156 -0
- package/src/utilities/router.ts +0 -0
- package/tsconfig.json +1 -4
- package/tsconfig.paths.json +8 -10
- package/src/packages/ts-zod-decorators/index.ts +0 -3
- package/src/packages/ts-zod-decorators/validate.decorator.ts +0 -20
- package/src/packages/ts-zod-decorators/validator.class.ts +0 -72
- package/src/packages/ts-zod-decorators/zod-input.decorator.ts +0 -12
- package/src/packages/ts-zod-decorators/zod-output.decorator.ts +0 -11
- package/src/types.ts +0 -16
- package/src/utilities.ts +0 -47
- /package/src/routers/{index.ts → index.router.ts} +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Response } from "express";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a standardized error response structure for API endpoints.
|
|
5
|
+
*
|
|
6
|
+
* This class models an API-friendly error, carrying a human message plus
|
|
7
|
+
* optional metadata (status, details, input, code, stack). Extends the built-in Error
|
|
8
|
+
* so it works naturally with try/catch blocks.
|
|
9
|
+
*/
|
|
10
|
+
export class ResponseError extends Error {
|
|
11
|
+
public constructor(
|
|
12
|
+
/**
|
|
13
|
+
* User-facing error message describing what went wrong.
|
|
14
|
+
*/
|
|
15
|
+
public message: string,
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Optional HTTP status code related to the error (e.g., 400, 404, 500).
|
|
19
|
+
*/
|
|
20
|
+
public status?: number,
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Optional human-readable details or context about the error.
|
|
24
|
+
*/
|
|
25
|
+
public details?: string,
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Optional input value that caused the error (useful for logging/diagnostics).
|
|
29
|
+
*/
|
|
30
|
+
public input?: string,
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Optional application-specific error code (e.g., "INVALID_INPUT").
|
|
34
|
+
*/
|
|
35
|
+
public code?: string,
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Optional stack trace string (usually provided by runtime).
|
|
39
|
+
* Note: In many environments, stack is inherited from Error; you may
|
|
40
|
+
* not need to redefine it here unless you have a specific reason.
|
|
41
|
+
*/
|
|
42
|
+
public stack?: string
|
|
43
|
+
) {
|
|
44
|
+
// Ensure the base Error class gets the message for standard properties like name, stack, etc.
|
|
45
|
+
super(message);
|
|
46
|
+
|
|
47
|
+
// If a custom stack is provided, you might assign it; otherwise, the runtime stack will be used.
|
|
48
|
+
if (stack) this.stack = stack;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Sends a standardized HTTP error response.
|
|
54
|
+
*
|
|
55
|
+
* This function sets the response status from the provided error (defaulting to 500)
|
|
56
|
+
* and serializes the error object as JSON.
|
|
57
|
+
*
|
|
58
|
+
* @param res - Express Response object to send the error on
|
|
59
|
+
* @param error - Error details to return to the client (must include status or default will be 500)
|
|
60
|
+
*/
|
|
61
|
+
export function sendHttpError(res: Response, error: ResponseError): void {
|
|
62
|
+
res.status(error.status ?? 500).json(error);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A generic alias representing a tuple of [result, error].
|
|
67
|
+
* - result is either T or null if an error occurred
|
|
68
|
+
* - error is either a ResponseError or null if the operation succeeded
|
|
69
|
+
*/
|
|
70
|
+
export type ReturnInfo<T> = [T | null, ResponseError | null];
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A Promise-wrapped version of ReturnInfo.
|
|
74
|
+
*/
|
|
75
|
+
export type AsyncReturnInfo<T> = Promise<ReturnInfo<T>>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Executes a function and captures a potential error as a ReturnInfo tuple.
|
|
79
|
+
*
|
|
80
|
+
* Returns a two-element tuple: [value, error]
|
|
81
|
+
* - value: the function result if it succeeds; null if an exception is thrown
|
|
82
|
+
* - error: the caught Error wrapped as a ResponseError (or the provided error) if the function throws; null if the function succeeds
|
|
83
|
+
*
|
|
84
|
+
* This utility helps avoid try/catch blocks at call sites by returning both the
|
|
85
|
+
* result and any error in a single value.
|
|
86
|
+
*
|
|
87
|
+
* @template T
|
|
88
|
+
* @param func - The function to execute
|
|
89
|
+
* @param error - The error object to return when an exception occurs (typically a ResponseError). If no error is provided, null is used.
|
|
90
|
+
* @returns ReturnInfo<T> A tuple: [value or null, error or null]
|
|
91
|
+
*/
|
|
92
|
+
export function invoke<T>(
|
|
93
|
+
func: () => T,
|
|
94
|
+
error: ResponseError | null
|
|
95
|
+
): ReturnInfo<T> {
|
|
96
|
+
try {
|
|
97
|
+
return [func(), null];
|
|
98
|
+
} catch {
|
|
99
|
+
return [null, error];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Creates a successful result from a ReturnInfo tuple.
|
|
105
|
+
*
|
|
106
|
+
* Given a ReturnInfo<T> of the form [value, error], this returns the value
|
|
107
|
+
* when the operation succeeded, or null when there was an error.
|
|
108
|
+
*
|
|
109
|
+
* @template T
|
|
110
|
+
* @param input - The ReturnInfo tuple
|
|
111
|
+
* @returns The successful value of type T, or null if there was an error
|
|
112
|
+
*/
|
|
113
|
+
export function successfulResult<T>(input: ReturnInfo<T>): T | null {
|
|
114
|
+
return input[0];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Normalizes and wraps an error into the common ReturnInfo shape.
|
|
119
|
+
*
|
|
120
|
+
* The function accepts a ReturnInfo-shaped input and extracts the error portion.
|
|
121
|
+
* If a non-Error value is provided, you should wrap it as a ResponseError beforehand.
|
|
122
|
+
* If the error is already a ResponseError, it is returned as-is.
|
|
123
|
+
*
|
|
124
|
+
* @template T
|
|
125
|
+
* @param responseError - The error to wrap, either as a ResponseError or as a ReturnInfo<T> where the error is at index 1
|
|
126
|
+
* @returns The extracted or wrapped ResponseError, or null if there is no error
|
|
127
|
+
*/
|
|
128
|
+
export function error<T>(responseError: ReturnInfo<T>): ResponseError | null {
|
|
129
|
+
return responseError[1];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Determines whether a ReturnInfo value represents a successful operation.
|
|
134
|
+
*
|
|
135
|
+
* A result is considered successful when there is no error (i.e., the error portion is null).
|
|
136
|
+
*
|
|
137
|
+
* @template T
|
|
138
|
+
* @param result - The ReturnInfo tuple [value | null, error | null]
|
|
139
|
+
* @returns true if there is no error; false otherwise
|
|
140
|
+
*/
|
|
141
|
+
export function isSuccessful<T>(result: ReturnInfo<T>): boolean {
|
|
142
|
+
return result[1] === null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Indicates whether a ReturnInfo value represents an error.
|
|
147
|
+
*
|
|
148
|
+
* This is the logical negation of isSuccess for a given ReturnInfo.
|
|
149
|
+
*
|
|
150
|
+
* @template T
|
|
151
|
+
* @param result - The ReturnInfo tuple [value | null, error | null]
|
|
152
|
+
* @returns true if an error is present (i.e., error is not null); false otherwise
|
|
153
|
+
*/
|
|
154
|
+
export function hasError<T>(result: ReturnInfo<T>): boolean {
|
|
155
|
+
return result[1] !== null;
|
|
156
|
+
}
|
|
File without changes
|
package/tsconfig.json
CHANGED
|
@@ -9,11 +9,8 @@
|
|
|
9
9
|
"forceConsistentCasingInFileNames": true,
|
|
10
10
|
"experimentalDecorators": true,
|
|
11
11
|
"emitDecoratorMetadata": true,
|
|
12
|
-
"baseUrl": ".",
|
|
13
12
|
"paths": {
|
|
14
|
-
"
|
|
15
|
-
"@r/*": ["src/routers/*"],
|
|
16
|
-
"@/*": ["src/*"]
|
|
13
|
+
"@/*": ["./src/*"]
|
|
17
14
|
}
|
|
18
15
|
},
|
|
19
16
|
"include": ["**/*.ts", "**/*.js"],
|
package/tsconfig.paths.json
CHANGED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
-
import ZodValidator from './validator.class';
|
|
3
|
-
|
|
4
|
-
export const Validate: MethodDecorator = (
|
|
5
|
-
target: Object,
|
|
6
|
-
propertyKey: string | symbol,
|
|
7
|
-
descriptor: PropertyDescriptor,
|
|
8
|
-
) => {
|
|
9
|
-
const originalMethod = descriptor.value;
|
|
10
|
-
descriptor.value = async function (...args: unknown[]) {
|
|
11
|
-
ZodValidator.validateInput(target, propertyKey as string, args);
|
|
12
|
-
const result = originalMethod.apply(this, args);
|
|
13
|
-
let resultValue = result;
|
|
14
|
-
if (result instanceof Promise) {
|
|
15
|
-
resultValue = await result;
|
|
16
|
-
ZodValidator.validateOutput(target, propertyKey as string, resultValue);
|
|
17
|
-
}
|
|
18
|
-
return resultValue;
|
|
19
|
-
};
|
|
20
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
-
import * as z from "zod";
|
|
3
|
-
|
|
4
|
-
type Target = Object;
|
|
5
|
-
type MethodName = string;
|
|
6
|
-
type Metadata = {
|
|
7
|
-
paramsIndex: number[];
|
|
8
|
-
inputSchema?: z.ZodObject<any, any>;
|
|
9
|
-
outputSchema?: z.ZodObject<any, any>;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export default class ZodValidator {
|
|
13
|
-
private static methodValidatorMap: Map<Target, Map<MethodName, Metadata>> =
|
|
14
|
-
new Map();
|
|
15
|
-
|
|
16
|
-
static registerInputParameterValidationSchema(
|
|
17
|
-
target: Object,
|
|
18
|
-
methodName: MethodName,
|
|
19
|
-
paramIndex: number,
|
|
20
|
-
schema: z.ZodObject<any, any>
|
|
21
|
-
) {
|
|
22
|
-
let paramMap = this.methodValidatorMap.get(target)!;
|
|
23
|
-
if (!paramMap) {
|
|
24
|
-
paramMap = new Map();
|
|
25
|
-
this.methodValidatorMap.set(target, paramMap);
|
|
26
|
-
}
|
|
27
|
-
let metadata = paramMap.get(methodName)!;
|
|
28
|
-
if (!metadata) {
|
|
29
|
-
metadata = { paramsIndex: [], inputSchema: schema };
|
|
30
|
-
paramMap.set(methodName, metadata);
|
|
31
|
-
}
|
|
32
|
-
metadata.paramsIndex.push(paramIndex);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
static registerMethodValidationOutputSchema(
|
|
36
|
-
target: Object,
|
|
37
|
-
methodName: MethodName,
|
|
38
|
-
schema: z.ZodObject<any, any>
|
|
39
|
-
) {
|
|
40
|
-
let paramMap = this.methodValidatorMap.get(target)!;
|
|
41
|
-
if (!paramMap) {
|
|
42
|
-
paramMap = new Map();
|
|
43
|
-
this.methodValidatorMap.set(target, paramMap);
|
|
44
|
-
}
|
|
45
|
-
let metadata = paramMap.get(methodName)!;
|
|
46
|
-
if (!metadata) {
|
|
47
|
-
metadata = { paramsIndex: [], outputSchema: schema };
|
|
48
|
-
paramMap.set(methodName, metadata);
|
|
49
|
-
}
|
|
50
|
-
metadata.outputSchema = schema;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
static validateInput(
|
|
54
|
-
target: Object,
|
|
55
|
-
methodName: string,
|
|
56
|
-
paramValues: unknown[]
|
|
57
|
-
) {
|
|
58
|
-
const methodMetadataMap = this.methodValidatorMap.get(target)!;
|
|
59
|
-
const metadata = methodMetadataMap.get(methodName)!;
|
|
60
|
-
for (const [index, input] of paramValues.entries()) {
|
|
61
|
-
if (metadata.paramsIndex.indexOf(index) != -1) {
|
|
62
|
-
metadata.inputSchema?.parse(input);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
static validateOutput(target: Object, methodName: string, output: unknown) {
|
|
68
|
-
const methodMetadataMap = this.methodValidatorMap.get(target)!;
|
|
69
|
-
const metadata = methodMetadataMap.get(methodName)!;
|
|
70
|
-
metadata.outputSchema?.parse(output);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { ZodObject } from "zod";
|
|
2
|
-
import ZodValidator from "./validator.class";
|
|
3
|
-
|
|
4
|
-
export const ZodInput =
|
|
5
|
-
<T extends ZodObject<any, any>>(schema: T): ParameterDecorator =>
|
|
6
|
-
(target, propertyKey, parameterIndex) =>
|
|
7
|
-
ZodValidator.registerInputParameterValidationSchema(
|
|
8
|
-
target,
|
|
9
|
-
propertyKey as string,
|
|
10
|
-
parameterIndex,
|
|
11
|
-
schema
|
|
12
|
-
);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { ZodObject } from "zod";
|
|
2
|
-
import ZodValidator from "./validator.class";
|
|
3
|
-
|
|
4
|
-
export const ZodOutput =
|
|
5
|
-
<T extends ZodObject<any, any>>(schema: T): MethodDecorator =>
|
|
6
|
-
(target, propertyKey) =>
|
|
7
|
-
ZodValidator.registerMethodValidationOutputSchema(
|
|
8
|
-
target,
|
|
9
|
-
propertyKey as string,
|
|
10
|
-
schema
|
|
11
|
-
);
|
package/src/types.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents a standardized error response structure for API endpoints
|
|
3
|
-
* @interface
|
|
4
|
-
* @property {number} status - HTTP status code
|
|
5
|
-
* @property {string} [name] - Error name/type
|
|
6
|
-
* @property {string} message - Human-readable error message
|
|
7
|
-
* @property {string} [stack] - Error stack trace (development only)
|
|
8
|
-
* @property {string} [details] - Additional error details
|
|
9
|
-
*/
|
|
10
|
-
export interface ResponseError {
|
|
11
|
-
status: number;
|
|
12
|
-
name?: string;
|
|
13
|
-
message: string;
|
|
14
|
-
stack?: string;
|
|
15
|
-
details?: string;
|
|
16
|
-
}
|
package/src/utilities.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { Response } from "express";
|
|
2
|
-
import { ResponseError } from "./types";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Sends a standardized error response
|
|
6
|
-
* @param {Response} res - Express response object
|
|
7
|
-
* @param {ResponseError} error - Error details object
|
|
8
|
-
*/
|
|
9
|
-
export function sendError(res: Response, error: ResponseError): void {
|
|
10
|
-
res.status(error.status).json(error);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Parses and validates ID parameter from string to number
|
|
15
|
-
* @param {string} input - Input string to parse
|
|
16
|
-
* @returns {number|ResponseError} Parsed number or error object
|
|
17
|
-
*/
|
|
18
|
-
export function tryParseId(input: string): number | ResponseError {
|
|
19
|
-
try {
|
|
20
|
-
return parseInt(input) satisfies number;
|
|
21
|
-
} catch {
|
|
22
|
-
return {
|
|
23
|
-
status: 400,
|
|
24
|
-
message: "wrong input",
|
|
25
|
-
details: "The id parameter must be an integer number.",
|
|
26
|
-
} satisfies ResponseError;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Checks if the provided object is a ResponseError.
|
|
32
|
-
*
|
|
33
|
-
* A ResponseError is an object that contains at least the properties:
|
|
34
|
-
* - message: string
|
|
35
|
-
* - status: number
|
|
36
|
-
*
|
|
37
|
-
* @param obj - The object to check.
|
|
38
|
-
* @returns true if the object is a ResponseError, false otherwise.
|
|
39
|
-
*/
|
|
40
|
-
export function isResponseError(obj: unknown): boolean {
|
|
41
|
-
return (
|
|
42
|
-
obj != null &&
|
|
43
|
-
typeof obj === "object" &&
|
|
44
|
-
"message" in obj &&
|
|
45
|
-
"status" in obj
|
|
46
|
-
);
|
|
47
|
-
}
|
|
File without changes
|