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.
Files changed (37) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/README.md +114 -181
  3. package/package.json +12 -7
  4. package/src/app.ts +2 -112
  5. package/src/config.ts +33 -64
  6. package/src/constants.ts +7 -0
  7. package/src/db.ts +183 -0
  8. package/src/entities/order.entity.ts +68 -0
  9. package/src/entities/product.entity.ts +75 -0
  10. package/src/entities/user.entity.ts +38 -0
  11. package/src/main.ts +85 -0
  12. package/src/routers/orders/dto/order.dto.ts +54 -29
  13. package/src/routers/orders/{index.ts → index.router.ts} +13 -13
  14. package/src/routers/orders/order.controller.ts +118 -120
  15. package/src/routers/products/dto/product.dto.ts +86 -30
  16. package/src/routers/products/{index.ts → index.router.ts} +14 -15
  17. package/src/routers/products/product.controller.ts +136 -161
  18. package/src/routers/users/dto/user.dto.ts +14 -18
  19. package/src/routers/users/{index.ts → index.router.ts} +6 -7
  20. package/src/routers/users/user.controller.ts +87 -118
  21. package/src/swagger-options.ts +39 -0
  22. package/src/utilities/assign.ts +66 -0
  23. package/src/utilities/cache/memory-cache.ts +74 -0
  24. package/src/utilities/cache/redis-cache.ts +111 -0
  25. package/src/utilities/conversion.ts +158 -0
  26. package/src/utilities/error-handling.ts +156 -0
  27. package/src/utilities/router.ts +0 -0
  28. package/tsconfig.json +1 -4
  29. package/tsconfig.paths.json +8 -10
  30. package/src/packages/ts-zod-decorators/index.ts +0 -3
  31. package/src/packages/ts-zod-decorators/validate.decorator.ts +0 -20
  32. package/src/packages/ts-zod-decorators/validator.class.ts +0 -72
  33. package/src/packages/ts-zod-decorators/zod-input.decorator.ts +0 -12
  34. package/src/packages/ts-zod-decorators/zod-output.decorator.ts +0 -11
  35. package/src/types.ts +0 -16
  36. package/src/utilities.ts +0 -47
  37. /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
- "@pkg/*": ["src/packages/*"],
15
- "@r/*": ["src/routers/*"],
16
- "@/*": ["src/*"]
13
+ "@/*": ["./src/*"]
17
14
  }
18
15
  },
19
16
  "include": ["**/*.ts", "**/*.js"],
@@ -1,10 +1,8 @@
1
- {
2
- "compilerOptions": {
3
- "baseUrl": ".",
4
- "paths": {
5
- "@pkg/*": ["dist/packages/*"],
6
- "@r/*": ["dist/routers/*"],
7
- "@/*": ["dist/*"]
8
- }
9
- }
10
- }
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "paths": {
5
+ "@/*": ["dist/*"]
6
+ }
7
+ }
8
+ }
@@ -1,3 +0,0 @@
1
- export * from './validate.decorator';
2
- export * from './zod-output.decorator';
3
- export * from './zod-input.decorator';
@@ -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