kist 0.0.0 → 0.1.31
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 +53 -0
- package/js/core/config/ConfigStore.js +136 -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 copy.ts +201 -0
- package/ts/core/config/ConfigStore.ts +157 -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,201 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { ConfigInterface } from "../../interface/ConfigInterface";
|
|
6
|
+
import { AbstractProcess } from "../abstract/AbstractProcess";
|
|
7
|
+
import { defaultConfig } from "./defaultConfig";
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Class
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* ConfigStore is a singleton that loads and manages the application's
|
|
15
|
+
* configuration.
|
|
16
|
+
* It prioritizes CLI arguments over configuration file values.
|
|
17
|
+
*/
|
|
18
|
+
export class ConfigStore extends AbstractProcess {
|
|
19
|
+
// Parameters
|
|
20
|
+
// ========================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Singleton instance of the ConfigStore.
|
|
24
|
+
*/
|
|
25
|
+
private static instance: ConfigStore | null = null;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The current configuration stored in the ConfigStore.
|
|
29
|
+
*/
|
|
30
|
+
private config: ConfigInterface;
|
|
31
|
+
|
|
32
|
+
// Constructor
|
|
33
|
+
// ========================================================================
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Private constructor to enforce the singleton pattern.
|
|
37
|
+
* Initializes the store with the default configuration.
|
|
38
|
+
*/
|
|
39
|
+
private constructor() {
|
|
40
|
+
super();
|
|
41
|
+
this.config = defaultConfig;
|
|
42
|
+
this.logDebug("ConfigStore initialized with default configuration.");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Static Methods
|
|
46
|
+
// ========================================================================
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Retrieves the singleton instance of ConfigStore, initializing it if
|
|
50
|
+
* necessary.
|
|
51
|
+
* @returns The singleton instance of ConfigStore.
|
|
52
|
+
*/
|
|
53
|
+
public static getInstance(): ConfigStore {
|
|
54
|
+
if (!ConfigStore.instance) {
|
|
55
|
+
ConfigStore.instance = new ConfigStore();
|
|
56
|
+
}
|
|
57
|
+
return ConfigStore.instance;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Instance Methods
|
|
61
|
+
// ========================================================================
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Retrieves a value from the configuration by key.
|
|
65
|
+
* Supports nested keys using dot notation (e.g., "options.logLevel").
|
|
66
|
+
*
|
|
67
|
+
* @param key - The key of the configuration to retrieve.
|
|
68
|
+
* @returns The configuration value or undefined if not found.
|
|
69
|
+
*/
|
|
70
|
+
public get<T>(key: string): T | undefined {
|
|
71
|
+
const keys = key.split(".");
|
|
72
|
+
let current: any = this.config;
|
|
73
|
+
|
|
74
|
+
for (const k of keys) {
|
|
75
|
+
if (current[k] === undefined) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
current = current[k];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.logDebug(
|
|
82
|
+
`Configuration key "${key}" retrieved with value: ${JSON.stringify(current)}`,
|
|
83
|
+
);
|
|
84
|
+
return current as T;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Sets a value in the configuration by key.
|
|
89
|
+
* Supports nested keys using dot notation (e.g., "options.logLevel").
|
|
90
|
+
*
|
|
91
|
+
* @param key - The key of the configuration to set.
|
|
92
|
+
* @param value - The value to set.
|
|
93
|
+
*/
|
|
94
|
+
public set(key: string, value: unknown): void {
|
|
95
|
+
const keys = key.split(".");
|
|
96
|
+
let current: any = this.config;
|
|
97
|
+
|
|
98
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
99
|
+
const k = keys[i];
|
|
100
|
+
if (!current[k] || typeof current[k] !== "object") {
|
|
101
|
+
current[k] = {};
|
|
102
|
+
}
|
|
103
|
+
current = current[k];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
current[keys[keys.length - 1]] = value;
|
|
107
|
+
this.logDebug(
|
|
108
|
+
`Set configuration key "${key}" to: ${JSON.stringify(value)}`,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Merges the provided configuration into the existing configuration.
|
|
114
|
+
* Uses a deep merge strategy to combine objects and overwrite primitives.
|
|
115
|
+
*
|
|
116
|
+
* @param newConfig - The new configuration to merge.
|
|
117
|
+
*/
|
|
118
|
+
public merge(newConfig: Partial<ConfigInterface>): void {
|
|
119
|
+
this.config = this.deepMerge(this.config, newConfig);
|
|
120
|
+
this.logDebug("Configuration successfully merged.");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Retrieves the current configuration.
|
|
125
|
+
*
|
|
126
|
+
* @returns The current configuration object.
|
|
127
|
+
*/
|
|
128
|
+
public getConfig(): ConfigInterface {
|
|
129
|
+
return this.config;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Prints the current configuration to the console in a readable format.
|
|
134
|
+
*/
|
|
135
|
+
public print(): void {
|
|
136
|
+
console.log("Current Configuration:");
|
|
137
|
+
console.log(JSON.stringify(this.config, null, 2));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Deeply merges two objects.
|
|
142
|
+
*
|
|
143
|
+
* @param target - The target object to merge into.
|
|
144
|
+
* @param source - The source object to merge from.
|
|
145
|
+
* @returns The merged object.
|
|
146
|
+
*/
|
|
147
|
+
// private deepMerge(target: any, source: any): any {
|
|
148
|
+
// if (typeof target !== "object" || target === null) {
|
|
149
|
+
// return source;
|
|
150
|
+
// }
|
|
151
|
+
|
|
152
|
+
// for (const key of Object.keys(source)) {
|
|
153
|
+
// if (
|
|
154
|
+
// source[key] &&
|
|
155
|
+
// typeof source[key] === "object" &&
|
|
156
|
+
// !Array.isArray(source[key])
|
|
157
|
+
// ) {
|
|
158
|
+
// if (!target[key] || typeof target[key] !== "object") {
|
|
159
|
+
// target[key] = {};
|
|
160
|
+
// }
|
|
161
|
+
// target[key] = this.deepMerge(target[key], source[key]);
|
|
162
|
+
// } else {
|
|
163
|
+
// target[key] = source[key];
|
|
164
|
+
// }
|
|
165
|
+
// }
|
|
166
|
+
|
|
167
|
+
// return target;
|
|
168
|
+
// }
|
|
169
|
+
private deepMerge(target: any, source: any): any {
|
|
170
|
+
if (typeof target !== "object" || target === null) {
|
|
171
|
+
return source;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
for (const key of Object.keys(source)) {
|
|
175
|
+
// Prevent prototype pollution
|
|
176
|
+
if (
|
|
177
|
+
key === "__proto__" ||
|
|
178
|
+
key === "constructor" ||
|
|
179
|
+
key === "prototype"
|
|
180
|
+
) {
|
|
181
|
+
this.logWarn(`Skipping potentially unsafe key: "${key}"`);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (
|
|
186
|
+
source[key] &&
|
|
187
|
+
typeof source[key] === "object" &&
|
|
188
|
+
!Array.isArray(source[key])
|
|
189
|
+
) {
|
|
190
|
+
if (!target[key] || typeof target[key] !== "object") {
|
|
191
|
+
target[key] = {};
|
|
192
|
+
}
|
|
193
|
+
target[key] = this.deepMerge(target[key], source[key]);
|
|
194
|
+
} else {
|
|
195
|
+
target[key] = source[key];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return target;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { ConfigInterface } from "../../interface/ConfigInterface";
|
|
6
|
+
import { AbstractProcess } from "../abstract/AbstractProcess";
|
|
7
|
+
import { defaultConfig } from "./defaultConfig";
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Class
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* ConfigStore is a singleton that loads and manages the application's configuration.
|
|
15
|
+
* It prioritizes CLI arguments over configuration file values.
|
|
16
|
+
*/
|
|
17
|
+
export class ConfigStore extends AbstractProcess {
|
|
18
|
+
// Singleton instance
|
|
19
|
+
private static instance: ConfigStore | null = null;
|
|
20
|
+
|
|
21
|
+
// The current configuration stored in the ConfigStore.
|
|
22
|
+
private config: ConfigInterface;
|
|
23
|
+
|
|
24
|
+
// Constructor (Private to enforce Singleton Pattern)
|
|
25
|
+
private constructor() {
|
|
26
|
+
super();
|
|
27
|
+
this.config = defaultConfig;
|
|
28
|
+
this.logDebug("ConfigStore initialized with default configuration.");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Retrieves the singleton instance of ConfigStore.
|
|
33
|
+
* @returns The singleton instance of ConfigStore.
|
|
34
|
+
*/
|
|
35
|
+
public static getInstance(): ConfigStore {
|
|
36
|
+
if (!ConfigStore.instance) {
|
|
37
|
+
ConfigStore.instance = new ConfigStore();
|
|
38
|
+
}
|
|
39
|
+
return ConfigStore.instance;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves a value from the configuration using dot notation.
|
|
44
|
+
*
|
|
45
|
+
* @param key - The key of the configuration to retrieve.
|
|
46
|
+
* @returns The configuration value or undefined if not found.
|
|
47
|
+
*/
|
|
48
|
+
public get<T>(key: string): T | undefined {
|
|
49
|
+
const keys = key.split(".");
|
|
50
|
+
let current: any = this.config;
|
|
51
|
+
|
|
52
|
+
for (const k of keys) {
|
|
53
|
+
if (current[k] === undefined) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
current = current[k];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.logDebug(`Configuration key "${key}" retrieved.`);
|
|
60
|
+
return current as T;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Sets a value in the configuration using dot notation.
|
|
65
|
+
*
|
|
66
|
+
* @param key - The key of the configuration to set.
|
|
67
|
+
* @param value - The value to set.
|
|
68
|
+
*/
|
|
69
|
+
public set(key: string, value: unknown): void {
|
|
70
|
+
const keys = key.split(".");
|
|
71
|
+
let current: any = this.config;
|
|
72
|
+
|
|
73
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
74
|
+
const k = keys[i];
|
|
75
|
+
|
|
76
|
+
// Prevent prototype pollution by blocking reserved keywords
|
|
77
|
+
if (["__proto__", "constructor", "prototype"].includes(k)) {
|
|
78
|
+
this.logWarn(`Attempted prototype pollution detected: "${k}"`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Ensure property exists and is an object
|
|
83
|
+
if (!Object.prototype.hasOwnProperty.call(current, k) || typeof current[k] !== "object") {
|
|
84
|
+
current[k] = Object.create(null); // Use a null prototype object
|
|
85
|
+
}
|
|
86
|
+
current = current[k];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const finalKey = keys[keys.length - 1];
|
|
90
|
+
|
|
91
|
+
// Prevent prototype pollution at the final assignment
|
|
92
|
+
if (["__proto__", "constructor", "prototype"].includes(finalKey)) {
|
|
93
|
+
this.logWarn(`Attempted prototype pollution detected: "${finalKey}"`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
current[finalKey] = value;
|
|
98
|
+
this.logDebug(`Set configuration key "${key}" to: ${JSON.stringify(value)}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Merges the provided configuration into the existing configuration using deep merge.
|
|
103
|
+
*
|
|
104
|
+
* @param newConfig - The new configuration to merge.
|
|
105
|
+
*/
|
|
106
|
+
public merge(newConfig: Partial<ConfigInterface>): void {
|
|
107
|
+
this.config = this.deepMerge(this.config, newConfig);
|
|
108
|
+
this.logDebug("Configuration successfully merged.");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Retrieves the current configuration object.
|
|
113
|
+
* @returns The current configuration.
|
|
114
|
+
*/
|
|
115
|
+
public getConfig(): ConfigInterface {
|
|
116
|
+
return this.config;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Prints the current configuration to the console.
|
|
121
|
+
*/
|
|
122
|
+
public print(): void {
|
|
123
|
+
console.log("Current Configuration:", JSON.stringify(this.config, null, 2));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Deeply merges two objects, preventing prototype pollution.
|
|
128
|
+
*
|
|
129
|
+
* @param target - The target object.
|
|
130
|
+
* @param source - The source object.
|
|
131
|
+
* @returns The merged object.
|
|
132
|
+
*/
|
|
133
|
+
private deepMerge(target: any, source: any): any {
|
|
134
|
+
if (typeof target !== "object" || target === null) {
|
|
135
|
+
return source;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
for (const key of Object.keys(source)) {
|
|
139
|
+
// Prevent prototype pollution
|
|
140
|
+
if (["__proto__", "constructor", "prototype"].includes(key)) {
|
|
141
|
+
this.logWarn(`Skipping unsafe key during merge: "${key}"`);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
146
|
+
if (!Object.prototype.hasOwnProperty.call(target, key) || typeof target[key] !== "object") {
|
|
147
|
+
target[key] = Object.create(null);
|
|
148
|
+
}
|
|
149
|
+
target[key] = this.deepMerge(target[key], source[key]);
|
|
150
|
+
} else {
|
|
151
|
+
target[key] = source[key];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return target;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { ConfigInterface } from "../../interface/ConfigInterface";
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Constants
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Default configuration for the kist pipeline.
|
|
13
|
+
*/
|
|
14
|
+
export const defaultConfig: ConfigInterface = {
|
|
15
|
+
metadata: {
|
|
16
|
+
/**
|
|
17
|
+
* The name of the pipeline for identification and reporting.
|
|
18
|
+
*/
|
|
19
|
+
name: "kist pipeline",
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Semantic version of the pipeline configuration for tracking changes.
|
|
23
|
+
*/
|
|
24
|
+
version: "1.0.0",
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Detailed description outlining the purpose of the pipeline.
|
|
28
|
+
*/
|
|
29
|
+
description: "A generic pipeline configuration for kist.",
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The author or owner of the pipeline configuration.
|
|
33
|
+
*/
|
|
34
|
+
author: "Anonymous",
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Arbitrary key-value pairs to describe the pipeline.
|
|
38
|
+
*/
|
|
39
|
+
tags: {
|
|
40
|
+
category: "generic",
|
|
41
|
+
environment: "development",
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Timestamp indicating when the configuration was created or last updated.
|
|
46
|
+
* Automatically set to the current date/time.
|
|
47
|
+
*/
|
|
48
|
+
timestamp: new Date().toISOString(),
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* License under which the pipeline configuration is shared or used.
|
|
52
|
+
*/
|
|
53
|
+
license: "MIT",
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* URL pointing to documentation or additional resources for the pipeline.
|
|
57
|
+
*/
|
|
58
|
+
documentation: "https://example.com/documentation",
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Contact information for questions or support.
|
|
62
|
+
*/
|
|
63
|
+
contact: "support@example.com",
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Dependencies or related systems required by the pipeline configuration.
|
|
67
|
+
*/
|
|
68
|
+
dependencies: ["Node.js >=14.0", "Docker >=20.10"],
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Environments where the pipeline is intended to run.
|
|
72
|
+
*/
|
|
73
|
+
environments: ["local", "CI/CD", "staging", "production"],
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
options: {
|
|
77
|
+
/**
|
|
78
|
+
* Configuration settings for live reload functionality.
|
|
79
|
+
*/
|
|
80
|
+
live: {
|
|
81
|
+
/**
|
|
82
|
+
* Indicates whether live reload is enabled.
|
|
83
|
+
*/
|
|
84
|
+
enabled: false,
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Port on which the live reload server listens.
|
|
88
|
+
*/
|
|
89
|
+
port: 3000,
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Root directory for serving static files.
|
|
93
|
+
*/
|
|
94
|
+
root: "public",
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Paths to watch for changes.
|
|
98
|
+
*/
|
|
99
|
+
watchPaths: ["src/**/*", "config/**/*", "kist.yaml"],
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Paths or patterns to ignore while watching.
|
|
103
|
+
*/
|
|
104
|
+
ignoredPaths: ["node_modules/*"],
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Configuration options for pipeline execution.
|
|
109
|
+
*/
|
|
110
|
+
pipeline: {
|
|
111
|
+
/**
|
|
112
|
+
* Default timeout in milliseconds for each step in the pipeline.
|
|
113
|
+
*/
|
|
114
|
+
stepTimeout: 30000,
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Whether to halt the pipeline if a step fails.
|
|
118
|
+
*/
|
|
119
|
+
haltOnFailure: true,
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Maximum number of concurrent stages allowed to run in parallel.
|
|
123
|
+
* Set to 0 for no limit.
|
|
124
|
+
*/
|
|
125
|
+
maxConcurrentStages: 0,
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Retry strategy for steps that fail.
|
|
129
|
+
*/
|
|
130
|
+
retryStrategy: {
|
|
131
|
+
/**
|
|
132
|
+
* Number of retry attempts before marking a step as failed.
|
|
133
|
+
*/
|
|
134
|
+
retries: 3,
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Delay in milliseconds between retry attempts.
|
|
138
|
+
*/
|
|
139
|
+
delay: 1000,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Logging level for the pipeline.
|
|
145
|
+
*/
|
|
146
|
+
logLevel: "info",
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Default stages for the pipeline. Initially set to an empty array.
|
|
151
|
+
* Users can define and add their own stages.
|
|
152
|
+
*/
|
|
153
|
+
stages: [],
|
|
154
|
+
};
|
|
File without changes
|
package/ts/core/index.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Core Module Exports
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Export core classes and modules for use in the application.
|
|
7
|
+
* Ensure all essential components are listed here to provide a unified API.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Core Classes
|
|
11
|
+
export { Action } from "./pipeline/Action";
|
|
12
|
+
export { Pipeline } from "./pipeline/Pipeline";
|
|
13
|
+
export { PipelineManager } from "./pipeline/PipelineManager";
|
|
14
|
+
export { Stage } from "./pipeline/Stage";
|
|
15
|
+
export { Step } from "./pipeline/Step";
|
|
16
|
+
|
|
17
|
+
// Utility Functions and Modules
|
|
18
|
+
// If there are reusable utilities, add them here.
|
|
19
|
+
// Example:
|
|
20
|
+
// export { someUtilityFunction } from "./utils";
|
|
21
|
+
|
|
22
|
+
// Action Registry
|
|
23
|
+
// Export functions related to action registration and retrieval.
|
|
24
|
+
// export {
|
|
25
|
+
// registerAction,
|
|
26
|
+
// getAction,
|
|
27
|
+
// listRegisteredActions
|
|
28
|
+
// } from "../actions/ActionRegistry";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Note: If new modules or files are added in the `core` directory,
|
|
32
|
+
* consider using an automated script to dynamically export them here.
|
|
33
|
+
* Tools like `barrel` can help maintain such an index file efficiently.
|
|
34
|
+
*/
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { ActionInterface } from "../../interface/ActionInterface";
|
|
6
|
+
import { ActionOptionsType } from "../../types/ActionOptionsType";
|
|
7
|
+
import { AbstractProcess } from "../abstract/AbstractProcess";
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Class
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Action is an abstract base class that serves as a foundation for all step
|
|
15
|
+
* actions in the pipeline. It provides a consistent structure and utility
|
|
16
|
+
* methods for derived action classes, making it easier to implement and
|
|
17
|
+
* integrate custom behaviors like `BuildAction`, `LintAction`, and more.
|
|
18
|
+
*/
|
|
19
|
+
export abstract class Action
|
|
20
|
+
extends AbstractProcess
|
|
21
|
+
implements ActionInterface
|
|
22
|
+
{
|
|
23
|
+
// Parameters
|
|
24
|
+
// ========================================================================
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Gets the unique name of the action.
|
|
28
|
+
* The name is derived from the class name of the concrete action.
|
|
29
|
+
*/
|
|
30
|
+
public get name(): string {
|
|
31
|
+
return this.constructor.name;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Constructor
|
|
35
|
+
// ========================================================================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Constructs a new Action instance.
|
|
39
|
+
* Inherits the logger from the AbstractProcess base class.
|
|
40
|
+
*/
|
|
41
|
+
constructor() {
|
|
42
|
+
super();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Methods
|
|
46
|
+
// ========================================================================
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Provides a basic validation mechanism for action options.
|
|
50
|
+
* Derived classes can override this method to implement specific
|
|
51
|
+
* validation logic.
|
|
52
|
+
*
|
|
53
|
+
* @param options - The options to validate, ensuring they meet the
|
|
54
|
+
* action"s specific requirements.
|
|
55
|
+
* @returns A boolean indicating whether the options are valid. Default
|
|
56
|
+
* implementation always returns true.
|
|
57
|
+
*/
|
|
58
|
+
validateOptions(options: ActionOptionsType): boolean {
|
|
59
|
+
// Default validation: always returns true, can be overridden in
|
|
60
|
+
// derived classes
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Abstract method that must be implemented by derived classes to perform
|
|
66
|
+
* the action"s main logic.
|
|
67
|
+
* This method is invoked during the step execution process.
|
|
68
|
+
*
|
|
69
|
+
* @param options - A structured set of options specific to the action's
|
|
70
|
+
* configuration.
|
|
71
|
+
* @returns A Promise that resolves when the action completes successfully,
|
|
72
|
+
* or rejects with an error if the action fails.
|
|
73
|
+
*/
|
|
74
|
+
abstract execute(options: ActionOptionsType): Promise<void>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Provides a summary or description of the action.
|
|
78
|
+
* This method can be overridden by derived classes to provide more
|
|
79
|
+
* specific details about the action.
|
|
80
|
+
*
|
|
81
|
+
* @returns A string description of the action.
|
|
82
|
+
*/
|
|
83
|
+
describe(): string {
|
|
84
|
+
return "Base action for executing steps in the pipeline.";
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Logs a message indicating the start of the action's execution.
|
|
89
|
+
* Useful for tracking progress in pipelines with multiple steps.
|
|
90
|
+
*/
|
|
91
|
+
protected logStart(): void {
|
|
92
|
+
this.logInfo(`Starting action: ${this.name}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Logs a message indicating the successful completion of the action.
|
|
97
|
+
*/
|
|
98
|
+
protected logSuccess(): void {
|
|
99
|
+
this.logInfo(`Successfully completed action: ${this.name}`);
|
|
100
|
+
}
|
|
101
|
+
}
|