kist 0.0.0 → 0.1.30
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/LICENSE +21 -0
- package/README.md +298 -3
- package/js/actions/CoreActions.d.ts +6 -0
- package/js/actions/CoreActions.js +47 -0
- package/js/actions/DirectoryCleanAction/DirectoryCleanAction.d.ts +36 -0
- package/js/actions/DirectoryCleanAction/DirectoryCleanAction.js +123 -0
- package/js/actions/DirectoryCleanAction/index.d.ts +2 -0
- package/js/actions/DirectoryCleanAction/index.js +8 -0
- package/js/actions/DirectoryCopyAction/DirectoryCopyAction.d.ts +42 -0
- package/js/actions/DirectoryCopyAction/DirectoryCopyAction.js +118 -0
- package/js/actions/DirectoryCopyAction/index.d.ts +2 -0
- package/js/actions/DirectoryCopyAction/index.js +8 -0
- package/js/actions/DirectoryCreateAction/DirectoryCreateAction.d.ts +30 -0
- package/js/actions/DirectoryCreateAction/DirectoryCreateAction.js +85 -0
- package/js/actions/DirectoryCreateAction/index.d.ts +2 -0
- package/js/actions/DirectoryCreateAction/index.js +8 -0
- package/js/actions/DocumentationAction/DocumentationAction.d.ts +23 -0
- package/js/actions/DocumentationAction/DocumentationAction.js +88 -0
- package/js/actions/DocumentationAction/index.d.ts +2 -0
- package/js/actions/DocumentationAction/index.js +8 -0
- package/js/actions/FileCopyAction/FileCopyAction.d.ts +42 -0
- package/js/actions/FileCopyAction/FileCopyAction.js +127 -0
- package/js/actions/FileCopyAction/index.d.ts +2 -0
- package/js/actions/FileCopyAction/index.js +8 -0
- package/js/actions/FileRenameAction/FileRenameAction.d.ts +30 -0
- package/js/actions/FileRenameAction/FileRenameAction.js +84 -0
- package/js/actions/FileRenameAction/index.d.ts +2 -0
- package/js/actions/FileRenameAction/index.js +8 -0
- package/js/actions/JavaScriptMinifyAction/JavaScriptMinifyAction.d.ts +31 -0
- package/js/actions/JavaScriptMinifyAction/JavaScriptMinifyAction.js +98 -0
- package/js/actions/JavaScriptMinifyAction/index.d.ts +2 -0
- package/js/actions/JavaScriptMinifyAction/index.js +8 -0
- package/js/actions/JavaScriptMinifyAction/terser.config.d.ts +27 -0
- package/js/actions/JavaScriptMinifyAction/terser.config.js +119 -0
- package/js/actions/LintAction/LintAction.d.ts +17 -0
- package/js/actions/LintAction/LintAction.js +63 -0
- package/js/actions/LintAction/index.d.ts +2 -0
- package/js/actions/LintAction/index.js +8 -0
- package/js/actions/PackageManagerAction/PackageManagerAction.d.ts +57 -0
- package/js/actions/PackageManagerAction/PackageManagerAction.js +161 -0
- package/js/actions/PackageManagerAction/index.d.ts +2 -0
- package/js/actions/PackageManagerAction/index.js +8 -0
- package/js/actions/PackageManagerAction/package.config.d.ts +16 -0
- package/js/actions/PackageManagerAction/package.config.js +91 -0
- package/js/actions/StyleProcessingAction/StyleProcessingAction.d.ts +34 -0
- package/js/actions/StyleProcessingAction/StyleProcessingAction.js +164 -0
- package/js/actions/StyleProcessingAction/index.d.ts +2 -0
- package/js/actions/StyleProcessingAction/index.js +8 -0
- package/js/actions/StyleProcessingAction/postcss.config.compressed.d.ts +10 -0
- package/js/actions/StyleProcessingAction/postcss.config.compressed.js +31 -0
- package/js/actions/StyleProcessingAction/postcss.config.expanded.d.ts +16 -0
- package/js/actions/StyleProcessingAction/postcss.config.expanded.js +45 -0
- package/js/actions/SvgPackagerAction/SvgPackagerAction.d.ts +68 -0
- package/js/actions/SvgPackagerAction/SvgPackagerAction.js +186 -0
- package/js/actions/SvgPackagerAction/index.d.ts +2 -0
- package/js/actions/SvgPackagerAction/index.js +8 -0
- package/js/actions/SvgReaderAction/SvgReaderAction.d.ts +32 -0
- package/js/actions/SvgReaderAction/SvgReaderAction.js +87 -0
- package/js/actions/SvgReaderAction/index.d.ts +2 -0
- package/js/actions/SvgReaderAction/index.js +8 -0
- package/js/actions/SvgSpriteAction/SvgSpriteAction.d.ts +37 -0
- package/js/actions/SvgSpriteAction/SvgSpriteAction.js +114 -0
- package/js/actions/SvgSpriteAction/index.d.ts +2 -0
- package/js/actions/SvgSpriteAction/index.js +8 -0
- package/js/actions/SvgSpriteAction/svgsprite.config.d.ts +3 -0
- package/js/actions/SvgSpriteAction/svgsprite.config.js +117 -0
- package/js/actions/SvgToPngAction/SvgToPngAction.d.ts +28 -0
- package/js/actions/SvgToPngAction/SvgToPngAction.js +108 -0
- package/js/actions/SvgToPngAction/index.d.ts +2 -0
- package/js/actions/SvgToPngAction/index.js +8 -0
- package/js/actions/TypeScriptCompilerAction/TypeScriptCompilerAction.d.ts +28 -0
- package/js/actions/TypeScriptCompilerAction/TypeScriptCompilerAction.js +96 -0
- package/js/actions/TypeScriptCompilerAction/index.d.ts +2 -0
- package/js/actions/TypeScriptCompilerAction/index.js +8 -0
- package/js/actions/VersionWriteAction/VersionWriteAction.d.ts +45 -0
- package/js/actions/VersionWriteAction/VersionWriteAction.js +147 -0
- package/js/actions/VersionWriteAction/index.d.ts +2 -0
- package/js/actions/VersionWriteAction/index.js +8 -0
- package/js/cli/ArgumentParser.d.ts +62 -0
- package/js/cli/ArgumentParser.js +118 -0
- package/js/cli.d.ts +6 -0
- package/js/cli.js +58 -0
- package/js/core/abstract/AbstractProcess.d.ts +62 -0
- package/js/core/abstract/AbstractProcess.js +96 -0
- package/js/core/abstract/AbstractValidator.d.ts +72 -0
- package/js/core/abstract/AbstractValidator.js +128 -0
- package/js/core/config/ConfigLoader.d.ts +47 -0
- package/js/core/config/ConfigLoader.js +130 -0
- package/js/core/config/ConfigStore.d.ts +69 -0
- package/js/core/config/ConfigStore.js +168 -0
- package/js/core/config/defaultConfig.d.ts +5 -0
- package/js/core/config/defaultConfig.js +131 -0
- package/js/core/pipeline/Action.d.ts +60 -0
- package/js/core/pipeline/Action.js +77 -0
- package/js/core/pipeline/ActionRegistry.d.ts +80 -0
- package/js/core/pipeline/ActionRegistry.js +180 -0
- package/js/core/pipeline/Pipeline.d.ts +42 -0
- package/js/core/pipeline/Pipeline.js +107 -0
- package/js/core/pipeline/PipelineManager.d.ts +55 -0
- package/js/core/pipeline/PipelineManager.js +164 -0
- package/js/core/pipeline/Stage.d.ts +45 -0
- package/js/core/pipeline/Stage.js +110 -0
- package/js/core/pipeline/Step.d.ts +26 -0
- package/js/core/pipeline/Step.js +85 -0
- package/js/core/validation/OptionsValidator.d.ts +43 -0
- package/js/core/validation/OptionsValidator.js +123 -0
- package/js/index.d.ts +3 -0
- package/js/index.js +36 -0
- package/js/interface/ActionInterface.d.ts +57 -0
- package/js/interface/ActionInterface.js +5 -0
- package/js/interface/ActionPlugin.d.ts +4 -0
- package/js/interface/ActionPlugin.js +5 -0
- package/js/interface/ConfigInterface.d.ts +43 -0
- package/js/interface/ConfigInterface.js +5 -0
- package/js/interface/LiveOptionsInterface.d.ts +42 -0
- package/js/interface/LiveOptionsInterface.js +2 -0
- package/js/interface/MetadataInterface.d.ts +95 -0
- package/js/interface/MetadataInterface.js +2 -0
- package/js/interface/OptionsInterface.d.ts +45 -0
- package/js/interface/OptionsInterface.js +5 -0
- package/js/interface/PipelineOptionsInterface.d.ts +66 -0
- package/js/interface/PipelineOptionsInterface.js +5 -0
- package/js/interface/StageInterface.d.ts +79 -0
- package/js/interface/StageInterface.js +5 -0
- package/js/interface/StepInterface.d.ts +66 -0
- package/js/interface/StepInterface.js +5 -0
- package/js/interface/StepOptionsInterface.d.ts +38 -0
- package/js/interface/StepOptionsInterface.js +21 -0
- package/js/interface/index.d.ts +7 -0
- package/js/interface/index.js +3 -0
- package/js/kist.d.ts +58 -0
- package/js/kist.js +145 -0
- package/js/live/LiveServer.d.ts +95 -0
- package/js/live/LiveServer.js +233 -0
- package/js/live/LiveWatcher.d.ts +45 -0
- package/js/live/LiveWatcher.js +140 -0
- package/js/logger/Logger.d.ts +94 -0
- package/js/logger/Logger.js +151 -0
- package/js/logger/LoggerStyles.d.ts +23 -0
- package/js/logger/LoggerStyles.js +30 -0
- package/js/types/ActionOptionsType.d.ts +8 -0
- package/js/types/ActionOptionsType.js +2 -0
- package/js/types/index.d.ts +1 -0
- package/js/types/index.js +3 -0
- package/package.json +93 -7
- package/ts/actions/CoreActions.ts +64 -0
- package/ts/actions/DirectoryCleanAction/DirectoryCleanAction.ts +121 -0
- package/ts/actions/DirectoryCleanAction/index.ts +11 -0
- package/ts/actions/DirectoryCopyAction/DirectoryCopyAction.ts +118 -0
- package/ts/actions/DirectoryCopyAction/index.ts +11 -0
- package/ts/actions/DirectoryCreateAction/DirectoryCreateAction.ts +81 -0
- package/ts/actions/DirectoryCreateAction/index.ts +11 -0
- package/ts/actions/DocumentationAction/DocumentationAction.ts +100 -0
- package/ts/actions/DocumentationAction/index.ts +11 -0
- package/ts/actions/FileCopyAction/FileCopyAction.ts +125 -0
- package/ts/actions/FileCopyAction/index.ts +11 -0
- package/ts/actions/FileRenameAction/FileRenameAction.ts +82 -0
- package/ts/actions/FileRenameAction/index.ts +11 -0
- package/ts/actions/JavaScriptMinifyAction/JavaScriptMinifyAction.ts +109 -0
- package/ts/actions/JavaScriptMinifyAction/index.ts +11 -0
- package/ts/actions/JavaScriptMinifyAction/terser.config.ts +177 -0
- package/ts/actions/LintAction/LintAction.ts +67 -0
- package/ts/actions/LintAction/index.ts +11 -0
- package/ts/actions/PackageManagerAction/PackageManagerAction.ts +176 -0
- package/ts/actions/PackageManagerAction/index.ts +11 -0
- package/ts/actions/PackageManagerAction/package.config.ts +94 -0
- package/ts/actions/SassDocAction/SassDocAction.ts +66 -0
- package/ts/actions/SassDocAction/index.ts +11 -0
- package/ts/actions/StyleProcessingAction/StyleProcessingAction.ts +142 -0
- package/ts/actions/StyleProcessingAction/index.ts +11 -0
- package/ts/actions/StyleProcessingAction/postcss.config.compressed.ts +31 -0
- package/ts/actions/StyleProcessingAction/postcss.config.expanded.ts +47 -0
- package/ts/actions/SvgPackagerAction/SvgPackagerAction.ts +187 -0
- package/ts/actions/SvgPackagerAction/index.ts +11 -0
- package/ts/actions/SvgReaderAction/SvgReaderAction.ts +77 -0
- package/ts/actions/SvgReaderAction/index.ts +11 -0
- package/ts/actions/SvgSpriteAction/SvgSpriteAction.ts +127 -0
- package/ts/actions/SvgSpriteAction/index.ts +11 -0
- package/ts/actions/SvgSpriteAction/svgsprite.config.ts +123 -0
- package/ts/actions/SvgToPngAction/SvgToPngAction.ts +113 -0
- package/ts/actions/SvgToPngAction/index.ts +11 -0
- package/ts/actions/TypeScriptCompilerAction/TypeScriptCompilerAction.ts +117 -0
- package/ts/actions/TypeScriptCompilerAction/index.ts +11 -0
- package/ts/actions/VersionWriteAction/VersionWriteAction.ts +174 -0
- package/ts/actions/VersionWriteAction/index.ts +11 -0
- package/ts/actions/index.ts +0 -0
- package/ts/cli/ArgumentParser.ts +150 -0
- package/ts/cli/index.ts +1 -0
- package/ts/cli.ts +56 -0
- package/ts/core/abstract/AbstractProcess.ts +109 -0
- package/ts/core/abstract/AbstractSingleton.ts +46 -0
- package/ts/core/abstract/AbstractValidator.ts +167 -0
- package/ts/core/abstract/index.ts +0 -0
- package/ts/core/config/ConfigLoader.ts +141 -0
- package/ts/core/config/ConfigStore.ts +201 -0
- package/ts/core/config/defaultConfig.ts +154 -0
- package/ts/core/config/index.ts +0 -0
- package/ts/core/index.ts +34 -0
- package/ts/core/pipeline/Action.ts +101 -0
- package/ts/core/pipeline/ActionRegistry.ts +216 -0
- package/ts/core/pipeline/Pipeline.ts +121 -0
- package/ts/core/pipeline/PipelineManager.ts +170 -0
- package/ts/core/pipeline/Stage.ts +131 -0
- package/ts/core/pipeline/Step.ts +96 -0
- package/ts/core/pipeline/index.ts +0 -0
- package/ts/core/validation/ActionValidator.ts +97 -0
- package/ts/core/validation/ConfigValidator.ts +103 -0
- package/ts/core/validation/OptionsValidator.ts +179 -0
- package/ts/core/validation/StageValidator.ts +175 -0
- package/ts/core/validation/StepValidator.ts +203 -0
- package/ts/core/validation/index.ts +0 -0
- package/ts/index.ts +26 -0
- package/ts/interface/ActionInterface.ts +70 -0
- package/ts/interface/ActionPlugin.ts +14 -0
- package/ts/interface/ConfigInterface.ts +55 -0
- package/ts/interface/File.ts +24 -0
- package/ts/interface/LiveOptionsInterface.ts +46 -0
- package/ts/interface/MetadataInterface.ts +105 -0
- package/ts/interface/OptionsInterface.ts +58 -0
- package/ts/interface/PackageJson.ts +171 -0
- package/ts/interface/PipelineOptionsInterface.ts +74 -0
- package/ts/interface/SVG.ts +84 -0
- package/ts/interface/StageInterface.ts +96 -0
- package/ts/interface/StepInterface.ts +83 -0
- package/ts/interface/StepOptionsInterface.ts +57 -0
- package/ts/interface/index.ts +9 -0
- package/ts/kist.ts +161 -0
- package/ts/live/LiveServer.ts +311 -0
- package/ts/live/LiveWatcher.ts +150 -0
- package/ts/live/index.ts +11 -0
- package/ts/logger/Logger.ts +187 -0
- package/ts/logger/LoggerStyles.ts +28 -0
- package/ts/logger/index.ts +0 -0
- package/ts/types/ActionOptionsType.ts +10 -0
- package/ts/types/index.ts +3 -0
- package/index.js +0 -3
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { AbstractProcess } from "../core/abstract/AbstractProcess";
|
|
2
|
+
/**
|
|
3
|
+
* LiveServer class provides functionality to serve static files,
|
|
4
|
+
* inject live reload scripts into HTML responses, and manage WebSocket
|
|
5
|
+
* connections to enable live reload capabilities.
|
|
6
|
+
*/
|
|
7
|
+
export declare class LiveServer extends AbstractProcess {
|
|
8
|
+
/**
|
|
9
|
+
* Express application
|
|
10
|
+
*/
|
|
11
|
+
private app;
|
|
12
|
+
/**
|
|
13
|
+
* The underlying HTTP server used by the LiveServer.
|
|
14
|
+
* Handles incoming HTTP requests and serves static files.
|
|
15
|
+
*/
|
|
16
|
+
private server;
|
|
17
|
+
/**
|
|
18
|
+
* The WebSocket server responsible for managing WebSocket connections.
|
|
19
|
+
* Enables real-time communication with connected clients.
|
|
20
|
+
*/
|
|
21
|
+
private wss;
|
|
22
|
+
/**
|
|
23
|
+
* A set of WebSocket clients currently connected to the server.
|
|
24
|
+
* Each client represents an active WebSocket connection.
|
|
25
|
+
*/
|
|
26
|
+
private clients;
|
|
27
|
+
/**
|
|
28
|
+
* The port number on which the server is running.
|
|
29
|
+
* Defaults to 3000 if not specified in the configuration.
|
|
30
|
+
*/
|
|
31
|
+
private port;
|
|
32
|
+
/**
|
|
33
|
+
* The root directory from which static files are served.
|
|
34
|
+
* Defaults to the "public" folder in the current working directory.
|
|
35
|
+
*/
|
|
36
|
+
private root;
|
|
37
|
+
/**
|
|
38
|
+
* An array of paths to watch for changes.
|
|
39
|
+
* When a file within these paths changes, the server triggers live reload.
|
|
40
|
+
*/
|
|
41
|
+
private watchPaths;
|
|
42
|
+
/**
|
|
43
|
+
* An array of paths or patterns to ignore during file watching.
|
|
44
|
+
* Prevents unnecessary reloads caused by changes in these paths.
|
|
45
|
+
* Defaults to ignoring the "node_modules" directory.
|
|
46
|
+
*/
|
|
47
|
+
private ignoredPaths;
|
|
48
|
+
/**
|
|
49
|
+
* Initializes the LiveServer.
|
|
50
|
+
// * @param port - The port on which the server will listen.
|
|
51
|
+
*/
|
|
52
|
+
constructor();
|
|
53
|
+
/**
|
|
54
|
+
* Initializes the HTTP server and WebSocket server.
|
|
55
|
+
*/
|
|
56
|
+
private initializeServer;
|
|
57
|
+
/** Logs initialization details for the LiveServer. */
|
|
58
|
+
private logInitializationDetails;
|
|
59
|
+
/**
|
|
60
|
+
* Sets up rate limiting middleware to prevent abuse of HTTP requests.
|
|
61
|
+
*/
|
|
62
|
+
private setupRateLimiter;
|
|
63
|
+
/**
|
|
64
|
+
* Sets up WebSocket handlers to manage client connections.
|
|
65
|
+
*/
|
|
66
|
+
private setupWebSocketHandlers;
|
|
67
|
+
/**
|
|
68
|
+
* Sets up middleware for serving static files and injecting the live
|
|
69
|
+
* reload script into HTML files.
|
|
70
|
+
*/
|
|
71
|
+
private setupMiddleware;
|
|
72
|
+
/**
|
|
73
|
+
* Middleware function to inject the live reload script into HTML
|
|
74
|
+
* responses. Prevents directory traversal attacks by sanitizing the
|
|
75
|
+
* requested file path.
|
|
76
|
+
* @param req - The HTTP request object.
|
|
77
|
+
* @param res - The HTTP response object.
|
|
78
|
+
* @param next - The next middleware function.
|
|
79
|
+
*/
|
|
80
|
+
private injectLiveReloadScript;
|
|
81
|
+
/**
|
|
82
|
+
* Sends a reload signal to all connected WebSocket clients.
|
|
83
|
+
*/
|
|
84
|
+
reloadClients(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Gracefully shuts down the server and all WebSocket connections.
|
|
87
|
+
*/
|
|
88
|
+
shutdown(): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Type guard to check if an error is an instance of NodeJS.ErrnoException.
|
|
91
|
+
* @param error - The error to check.
|
|
92
|
+
* @returns True if the error has a `code` property.
|
|
93
|
+
*/
|
|
94
|
+
private isErrnoException;
|
|
95
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Import
|
|
4
|
+
// ============================================================================
|
|
5
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.LiveServer = void 0;
|
|
19
|
+
const express_1 = __importDefault(require("express"));
|
|
20
|
+
const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
22
|
+
const ws_1 = require("ws");
|
|
23
|
+
const AbstractProcess_1 = require("../core/abstract/AbstractProcess");
|
|
24
|
+
const ConfigStore_1 = require("../core/config/ConfigStore");
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Class
|
|
27
|
+
// ============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* LiveServer class provides functionality to serve static files,
|
|
30
|
+
* inject live reload scripts into HTML responses, and manage WebSocket
|
|
31
|
+
* connections to enable live reload capabilities.
|
|
32
|
+
*/
|
|
33
|
+
class LiveServer extends AbstractProcess_1.AbstractProcess {
|
|
34
|
+
// Constructor
|
|
35
|
+
// ========================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Initializes the LiveServer.
|
|
38
|
+
// * @param port - The port on which the server will listen.
|
|
39
|
+
*/
|
|
40
|
+
constructor() {
|
|
41
|
+
super();
|
|
42
|
+
// Parameters
|
|
43
|
+
// ========================================================================
|
|
44
|
+
/**
|
|
45
|
+
* Express application
|
|
46
|
+
*/
|
|
47
|
+
this.app = (0, express_1.default)();
|
|
48
|
+
/**
|
|
49
|
+
* A set of WebSocket clients currently connected to the server.
|
|
50
|
+
* Each client represents an active WebSocket connection.
|
|
51
|
+
*/
|
|
52
|
+
this.clients = new Set();
|
|
53
|
+
const configStore = ConfigStore_1.ConfigStore.getInstance();
|
|
54
|
+
const liveReloadOptions = configStore.get("options.live") || {};
|
|
55
|
+
// Extract and apply live reload options with defaults
|
|
56
|
+
this.port = liveReloadOptions.port || 3000;
|
|
57
|
+
this.root = path_1.default.resolve(process.cwd(), liveReloadOptions.root || "public");
|
|
58
|
+
this.watchPaths = (liveReloadOptions.watchPaths || [
|
|
59
|
+
"src/**/*",
|
|
60
|
+
"config/**/*",
|
|
61
|
+
"pack.yaml",
|
|
62
|
+
]).map((p) => path_1.default.resolve(process.cwd(), p));
|
|
63
|
+
this.ignoredPaths = (liveReloadOptions.ignoredPaths || ["node_modules"]).map((p) => path_1.default.resolve(process.cwd(), p));
|
|
64
|
+
// Log initialization details
|
|
65
|
+
this.logInitializationDetails();
|
|
66
|
+
// Initialize server
|
|
67
|
+
// this.initializeServer();
|
|
68
|
+
// Start the HTTP server
|
|
69
|
+
this.server = this.app.listen(this.port, () => {
|
|
70
|
+
this.logInfo(`Live Server running at http://localhost:${this.port}`);
|
|
71
|
+
});
|
|
72
|
+
// Initialize WebSocket server
|
|
73
|
+
this.wss = new ws_1.WebSocketServer({ server: this.server });
|
|
74
|
+
// Set up rate limiting
|
|
75
|
+
this.setupRateLimiter();
|
|
76
|
+
// Set up WebSocket handlers
|
|
77
|
+
this.setupWebSocketHandlers();
|
|
78
|
+
// Set up middleware
|
|
79
|
+
this.setupMiddleware();
|
|
80
|
+
}
|
|
81
|
+
// Methods
|
|
82
|
+
// ========================================================================
|
|
83
|
+
/**
|
|
84
|
+
* Initializes the HTTP server and WebSocket server.
|
|
85
|
+
*/
|
|
86
|
+
initializeServer() {
|
|
87
|
+
// Start the HTTP server
|
|
88
|
+
this.server = this.app.listen(this.port, () => {
|
|
89
|
+
this.logInfo(`Live Server running at http://localhost:${this.port}`);
|
|
90
|
+
});
|
|
91
|
+
// Initialize WebSocket server
|
|
92
|
+
this.wss = new ws_1.WebSocketServer({ server: this.server });
|
|
93
|
+
}
|
|
94
|
+
/** Logs initialization details for the LiveServer. */
|
|
95
|
+
logInitializationDetails() {
|
|
96
|
+
this.logInfo(`LiveServer initialized with port: ${this.port}`);
|
|
97
|
+
this.logInfo(`Serving static files from: ${this.root}`);
|
|
98
|
+
this.logInfo(`Watching paths: ${JSON.stringify(this.watchPaths)}`);
|
|
99
|
+
this.logInfo(`Ignoring paths: ${JSON.stringify(this.ignoredPaths)}`);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Sets up rate limiting middleware to prevent abuse of HTTP requests.
|
|
103
|
+
*/
|
|
104
|
+
setupRateLimiter() {
|
|
105
|
+
const limiter = (0, express_rate_limit_1.default)({
|
|
106
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
107
|
+
max: 100, // Limit each IP to 100 requests per windowMs
|
|
108
|
+
message: "Too many requests from this IP, please try again later.",
|
|
109
|
+
});
|
|
110
|
+
this.app.use(limiter);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Sets up WebSocket handlers to manage client connections.
|
|
114
|
+
*/
|
|
115
|
+
setupWebSocketHandlers() {
|
|
116
|
+
this.wss.on("connection", (ws) => {
|
|
117
|
+
this.logInfo("New WebSocket connection established.");
|
|
118
|
+
this.clients.add(ws);
|
|
119
|
+
ws.on("message", (message) => {
|
|
120
|
+
this.logInfo(`WebSocket message received: ${message.toString()}`);
|
|
121
|
+
});
|
|
122
|
+
ws.on("close", () => {
|
|
123
|
+
this.logInfo("WebSocket connection closed.");
|
|
124
|
+
this.clients.delete(ws);
|
|
125
|
+
});
|
|
126
|
+
ws.on("error", (error) => {
|
|
127
|
+
console.error("WebSocket encountered an error:", error);
|
|
128
|
+
this.clients.delete(ws);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Sets up middleware for serving static files and injecting the live
|
|
134
|
+
* reload script into HTML files.
|
|
135
|
+
*/
|
|
136
|
+
setupMiddleware() {
|
|
137
|
+
// Securely serve static files from the "public" directory
|
|
138
|
+
// const publicPath = path.resolve(
|
|
139
|
+
// __dirname,
|
|
140
|
+
// "public"
|
|
141
|
+
// );
|
|
142
|
+
this.logInfo(`Resolved public directory: ${this.root}`);
|
|
143
|
+
this.logInfo(`Serving static files from: ${this.root}`);
|
|
144
|
+
this.app.use(express_1.default.static(this.root));
|
|
145
|
+
// Middleware to inject the live reload script into HTML files
|
|
146
|
+
this.app.use(this.injectLiveReloadScript.bind(this));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Middleware function to inject the live reload script into HTML
|
|
150
|
+
* responses. Prevents directory traversal attacks by sanitizing the
|
|
151
|
+
* requested file path.
|
|
152
|
+
* @param req - The HTTP request object.
|
|
153
|
+
* @param res - The HTTP response object.
|
|
154
|
+
* @param next - The next middleware function.
|
|
155
|
+
*/
|
|
156
|
+
injectLiveReloadScript(req, res, next) {
|
|
157
|
+
if (req.url.endsWith(".html")) {
|
|
158
|
+
const sanitizedPath = path_1.default.join(path_1.default.resolve(__dirname, "public"),
|
|
159
|
+
// Prevent directory traversal
|
|
160
|
+
path_1.default.normalize(req.url).replace(/^(\.\.(\/|\\|$))+/g, ""));
|
|
161
|
+
res.sendFile(sanitizedPath, (err) => {
|
|
162
|
+
if (err) {
|
|
163
|
+
console.error("Error sending HTML file:", err);
|
|
164
|
+
next(err);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
res.write(`<script>
|
|
168
|
+
const ws = new WebSocket("ws://localhost:${this.port}");
|
|
169
|
+
ws.onmessage = (event) => {
|
|
170
|
+
if (event.data === "reload") {
|
|
171
|
+
this.logInfo("Reloading page...");
|
|
172
|
+
window.location.reload();
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
</script>`);
|
|
176
|
+
res.end();
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
next();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Sends a reload signal to all connected WebSocket clients.
|
|
186
|
+
*/
|
|
187
|
+
reloadClients() {
|
|
188
|
+
this.logInfo("Reloading all connected clients...");
|
|
189
|
+
this.clients.forEach((client) => {
|
|
190
|
+
if (client.readyState === ws_1.WebSocket.OPEN) {
|
|
191
|
+
client.send("reload");
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Gracefully shuts down the server and all WebSocket connections.
|
|
197
|
+
*/
|
|
198
|
+
shutdown() {
|
|
199
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
+
this.logInfo("Shutting down Live Reload Server...");
|
|
201
|
+
this.clients.forEach((client) => client.close());
|
|
202
|
+
this.wss.close();
|
|
203
|
+
yield new Promise((resolve, reject) => {
|
|
204
|
+
this.server.close((err) => {
|
|
205
|
+
if (err) {
|
|
206
|
+
if (this.isErrnoException(err) &&
|
|
207
|
+
err.code === "ERR_SERVER_NOT_RUNNING") {
|
|
208
|
+
this.logWarn("Server is not running, skipping shutdown.");
|
|
209
|
+
resolve();
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
this.logError("Error shutting down server:", err);
|
|
213
|
+
reject(err);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
resolve();
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
this.logInfo("Live Reload Server has been shut down.");
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Type guard to check if an error is an instance of NodeJS.ErrnoException.
|
|
226
|
+
* @param error - The error to check.
|
|
227
|
+
* @returns True if the error has a `code` property.
|
|
228
|
+
*/
|
|
229
|
+
isErrnoException(error) {
|
|
230
|
+
return typeof error === "object" && error !== null && "code" in error;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.LiveServer = LiveServer;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AbstractProcess } from "../core/abstract/AbstractProcess";
|
|
2
|
+
/**
|
|
3
|
+
* LiveWatcher is a utility class for monitoring file and directory changes.
|
|
4
|
+
* It leverages the `chokidar` library to efficiently detect file changes and
|
|
5
|
+
* trigger appropriate callbacks.
|
|
6
|
+
*/
|
|
7
|
+
export declare class LiveWatcher extends AbstractProcess {
|
|
8
|
+
/**
|
|
9
|
+
* The chokidar file watcher instance.
|
|
10
|
+
*/
|
|
11
|
+
private watcher;
|
|
12
|
+
private pathsToWatch;
|
|
13
|
+
private ignoredPaths;
|
|
14
|
+
private onChange;
|
|
15
|
+
/**
|
|
16
|
+
* Creates an instance of LiveWatcher.
|
|
17
|
+
* @param pathsToWatch - An array of paths to monitor for changes.
|
|
18
|
+
* @param ignoredPaths - A regular expression to specify paths or patterns
|
|
19
|
+
* to exclude from watching.
|
|
20
|
+
* @param onChange - A callback function that is executed when a file
|
|
21
|
+
* change is detected.
|
|
22
|
+
*/
|
|
23
|
+
constructor(onChange: (filePath: string) => void);
|
|
24
|
+
/**
|
|
25
|
+
* Initializes and configures the chokidar watcher to monitor files and
|
|
26
|
+
* directories.
|
|
27
|
+
*/
|
|
28
|
+
private setupWatchers;
|
|
29
|
+
/**
|
|
30
|
+
* Starts the file watcher if it is not already running. If the watcher
|
|
31
|
+
* was stopped previously, it re-initializes the watcher.
|
|
32
|
+
*/
|
|
33
|
+
startWatching(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Stops the file watcher and releases its resources. This is useful when
|
|
36
|
+
* you need to clean up or reinitialize the watcher.
|
|
37
|
+
*/
|
|
38
|
+
stopWatching(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Restarts the file watcher by first stopping the existing watcher (if
|
|
41
|
+
* any) and then starting a new one. This can be useful in scenarios where
|
|
42
|
+
* watcher configurations or paths have changed.
|
|
43
|
+
*/
|
|
44
|
+
restartWatcher(): Promise<void>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Import
|
|
4
|
+
// ============================================================================
|
|
5
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.LiveWatcher = void 0;
|
|
19
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
20
|
+
const AbstractProcess_1 = require("../core/abstract/AbstractProcess");
|
|
21
|
+
const ConfigStore_1 = require("../core/config/ConfigStore");
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Class
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* LiveWatcher is a utility class for monitoring file and directory changes.
|
|
27
|
+
* It leverages the `chokidar` library to efficiently detect file changes and
|
|
28
|
+
* trigger appropriate callbacks.
|
|
29
|
+
*/
|
|
30
|
+
class LiveWatcher extends AbstractProcess_1.AbstractProcess {
|
|
31
|
+
// Constructor
|
|
32
|
+
// ========================================================================
|
|
33
|
+
/**
|
|
34
|
+
* Creates an instance of LiveWatcher.
|
|
35
|
+
* @param pathsToWatch - An array of paths to monitor for changes.
|
|
36
|
+
* @param ignoredPaths - A regular expression to specify paths or patterns
|
|
37
|
+
* to exclude from watching.
|
|
38
|
+
* @param onChange - A callback function that is executed when a file
|
|
39
|
+
* change is detected.
|
|
40
|
+
*/
|
|
41
|
+
constructor(
|
|
42
|
+
// private pathsToWatch: string[],
|
|
43
|
+
// private ignoredPaths: RegExp,
|
|
44
|
+
onChange) {
|
|
45
|
+
var _a, _b;
|
|
46
|
+
super();
|
|
47
|
+
// Parameters
|
|
48
|
+
// ========================================================================
|
|
49
|
+
/**
|
|
50
|
+
* The chokidar file watcher instance.
|
|
51
|
+
*/
|
|
52
|
+
this.watcher = null;
|
|
53
|
+
// Retrieve live reload configuration from ConfigStore
|
|
54
|
+
const liveReloadOptions = ConfigStore_1.ConfigStore.getInstance().get("options.live") || {};
|
|
55
|
+
this.pathsToWatch = (_a = liveReloadOptions.watchPaths) !== null && _a !== void 0 ? _a : [
|
|
56
|
+
"src/**/*",
|
|
57
|
+
"config/**/*",
|
|
58
|
+
"pack.yaml",
|
|
59
|
+
];
|
|
60
|
+
this.ignoredPaths = (_b = liveReloadOptions.ignoredPaths) !== null && _b !== void 0 ? _b : ["node_modules"];
|
|
61
|
+
this.onChange = onChange;
|
|
62
|
+
this.startWatching();
|
|
63
|
+
}
|
|
64
|
+
// Methods
|
|
65
|
+
// ========================================================================
|
|
66
|
+
/**
|
|
67
|
+
* Initializes and configures the chokidar watcher to monitor files and
|
|
68
|
+
* directories.
|
|
69
|
+
*/
|
|
70
|
+
setupWatchers() {
|
|
71
|
+
if (!this.watcher)
|
|
72
|
+
return;
|
|
73
|
+
this.watcher
|
|
74
|
+
.on("ready", () => {
|
|
75
|
+
this.logInfo("File watching is active. Waiting for changes...");
|
|
76
|
+
})
|
|
77
|
+
.on("change", (filePath) => {
|
|
78
|
+
this.logInfo(`File changed: ${filePath}`);
|
|
79
|
+
try {
|
|
80
|
+
this.onChange(filePath);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
this.logError(`Error handling file change for ${filePath}:`, error);
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
.on("error", (error) => {
|
|
87
|
+
this.logError("Watcher encountered an error:", error);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Starts the file watcher if it is not already running. If the watcher
|
|
92
|
+
* was stopped previously, it re-initializes the watcher.
|
|
93
|
+
*/
|
|
94
|
+
startWatching() {
|
|
95
|
+
if (this.watcher) {
|
|
96
|
+
this.logInfo("Watcher is already running.");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.logInfo("Starting file watcher...");
|
|
100
|
+
this.watcher = chokidar_1.default.watch(this.pathsToWatch, {
|
|
101
|
+
ignored: this.ignoredPaths,
|
|
102
|
+
persistent: true,
|
|
103
|
+
// Prevents initial "add" events on startup
|
|
104
|
+
ignoreInitial: true,
|
|
105
|
+
awaitWriteFinish: {
|
|
106
|
+
// Polling interval to check for file stability
|
|
107
|
+
pollInterval: 100,
|
|
108
|
+
// Waits for file to finish writing
|
|
109
|
+
stabilityThreshold: 100,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
this.setupWatchers();
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Stops the file watcher and releases its resources. This is useful when
|
|
116
|
+
* you need to clean up or reinitialize the watcher.
|
|
117
|
+
*/
|
|
118
|
+
stopWatching() {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
if (this.watcher) {
|
|
121
|
+
yield this.watcher.close();
|
|
122
|
+
this.logInfo("File watching has been stopped.");
|
|
123
|
+
this.watcher = null;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Restarts the file watcher by first stopping the existing watcher (if
|
|
129
|
+
* any) and then starting a new one. This can be useful in scenarios where
|
|
130
|
+
* watcher configurations or paths have changed.
|
|
131
|
+
*/
|
|
132
|
+
restartWatcher() {
|
|
133
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
134
|
+
this.logInfo("Restarting file watcher...");
|
|
135
|
+
yield this.stopWatching();
|
|
136
|
+
this.startWatching();
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.LiveWatcher = LiveWatcher;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger class for handling console messages.
|
|
3
|
+
* Singleton instance ensures consistent logging behavior throughout the
|
|
4
|
+
* application.
|
|
5
|
+
*/
|
|
6
|
+
export declare class Logger {
|
|
7
|
+
/**
|
|
8
|
+
* Singleton instance
|
|
9
|
+
*/
|
|
10
|
+
private static instance;
|
|
11
|
+
/**
|
|
12
|
+
* Current log level
|
|
13
|
+
*/
|
|
14
|
+
private logLevel;
|
|
15
|
+
/**
|
|
16
|
+
* Private constructor to enforce singleton pattern.
|
|
17
|
+
* @param logLevel - The log level for controlling log output.
|
|
18
|
+
*/
|
|
19
|
+
private constructor();
|
|
20
|
+
/**
|
|
21
|
+
* Retrieves the singleton instance of Logger.
|
|
22
|
+
* Initializes a non-verbose Logger instance if it hasn't been explicitly
|
|
23
|
+
* initialized.
|
|
24
|
+
*
|
|
25
|
+
* @returns The Logger instance.
|
|
26
|
+
*/
|
|
27
|
+
static getInstance(logLevel?: "debug" | "info" | "warn" | "error"): Logger;
|
|
28
|
+
/**
|
|
29
|
+
* Resets the Logger instance.
|
|
30
|
+
* Useful for testing or reinitializing the Logger during runtime.
|
|
31
|
+
*/
|
|
32
|
+
static resetInstance(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Logs a message with a specific level if it meets the current log level.
|
|
35
|
+
*
|
|
36
|
+
* @param level - The log level (e.g., "INFO", "WARN", "ERROR").
|
|
37
|
+
* @param context - The context or class name where the log originates.
|
|
38
|
+
* @param message - The message content to log.
|
|
39
|
+
* @param fgStyle - The foreground color style to apply to the log level.
|
|
40
|
+
* @param bgStyle - The background color style to apply to the log level (default is reset).
|
|
41
|
+
*/
|
|
42
|
+
private log;
|
|
43
|
+
/**
|
|
44
|
+
* Determines if a log should be displayed based on the current log level.
|
|
45
|
+
*
|
|
46
|
+
* @param level - The level of the log being checked.
|
|
47
|
+
* @returns True if the log should be displayed, otherwise false.
|
|
48
|
+
*/
|
|
49
|
+
private shouldLog;
|
|
50
|
+
/**
|
|
51
|
+
* Logs an informational message.
|
|
52
|
+
*
|
|
53
|
+
* @param context - The originating class or module.
|
|
54
|
+
* @param message - The informational message to log.
|
|
55
|
+
*/
|
|
56
|
+
logInfo(context: string, message: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Logs a warning message.
|
|
59
|
+
*
|
|
60
|
+
* @param context - The originating class or module.
|
|
61
|
+
* @param message - The warning message to log.
|
|
62
|
+
*/
|
|
63
|
+
logWarn(context: string, message: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* Logs an error message.
|
|
66
|
+
*
|
|
67
|
+
* @param context - The originating class or module.
|
|
68
|
+
* @param message - The error message to log.
|
|
69
|
+
* @param error - (Optional) Additional error details.
|
|
70
|
+
*/
|
|
71
|
+
logError(context: string, message: string, error?: unknown): void;
|
|
72
|
+
/**
|
|
73
|
+
* Logs a debug message.
|
|
74
|
+
*
|
|
75
|
+
* @param context - The originating class or module.
|
|
76
|
+
* @param message - The debug message to log.
|
|
77
|
+
*/
|
|
78
|
+
logDebug(context: string, message: string): void;
|
|
79
|
+
/**
|
|
80
|
+
* Sets the log level dynamically.
|
|
81
|
+
*
|
|
82
|
+
* @param level - The log level to set (e.g., "debug", "info").
|
|
83
|
+
*/
|
|
84
|
+
setLogLevel(level: "debug" | "info" | "warn" | "error"): void;
|
|
85
|
+
/**
|
|
86
|
+
* Formats an error message for logging.
|
|
87
|
+
* Combines a base message with additional error details if available.
|
|
88
|
+
*
|
|
89
|
+
* @param message - The base error message.
|
|
90
|
+
* @param error - Additional error information, such as an Error object.
|
|
91
|
+
* @returns A formatted string combining the message and error details.
|
|
92
|
+
*/
|
|
93
|
+
private formatError;
|
|
94
|
+
}
|