@avleon/core 0.0.20 → 0.0.25
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/README.md +559 -2
- package/dist/application.d.ts +47 -0
- package/dist/application.js +50 -0
- package/dist/cache.d.ts +12 -0
- package/dist/cache.js +78 -0
- package/dist/collection.js +3 -2
- package/dist/container.d.ts +1 -0
- package/dist/container.js +2 -1
- package/dist/environment-variables.js +1 -1
- package/dist/file-storage.js +0 -128
- package/dist/helpers.d.ts +2 -0
- package/dist/helpers.js +41 -4
- package/dist/icore.d.ts +93 -42
- package/dist/icore.js +319 -251
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -2
- package/dist/middleware.js +0 -8
- package/dist/multipart.js +4 -1
- package/dist/openapi.d.ts +37 -37
- package/dist/params.js +2 -2
- package/dist/response.js +6 -2
- package/dist/route-methods.js +1 -1
- package/dist/swagger-schema.js +4 -1
- package/dist/testing.js +6 -3
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/optional-require.d.ts +8 -0
- package/dist/utils/optional-require.js +70 -0
- package/dist/validation.d.ts +4 -1
- package/dist/validation.js +10 -5
- package/package.json +26 -9
- package/src/application.ts +125 -0
- package/src/authentication.ts +16 -0
- package/src/cache.ts +91 -0
- package/src/collection.ts +254 -0
- package/src/config.ts +42 -0
- package/src/constants.ts +1 -0
- package/src/container.ts +54 -0
- package/src/controller.ts +127 -0
- package/src/decorators.ts +27 -0
- package/src/environment-variables.ts +46 -0
- package/src/exceptions/http-exceptions.ts +86 -0
- package/src/exceptions/index.ts +1 -0
- package/src/exceptions/system-exception.ts +34 -0
- package/src/file-storage.ts +206 -0
- package/src/helpers.ts +328 -0
- package/src/icore.ts +1140 -0
- package/src/index.ts +30 -0
- package/src/logger.ts +72 -0
- package/src/map-types.ts +159 -0
- package/src/middleware.ts +98 -0
- package/src/multipart.ts +116 -0
- package/src/openapi.ts +372 -0
- package/src/params.ts +111 -0
- package/src/queue.ts +126 -0
- package/src/response.ts +117 -0
- package/src/results.ts +30 -0
- package/src/route-methods.ts +186 -0
- package/src/swagger-schema.ts +213 -0
- package/src/testing.ts +220 -0
- package/src/types/app-builder.interface.ts +19 -0
- package/src/types/application.interface.ts +9 -0
- package/src/utils/hash.ts +5 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/optional-require.ts +50 -0
- package/src/validation.ts +156 -0
- package/src/validator-extend.ts +25 -0
- package/dist/classToOpenapi.d.ts +0 -0
- package/dist/classToOpenapi.js +0 -1
- package/dist/render.d.ts +0 -1
- package/dist/render.js +0 -8
- package/jest.config.ts +0 -9
- package/tsconfig.json +0 -25
- /package/dist/{security.d.ts → utils/hash.d.ts} +0 -0
- /package/dist/{security.js → utils/hash.js} +0 -0
package/dist/cache.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CacheManager = void 0;
|
|
4
|
+
class CacheManager {
|
|
5
|
+
constructor(redisInstance) {
|
|
6
|
+
this.store = new Map();
|
|
7
|
+
this.tagsMap = new Map();
|
|
8
|
+
this.redis = null;
|
|
9
|
+
this.redis = redisInstance || null;
|
|
10
|
+
}
|
|
11
|
+
redisTagKey(tag) {
|
|
12
|
+
return `cache-tags:${tag}`;
|
|
13
|
+
}
|
|
14
|
+
async get(key) {
|
|
15
|
+
if (this.redis) {
|
|
16
|
+
const val = await this.redis.get(key);
|
|
17
|
+
return val ? JSON.parse(val) : null;
|
|
18
|
+
}
|
|
19
|
+
const cached = this.store.get(key);
|
|
20
|
+
return cached ? cached.data : null;
|
|
21
|
+
}
|
|
22
|
+
async set(key, value, tags = [], ttl = 3600) {
|
|
23
|
+
const entry = {
|
|
24
|
+
data: value,
|
|
25
|
+
timestamp: Date.now(),
|
|
26
|
+
};
|
|
27
|
+
if (this.redis) {
|
|
28
|
+
await this.redis.set(key, JSON.stringify(entry.data), 'EX', ttl);
|
|
29
|
+
for (const tag of tags) {
|
|
30
|
+
await this.redis.sadd(this.redisTagKey(tag), key);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.store.set(key, entry);
|
|
35
|
+
for (const tag of tags) {
|
|
36
|
+
if (!this.tagsMap.has(tag))
|
|
37
|
+
this.tagsMap.set(tag, new Set());
|
|
38
|
+
this.tagsMap.get(tag).add(key);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async delete(key) {
|
|
43
|
+
if (this.redis) {
|
|
44
|
+
await this.redis.del(key);
|
|
45
|
+
// Also clean up from any tag sets
|
|
46
|
+
const tagKeys = await this.redis.keys('cache-tags:*');
|
|
47
|
+
for (const tagKey of tagKeys) {
|
|
48
|
+
await this.redis.srem(tagKey, key);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.store.delete(key);
|
|
53
|
+
for (const keys of this.tagsMap.values()) {
|
|
54
|
+
keys.delete(key);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async invalidateTag(tag) {
|
|
59
|
+
if (this.redis) {
|
|
60
|
+
const tagKey = this.redisTagKey(tag);
|
|
61
|
+
const keys = await this.redis.smembers(tagKey);
|
|
62
|
+
if (keys.length) {
|
|
63
|
+
await this.redis.del(...keys); // delete all cached keys
|
|
64
|
+
await this.redis.del(tagKey); // delete the tag set
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const keys = this.tagsMap.get(tag);
|
|
69
|
+
if (keys) {
|
|
70
|
+
for (const key of keys) {
|
|
71
|
+
this.store.delete(key);
|
|
72
|
+
}
|
|
73
|
+
this.tagsMap.delete(tag);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.CacheManager = CacheManager;
|
package/dist/collection.js
CHANGED
|
@@ -45,7 +45,7 @@ class BasicCollection {
|
|
|
45
45
|
const item = this.items.find(predicate);
|
|
46
46
|
if (item) {
|
|
47
47
|
const index = this.items.indexOf(item);
|
|
48
|
-
this.items[index] =
|
|
48
|
+
this.items[index] = { ...item, ...updater };
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
51
51
|
throw new exceptions_1.NotFoundException("Item not found");
|
|
@@ -108,8 +108,9 @@ class AsynchronousCollection {
|
|
|
108
108
|
}
|
|
109
109
|
getRepository() {
|
|
110
110
|
if (!this.repo) {
|
|
111
|
-
const dataSourceKey =
|
|
111
|
+
const dataSourceKey = "idatasource";
|
|
112
112
|
const dataSource = typedi_1.default.get(dataSourceKey);
|
|
113
|
+
console.log('datasource', dataSource);
|
|
113
114
|
const repository = dataSource.getRepository(this.model);
|
|
114
115
|
this.repo = repository;
|
|
115
116
|
return repository;
|
package/dist/container.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @url https://github.com/xtareq
|
|
6
6
|
*/
|
|
7
7
|
import TypediContainer from "typedi";
|
|
8
|
+
export declare const FEATURE_KEY: unique symbol;
|
|
8
9
|
export declare const ROUTE_META_KEY: unique symbol;
|
|
9
10
|
export declare const CONTROLLER_META_KEY: unique symbol;
|
|
10
11
|
export declare const PARAM_META_KEY: unique symbol;
|
package/dist/container.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.API_CONTROLLER_METADATA_KEY = exports.AUTHORIZATION_META_KEY = exports.DATASOURCE_META_KEY = exports.REQUEST_HEADER_META_KEY = exports.REQUEST_USER_META_KEY = exports.REQUEST_BODY_FILES_KEY = exports.REQUEST_BODY_FILE_KEY = exports.REQUEST_BODY_META_KEY = exports.QUERY_META_KEY = exports.PARAM_META_KEY = exports.CONTROLLER_META_KEY = exports.ROUTE_META_KEY = void 0;
|
|
6
|
+
exports.API_CONTROLLER_METADATA_KEY = exports.AUTHORIZATION_META_KEY = exports.DATASOURCE_META_KEY = exports.REQUEST_HEADER_META_KEY = exports.REQUEST_USER_META_KEY = exports.REQUEST_BODY_FILES_KEY = exports.REQUEST_BODY_FILE_KEY = exports.REQUEST_BODY_META_KEY = exports.QUERY_META_KEY = exports.PARAM_META_KEY = exports.CONTROLLER_META_KEY = exports.ROUTE_META_KEY = exports.FEATURE_KEY = void 0;
|
|
7
7
|
exports.registerController = registerController;
|
|
8
8
|
exports.registerService = registerService;
|
|
9
9
|
exports.getRegisteredServices = getRegisteredServices;
|
|
@@ -17,6 +17,7 @@ exports.registerDataSource = registerDataSource;
|
|
|
17
17
|
* @url https://github.com/xtareq
|
|
18
18
|
*/
|
|
19
19
|
const typedi_1 = __importDefault(require("typedi"));
|
|
20
|
+
exports.FEATURE_KEY = Symbol.for("features");
|
|
20
21
|
exports.ROUTE_META_KEY = Symbol("iroute:options");
|
|
21
22
|
exports.CONTROLLER_META_KEY = Symbol("icontroller:options");
|
|
22
23
|
exports.PARAM_META_KEY = Symbol("iparam:options");
|
|
@@ -27,7 +27,7 @@ let Environment = class Environment {
|
|
|
27
27
|
try {
|
|
28
28
|
const fileContent = fs_1.default.readFileSync(filePath, 'utf8');
|
|
29
29
|
const parsedEnv = dotenv_1.default.parse(fileContent);
|
|
30
|
-
return
|
|
30
|
+
return { ...parsedEnv, ...process.env };
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
33
33
|
console.error(`Error parsing .env file: ${error}`);
|
package/dist/file-storage.js
CHANGED
|
@@ -112,134 +112,6 @@ let FileStorage = class FileStorage {
|
|
|
112
112
|
throw new system_exception_1.SystemUseError("Can't upload file");
|
|
113
113
|
}
|
|
114
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.");
|
|
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
|
-
}
|
|
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
|
-
*/
|
|
243
115
|
async processImage(fileStream, outputPath) {
|
|
244
116
|
var _a, _b;
|
|
245
117
|
try {
|
package/dist/helpers.d.ts
CHANGED
|
@@ -29,4 +29,6 @@ type ValidationError = {
|
|
|
29
29
|
errors: any;
|
|
30
30
|
};
|
|
31
31
|
export declare function validateRequestBody(target: Constructor, value: object, options?: "object" | "array"): ValidationError;
|
|
32
|
+
export declare function pick<T extends object>(obj: T, paths: string[]): Partial<T>;
|
|
33
|
+
export declare function exclude<T extends object>(obj: T | T[], paths: string[]): Partial<T> | Partial<T>[];
|
|
32
34
|
export {};
|
package/dist/helpers.js
CHANGED
|
@@ -19,6 +19,8 @@ exports.jsonToInstance = jsonToInstance;
|
|
|
19
19
|
exports.transformObjectByInstanceToObject = transformObjectByInstanceToObject;
|
|
20
20
|
exports.validateObjectByInstance = validateObjectByInstance;
|
|
21
21
|
exports.validateRequestBody = validateRequestBody;
|
|
22
|
+
exports.pick = pick;
|
|
23
|
+
exports.exclude = exclude;
|
|
22
24
|
/**
|
|
23
25
|
* @copyright 2024
|
|
24
26
|
* @author Tareq Hossain
|
|
@@ -42,19 +44,15 @@ function inject(cls) {
|
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
function isConstructor(func) {
|
|
45
|
-
// Check if the func is a function
|
|
46
47
|
if (typeof func !== "function") {
|
|
47
48
|
return false;
|
|
48
49
|
}
|
|
49
|
-
// Check if it's an arrow function or a built-in JavaScript function
|
|
50
50
|
if (func === Function.prototype.bind || func instanceof RegExp) {
|
|
51
51
|
return false;
|
|
52
52
|
}
|
|
53
|
-
// Check if it has a `prototype` property
|
|
54
53
|
if (func.prototype && typeof func.prototype === "object") {
|
|
55
54
|
return true;
|
|
56
55
|
}
|
|
57
|
-
// If it's not a constructor, check if it can be called with the new keyword
|
|
58
56
|
try {
|
|
59
57
|
const instance = new func();
|
|
60
58
|
return typeof instance === "object";
|
|
@@ -253,3 +251,42 @@ function validateRequestBody(target, value, options = "array") {
|
|
|
253
251
|
: error.map((x) => ({ path: x.property, constraints: x.constraints }));
|
|
254
252
|
return { count: error.length, errors };
|
|
255
253
|
}
|
|
254
|
+
function pick(obj, paths) {
|
|
255
|
+
const result = {};
|
|
256
|
+
for (const path of paths) {
|
|
257
|
+
const keys = path.split(".");
|
|
258
|
+
let source = obj;
|
|
259
|
+
let target = result;
|
|
260
|
+
for (let i = 0; i < keys.length; i++) {
|
|
261
|
+
const key = keys[i];
|
|
262
|
+
if (!(key in source))
|
|
263
|
+
break;
|
|
264
|
+
if (i === keys.length - 1) {
|
|
265
|
+
target[key] = source[key];
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
source = source[key];
|
|
269
|
+
target[key] = target[key] || {};
|
|
270
|
+
target = target[key];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
function exclude(obj, paths) {
|
|
277
|
+
if (Array.isArray(obj)) {
|
|
278
|
+
return obj.map((item) => exclude(item, paths));
|
|
279
|
+
}
|
|
280
|
+
const clone = structuredClone(obj); // Or use lodash.cloneDeep
|
|
281
|
+
for (const path of paths) {
|
|
282
|
+
const keys = path.split(".");
|
|
283
|
+
let target = clone;
|
|
284
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
285
|
+
if (!(keys[i] in target))
|
|
286
|
+
break;
|
|
287
|
+
target = target[keys[i]];
|
|
288
|
+
}
|
|
289
|
+
target === null || target === void 0 ? true : delete target[keys[keys.length - 1]];
|
|
290
|
+
}
|
|
291
|
+
return clone;
|
|
292
|
+
}
|
package/dist/icore.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { FastifyReply, FastifyRequest, HookHandlerDoneFunction, InjectOptions, L
|
|
|
8
8
|
import { Constructable } from "typedi";
|
|
9
9
|
import { Constructor } from "./helpers";
|
|
10
10
|
import { PathLike } from "fs";
|
|
11
|
-
import { DataSourceOptions } from "typeorm";
|
|
11
|
+
import { DataSource, DataSourceOptions } from "typeorm";
|
|
12
12
|
import { AppMiddleware } from "./middleware";
|
|
13
13
|
import { OpenApiOptions, OpenApiUiOptions } from "./openapi";
|
|
14
14
|
import { IConfig } from "./config";
|
|
@@ -78,18 +78,24 @@ type MultipartOptions = {
|
|
|
78
78
|
} & FastifyMultipartOptions;
|
|
79
79
|
export type TestAppOptions = {
|
|
80
80
|
controllers: Constructor[];
|
|
81
|
+
dataSource?: DataSource;
|
|
81
82
|
};
|
|
82
83
|
export interface AvleonTestAppliction {
|
|
83
84
|
addDataSource: (dataSourceOptions: DataSourceOptions) => void;
|
|
84
85
|
getApp: (options?: TestAppOptions) => any;
|
|
85
|
-
getController: <T>(controller: Constructor<T
|
|
86
|
+
getController: <T>(controller: Constructor<T>, deps: any[]) => T;
|
|
86
87
|
}
|
|
88
|
+
export type AutoControllerOptions = {
|
|
89
|
+
auto: true;
|
|
90
|
+
path?: string;
|
|
91
|
+
};
|
|
87
92
|
export interface IAvleonApplication {
|
|
88
93
|
isDevelopment(): boolean;
|
|
89
94
|
useCors(corsOptions?: FastifyCorsOptions): void;
|
|
95
|
+
useDataSource<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
|
|
90
96
|
useOpenApi<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
|
|
91
|
-
useSwagger(options: OpenApiUiOptions): Promise<void>;
|
|
92
97
|
useMultipart(options: MultipartOptions): void;
|
|
98
|
+
useCache(options: any): void;
|
|
93
99
|
useMiddlewares<T extends AppMiddleware>(mclasses: Constructor<T>[]): void;
|
|
94
100
|
useAuthoriztion<T extends any>(middleware: Constructor<T>): void;
|
|
95
101
|
mapRoute<T extends (...args: any[]) => any>(method: "get" | "post" | "put" | "delete", path: string, fn: T): Promise<void>;
|
|
@@ -97,12 +103,16 @@ export interface IAvleonApplication {
|
|
|
97
103
|
mapPost<T extends (...args: any[]) => any>(path: string, fn: T): any;
|
|
98
104
|
mapPut<T extends (...args: any[]) => any>(path: string, fn: T): any;
|
|
99
105
|
mapDelete<T extends (...args: any[]) => any>(path: string, fn: T): any;
|
|
100
|
-
|
|
106
|
+
useControllers(controllers: any[]): any;
|
|
107
|
+
useControllers(controllersOptions: AutoControllerOptions): any;
|
|
108
|
+
useControllers(controllersOrOptions: any[] | AutoControllerOptions): any;
|
|
101
109
|
useStaticFiles(options?: StaticFileOptions): void;
|
|
102
110
|
run(port?: number): Promise<void>;
|
|
103
111
|
getTestApp(): TestApplication;
|
|
104
112
|
}
|
|
105
|
-
|
|
113
|
+
type OpenApiConfigClass<T = any> = Constructable<IConfig<T>>;
|
|
114
|
+
type OpenApiConfigInput<T = any> = OpenApiConfigClass<T> | T;
|
|
115
|
+
export declare class AvleonApplication {
|
|
106
116
|
private static instance;
|
|
107
117
|
private static buildOptions;
|
|
108
118
|
private app;
|
|
@@ -118,21 +128,78 @@ export declare class AvleonApplication implements IAvleonApplication {
|
|
|
118
128
|
private authorizeMiddleware?;
|
|
119
129
|
private appConfig;
|
|
120
130
|
private dataSource?;
|
|
131
|
+
private isMapFeatures;
|
|
132
|
+
private registerControllerAuto;
|
|
133
|
+
private registerControllerPath;
|
|
121
134
|
private metaCache;
|
|
122
135
|
private multipartOptions;
|
|
123
136
|
private constructor();
|
|
124
137
|
private isTest;
|
|
138
|
+
static getApp(): AvleonApplication;
|
|
125
139
|
static getInternalApp(buildOptions: any): AvleonApplication;
|
|
126
140
|
isDevelopment(): boolean;
|
|
127
141
|
private initSwagger;
|
|
128
142
|
useCors(corsOptions?: FastifyCorsOptions): void;
|
|
129
|
-
useOpenApi<T
|
|
143
|
+
useOpenApi<T = OpenApiUiOptions>(configOrClass: OpenApiConfigInput<T>, modifyConfig?: (config: T) => T): void;
|
|
130
144
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
145
|
+
* Registers the fastify-multipart plugin with the Fastify instance.
|
|
146
|
+
* This enables handling of multipart/form-data requests, typically used for file uploads.
|
|
147
|
+
*
|
|
148
|
+
* @param {MultipartOptions} options - Options to configure the fastify-multipart plugin.
|
|
149
|
+
* @param {FastifyInstance} this.app - The Fastify instance to register the plugin with.
|
|
150
|
+
* @property {MultipartOptions} this.multipartOptions - Stores the provided multipart options.
|
|
151
|
+
* @see {@link https://github.com/fastify/fastify-multipart} for more details on available options.
|
|
133
152
|
*/
|
|
134
|
-
useSwagger(options: OpenApiUiOptions): Promise<void>;
|
|
135
153
|
useMultipart(options: MultipartOptions): void;
|
|
154
|
+
/**
|
|
155
|
+
* Configures and initializes a TypeORM DataSource based on the provided configuration class.
|
|
156
|
+
* It retrieves the configuration from the application's configuration service and allows for optional modification.
|
|
157
|
+
* The initialized DataSource is then stored and registered within a dependency injection container.
|
|
158
|
+
*
|
|
159
|
+
* @template T - A generic type extending the `IConfig` interface, representing the configuration class.
|
|
160
|
+
* @template R - A generic type representing the return type of the configuration method of the `ConfigClass`.
|
|
161
|
+
* @param {Constructable<T>} ConfigClass - The constructor of the configuration class to be used for creating the DataSource.
|
|
162
|
+
* @param {(config: R) => R} [modifyConfig] - An optional function that takes the initial configuration and returns a modified configuration.
|
|
163
|
+
* @returns {void}
|
|
164
|
+
* @property {DataSourceOptions} this.dataSourceOptions - Stores the final DataSource options after potential modification.
|
|
165
|
+
* @property {DataSource} this.dataSource - Stores the initialized TypeORM DataSource instance.
|
|
166
|
+
* @see {@link https://typeorm.io/} for more information about TypeORM.
|
|
167
|
+
*/
|
|
168
|
+
useDataSource<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
|
|
169
|
+
useCache(options: any): void;
|
|
170
|
+
/**
|
|
171
|
+
* Registers an array of middleware classes to be executed before request handlers.
|
|
172
|
+
* It retrieves instances of the middleware classes from the dependency injection container
|
|
173
|
+
* and adds them as 'preHandler' hooks to the Fastify application.
|
|
174
|
+
*
|
|
175
|
+
* @template T - A generic type extending the `AppMiddleware` interface, representing the middleware class.
|
|
176
|
+
* @param {Constructor<T>[]} mclasses - An array of middleware class constructors to be registered.
|
|
177
|
+
* @returns {void}
|
|
178
|
+
* @property {Map<string, T>} this.middlewares - Stores the registered middleware instances, keyed by their class names.
|
|
179
|
+
* @see {@link https://www.fastify.io/docs/latest/Reference/Hooks/#prehandler} for more information about Fastify preHandler hooks.
|
|
180
|
+
*/
|
|
181
|
+
useMiddlewares<T extends AppMiddleware>(mclasses: Constructor<T>[]): void;
|
|
182
|
+
/**
|
|
183
|
+
* Registers a middleware constructor to be used for authorization purposes.
|
|
184
|
+
* The specific implementation and usage of this middleware will depend on the application's authorization logic.
|
|
185
|
+
*
|
|
186
|
+
* @template T - A generic type representing the constructor of the authorization middleware.
|
|
187
|
+
* @param {Constructor<T>} middleware - The constructor of the middleware to be used for authorization.
|
|
188
|
+
* @returns {void}
|
|
189
|
+
* @property {any} this.authorizeMiddleware - Stores the constructor of the authorization middleware.
|
|
190
|
+
*/
|
|
191
|
+
useAuthoriztion<T extends any>(middleware: Constructor<T>): void;
|
|
192
|
+
/**
|
|
193
|
+
* Registers the `@fastify/static` plugin to serve static files.
|
|
194
|
+
* It configures the root directory and URL prefix for serving static assets.
|
|
195
|
+
*
|
|
196
|
+
* @param {StaticFileOptions} [options={ path: undefined, prefix: undefined }] - Optional configuration for serving static files.
|
|
197
|
+
* @param {string} [options.path] - The absolute path to the static files directory. Defaults to 'process.cwd()/public'.
|
|
198
|
+
* @param {string} [options.prefix] - The URL prefix for serving static files. Defaults to '/static/'.
|
|
199
|
+
* @returns {void}
|
|
200
|
+
* @see {@link https://github.com/fastify/fastify-static} for more details on available options.
|
|
201
|
+
*/
|
|
202
|
+
useStaticFiles(options?: StaticFileOptions): void;
|
|
136
203
|
private handleMiddlewares;
|
|
137
204
|
private executeMiddlewares;
|
|
138
205
|
/**
|
|
@@ -155,36 +222,33 @@ export declare class AvleonApplication implements IAvleonApplication {
|
|
|
155
222
|
* @returns
|
|
156
223
|
*/
|
|
157
224
|
private _processMeta;
|
|
158
|
-
|
|
159
|
-
|
|
225
|
+
private _resolveControllerDir;
|
|
226
|
+
private autoControllers;
|
|
227
|
+
useControllers(controllers: Constructor[] | AutoControllerOptions): void;
|
|
160
228
|
private _mapControllers;
|
|
161
|
-
mapControllersAuto(): void;
|
|
162
|
-
handleRoute(args: any): Promise<void>;
|
|
163
229
|
private mapFn;
|
|
164
|
-
useMiddlewares<T extends AppMiddleware>(mclasses: Constructor<T>[]): void;
|
|
165
|
-
useAuthoriztion<T extends any>(middleware: Constructor<T>): void;
|
|
166
230
|
private _handleError;
|
|
167
231
|
mapRoute<T extends (...args: any[]) => any>(method: "get" | "post" | "put" | "delete", path: string | undefined, fn: T): Promise<void>;
|
|
168
232
|
private _routeHandler;
|
|
169
233
|
mapGet<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
|
|
170
234
|
useMiddleware: <M extends AppMiddleware>(middlewares: Constructor<AppMiddleware>[]) => /*elided*/ any;
|
|
171
|
-
|
|
235
|
+
useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
|
|
172
236
|
};
|
|
173
237
|
mapPost<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
|
|
174
238
|
useMiddleware: <M extends AppMiddleware>(middlewares: Constructor<AppMiddleware>[]) => /*elided*/ any;
|
|
175
|
-
|
|
239
|
+
useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
|
|
176
240
|
};
|
|
177
241
|
mapPut<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
|
|
178
242
|
useMiddleware: <M extends AppMiddleware>(middlewares: Constructor<AppMiddleware>[]) => /*elided*/ any;
|
|
179
|
-
|
|
243
|
+
useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
|
|
180
244
|
};
|
|
181
245
|
mapDelete<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
|
|
182
246
|
useMiddleware: <M extends AppMiddleware>(middlewares: Constructor<AppMiddleware>[]) => /*elided*/ any;
|
|
183
|
-
|
|
247
|
+
useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
|
|
184
248
|
};
|
|
185
|
-
|
|
249
|
+
private _mapFeatures;
|
|
186
250
|
initializeDatabase(): Promise<void>;
|
|
187
|
-
run(port?: number): Promise<void>;
|
|
251
|
+
run(port?: number, fn?: CallableFunction): Promise<void>;
|
|
188
252
|
getTestApp(buildOptions?: any): TestApplication;
|
|
189
253
|
}
|
|
190
254
|
export type Application = typeof AvleonApplication;
|
|
@@ -197,32 +261,19 @@ export interface IAppBuilder {
|
|
|
197
261
|
addDataSource<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
|
|
198
262
|
build<T extends IAvleonApplication>(): T;
|
|
199
263
|
}
|
|
200
|
-
export declare class
|
|
264
|
+
export declare class AvleonTest {
|
|
201
265
|
private static instance;
|
|
202
266
|
private app;
|
|
203
267
|
private dataSourceOptions?;
|
|
204
268
|
private constructor();
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
private getController;
|
|
269
|
+
private addDatasource;
|
|
270
|
+
getController<T>(controller: Constructor<T>, deps?: any[]): T;
|
|
208
271
|
private getService;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
272
|
+
static createTestApplication(options: TestAppOptions): TestApplication;
|
|
273
|
+
static from(app: AvleonApplication): TestApplication;
|
|
274
|
+
static clean(): void;
|
|
212
275
|
}
|
|
213
|
-
export declare class
|
|
214
|
-
|
|
215
|
-
private alreadyBuilt;
|
|
216
|
-
private database;
|
|
217
|
-
private dataSource?;
|
|
218
|
-
private multipartOptions;
|
|
219
|
-
private dataSourceOptions?;
|
|
220
|
-
private testBuilder;
|
|
221
|
-
private appConfig;
|
|
222
|
-
private constructor();
|
|
223
|
-
static createAppBuilder(): Builder;
|
|
224
|
-
registerPlugin<T extends Function, S extends {}>(plugin: T, options: S): Promise<void>;
|
|
225
|
-
addDataSource<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
|
|
226
|
-
build<T extends IAvleonApplication>(): T;
|
|
276
|
+
export declare class Avleon {
|
|
277
|
+
static createApplication(): AvleonApplication;
|
|
227
278
|
}
|
|
228
279
|
export {};
|