gg-tools-kit 1.0.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/README.md +0 -0
- package/dist/GGToolsKit.d.ts +8 -0
- package/dist/GGToolsKit.js +17 -0
- package/dist/containers/InitContainers.d.ts +7 -0
- package/dist/containers/InitContainers.js +27 -0
- package/dist/containers/ProtectionsContainer.d.ts +21 -0
- package/dist/containers/ProtectionsContainer.js +53 -0
- package/dist/containers/UtilsContainer.d.ts +32 -0
- package/dist/containers/UtilsContainer.js +96 -0
- package/dist/projFilesControl/InitProj.d.ts +8 -0
- package/dist/projFilesControl/InitProj.js +194 -0
- package/dist/projFilesControl/InstallSecondaryLibraries.d.ts +4 -0
- package/dist/projFilesControl/InstallSecondaryLibraries.js +26 -0
- package/dist/protections/Compression.d.ts +14 -0
- package/dist/protections/Compression.js +51 -0
- package/dist/protections/HelmetProtection.d.ts +6 -0
- package/dist/protections/HelmetProtection.js +38 -0
- package/dist/protections/Logger.d.ts +9 -0
- package/dist/protections/Logger.js +51 -0
- package/dist/protections/XSSProtection.d.ts +9 -0
- package/dist/protections/XSSProtection.js +63 -0
- package/dist/utils/Array.d.ts +10 -0
- package/dist/utils/Array.js +51 -0
- package/dist/utils/Audio.d.ts +6 -0
- package/dist/utils/Audio.js +77 -0
- package/dist/utils/Date.d.ts +4 -0
- package/dist/utils/Date.js +22 -0
- package/dist/utils/Files.d.ts +15 -0
- package/dist/utils/Files.js +120 -0
- package/dist/utils/RequestData.d.ts +15 -0
- package/dist/utils/RequestData.js +30 -0
- package/dist/utils/Vidoe.d.ts +4 -0
- package/dist/utils/Vidoe.js +28 -0
- package/package.json +41 -0
package/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import Init from "./containers/InitContainers";
|
|
2
|
+
import Protections from "./containers/ProtectionsContainer";
|
|
3
|
+
import Utils from "./containers/UtilsContainer";
|
|
4
|
+
export default class GGToolsKit {
|
|
5
|
+
static Init: typeof Init;
|
|
6
|
+
static Protections: typeof Protections;
|
|
7
|
+
static Utils: typeof Utils;
|
|
8
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const InitContainers_1 = __importDefault(require("./containers/InitContainers"));
|
|
7
|
+
const ProtectionsContainer_1 = __importDefault(require("./containers/ProtectionsContainer"));
|
|
8
|
+
const UtilsContainer_1 = __importDefault(require("./containers/UtilsContainer"));
|
|
9
|
+
class GGToolsKit {
|
|
10
|
+
}
|
|
11
|
+
// Initialization Container
|
|
12
|
+
GGToolsKit.Init = InitContainers_1.default;
|
|
13
|
+
// Protections Container
|
|
14
|
+
GGToolsKit.Protections = ProtectionsContainer_1.default;
|
|
15
|
+
// Utils Container
|
|
16
|
+
GGToolsKit.Utils = UtilsContainer_1.default;
|
|
17
|
+
exports.default = GGToolsKit;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default class Init {
|
|
2
|
+
static initBackendProject(TypeScript?: boolean, projectPath?: string): void;
|
|
3
|
+
static installPackages(TypeScript?: boolean, projectPath?: string): void;
|
|
4
|
+
static createFullProject(TypeScript?: boolean, projectPath?: string): void;
|
|
5
|
+
static installAudioLibrary(): void;
|
|
6
|
+
static installVideoLibrary(): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const InitProj_1 = __importDefault(require("../projFilesControl/InitProj"));
|
|
7
|
+
const InstallSecondaryLibraries_1 = __importDefault(require("../projFilesControl/InstallSecondaryLibraries"));
|
|
8
|
+
class Init {
|
|
9
|
+
// Project Initialization
|
|
10
|
+
static initBackendProject(TypeScript = false, projectPath = process.cwd()) {
|
|
11
|
+
return InitProj_1.default.initBackendProject(TypeScript, projectPath);
|
|
12
|
+
}
|
|
13
|
+
static installPackages(TypeScript = false, projectPath = process.cwd()) {
|
|
14
|
+
return InitProj_1.default.installPackages(TypeScript, projectPath);
|
|
15
|
+
}
|
|
16
|
+
static createFullProject(TypeScript = false, projectPath = process.cwd()) {
|
|
17
|
+
return InitProj_1.default.createFullProject(TypeScript, projectPath);
|
|
18
|
+
}
|
|
19
|
+
// Secondary Libraries Control
|
|
20
|
+
static installAudioLibrary() {
|
|
21
|
+
return InstallSecondaryLibraries_1.default.installAudioLibrary();
|
|
22
|
+
}
|
|
23
|
+
static installVideoLibrary() {
|
|
24
|
+
return InstallSecondaryLibraries_1.default.installVideoLibrary();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = Init;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Compression from "../protections/Compression";
|
|
2
|
+
import HelmetProtection from "../protections/HelmetProtection";
|
|
3
|
+
import Logger from "../protections/Logger";
|
|
4
|
+
import XSSProtection from "../protections/XSSProtection";
|
|
5
|
+
export default class Protections {
|
|
6
|
+
compression: Compression;
|
|
7
|
+
helmet: HelmetProtection;
|
|
8
|
+
logger: Logger;
|
|
9
|
+
xss: XSSProtection;
|
|
10
|
+
constructor();
|
|
11
|
+
getAllMiddlewares(): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>[];
|
|
12
|
+
configure(config: {
|
|
13
|
+
compression?: any;
|
|
14
|
+
helmet?: any;
|
|
15
|
+
logger?: {
|
|
16
|
+
format?: string;
|
|
17
|
+
filePath?: string;
|
|
18
|
+
};
|
|
19
|
+
xss?: any;
|
|
20
|
+
}): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const Compression_1 = __importDefault(require("../protections/Compression"));
|
|
7
|
+
const HelmetProtection_1 = __importDefault(require("../protections/HelmetProtection"));
|
|
8
|
+
const Logger_1 = __importDefault(require("../protections/Logger"));
|
|
9
|
+
const XSSProtection_1 = __importDefault(require("../protections/XSSProtection"));
|
|
10
|
+
class Protections {
|
|
11
|
+
constructor() {
|
|
12
|
+
// Initialize all protection classes
|
|
13
|
+
this.compression = new Compression_1.default();
|
|
14
|
+
this.helmet = new HelmetProtection_1.default();
|
|
15
|
+
this.logger = new Logger_1.default("dev"); // default logger format
|
|
16
|
+
this.xss = new XSSProtection_1.default();
|
|
17
|
+
}
|
|
18
|
+
// Method to get all middlewares
|
|
19
|
+
getAllMiddlewares() {
|
|
20
|
+
return [
|
|
21
|
+
this.compression.init(),
|
|
22
|
+
this.helmet.getMiddleware(),
|
|
23
|
+
this.logger.getMiddleware(),
|
|
24
|
+
(req, res, next) => this.xss.cleanBody(req, res, next), // prevent losing "this"
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
// Method to apply custom configuration
|
|
28
|
+
configure(config) {
|
|
29
|
+
// Compression
|
|
30
|
+
if (config.compression) {
|
|
31
|
+
this.compression.setOptions(config.compression);
|
|
32
|
+
}
|
|
33
|
+
// Helmet
|
|
34
|
+
if (config.helmet) {
|
|
35
|
+
this.helmet.setOptions(config.helmet);
|
|
36
|
+
}
|
|
37
|
+
// Logger
|
|
38
|
+
if (config.logger) {
|
|
39
|
+
const { format, filePath } = config.logger;
|
|
40
|
+
if (filePath) {
|
|
41
|
+
this.logger.setLogFile(filePath);
|
|
42
|
+
}
|
|
43
|
+
if (format) {
|
|
44
|
+
this.logger.setFormat(format);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// XSS
|
|
48
|
+
if (config.xss) {
|
|
49
|
+
this.xss.setOptions(config.xss);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.default = Protections;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import RequestData from "../utils/RequestData";
|
|
2
|
+
import { Request } from "express";
|
|
3
|
+
export default class Utils {
|
|
4
|
+
private static audio;
|
|
5
|
+
private static video;
|
|
6
|
+
private static file;
|
|
7
|
+
private static date;
|
|
8
|
+
static getAudioDuration(filePath: string): Promise<string>;
|
|
9
|
+
static getVideoDuration(filePath: string): Promise<string>;
|
|
10
|
+
static getFileSize(filePath: string, unit?: "B" | "b" | "KB" | "kb" | "MB" | "mb" | "GB" | "gb"): string;
|
|
11
|
+
static getFileExtension(filePath: string): string;
|
|
12
|
+
static isImageFile(filePath: string): boolean;
|
|
13
|
+
static isVideoFile(filePath: string): boolean;
|
|
14
|
+
static isAudioFile(filePath: string): boolean;
|
|
15
|
+
static isDocumentFile(filePath: string): boolean;
|
|
16
|
+
static isArchiveFile(filePath: string): boolean;
|
|
17
|
+
static today(separator?: string): string;
|
|
18
|
+
static nowTime(separator?: string): string;
|
|
19
|
+
static getRequestIp(req: Request): string;
|
|
20
|
+
static getRequestMethod(req: Request): string;
|
|
21
|
+
static getRequestApi(req: Request): string;
|
|
22
|
+
static getRequestUserAgent(req: Request): string;
|
|
23
|
+
static getReqInfos(req: Request): ReturnType<typeof RequestData.getReqInfos>;
|
|
24
|
+
static shuffleArray<T>(array: T[]): T[];
|
|
25
|
+
static removeDuplicatesFromArray<T>(array: T[]): T[];
|
|
26
|
+
static getRandomElement<T>(array: T[]): T | undefined;
|
|
27
|
+
static flattenArray<T>(array: T[][]): T[];
|
|
28
|
+
static maxFromArray(array: number[]): number | undefined;
|
|
29
|
+
static minFromArray(array: number[]): number | undefined;
|
|
30
|
+
static sumArray(array: number[]): number;
|
|
31
|
+
static averageArray(array: number[]): number | undefined;
|
|
32
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const Audio_1 = __importDefault(require("../utils/Audio"));
|
|
7
|
+
const Vidoe_1 = __importDefault(require("../utils/Vidoe"));
|
|
8
|
+
const Files_1 = __importDefault(require("../utils/Files"));
|
|
9
|
+
const Date_1 = __importDefault(require("../utils/Date"));
|
|
10
|
+
const RequestData_1 = __importDefault(require("../utils/RequestData"));
|
|
11
|
+
const Array_1 = __importDefault(require("../utils/Array"));
|
|
12
|
+
class Utils {
|
|
13
|
+
// Audio Utils
|
|
14
|
+
static getAudioDuration(filePath) {
|
|
15
|
+
return this.audio.getAudioDuration(filePath);
|
|
16
|
+
}
|
|
17
|
+
// Video Utils
|
|
18
|
+
static getVideoDuration(filePath) {
|
|
19
|
+
return this.video.getVideoDuration(filePath);
|
|
20
|
+
}
|
|
21
|
+
// File Utils
|
|
22
|
+
static getFileSize(filePath, unit = "KB") {
|
|
23
|
+
return this.file.getFileSize(filePath, unit);
|
|
24
|
+
}
|
|
25
|
+
static getFileExtension(filePath) {
|
|
26
|
+
return this.file.getFileExtension(filePath);
|
|
27
|
+
}
|
|
28
|
+
static isImageFile(filePath) {
|
|
29
|
+
return this.file.isImageFile(filePath);
|
|
30
|
+
}
|
|
31
|
+
static isVideoFile(filePath) {
|
|
32
|
+
return this.file.isVideoFile(filePath);
|
|
33
|
+
}
|
|
34
|
+
static isAudioFile(filePath) {
|
|
35
|
+
return this.file.isAudioFile(filePath);
|
|
36
|
+
}
|
|
37
|
+
static isDocumentFile(filePath) {
|
|
38
|
+
return this.file.isDocumentFile(filePath);
|
|
39
|
+
}
|
|
40
|
+
static isArchiveFile(filePath) {
|
|
41
|
+
return this.file.isArchiveFile(filePath);
|
|
42
|
+
}
|
|
43
|
+
// Date Utils
|
|
44
|
+
static today(separator = "/") {
|
|
45
|
+
return this.date.today(separator);
|
|
46
|
+
}
|
|
47
|
+
static nowTime(separator = ":") {
|
|
48
|
+
return this.date.nowTime(separator);
|
|
49
|
+
}
|
|
50
|
+
// RequestData Utils
|
|
51
|
+
static getRequestIp(req) {
|
|
52
|
+
return RequestData_1.default.getRequestIp(req);
|
|
53
|
+
}
|
|
54
|
+
static getRequestMethod(req) {
|
|
55
|
+
return RequestData_1.default.getRequestMethod(req);
|
|
56
|
+
}
|
|
57
|
+
static getRequestApi(req) {
|
|
58
|
+
return RequestData_1.default.getRequestApi(req);
|
|
59
|
+
}
|
|
60
|
+
static getRequestUserAgent(req) {
|
|
61
|
+
return RequestData_1.default.getRequestUserAgent(req);
|
|
62
|
+
}
|
|
63
|
+
static getReqInfos(req) {
|
|
64
|
+
return RequestData_1.default.getReqInfos(req);
|
|
65
|
+
}
|
|
66
|
+
// Array Utils
|
|
67
|
+
static shuffleArray(array) {
|
|
68
|
+
return Array_1.default.shuffle(array);
|
|
69
|
+
}
|
|
70
|
+
static removeDuplicatesFromArray(array) {
|
|
71
|
+
return Array_1.default.removeDuplicates(array);
|
|
72
|
+
}
|
|
73
|
+
static getRandomElement(array) {
|
|
74
|
+
return Array_1.default.getRandomElement(array);
|
|
75
|
+
}
|
|
76
|
+
static flattenArray(array) {
|
|
77
|
+
return Array_1.default.flatten(array);
|
|
78
|
+
}
|
|
79
|
+
static maxFromArray(array) {
|
|
80
|
+
return Array_1.default.max(array);
|
|
81
|
+
}
|
|
82
|
+
static minFromArray(array) {
|
|
83
|
+
return Array_1.default.min(array);
|
|
84
|
+
}
|
|
85
|
+
static sumArray(array) {
|
|
86
|
+
return Array_1.default.sum(array);
|
|
87
|
+
}
|
|
88
|
+
static averageArray(array) {
|
|
89
|
+
return Array_1.default.average(array);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
Utils.audio = Audio_1.default;
|
|
93
|
+
Utils.video = Vidoe_1.default;
|
|
94
|
+
Utils.file = Files_1.default;
|
|
95
|
+
Utils.date = Date_1.default;
|
|
96
|
+
exports.default = Utils;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default class InitProj {
|
|
2
|
+
static initBackendProject(TypeScript?: boolean, projectPath?: string): void;
|
|
3
|
+
private static createIndexFiles;
|
|
4
|
+
static installPackages(TypeScript?: boolean, projectPath?: string): void;
|
|
5
|
+
private static createTsConfig;
|
|
6
|
+
private static updatePackageJson;
|
|
7
|
+
static createFullProject(TypeScript?: boolean, projectPath?: string): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
class InitProj {
|
|
10
|
+
// Initialize a backend project structure
|
|
11
|
+
static initBackendProject(TypeScript = false, projectPath = process.cwd()) {
|
|
12
|
+
const language = TypeScript
|
|
13
|
+
? "typescript"
|
|
14
|
+
: "javascript";
|
|
15
|
+
try {
|
|
16
|
+
// Main src directory
|
|
17
|
+
const srcPath = path_1.default.join(projectPath, "src");
|
|
18
|
+
// Backend folders structure
|
|
19
|
+
const folders = [
|
|
20
|
+
"src",
|
|
21
|
+
"src/controllers",
|
|
22
|
+
"src/models",
|
|
23
|
+
"src/routes",
|
|
24
|
+
"src/middlewares",
|
|
25
|
+
"src/utils",
|
|
26
|
+
];
|
|
27
|
+
// Create all folders
|
|
28
|
+
folders.forEach((folder) => {
|
|
29
|
+
const folderPath = path_1.default.join(projectPath, folder);
|
|
30
|
+
if (!fs_1.default.existsSync(folderPath)) {
|
|
31
|
+
fs_1.default.mkdirSync(folderPath, { recursive: true });
|
|
32
|
+
console.log(`✓ Created: ${folder}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.log(`🩸 Already exists: ${folder}`);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// Create index files for each folder
|
|
39
|
+
this.createIndexFiles(projectPath, language);
|
|
40
|
+
console.log(`\n✅ Backend project (${language.toUpperCase()}) created successfully!`);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
throw new Error(`Failed to initialize project: ${error.message}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Create index files in main folders
|
|
47
|
+
static createIndexFiles(projectPath, language) {
|
|
48
|
+
const fileExtension = language === "typescript" ? "ts" : "js";
|
|
49
|
+
// TypeScript version
|
|
50
|
+
const tsContent = `import express from "express";
|
|
51
|
+
|
|
52
|
+
const app = express();
|
|
53
|
+
app.use(express.json());
|
|
54
|
+
|
|
55
|
+
app.get("/", (req, res) => {
|
|
56
|
+
res.json({ message: "Hello from Express + TypeScript!" });
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
app.listen(3000, () => console.log("Server running on port 3000"));
|
|
60
|
+
`;
|
|
61
|
+
// JavaScript version
|
|
62
|
+
const jsContent = `const express = require("express");
|
|
63
|
+
|
|
64
|
+
const app = express();
|
|
65
|
+
app.use(express.json());
|
|
66
|
+
|
|
67
|
+
app.get("/", (req, res) => {
|
|
68
|
+
res.json({ message: "Hello from Express + JavaScript!" });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
app.listen(3000, () => console.log("Server running on port 3000"));
|
|
72
|
+
`;
|
|
73
|
+
const content = language === "typescript" ? tsContent : jsContent;
|
|
74
|
+
fs_1.default.writeFileSync(path_1.default.join(projectPath, "src", `index.${fileExtension}`), content);
|
|
75
|
+
}
|
|
76
|
+
// Install essential packages
|
|
77
|
+
static installPackages(TypeScript = false, projectPath = process.cwd()) {
|
|
78
|
+
try {
|
|
79
|
+
console.log("\n📦 Installing packages...\n");
|
|
80
|
+
// Core packages for both languages
|
|
81
|
+
const corePackages = [
|
|
82
|
+
"express",
|
|
83
|
+
"compression@1.7.4",
|
|
84
|
+
"helmet",
|
|
85
|
+
"morgan",
|
|
86
|
+
"xss",
|
|
87
|
+
"dotenv",
|
|
88
|
+
"cors",
|
|
89
|
+
];
|
|
90
|
+
// TypeScript specific packages
|
|
91
|
+
const tsDevPackages = [
|
|
92
|
+
"@types/express",
|
|
93
|
+
"@types/compression",
|
|
94
|
+
"@types/morgan",
|
|
95
|
+
"@types/cors",
|
|
96
|
+
"@types/node",
|
|
97
|
+
"typescript",
|
|
98
|
+
"ts-node",
|
|
99
|
+
"ts-node-dev",
|
|
100
|
+
];
|
|
101
|
+
// Install core packages
|
|
102
|
+
console.log("Installing core packages...");
|
|
103
|
+
(0, child_process_1.execSync)(`npm install ${corePackages.join(" ")}`, {
|
|
104
|
+
cwd: projectPath,
|
|
105
|
+
stdio: "inherit",
|
|
106
|
+
});
|
|
107
|
+
// Install TypeScript packages if needed
|
|
108
|
+
if (TypeScript) {
|
|
109
|
+
console.log("\nInstalling TypeScript packages...");
|
|
110
|
+
(0, child_process_1.execSync)(`npm install --save-dev ${tsDevPackages.join(" ")}`, {
|
|
111
|
+
cwd: projectPath,
|
|
112
|
+
stdio: "inherit",
|
|
113
|
+
});
|
|
114
|
+
// Create tsconfig.json
|
|
115
|
+
this.createTsConfig(projectPath);
|
|
116
|
+
}
|
|
117
|
+
// Update package.json
|
|
118
|
+
this.updatePackageJson(TypeScript, projectPath);
|
|
119
|
+
console.log("\n✅ All packages installed successfully!");
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
throw new Error(`Failed to install packages: ${error.message}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Create tsconfig.json for TypeScript projects
|
|
126
|
+
static createTsConfig(projectPath) {
|
|
127
|
+
const tsConfig = {
|
|
128
|
+
compilerOptions: {
|
|
129
|
+
target: "ES2020",
|
|
130
|
+
module: "commonjs",
|
|
131
|
+
lib: ["ES2020"],
|
|
132
|
+
outDir: "./dist",
|
|
133
|
+
rootDir: "./src",
|
|
134
|
+
strict: true,
|
|
135
|
+
esModuleInterop: true,
|
|
136
|
+
skipLibCheck: true,
|
|
137
|
+
forceConsistentCasingInFileNames: true,
|
|
138
|
+
resolveJsonModule: true,
|
|
139
|
+
moduleResolution: "node",
|
|
140
|
+
},
|
|
141
|
+
include: ["src/**/*"],
|
|
142
|
+
exclude: ["node_modules", "dist"],
|
|
143
|
+
};
|
|
144
|
+
fs_1.default.writeFileSync(path_1.default.join(projectPath, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
|
|
145
|
+
console.log("✓ Created tsconfig.json");
|
|
146
|
+
}
|
|
147
|
+
// Update package.json based on project type
|
|
148
|
+
static updatePackageJson(TypeScript, projectPath) {
|
|
149
|
+
const packageJsonPath = path_1.default.join(projectPath, "package.json");
|
|
150
|
+
if (!fs_1.default.existsSync(packageJsonPath)) {
|
|
151
|
+
console.log("⚠ package.json not found, skipping update");
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, "utf-8"));
|
|
156
|
+
if (TypeScript) {
|
|
157
|
+
// TypeScript project - remove type field or set to commonjs
|
|
158
|
+
delete packageJson.type;
|
|
159
|
+
// Add TypeScript scripts
|
|
160
|
+
packageJson.scripts = {
|
|
161
|
+
...packageJson.scripts,
|
|
162
|
+
dev: "ts-node-dev --respawn --transpile-only src/index.ts",
|
|
163
|
+
build: "tsc",
|
|
164
|
+
start: "node dist/index.js",
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
// JavaScript project - set type to module (ES6)
|
|
169
|
+
packageJson.type = "module";
|
|
170
|
+
// Add JavaScript scripts
|
|
171
|
+
packageJson.scripts = {
|
|
172
|
+
...packageJson.scripts,
|
|
173
|
+
dev: "node src/index.js",
|
|
174
|
+
start: "node src/index.js",
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
fs_1.default.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
178
|
+
console.log(`✓ Updated package.json (type: ${TypeScript ? "TypeScript (no type field)" : "module"})`);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
console.error("❌ Failed to update package.json:", error.message);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Create complete project (structure + packages)
|
|
185
|
+
static createFullProject(TypeScript = false, projectPath = process.cwd()) {
|
|
186
|
+
console.log("🚀 Creating full backend project...\n");
|
|
187
|
+
// Create structure
|
|
188
|
+
this.initBackendProject(TypeScript, projectPath);
|
|
189
|
+
// Install packages
|
|
190
|
+
this.installPackages(TypeScript, projectPath);
|
|
191
|
+
console.log("\n🎉 Project setup completed!");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
exports.default = InitProj;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const child_process_1 = require("child_process");
|
|
4
|
+
class ControlSecondaryLibraries {
|
|
5
|
+
// Install audio library using npm
|
|
6
|
+
static installAudioLibrary() {
|
|
7
|
+
try {
|
|
8
|
+
(0, child_process_1.execSync)("npm install music-metadata", { stdio: "inherit" });
|
|
9
|
+
console.log("✓ Audio library installed successfully.");
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
throw new Error(`Failed to install audio library: ${error.message}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
// Install video library using npm
|
|
16
|
+
static installVideoLibrary() {
|
|
17
|
+
try {
|
|
18
|
+
(0, child_process_1.execSync)("npm install get-video-duration", { stdio: "inherit" });
|
|
19
|
+
console.log("✓ Video library installed successfully.");
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new Error(`Failed to install video library: ${error.message}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.default = ControlSecondaryLibraries;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface InputCompressionOptions {
|
|
2
|
+
threshold?: number;
|
|
3
|
+
level?: number;
|
|
4
|
+
memLevel?: number;
|
|
5
|
+
chunkSize?: number;
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
}
|
|
8
|
+
export default class Compression {
|
|
9
|
+
private options;
|
|
10
|
+
constructor(options?: InputCompressionOptions);
|
|
11
|
+
init(): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
|
|
12
|
+
setOptions(options: InputCompressionOptions): void;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const compression_1 = __importDefault(require("compression"));
|
|
7
|
+
class Compression {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
// Extract zlib-specific options
|
|
10
|
+
const { level, memLevel, chunkSize, ...restOptions } = options;
|
|
11
|
+
// Default compression options and user overrides
|
|
12
|
+
this.options = {
|
|
13
|
+
// Minimum response size in bytes to compress
|
|
14
|
+
threshold: 1024, // 1KB
|
|
15
|
+
zlib: {
|
|
16
|
+
// Compression level (0-9)
|
|
17
|
+
level: level ?? 6, // Default is 6
|
|
18
|
+
// Memory level (1-9)
|
|
19
|
+
memLevel: memLevel ?? 8, // Default is 8
|
|
20
|
+
// Size of the buffer for compression
|
|
21
|
+
chunkSize: chunkSize ?? 16384, // 16KB
|
|
22
|
+
},
|
|
23
|
+
// If user provides options, they will override defaults
|
|
24
|
+
...restOptions,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// Middleware to apply compression
|
|
28
|
+
init() {
|
|
29
|
+
return (0, compression_1.default)(this.options);
|
|
30
|
+
}
|
|
31
|
+
// Method to update compression options
|
|
32
|
+
setOptions(options) {
|
|
33
|
+
// Extract zlib-specific options
|
|
34
|
+
const { level, memLevel, chunkSize, ...restOptions } = options;
|
|
35
|
+
// Build updated zlib options
|
|
36
|
+
const zlibOptions = { ...this.options.zlib };
|
|
37
|
+
if (level !== undefined)
|
|
38
|
+
zlibOptions.level = level;
|
|
39
|
+
if (memLevel !== undefined)
|
|
40
|
+
zlibOptions.memLevel = memLevel;
|
|
41
|
+
if (chunkSize !== undefined)
|
|
42
|
+
zlibOptions.chunkSize = chunkSize;
|
|
43
|
+
// Merge new options with existing ones
|
|
44
|
+
this.options = {
|
|
45
|
+
...this.options,
|
|
46
|
+
...restOptions,
|
|
47
|
+
zlib: zlibOptions,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.default = Compression;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export default class HelmetProtection {
|
|
2
|
+
private options;
|
|
3
|
+
constructor(options?: object);
|
|
4
|
+
setOptions(options: object): void;
|
|
5
|
+
getMiddleware(): (req: import("node:http").IncomingMessage, res: import("node:http").ServerResponse, next: (err?: unknown) => void) => void;
|
|
6
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const helmet_1 = __importDefault(require("helmet"));
|
|
7
|
+
class HelmetProtection {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
// Default Helmet options
|
|
10
|
+
this.options = {
|
|
11
|
+
frameguard: { action: "sameorigin" },
|
|
12
|
+
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
|
|
13
|
+
referrerPolicy: { policy: "no-referrer" },
|
|
14
|
+
noSniff: true,
|
|
15
|
+
ieNoOpen: true,
|
|
16
|
+
hidePoweredBy: true,
|
|
17
|
+
crossOriginResourcePolicy: { policy: "cross-origin" },
|
|
18
|
+
crossOriginOpenerPolicy: { policy: "same-origin" },
|
|
19
|
+
contentSecurityPolicy: {
|
|
20
|
+
directives: {
|
|
21
|
+
"default-src": ["'self'"],
|
|
22
|
+
"img-src": ["'self'", "data:", process.env.FRONTEND_URL],
|
|
23
|
+
"media-src": ["'self'", "data:", process.env.FRONTEND_URL],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
...options, // If user provides options, they will override defaults
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// Method to update Helmet options
|
|
30
|
+
setOptions(options) {
|
|
31
|
+
this.options = { ...this.options, ...options }; // Merge new options with existing ones
|
|
32
|
+
}
|
|
33
|
+
// Middleware to apply Helmet protection
|
|
34
|
+
getMiddleware() {
|
|
35
|
+
return (0, helmet_1.default)(this.options);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.default = HelmetProtection;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export default class Logger {
|
|
2
|
+
private format;
|
|
3
|
+
private stream;
|
|
4
|
+
constructor(format: string);
|
|
5
|
+
constructor(format: string, filePath: string);
|
|
6
|
+
getMiddleware(): (req: import("node:http").IncomingMessage, res: import("node:http").ServerResponse<import("node:http").IncomingMessage>, callback: (err?: Error) => void) => void;
|
|
7
|
+
setFormat(format: string): void;
|
|
8
|
+
setLogFile(filePath: string): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const morgan_1 = __importDefault(require("morgan"));
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
class Logger {
|
|
10
|
+
constructor(format, filePath) {
|
|
11
|
+
this.format = format;
|
|
12
|
+
if (filePath) {
|
|
13
|
+
// convert path to full path
|
|
14
|
+
const fullPath = path_1.default.resolve(filePath);
|
|
15
|
+
// create a write stream (in append mode)
|
|
16
|
+
const accessLogStream = fs_1.default.createWriteStream(fullPath, { flags: "a" });
|
|
17
|
+
this.stream = {
|
|
18
|
+
write: (message) => {
|
|
19
|
+
accessLogStream.write(message);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
// Default to console
|
|
25
|
+
this.stream = {
|
|
26
|
+
write: (message) => {
|
|
27
|
+
process.stdout.write(message);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Middleware to log requests
|
|
33
|
+
getMiddleware() {
|
|
34
|
+
return (0, morgan_1.default)(this.format, { stream: this.stream });
|
|
35
|
+
}
|
|
36
|
+
// Method to update log format
|
|
37
|
+
setFormat(format) {
|
|
38
|
+
this.format = format;
|
|
39
|
+
}
|
|
40
|
+
// Method to update log file path
|
|
41
|
+
setLogFile(filePath) {
|
|
42
|
+
const fullPath = path_1.default.resolve(filePath);
|
|
43
|
+
const accessLogStream = fs_1.default.createWriteStream(fullPath, { flags: "a" });
|
|
44
|
+
this.stream = {
|
|
45
|
+
write: (message) => {
|
|
46
|
+
accessLogStream.write(message);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.default = Logger;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IFilterXSSOptions } from "xss";
|
|
2
|
+
import { Request, Response, NextFunction } from "express";
|
|
3
|
+
export default class XSSProtection {
|
|
4
|
+
private filter;
|
|
5
|
+
constructor(options?: IFilterXSSOptions);
|
|
6
|
+
cleanBody: (req: Request, res: Response, next: NextFunction) => void;
|
|
7
|
+
cleanText(text: string): string;
|
|
8
|
+
setOptions(options?: IFilterXSSOptions): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const xss_1 = __importStar(require("xss"));
|
|
37
|
+
class XSSProtection {
|
|
38
|
+
constructor(options = {}) {
|
|
39
|
+
// Middleware to clean request body
|
|
40
|
+
this.cleanBody = (req, res, next) => {
|
|
41
|
+
if (req.body) {
|
|
42
|
+
for (const key in req.body) {
|
|
43
|
+
// Only clean string fields
|
|
44
|
+
if (typeof req.body[key] === "string") {
|
|
45
|
+
req.body[key] = (0, xss_1.default)(req.body[key]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
next();
|
|
50
|
+
};
|
|
51
|
+
// Default XSS filter options can be set here
|
|
52
|
+
this.filter = new xss_1.FilterXSS(options);
|
|
53
|
+
}
|
|
54
|
+
// Method to clean arbitrary text
|
|
55
|
+
cleanText(text) {
|
|
56
|
+
return this.filter.process(text);
|
|
57
|
+
}
|
|
58
|
+
// Method to update XSS filter options
|
|
59
|
+
setOptions(options = {}) {
|
|
60
|
+
this.filter = new xss_1.FilterXSS(options);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.default = XSSProtection;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default class ArrayUtils {
|
|
2
|
+
static shuffle<T>(array: T[]): T[];
|
|
3
|
+
static removeDuplicates<T>(array: T[]): T[];
|
|
4
|
+
static getRandomElement<T>(array: T[]): T | undefined;
|
|
5
|
+
static flatten<T>(array: T[][]): T[];
|
|
6
|
+
static max(array: number[]): number | undefined;
|
|
7
|
+
static min(array: number[]): number | undefined;
|
|
8
|
+
static sum(array: number[]): number;
|
|
9
|
+
static average(array: number[]): number | undefined;
|
|
10
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class ArrayUtils {
|
|
4
|
+
// Randomly rearranging the array elements
|
|
5
|
+
static shuffle(array) {
|
|
6
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
7
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
8
|
+
[array[i], array[j]] = [array[j], array[i]];
|
|
9
|
+
}
|
|
10
|
+
return array;
|
|
11
|
+
}
|
|
12
|
+
// Remove duplicate elements from the array
|
|
13
|
+
static removeDuplicates(array) {
|
|
14
|
+
return [...new Set(array)];
|
|
15
|
+
}
|
|
16
|
+
// Get a random element from the array
|
|
17
|
+
static getRandomElement(array) {
|
|
18
|
+
if (array.length === 0)
|
|
19
|
+
return undefined;
|
|
20
|
+
const index = Math.floor(Math.random() * array.length);
|
|
21
|
+
return array[index];
|
|
22
|
+
}
|
|
23
|
+
// Flatten a nested array
|
|
24
|
+
static flatten(array) {
|
|
25
|
+
return array.reduce((acc, val) => acc.concat(val), []);
|
|
26
|
+
}
|
|
27
|
+
// Get the maximum value in a numeric array
|
|
28
|
+
static max(array) {
|
|
29
|
+
if (array.length === 0)
|
|
30
|
+
return undefined;
|
|
31
|
+
return Math.max(...array);
|
|
32
|
+
}
|
|
33
|
+
// Get the minimum value in a numeric array
|
|
34
|
+
static min(array) {
|
|
35
|
+
if (array.length === 0)
|
|
36
|
+
return undefined;
|
|
37
|
+
return Math.min(...array);
|
|
38
|
+
}
|
|
39
|
+
// Calculate the sum of a numeric array
|
|
40
|
+
static sum(array) {
|
|
41
|
+
return array.reduce((acc, val) => acc + val, 0);
|
|
42
|
+
}
|
|
43
|
+
// Calculate the average of a numeric array
|
|
44
|
+
static average(array) {
|
|
45
|
+
if (array.length === 0)
|
|
46
|
+
return undefined;
|
|
47
|
+
const sum = this.sum(array);
|
|
48
|
+
return sum / array.length;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.default = ArrayUtils;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const musicMetadata = __importStar(require("music-metadata"));
|
|
37
|
+
class AudioUtils {
|
|
38
|
+
// Calculate the duration of the sound in seconds
|
|
39
|
+
static async calculateAudioDuration(filePath) {
|
|
40
|
+
try {
|
|
41
|
+
const metadata = await musicMetadata.parseFile(filePath);
|
|
42
|
+
return metadata.format.duration ?? 0;
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
console.error("Error reading audio metadata:", err.message);
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Length format as hh:mm:ss
|
|
50
|
+
static formatDuration(seconds) {
|
|
51
|
+
seconds = Math.floor(seconds);
|
|
52
|
+
const hrs = Math.floor(seconds / 3600);
|
|
53
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
54
|
+
const secs = seconds % 60;
|
|
55
|
+
const hh = hrs > 0 ? String(hrs).padStart(2, "0") + ":" : "";
|
|
56
|
+
const mm = String(minutes).padStart(2, "0");
|
|
57
|
+
const ss = String(secs).padStart(2, "0");
|
|
58
|
+
return hh + mm + ":" + ss;
|
|
59
|
+
}
|
|
60
|
+
// Verify supported file types
|
|
61
|
+
static async verifyFileType(filePath) {
|
|
62
|
+
if (!filePath.endsWith(".mp3") && !filePath.endsWith(".wav")) {
|
|
63
|
+
console.warn("File type not supported.");
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
// Get formatted duration
|
|
69
|
+
static async getAudioDuration(filePath) {
|
|
70
|
+
if (!(await this.verifyFileType(filePath))) {
|
|
71
|
+
return "00:00";
|
|
72
|
+
}
|
|
73
|
+
const seconds = await this.calculateAudioDuration(filePath);
|
|
74
|
+
return this.formatDuration(seconds);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.default = AudioUtils;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class DateUtils {
|
|
4
|
+
// Get current date in YYYY/MM/DD or other format
|
|
5
|
+
static today(separator = "/") {
|
|
6
|
+
const date = new Date();
|
|
7
|
+
const year = date.getFullYear();
|
|
8
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
9
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
10
|
+
return `${year}${separator}${month}${separator}${day}`;
|
|
11
|
+
}
|
|
12
|
+
// Get current time in HH:MM:SS or other format
|
|
13
|
+
static nowTime(separator = ":") {
|
|
14
|
+
const date = new Date();
|
|
15
|
+
const hours = `${date.getHours() < 12 ? "AM" : "PM"} ${String(date.getHours() % 12 || 12).padStart(2, "0")}`;
|
|
16
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
17
|
+
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
18
|
+
return `${hours}${separator}${minutes}${separator}${seconds}`;
|
|
19
|
+
}
|
|
20
|
+
;
|
|
21
|
+
}
|
|
22
|
+
exports.default = DateUtils;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export default class FileUtils {
|
|
2
|
+
private static readonly imageExtensions;
|
|
3
|
+
private static readonly videoExtensions;
|
|
4
|
+
private static readonly audioExtensions;
|
|
5
|
+
private static readonly documentExtensions;
|
|
6
|
+
private static readonly archiveExtensions;
|
|
7
|
+
private static getRawSize;
|
|
8
|
+
static getFileSize(filePath: string, unit?: "B" | "b" | "KB" | "kb" | "MB" | "mb" | "GB" | "gb"): string;
|
|
9
|
+
static getFileExtension(filePath: string): string;
|
|
10
|
+
static isImageFile(filePath: string): boolean;
|
|
11
|
+
static isVideoFile(filePath: string): boolean;
|
|
12
|
+
static isAudioFile(filePath: string): boolean;
|
|
13
|
+
static isDocumentFile(filePath: string): boolean;
|
|
14
|
+
static isArchiveFile(filePath: string): boolean;
|
|
15
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
class FileUtils {
|
|
9
|
+
// Get raw file size in bytes
|
|
10
|
+
static getRawSize(filePath) {
|
|
11
|
+
try {
|
|
12
|
+
const stats = fs_1.default.statSync(filePath);
|
|
13
|
+
return stats.size;
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
throw new Error(`Error getting file size: ${err.message}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// Get size in defrined unit
|
|
20
|
+
static getFileSize(filePath, unit = "KB") {
|
|
21
|
+
const bytes = this.getRawSize(filePath);
|
|
22
|
+
switch (unit) {
|
|
23
|
+
case "B":
|
|
24
|
+
case "b":
|
|
25
|
+
return `${bytes} B`;
|
|
26
|
+
case "KB":
|
|
27
|
+
case "kb":
|
|
28
|
+
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
29
|
+
case "MB":
|
|
30
|
+
case "mb":
|
|
31
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
32
|
+
case "GB":
|
|
33
|
+
case "gb":
|
|
34
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
|
35
|
+
default:
|
|
36
|
+
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Get file extension
|
|
40
|
+
static getFileExtension(filePath) {
|
|
41
|
+
return path_1.default.extname(filePath).slice(1);
|
|
42
|
+
}
|
|
43
|
+
// Check if file is an image
|
|
44
|
+
static isImageFile(filePath) {
|
|
45
|
+
const ext = this.getFileExtension(filePath).toLowerCase();
|
|
46
|
+
return this.imageExtensions.includes(ext);
|
|
47
|
+
}
|
|
48
|
+
// Check if file is a video
|
|
49
|
+
static isVideoFile(filePath) {
|
|
50
|
+
const ext = this.getFileExtension(filePath).toLowerCase();
|
|
51
|
+
return this.videoExtensions.includes(ext);
|
|
52
|
+
}
|
|
53
|
+
// Check if file is an audio
|
|
54
|
+
static isAudioFile(filePath) {
|
|
55
|
+
const ext = this.getFileExtension(filePath).toLowerCase();
|
|
56
|
+
return this.audioExtensions.includes(ext);
|
|
57
|
+
}
|
|
58
|
+
// Check if file is a document
|
|
59
|
+
static isDocumentFile(filePath) {
|
|
60
|
+
const ext = this.getFileExtension(filePath).toLowerCase();
|
|
61
|
+
return this.documentExtensions.includes(ext);
|
|
62
|
+
}
|
|
63
|
+
// Check if file is a compressed archive
|
|
64
|
+
static isArchiveFile(filePath) {
|
|
65
|
+
const ext = this.getFileExtension(filePath).toLowerCase();
|
|
66
|
+
return this.archiveExtensions.includes(ext);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Supported image extensions
|
|
70
|
+
FileUtils.imageExtensions = [
|
|
71
|
+
"jpg",
|
|
72
|
+
"jpeg",
|
|
73
|
+
"png",
|
|
74
|
+
"gif",
|
|
75
|
+
"bmp",
|
|
76
|
+
"webp",
|
|
77
|
+
"tiff",
|
|
78
|
+
"svg",
|
|
79
|
+
];
|
|
80
|
+
// Supported video extensions
|
|
81
|
+
FileUtils.videoExtensions = [
|
|
82
|
+
"mp4",
|
|
83
|
+
"avi",
|
|
84
|
+
"mov",
|
|
85
|
+
"wmv",
|
|
86
|
+
"flv",
|
|
87
|
+
"mkv",
|
|
88
|
+
"webm",
|
|
89
|
+
];
|
|
90
|
+
// Supported audio extensions
|
|
91
|
+
FileUtils.audioExtensions = [
|
|
92
|
+
"mp3",
|
|
93
|
+
"wav",
|
|
94
|
+
"flac",
|
|
95
|
+
"aac",
|
|
96
|
+
"ogg",
|
|
97
|
+
"m4a",
|
|
98
|
+
];
|
|
99
|
+
// Supported document extensions
|
|
100
|
+
FileUtils.documentExtensions = [
|
|
101
|
+
"pdf",
|
|
102
|
+
"doc",
|
|
103
|
+
"docx",
|
|
104
|
+
"xls",
|
|
105
|
+
"xlsx",
|
|
106
|
+
"ppt",
|
|
107
|
+
"pptx",
|
|
108
|
+
"txt",
|
|
109
|
+
"rtf",
|
|
110
|
+
];
|
|
111
|
+
// Supported archive extensions
|
|
112
|
+
FileUtils.archiveExtensions = [
|
|
113
|
+
"zip",
|
|
114
|
+
"rar",
|
|
115
|
+
"7z",
|
|
116
|
+
"tar",
|
|
117
|
+
"gz",
|
|
118
|
+
"bz2",
|
|
119
|
+
];
|
|
120
|
+
exports.default = FileUtils;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Request } from "express";
|
|
2
|
+
interface RequestInfo {
|
|
3
|
+
ip: string;
|
|
4
|
+
method: string;
|
|
5
|
+
api: string;
|
|
6
|
+
userAgent: string;
|
|
7
|
+
}
|
|
8
|
+
export default class RequestData {
|
|
9
|
+
static getRequestIp(req: Request): string;
|
|
10
|
+
static getRequestMethod(req: Request): string;
|
|
11
|
+
static getRequestApi(req: Request): string;
|
|
12
|
+
static getRequestUserAgent(req: Request): string;
|
|
13
|
+
static getReqInfos(req: Request): RequestInfo;
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class RequestData {
|
|
4
|
+
static getRequestIp(req) {
|
|
5
|
+
const forwarded = req.headers["x-forwarded-for"];
|
|
6
|
+
const forwardedIp = Array.isArray(forwarded)
|
|
7
|
+
? forwarded[0]
|
|
8
|
+
: forwarded?.split(",")[0]?.trim();
|
|
9
|
+
return (forwardedIp ||
|
|
10
|
+
req.socket.remoteAddress?.replace(/^::ffff:/, "") ||
|
|
11
|
+
"Unknown");
|
|
12
|
+
}
|
|
13
|
+
static getRequestMethod(req) {
|
|
14
|
+
return req.method;
|
|
15
|
+
}
|
|
16
|
+
static getRequestApi(req) {
|
|
17
|
+
return req.originalUrl;
|
|
18
|
+
}
|
|
19
|
+
static getRequestUserAgent(req) {
|
|
20
|
+
return req.headers["user-agent"] || "Unknown";
|
|
21
|
+
}
|
|
22
|
+
static getReqInfos(req) {
|
|
23
|
+
const ip = this.getRequestIp(req);
|
|
24
|
+
const method = this.getRequestMethod(req);
|
|
25
|
+
const api = this.getRequestApi(req);
|
|
26
|
+
const userAgent = this.getRequestUserAgent(req);
|
|
27
|
+
return { ip, method, api, userAgent };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.default = RequestData;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const get_video_duration_1 = require("get-video-duration");
|
|
4
|
+
class VideoUtils {
|
|
5
|
+
// Format duration as hh:mm:ss
|
|
6
|
+
static formatDuration(seconds) {
|
|
7
|
+
seconds = Math.floor(seconds);
|
|
8
|
+
const hrs = Math.floor(seconds / 3600);
|
|
9
|
+
const mins = Math.floor((seconds % 3600) / 60);
|
|
10
|
+
const secs = seconds % 60;
|
|
11
|
+
const hh = hrs > 0 ? String(hrs).padStart(2, "0") + ":" : "";
|
|
12
|
+
const mm = String(mins).padStart(2, "0");
|
|
13
|
+
const ss = String(secs).padStart(2, "0");
|
|
14
|
+
return hh + mm + ":" + ss;
|
|
15
|
+
}
|
|
16
|
+
// Get formatted duration
|
|
17
|
+
static async getVideoDuration(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
const seconds = await (0, get_video_duration_1.getVideoDurationInSeconds)(filePath);
|
|
20
|
+
return this.formatDuration(seconds);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
console.error("Error reading video metadata:", err.message);
|
|
24
|
+
return "00:00";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.default = VideoUtils;
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gg-tools-kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A Node.js toolkit for utilities and protections",
|
|
5
|
+
"main": "dist/GGToolsKit.js",
|
|
6
|
+
"types": "dist/GGToolsKit.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "ts-node-dev --respawn --transpile-only src/GGToolsKit.ts",
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"start": "node dist/GGToolsKit.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [],
|
|
13
|
+
"author": "MohenedGG",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"type": "commonjs",
|
|
16
|
+
"files": ["dist"],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"compression": "^1.7.4",
|
|
19
|
+
"cookie-parser": "^1.4.7",
|
|
20
|
+
"cors": "^2.8.5",
|
|
21
|
+
"dotenv": "^17.2.3",
|
|
22
|
+
"express": "^5.2.1",
|
|
23
|
+
"express-compression": "^1.0.2",
|
|
24
|
+
"get-video-duration": "^5.0.0",
|
|
25
|
+
"helmet": "^8.1.0",
|
|
26
|
+
"hpp": "^0.2.3",
|
|
27
|
+
"morgan": "^1.10.1",
|
|
28
|
+
"music-metadata": "^11.10.3",
|
|
29
|
+
"xss": "^1.0.15"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/compression": "^1.8.1",
|
|
33
|
+
"@types/express": "^5.0.6",
|
|
34
|
+
"@types/helmet": "^0.0.48",
|
|
35
|
+
"@types/morgan": "^1.9.10",
|
|
36
|
+
"@types/node": "^25.0.0",
|
|
37
|
+
"ts-node": "^10.9.2",
|
|
38
|
+
"ts-node-dev": "^2.0.0",
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
|
+
}
|
|
41
|
+
}
|