@avleon/core 0.0.11 → 0.0.13

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.
@@ -47,6 +47,6 @@ declare class BasicCollection<T> implements ICollection<T> {
47
47
  export declare class Collection {
48
48
  private constructor();
49
49
  static from<T>(items: T[]): BasicCollection<T>;
50
- static fromRepositry<T extends ObjectLiteral>(entity: EntityTarget<T>): Repository<T>;
50
+ static fromRepository<T extends ObjectLiteral>(entity: EntityTarget<T>): Repository<T>;
51
51
  }
52
52
  export {};
@@ -282,7 +282,7 @@ class Collection {
282
282
  static from(items) {
283
283
  return BasicCollection.from(items);
284
284
  }
285
- static fromRepositry(entity) {
285
+ static fromRepository(entity) {
286
286
  return AsynchronousCollection.fromRepository(entity);
287
287
  }
288
288
  }
@@ -1,17 +1,34 @@
1
- import { MultipartFile } from './multipart';
1
+ import { PathLike } from "fs";
2
+ import { MultipartFile } from "./multipart";
2
3
  interface TransformOptions {
3
4
  resize?: {
4
5
  width: number;
5
6
  height: number;
6
7
  };
7
- format?: 'jpeg' | 'png' | 'webp' | 'avif';
8
+ format?: "jpeg" | "png" | "webp" | "avif";
8
9
  quality?: number;
9
10
  }
10
- export declare class FileStorage {
11
+ export interface FileStorageInterface {
12
+ transform(options: TransformOptions): FileStorage;
13
+ save(file: MultipartFile, options?: SaveOptionsSingle): Promise<MultipartFile | undefined>;
14
+ saveAll(files: MultipartFile[], options?: SaveOptions): Promise<MultipartFile[] | undefined>;
15
+ remove(filepath: PathLike): Promise<void>;
16
+ }
17
+ export interface SaveOptions {
18
+ overwrite?: boolean;
19
+ to?: string;
20
+ }
21
+ export interface SaveOptionsSingle extends SaveOptions {
22
+ saveAs?: string;
23
+ }
24
+ export declare class FileStorage implements FileStorageInterface {
11
25
  private transformOptions;
12
26
  transform(options: TransformOptions): this;
13
- save(f: MultipartFile, options: any): Promise<import("@fastify/multipart").MultipartFile | undefined>;
14
- saveAs(f: MultipartFile, filename: string, options: any): Promise<import("@fastify/multipart").MultipartFile | undefined>;
27
+ private isFileExists;
28
+ save(f: MultipartFile, options?: SaveOptionsSingle): Promise<import("@fastify/multipart").MultipartFile | undefined>;
29
+ remove(filepath: PathLike): Promise<void>;
30
+ saveAll(files: MultipartFile[], options?: SaveOptions): Promise<MultipartFile[]>;
15
31
  private processImage;
32
+ private ensureDirectoryExists;
16
33
  }
17
34
  export {};
@@ -48,7 +48,7 @@ const path_1 = __importDefault(require("path"));
48
48
  const promises_1 = require("stream/promises");
49
49
  const http_exceptions_1 = require("./exceptions/http-exceptions");
50
50
  const decorators_1 = require("./decorators");
51
- const os_1 = __importDefault(require("os"));
51
+ const system_exception_1 = require("./exceptions/system-exception");
52
52
  let FileStorage = class FileStorage {
53
53
  constructor() {
54
54
  this.transformOptions = null;
@@ -57,77 +57,218 @@ let FileStorage = class FileStorage {
57
57
  this.transformOptions = options;
58
58
  return this;
59
59
  }
60
+ isFileExists(fpath) {
61
+ return fs_1.default.existsSync(fpath);
62
+ }
60
63
  async save(f, options) {
61
- if (f && f.file) {
62
- let fname = f.filename;
63
- if (options) {
64
- if (options.dest) {
65
- fname = options.saveAs ? options.dest + '/' + options.saveAs : options.dest + '/' + f.filename;
66
- }
67
- else {
68
- fname = path_1.default.join(process.cwd(), `public/${options.saveAs ? options.saveAs : f.filename}`);
64
+ let foptions = {
65
+ overwrite: options && options.overwrite ? options.overwrite : true,
66
+ };
67
+ try {
68
+ if (f.type == "file") {
69
+ const fname = path_1.default.join(process.cwd(), `public/${f.filename}`);
70
+ if (!foptions.overwrite && this.isFileExists(fname)) {
71
+ throw new system_exception_1.SystemUseError("File already exits.");
69
72
  }
70
- }
71
- else {
72
- fname = path_1.default.join(process.cwd(), `public/${f.filename}`);
73
- }
74
- if (fs_1.default.existsSync(fname) && !options.overwrite) {
75
- throw new http_exceptions_1.InternalErrorException("File already exists.");
76
- }
77
- if (this.transformOptions) {
78
- const tempFilePath = path_1.default.join(os_1.default.tmpdir(), `temp-${Date.now()}-${f.filename}`);
79
- await (0, promises_1.pipeline)(f.file, fs_1.default.createWriteStream(tempFilePath));
80
- await this.processImage(fs_1.default.createReadStream(tempFilePath), fname);
81
- fs_1.default.unlinkSync(tempFilePath);
82
- }
83
- else {
84
73
  await (0, promises_1.pipeline)(f.file, fs_1.default.createWriteStream(fname));
74
+ return f;
85
75
  }
86
- return Object.assign(Object.assign({}, f), { filename: (options === null || options === void 0 ? void 0 : options.saveAs) ? options.saveAs : f.filename });
76
+ }
77
+ catch (err) {
78
+ throw new system_exception_1.SystemUseError("Can't upload file");
87
79
  }
88
80
  }
89
- async saveAs(f, filename, options) {
90
- if (f && f.file) {
91
- let fname = filename;
92
- if (options && options.dest) {
93
- fname = options.dest + '/' + filename;
94
- }
95
- else {
96
- fname = path_1.default.join(process.cwd(), `public/${filename}`);
97
- }
98
- if (fs_1.default.existsSync(fname) && !options.overwrite) {
99
- throw new http_exceptions_1.InternalErrorException("File already exists.");
100
- }
101
- if (this.transformOptions) {
102
- await this.processImage(f.file, fname);
103
- }
104
- else {
105
- await (0, promises_1.pipeline)(f.file, fs_1.default.createWriteStream(fname));
81
+ async remove(filepath) {
82
+ if (!this.isFileExists(path_1.default.join(process.cwd(), "public/" + filepath))) {
83
+ throw new system_exception_1.SystemUseError("File doesn't exists.");
84
+ }
85
+ return fs_1.default.unlinkSync(path_1.default.join(process.cwd(), "public/" + filepath));
86
+ }
87
+ async saveAll(files, options) {
88
+ try {
89
+ let foptions = {
90
+ overwrite: options && options.overwrite ? options.overwrite : true,
91
+ };
92
+ for (let f of files) {
93
+ let uploadPath = `public`;
94
+ if (options === null || options === void 0 ? void 0 : options.to) {
95
+ uploadPath = `public/${options.to}`;
96
+ }
97
+ const fname = path_1.default.join(process.cwd(), `${uploadPath}/${f.filename}`);
98
+ await this.ensureDirectoryExists(fname);
99
+ if (f.file) {
100
+ await (0, promises_1.pipeline)(f.file, fs_1.default.createWriteStream(fname));
101
+ }
102
+ else {
103
+ const fp = f;
104
+ await (0, promises_1.pipeline)(fs_1.default.createReadStream(fp.filepath), fs_1.default.createWriteStream(fname));
105
+ fs_1.default.unlinkSync(fp.filepath);
106
+ }
106
107
  }
107
- return Object.assign(Object.assign({}, f), { filename: filename });
108
+ return files;
109
+ }
110
+ catch (error) {
111
+ console.error(error);
112
+ throw new system_exception_1.SystemUseError("Can't upload file");
113
+ }
114
+ }
115
+ /* private async saveSingleFile(
116
+ f: MultipartFile,
117
+ options: any
118
+ ): Promise<MultipartFile | null> {
119
+ if (f && f.type == "file") {
120
+ let fname = f.filename;
121
+ if (options) {
122
+ if (options.dest) {
123
+ fname = options.saveAs
124
+ ? options.dest + "/" + options.saveAs
125
+ : options.dest + "/" + f.filename;
126
+ } else {
127
+ fname = path.join(
128
+ process.cwd(),
129
+ `public/${options.saveAs ? options.saveAs : f.filename}`
130
+ );
131
+ }
132
+ } else {
133
+ fname = path.join(process.cwd(), `public/${f.filename}`);
134
+ }
135
+ await this.ensureDirectoryExists(fname); // Ensure directory exists
136
+
137
+ if (fs.existsSync(fname) && !options.overwrite) {
138
+ throw new InternalErrorException("File already exists.");
108
139
  }
140
+
141
+ if (this.transformOptions) {
142
+ if (f.type == "file") {
143
+ const tempFilePath = path.join(
144
+ os.tmpdir(),
145
+ `temp-${Date.now()}-${f.filename}`
146
+ );
147
+ await pipeline(f.file!, fs.createWriteStream(tempFilePath));
148
+ await this.processImage(fs.createReadStream(tempFilePath), fname);
149
+ fs.unlinkSync(tempFilePath);
150
+ } else if (f.type == "fil") {
151
+ await this.processImage(fs.createReadStream(f.filepath), fname);
152
+ }
153
+ } else {
154
+ if (f.file) {
155
+ await pipeline(f.file!, fs.createWriteStream(fname));
156
+ } else if (f.filepath) {
157
+ fs.copyFileSync(f.filepath, fname);
158
+ }
159
+ }
160
+ return {
161
+ ...f,
162
+ filename: options?.saveAs ? options.saveAs : f.filename,
163
+ } as MultipartFile;
164
+ }
165
+ return null;
166
+ }
167
+
168
+ async saveAs(
169
+ f: MultipartFile | MultipartFile[],
170
+ filename: string | string[],
171
+ options: any
172
+ ) {
173
+ if (
174
+ Array.isArray(f) &&
175
+ Array.isArray(filename) &&
176
+ f.length === filename.length
177
+ ) {
178
+ const savedFiles: MultipartFile[] = [];
179
+ for (let i = 0; i < f.length; i++) {
180
+ const savedFile = await this.saveSingleFileAs(
181
+ f[i],
182
+ filename[i],
183
+ options
184
+ );
185
+ if (savedFile) {
186
+ savedFiles.push(savedFile);
187
+ }
188
+ }
189
+ return savedFiles;
190
+ } else if (!Array.isArray(f) && !Array.isArray(filename)) {
191
+ return await this.saveSingleFileAs(f, filename as string, options);
192
+ } else {
193
+ throw new InternalErrorException(
194
+ "File and filename array lengths do not match."
195
+ );
196
+ }
109
197
  }
198
+
199
+ private async saveSingleFileAs(
200
+ f: MultipartFile,
201
+ filename: string,
202
+ options: any
203
+ ): Promise<MultipartFile | null> {
204
+ if (f) {
205
+ let fname = filename;
206
+
207
+ if (options && options.dest) {
208
+ fname = options.dest + "/" + filename;
209
+ } else {
210
+ fname = path.join(process.cwd(), `public/${filename}`);
211
+ }
212
+ await this.ensureDirectoryExists(fname);
213
+
214
+ if (fs.existsSync(fname) && !options.overwrite) {
215
+ throw new InternalErrorException("File already exists.");
216
+ }
217
+
218
+ if (this.transformOptions) {
219
+ if (f.file) {
220
+ const tempFilePath = path.join(
221
+ os.tmpdir(),
222
+ `temp-${Date.now()}-${f.filename}`
223
+ );
224
+ await pipeline(f.file!, fs.createWriteStream(tempFilePath));
225
+ await this.processImage(fs.createReadStream(tempFilePath), fname);
226
+ fs.unlinkSync(tempFilePath);
227
+ } else if (f.filepath) {
228
+ await this.processImage(fs.createReadStream(f.filepath), fname);
229
+ }
230
+ } else {
231
+ if (f.file) {
232
+ await pipeline(f.file!, fs.createWriteStream(fname));
233
+ } else if (f.filepath) {
234
+ fs.copyFileSync(f.filepath, fname);
235
+ }
236
+ }
237
+
238
+ return { ...f, filename: filename } as MultipartFile;
239
+ }
240
+ return null;
241
+ }
242
+ */
110
243
  async processImage(fileStream, outputPath) {
111
244
  var _a, _b;
112
245
  try {
113
- const sharp = await Promise.resolve().then(() => __importStar(require('sharp'))); // Lazy import sharp
246
+ const sharp = await Promise.resolve().then(() => __importStar(require("sharp"))); // Lazy import sharp
114
247
  let sharpPipeline = sharp.default();
115
248
  if ((_a = this.transformOptions) === null || _a === void 0 ? void 0 : _a.resize) {
116
249
  sharpPipeline = sharpPipeline.resize(this.transformOptions.resize.width, this.transformOptions.resize.height);
117
250
  }
118
251
  if ((_b = this.transformOptions) === null || _b === void 0 ? void 0 : _b.format) {
119
252
  switch (this.transformOptions.format) {
120
- case 'jpeg':
121
- sharpPipeline = sharpPipeline.jpeg({ quality: this.transformOptions.quality || 80 });
253
+ case "jpeg":
254
+ sharpPipeline = sharpPipeline.jpeg({
255
+ quality: this.transformOptions.quality || 80,
256
+ });
122
257
  break;
123
- case 'png':
124
- sharpPipeline = sharpPipeline.png({ quality: this.transformOptions.quality || 80 });
258
+ case "png":
259
+ sharpPipeline = sharpPipeline.png({
260
+ quality: this.transformOptions.quality || 80,
261
+ });
125
262
  break;
126
- case 'webp':
127
- sharpPipeline = sharpPipeline.webp({ quality: this.transformOptions.quality || 80 });
263
+ case "webp":
264
+ sharpPipeline = sharpPipeline.webp({
265
+ quality: this.transformOptions.quality || 80,
266
+ });
128
267
  break;
129
- case 'avif':
130
- sharpPipeline = sharpPipeline.avif({ quality: this.transformOptions.quality || 80 });
268
+ case "avif":
269
+ sharpPipeline = sharpPipeline.avif({
270
+ quality: this.transformOptions.quality || 80,
271
+ });
131
272
  break;
132
273
  default:
133
274
  break;
@@ -136,16 +277,23 @@ let FileStorage = class FileStorage {
136
277
  await (0, promises_1.pipeline)(fileStream, sharpPipeline, fs_1.default.createWriteStream(outputPath));
137
278
  }
138
279
  catch (error) {
139
- if (error.code === 'MODULE_NOT_FOUND' && error.message.includes('sharp')) {
140
- throw new http_exceptions_1.InternalErrorException('sharp module not found. Please install sharp to use image transformations.');
280
+ if (error.code === "MODULE_NOT_FOUND" &&
281
+ error.message.includes("sharp")) {
282
+ throw new http_exceptions_1.InternalErrorException("sharp module not found. Please install sharp to use image transformations.");
141
283
  }
142
- console.error('Image processing failed:', error);
143
- throw new http_exceptions_1.InternalErrorException('Image processing failed.');
284
+ console.error("Image processing failed:", error);
285
+ throw new http_exceptions_1.InternalErrorException("Image processing failed.");
144
286
  }
145
287
  finally {
146
288
  this.transformOptions = null; // Reset transform options after processing
147
289
  }
148
290
  }
291
+ async ensureDirectoryExists(filePath) {
292
+ const dir = path_1.default.dirname(filePath);
293
+ if (!fs_1.default.existsSync(dir)) {
294
+ fs_1.default.mkdirSync(dir, { recursive: true });
295
+ }
296
+ }
149
297
  };
150
298
  exports.FileStorage = FileStorage;
151
299
  exports.FileStorage = FileStorage = __decorate([
package/dist/icore.d.ts CHANGED
@@ -41,6 +41,12 @@ export interface ParamMetaOptions {
41
41
  validatorClass: boolean;
42
42
  type: "route:param" | "route:query" | "route:body" | "route:header" | "route:user" | "route:file" | "route:files";
43
43
  }
44
+ export interface ParamMetaFilesOptions {
45
+ index: number;
46
+ type: "route:files";
47
+ files: MultipartFile[];
48
+ fieldName: string;
49
+ }
44
50
  export interface MethodParamMeta {
45
51
  params: ParamMetaOptions[];
46
52
  query: ParamMetaOptions[];
@@ -49,7 +55,7 @@ export interface MethodParamMeta {
49
55
  currentUser: ParamMetaOptions[];
50
56
  swagger?: OpenApiUiOptions;
51
57
  file?: any[];
52
- files?: MultipartFile[];
58
+ files?: ParamMetaFilesOptions[];
53
59
  }
54
60
  type StaticFileOptions = {
55
61
  path?: PathLike;
package/dist/icore.js CHANGED
@@ -193,7 +193,6 @@ class AvleonApplication {
193
193
  return;
194
194
  const prototype = Object.getPrototypeOf(ctrl);
195
195
  const methods = Object.getOwnPropertyNames(prototype).filter((name) => name !== "constructor");
196
- let classMiddlewares = [];
197
196
  const tag = ctrl.constructor.name.replace("Controller", "");
198
197
  const swaggerControllerMeta = Reflect.getMetadata("controller:openapi", ctrl.constructor) || {};
199
198
  const authClsMeata = Reflect.getMetadata(container_1.AUTHORIZATION_META_KEY, ctrl.constructor) || { authorize: false, options: undefined };
@@ -279,7 +278,7 @@ class AvleonApplication {
279
278
  * @returns
280
279
  */
281
280
  async _mapArgs(req, meta) {
282
- var _a, e_2, _b, _c;
281
+ var _a, e_2, _b, _c, _d, e_3, _e, _f;
283
282
  if (!req.hasOwnProperty("_argsCache")) {
284
283
  Object.defineProperty(req, "_argsCache", {
285
284
  value: new Map(),
@@ -293,15 +292,15 @@ class AvleonApplication {
293
292
  }
294
293
  const args = meta.params.map((p) => req.params[p.key] || null);
295
294
  meta.query.forEach((q) => (args[q.index] = q.key === "all" ? req.query : req.query[q.key]));
296
- meta.body.forEach((body) => (args[body.index] = req.body));
295
+ meta.body.forEach((body) => (args[body.index] = Object.assign(Object.assign({}, req.body), req.formData)));
297
296
  meta.currentUser.forEach((user) => (args[user.index] = req.user));
298
297
  meta.headers.forEach((header) => (args[header.index] =
299
298
  header.key === "all" ? req.headers : req.headers[header.key]));
300
299
  if (meta.file) {
301
300
  try {
302
- for (var _d = true, _e = __asyncValues(meta.file), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
303
- _c = _f.value;
304
- _d = false;
301
+ for (var _g = true, _h = __asyncValues(meta.file), _j; _j = await _h.next(), _a = _j.done, !_a; _g = true) {
302
+ _c = _j.value;
303
+ _g = false;
305
304
  let f = _c;
306
305
  args[f.index] = await req.file();
307
306
  }
@@ -309,11 +308,48 @@ class AvleonApplication {
309
308
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
310
309
  finally {
311
310
  try {
312
- if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
311
+ if (!_g && !_a && (_b = _h.return)) await _b.call(_h);
313
312
  }
314
313
  finally { if (e_2) throw e_2.error; }
315
314
  }
316
315
  }
316
+ if (meta.files) {
317
+ const files = await req.saveRequestFiles();
318
+ if (!files || files.length === 0) {
319
+ throw new exceptions_1.BadRequestException({ error: "No files uploaded" });
320
+ }
321
+ const fileInfo = files.map((file) => ({
322
+ type: file.type,
323
+ filepath: file.filepath,
324
+ fieldname: file.fieldname,
325
+ filename: file.filename,
326
+ encoding: file.encoding,
327
+ mimetype: file.mimetype,
328
+ fields: file.fields,
329
+ }));
330
+ try {
331
+ for (var _k = true, _l = __asyncValues(meta.files), _m; _m = await _l.next(), _d = _m.done, !_d; _k = true) {
332
+ _f = _m.value;
333
+ _k = false;
334
+ let f = _f;
335
+ const findex = fileInfo.findIndex((x) => x.fieldname == f.fieldName);
336
+ if (f.fieldName != "all" && findex == -1) {
337
+ throw new exceptions_1.BadRequestException(`${f.fieldName} doesn't exists in request files tree.`);
338
+ }
339
+ args[f.index] =
340
+ f.fieldName == "all"
341
+ ? fileInfo
342
+ : fileInfo.filter((x) => x.fieldname == f.fieldName);
343
+ }
344
+ }
345
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
346
+ finally {
347
+ try {
348
+ if (!_k && !_d && (_e = _l.return)) await _e.call(_l);
349
+ }
350
+ finally { if (e_3) throw e_3.error; }
351
+ }
352
+ }
317
353
  cache.set(cacheKey, args);
318
354
  return args;
319
355
  }
@@ -579,7 +615,7 @@ class TestBuilder {
579
615
  }
580
616
  async getTestApplication(options) {
581
617
  const app = AvleonApplication.getInternalApp({
582
- dataSourceOptions: this.dataSourceOptions
618
+ dataSourceOptions: this.dataSourceOptions,
583
619
  });
584
620
  app.mapControllers([...options.controllers]);
585
621
  const fa = await app.getTestApp();
@@ -4,14 +4,14 @@
4
4
  * @email xtrinsic96@gmail.com
5
5
  * @url https://github.com/xtareq
6
6
  */
7
- import { MultipartFile as FsM } from "@fastify/multipart";
7
+ import { MultipartFile as FsM, SavedMultipartFile } from "@fastify/multipart";
8
8
  import { IRequest } from "./icore";
9
9
  export declare function UploadFile(fieldName: string): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
10
- export declare function UploadFiles(fieldName: string): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
10
+ export declare function UploadFiles(fieldName?: string): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
11
11
  type Foptions = {
12
12
  saveAs?: string;
13
13
  dest?: true;
14
14
  };
15
- export type MultipartFile = FsM;
15
+ export type MultipartFile = FsM | SavedMultipartFile;
16
16
  export declare function UploadFileFromRequest(req: IRequest, options?: Foptions): Promise<FsM | undefined>;
17
17
  export {};
package/dist/multipart.js CHANGED
@@ -33,7 +33,10 @@ function UploadFiles(fieldName) {
33
33
  Reflect.defineMetadata(container_1.REQUEST_BODY_FILES_KEY, [], target, propertyKey);
34
34
  }
35
35
  const existingMetadata = Reflect.getMetadata(container_1.REQUEST_BODY_FILES_KEY, target, propertyKey);
36
- existingMetadata.push({ fieldName, index: parameterIndex });
36
+ existingMetadata.push({
37
+ fieldName: fieldName ? fieldName : "all",
38
+ index: parameterIndex,
39
+ });
37
40
  Reflect.defineMetadata(container_1.REQUEST_BODY_FILES_KEY, existingMetadata, target, propertyKey);
38
41
  };
39
42
  }
@@ -43,7 +46,9 @@ function UploadFileFromRequest(req, options) {
43
46
  let fname = f.filename;
44
47
  if (options) {
45
48
  if (options.dest) {
46
- fname = options.saveAs ? options.dest + '/' + options.saveAs : options.dest + '/' + f.filename;
49
+ fname = options.saveAs
50
+ ? options.dest + "/" + options.saveAs
51
+ : options.dest + "/" + f.filename;
47
52
  }
48
53
  else {
49
54
  fname = path_1.default.join(process.cwd(), `public/${options.saveAs ? options.saveAs : f.filename}`);
@@ -11,6 +11,15 @@ export interface IHttpResponse<T extends any> {
11
11
  data: T | null;
12
12
  }
13
13
  export declare class HttpResponse {
14
- static Ok<T>(obj: any, s?: ClassConstructor<T>): any;
15
- static NoContent(): void;
14
+ static Ok<T>(obj: any, s?: ClassConstructor<T>): IHttpResponse<T>;
15
+ static Created<T>(obj: any, s?: ClassConstructor<T>): IHttpResponse<T>;
16
+ static NoContent(): IHttpResponse<null>;
17
+ static BadRequest(message: string, data?: any): IHttpResponse<any>;
18
+ static Unauthorized(message: string, data?: any): IHttpResponse<any>;
19
+ static Forbidden(message: string, data?: any): IHttpResponse<any>;
20
+ static NotFound(message: string, data?: any): IHttpResponse<any>;
21
+ static InternalServerError(message?: string, data?: any): IHttpResponse<any>;
22
+ static Conflict(message: string, data?: any): IHttpResponse<any>;
23
+ static UnprocessableEntity(message: string, data?: any): IHttpResponse<any>;
24
+ static TooManyRequests(message: string, data?: any): IHttpResponse<any>;
16
25
  }
package/dist/response.js CHANGED
@@ -22,16 +22,56 @@ class HttpResponse {
22
22
  static Ok(obj, s) {
23
23
  if (s) {
24
24
  const isPaginated = obj === null || obj === void 0 ? void 0 : obj.hasOwnProperty("total");
25
- // Ensure transformation applies only allowed properties
26
- const transformedData = (0, class_transformer_1.plainToInstance)(s, isPaginated ? obj.data : obj, {
25
+ const dataToTransform = isPaginated ? obj.data : obj;
26
+ const transformedData = (0, class_transformer_1.plainToInstance)(s, dataToTransform, {
27
27
  enableImplicitConversion: true,
28
- excludeExtraneousValues: true, // Ensures only @Expose() properties are included
28
+ excludeExtraneousValues: true,
29
29
  });
30
- return Object.assign({ message: "success" }, (isPaginated
31
- ? Object.assign(Object.assign({}, obj), { data: (0, class_transformer_1.instanceToPlain)(transformedData) }) : { data: (0, class_transformer_1.instanceToPlain)(transformedData) }));
30
+ const transformedResult = isPaginated
31
+ ? Object.assign(Object.assign({}, obj), { data: (0, class_transformer_1.instanceToPlain)(transformedData) }) : { data: (0, class_transformer_1.instanceToPlain)(transformedData) };
32
+ return Object.assign({ message: "success" }, transformedResult);
32
33
  }
33
34
  return { message: "success", data: obj };
34
35
  }
35
- static NoContent() { }
36
+ static Created(obj, s) {
37
+ if (s) {
38
+ const transformedData = (0, class_transformer_1.plainToInstance)(s, obj, {
39
+ enableImplicitConversion: true,
40
+ excludeExtraneousValues: true,
41
+ });
42
+ return {
43
+ message: "created",
44
+ data: (0, class_transformer_1.instanceToPlain)(transformedData),
45
+ };
46
+ }
47
+ return { message: "created", data: obj };
48
+ }
49
+ static NoContent() {
50
+ return { message: "no content", data: null };
51
+ }
52
+ static BadRequest(message, data = null) {
53
+ return { message: message, data: data };
54
+ }
55
+ static Unauthorized(message, data = null) {
56
+ return { message: message, data: data };
57
+ }
58
+ static Forbidden(message, data = null) {
59
+ return { message: message, data: data };
60
+ }
61
+ static NotFound(message, data = null) {
62
+ return { message: message, data: data };
63
+ }
64
+ static InternalServerError(message = "Internal server error", data = null) {
65
+ return { message: message, data: data };
66
+ }
67
+ static Conflict(message, data = null) {
68
+ return { message: message, data: data };
69
+ }
70
+ static UnprocessableEntity(message, data = null) {
71
+ return { message: message, data: data };
72
+ }
73
+ static TooManyRequests(message, data = null) {
74
+ return { message: message, data: data };
75
+ }
36
76
  }
37
77
  exports.HttpResponse = HttpResponse;
package/package.json CHANGED
@@ -1,54 +1,52 @@
1
- {
2
- "name": "@avleon/core",
3
- "version": "0.0.11",
4
- "main": "./dist/index.js",
5
- "types": [
6
- "./dist/index.d.ts",
7
- "./exceptions/index.d.ts"
8
- ],
9
- "scripts": {
10
- "build": "rimraf dist && tsc",
11
- "watch": "tsc-watch",
12
- "test": "jest",
13
- "test:watch": "jest --watch"
14
- },
15
- "keywords": [],
16
- "author": "Tareq Hossain",
17
- "license": "ISC",
18
- "devDependencies": {
19
- "@types/jest": "^29.5.14",
20
- "class-transformer": "^0.5.1",
21
- "class-validator": "^0.14.1",
22
- "jest": "^29.7.0",
23
- "nodemon": "^3.1.7",
24
- "sharp": "^0.33.5",
25
- "ts-jest": "^29.2.5",
26
- "ts-node": "^10.9.2",
27
- "tsc-watch": "^6.2.1",
28
- "typeorm": "^0.3.20",
29
- "typescript": "^5.7.2"
30
- },
31
- "dependencies": {
32
- "@fastify/cors": "^11.0.0",
33
- "@fastify/multipart": "^9.0.3",
34
- "@fastify/static": "^8.1.1",
35
- "@fastify/swagger": "^9.4.0",
36
- "@fastify/swagger-ui": "^5.1.0",
37
- "bcryptjs": "^3.0.2",
38
- "dotenv": "^16.4.7",
39
- "fastify": "^5.1.0",
40
- "reflect-metadata": "^0.2.2",
41
- "typedi": "^0.10.0"
42
- },
43
- "peerDependencies": {
44
- "typeorm": "^0.3.20"
45
- },
46
- "directories": {
47
- "test": "tests"
48
- },
49
- "description": "avleon core",
50
- "repository": {
51
- "type": "git",
52
- "url": "git+https://github.com/avleonjs/avleon-core"
53
- }
1
+ {
2
+ "name": "@avleon/core",
3
+ "version": "0.0.13",
4
+ "main": "./dist/index.js",
5
+ "scripts": {
6
+ "build": "rimraf dist && tsc",
7
+ "watch": "tsc-watch",
8
+ "test": "jest",
9
+ "test:watch": "jest --watch"
10
+ },
11
+ "keywords": [],
12
+ "author": "Tareq Hossain",
13
+ "license": "ISC",
14
+ "devDependencies": {
15
+ "@types/jest": "^29.5.14",
16
+ "class-transformer": "^0.5.1",
17
+ "class-validator": "^0.14.1",
18
+ "jest": "^29.7.0",
19
+ "nodemon": "^3.1.7",
20
+ "sharp": "^0.33.5",
21
+ "ts-jest": "^29.2.5",
22
+ "ts-node": "^10.9.2",
23
+ "tsc-watch": "^6.2.1",
24
+ "typeorm": "^0.3.20",
25
+ "typescript": "^5.7.2"
26
+ },
27
+ "dependencies": {
28
+ "@fastify/cors": "^11.0.0",
29
+ "@fastify/multipart": "^9.0.3",
30
+ "@fastify/static": "^8.1.1",
31
+ "@fastify/swagger": "^9.4.0",
32
+ "@fastify/swagger-ui": "^5.1.0",
33
+ "bcryptjs": "^3.0.2",
34
+ "dotenv": "^16.4.7",
35
+ "fastify": "^5.1.0",
36
+ "reflect-metadata": "^0.2.2",
37
+ "typedi": "^0.10.0"
38
+ },
39
+ "peerDependencies": {
40
+ "typeorm": "^0.3.20",
41
+ "class-transformer": "^0.5.1",
42
+ "class-validator": "^0.14.1"
43
+ },
44
+ "directories": {
45
+ "test": "tests"
46
+ },
47
+ "description": "avleon core",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/avleonjs/avleon-core"
51
+ }
54
52
  }