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,96 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { ActionInterface } from "../../interface/ActionInterface";
|
|
6
|
+
import { StepInterface } from "../../interface/StepInterface";
|
|
7
|
+
import { AbstractProcess } from "../abstract/AbstractProcess";
|
|
8
|
+
import { ActionRegistry } from "./ActionRegistry";
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Class
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Represents a single step in a stage, encapsulating its execution logic.
|
|
16
|
+
* This class manages the resolution and execution of actions associated
|
|
17
|
+
* with each step.
|
|
18
|
+
*/
|
|
19
|
+
export class Step extends AbstractProcess {
|
|
20
|
+
// Parameters
|
|
21
|
+
// ========================================================================
|
|
22
|
+
|
|
23
|
+
private name: string;
|
|
24
|
+
private action: ActionInterface;
|
|
25
|
+
private options?: Record<string, any>;
|
|
26
|
+
|
|
27
|
+
// Constructor
|
|
28
|
+
// ========================================================================
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Constructs a Step instance based on the provided step definition.
|
|
32
|
+
* Dynamically resolves the action class from the registry.
|
|
33
|
+
*
|
|
34
|
+
* @param step - The step definition containing the step name, action name,
|
|
35
|
+
* and options.
|
|
36
|
+
* @throws Error if the specified action is not registered in the action
|
|
37
|
+
* registry.
|
|
38
|
+
*/
|
|
39
|
+
constructor(step: StepInterface) {
|
|
40
|
+
super();
|
|
41
|
+
this.name = step.name;
|
|
42
|
+
|
|
43
|
+
// Resolve the action class from the registry using the action name
|
|
44
|
+
const actionRegistry = ActionRegistry.getInstance();
|
|
45
|
+
// console.log(step.action)
|
|
46
|
+
// const ActionClass = actionRegistry.getAction(step.action.name);
|
|
47
|
+
const ActionClass = actionRegistry.getAction(String(step.action));
|
|
48
|
+
if (!ActionClass) {
|
|
49
|
+
let msg = `
|
|
50
|
+
Unknown action "${step.action}" for step "${this.name}".
|
|
51
|
+
Ensure the action is registered in the registry.
|
|
52
|
+
`;
|
|
53
|
+
this.logError(msg);
|
|
54
|
+
throw new Error(msg);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Initialize the action with the specific class from the registry
|
|
58
|
+
this.action = new ActionClass();
|
|
59
|
+
this.options = step.options;
|
|
60
|
+
|
|
61
|
+
this.logInfo(
|
|
62
|
+
`Step "${this.name}" initialized with action "${step.action.constructor.name}".`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Methods
|
|
67
|
+
// ========================================================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Executes the step by invoking its action's execute method.
|
|
71
|
+
*/
|
|
72
|
+
async execute(): Promise<void> {
|
|
73
|
+
this.logInfo(`Executing step: ${this.name}`);
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
// Validate options if the action provides a validation method
|
|
77
|
+
if (typeof this.action.validateOptions === "function") {
|
|
78
|
+
const isValid = this.action.validateOptions(
|
|
79
|
+
this.options || {},
|
|
80
|
+
);
|
|
81
|
+
if (!isValid) {
|
|
82
|
+
throw new Error(`Invalid options for step: ${this.name}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Execute the action with the provided options
|
|
87
|
+
await this.action.execute(this.options || {});
|
|
88
|
+
this.logInfo(`Step "${this.name}" completed successfully.`);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
this.logError(
|
|
91
|
+
`Error executing step "${this.name}": ${error}`,
|
|
92
|
+
error,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { AbstractValidator } from "../abstract/AbstractValidator";
|
|
6
|
+
import { ActionRegistry } from "../pipeline/ActionRegistry";
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Types
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Type representing the structure of action properties for validation.
|
|
14
|
+
*/
|
|
15
|
+
type ActionValidationKeys = "action";
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Class
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Validates actions by ensuring they are registered in the `ActionRegistry`.
|
|
23
|
+
* Extends `AbstractValidator` for consistent validation and logging.
|
|
24
|
+
*/
|
|
25
|
+
export class ActionValidator extends AbstractValidator<
|
|
26
|
+
Record<ActionValidationKeys, string>
|
|
27
|
+
> {
|
|
28
|
+
// Parameters
|
|
29
|
+
// ========================================================================
|
|
30
|
+
|
|
31
|
+
private actionRegistry: ActionRegistry;
|
|
32
|
+
|
|
33
|
+
// Constructor
|
|
34
|
+
// ========================================================================
|
|
35
|
+
|
|
36
|
+
constructor() {
|
|
37
|
+
super();
|
|
38
|
+
this.actionRegistry = ActionRegistry.getInstance();
|
|
39
|
+
this.logInfo("ActionValidator initialized.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Methods
|
|
43
|
+
// ========================================================================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Validates an action object with the structure { action: string }.
|
|
47
|
+
*
|
|
48
|
+
* @param target - The action object to validate.
|
|
49
|
+
* @throws Error if the action is invalid or not registered.
|
|
50
|
+
*/
|
|
51
|
+
public validate(target: Record<ActionValidationKeys, string>): void {
|
|
52
|
+
const action = target.action;
|
|
53
|
+
this.logInfo(`Validating action: "${action}"`);
|
|
54
|
+
|
|
55
|
+
if (!action || typeof action !== "string") {
|
|
56
|
+
this.throwValidationError(
|
|
57
|
+
"action",
|
|
58
|
+
action,
|
|
59
|
+
"Action name must be a non-empty string.",
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const registeredAction = this.actionRegistry.getAction(action);
|
|
64
|
+
|
|
65
|
+
if (!registeredAction) {
|
|
66
|
+
this.throwValidationError(
|
|
67
|
+
"action",
|
|
68
|
+
action,
|
|
69
|
+
`Action "${action}" is not registered in the ActionRegistry.`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.logValidationSuccess("action", action);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validates a specific property of the action object.
|
|
78
|
+
* This is required to fulfill the `AbstractValidator` contract.
|
|
79
|
+
*
|
|
80
|
+
* @param key - The property key (e.g., "action").
|
|
81
|
+
* @param value - The value of the property to validate.
|
|
82
|
+
* @throws Error if the validation fails.
|
|
83
|
+
*/
|
|
84
|
+
protected validateProperty<
|
|
85
|
+
K extends keyof Record<ActionValidationKeys, string>,
|
|
86
|
+
>(key: K, value: Record<ActionValidationKeys, string>[K]): void {
|
|
87
|
+
if (key === "action") {
|
|
88
|
+
this.validate({ action: value });
|
|
89
|
+
} else {
|
|
90
|
+
this.throwValidationError(
|
|
91
|
+
key,
|
|
92
|
+
value,
|
|
93
|
+
`Unknown property key: "${String(key)}".`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { ConfigInterface } from "../../interface/ConfigInterface";
|
|
6
|
+
import { AbstractValidator } from "../abstract/AbstractValidator";
|
|
7
|
+
import { StageValidator } from "./StageValidator";
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Class
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Validates the overall configuration, including stages and global options.
|
|
15
|
+
*/
|
|
16
|
+
export class ConfigValidator extends AbstractValidator<ConfigInterface> {
|
|
17
|
+
// Parameters
|
|
18
|
+
// ========================================================================
|
|
19
|
+
|
|
20
|
+
private stageValidator: StageValidator;
|
|
21
|
+
|
|
22
|
+
// Constructor
|
|
23
|
+
// ========================================================================
|
|
24
|
+
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
this.stageValidator = new StageValidator();
|
|
28
|
+
this.logInfo("ConfigValidator initialized.");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Methods
|
|
32
|
+
// ========================================================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Validates the entire configuration object.
|
|
36
|
+
* @param config - The configuration object to validate.
|
|
37
|
+
* @throws Error if validation fails.
|
|
38
|
+
*/
|
|
39
|
+
public validate(config: ConfigInterface): void {
|
|
40
|
+
this.logInfo("Validating configuration.");
|
|
41
|
+
|
|
42
|
+
// Validate each property of the configuration
|
|
43
|
+
for (const key in config) {
|
|
44
|
+
if (Object.prototype.hasOwnProperty.call(config, key)) {
|
|
45
|
+
this.validateProperty(
|
|
46
|
+
key as keyof ConfigInterface,
|
|
47
|
+
config[key as keyof ConfigInterface],
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this.logInfo("Configuration validated successfully.");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Validates a specific property of the configuration object.
|
|
57
|
+
*
|
|
58
|
+
* @param key - The key of the property to validate.
|
|
59
|
+
* @param value - The value of the property to validate.
|
|
60
|
+
* @throws Error if validation fails.
|
|
61
|
+
*/
|
|
62
|
+
protected validateProperty<K extends keyof ConfigInterface>(
|
|
63
|
+
key: K,
|
|
64
|
+
value: ConfigInterface[K],
|
|
65
|
+
): void {
|
|
66
|
+
switch (key) {
|
|
67
|
+
case "stages":
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
this.validateStages(value); // Validate only if it's an array
|
|
70
|
+
} else {
|
|
71
|
+
this.throwValidationError(
|
|
72
|
+
key,
|
|
73
|
+
value,
|
|
74
|
+
"'stages' must be an array.",
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
|
|
79
|
+
default:
|
|
80
|
+
// Add validation for other properties if needed
|
|
81
|
+
this.throwValidationError(
|
|
82
|
+
key,
|
|
83
|
+
value,
|
|
84
|
+
`Unknown or unsupported configuration property: "${String(key)}".`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this.logValidationSuccess(key, value);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Validates the stages in the configuration.
|
|
93
|
+
*
|
|
94
|
+
* @param stages - The stages to validate.
|
|
95
|
+
* @throws Error if validation fails.
|
|
96
|
+
*/
|
|
97
|
+
private validateStages(stages: ConfigInterface["stages"]): void {
|
|
98
|
+
for (const stage of stages) {
|
|
99
|
+
// Validate each stage
|
|
100
|
+
this.stageValidator.validate(stage);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { OptionsInterface } from "../../interface/OptionsInterface";
|
|
6
|
+
import { AbstractValidator } from "../abstract/AbstractValidator";
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Class
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* OptionsValidator provides centralized validation logic for pipeline options.
|
|
14
|
+
* Extends AbstractValidator for consistent validation and logging.
|
|
15
|
+
*/
|
|
16
|
+
export class OptionsValidator extends AbstractValidator<OptionsInterface> {
|
|
17
|
+
// Parameters
|
|
18
|
+
// ========================================================================
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A runtime mapping of enumerated options for validation.
|
|
22
|
+
*/
|
|
23
|
+
private static allowedValues: Partial<
|
|
24
|
+
Record<keyof OptionsInterface, unknown[]>
|
|
25
|
+
> = {
|
|
26
|
+
logLevel: ["debug", "info", "warn", "error"],
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// Constructor
|
|
30
|
+
// ========================================================================
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
this.logDebug("OptionsValidator initialized.");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Methods
|
|
38
|
+
// ========================================================================
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Validates a specific property of the options object.
|
|
42
|
+
*
|
|
43
|
+
* @param key - The key of the option to validate.
|
|
44
|
+
* @param value - The value of the option to validate.
|
|
45
|
+
* @throws Error if validation fails.
|
|
46
|
+
*/
|
|
47
|
+
protected validateProperty<K extends keyof OptionsInterface>(
|
|
48
|
+
key: K,
|
|
49
|
+
value: OptionsInterface[K],
|
|
50
|
+
): void {
|
|
51
|
+
if (value === undefined) {
|
|
52
|
+
this.throwValidationError(
|
|
53
|
+
key,
|
|
54
|
+
value,
|
|
55
|
+
`Option "${String(key)}" cannot be undefined.`,
|
|
56
|
+
);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const allowedValues = OptionsValidator.allowedValues[key];
|
|
61
|
+
if (allowedValues && !allowedValues.includes(value)) {
|
|
62
|
+
this.throwValidationError(
|
|
63
|
+
key,
|
|
64
|
+
value,
|
|
65
|
+
`Invalid value "${value}" for option "${String(key)}". Allowed values are: ${allowedValues.join(", ")}.`,
|
|
66
|
+
);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.validateByType(key, value);
|
|
71
|
+
this.logValidationSuccess(key, value);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Validates a property based on its type when it does not have predefined
|
|
76
|
+
* allowed values.
|
|
77
|
+
*
|
|
78
|
+
* @param key - The key to validate.
|
|
79
|
+
* @param value - The value to validate.
|
|
80
|
+
*/
|
|
81
|
+
private validateByType<K extends keyof OptionsInterface>(
|
|
82
|
+
key: K,
|
|
83
|
+
value: OptionsInterface[K],
|
|
84
|
+
): void {
|
|
85
|
+
switch (key) {
|
|
86
|
+
case "stepTimeout":
|
|
87
|
+
case "maxConcurrentStages":
|
|
88
|
+
if (typeof value === "number" && value >= 0) {
|
|
89
|
+
this.validateNumber(key, value);
|
|
90
|
+
} else {
|
|
91
|
+
this.throwValidationError(
|
|
92
|
+
key,
|
|
93
|
+
value,
|
|
94
|
+
"Must be a non-negative number.",
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
|
|
99
|
+
case "haltOnFailure":
|
|
100
|
+
case "tags":
|
|
101
|
+
if (this.isValidObject(value)) {
|
|
102
|
+
this.validateObject(key, value);
|
|
103
|
+
} else {
|
|
104
|
+
this.throwValidationError(
|
|
105
|
+
key,
|
|
106
|
+
value,
|
|
107
|
+
"Must be a valid object.",
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
|
|
112
|
+
case "live":
|
|
113
|
+
this.validateLiveOptions(value as OptionsInterface["live"]);
|
|
114
|
+
break;
|
|
115
|
+
|
|
116
|
+
default:
|
|
117
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
118
|
+
this.validateString(key, value);
|
|
119
|
+
} else {
|
|
120
|
+
this.throwValidationError(
|
|
121
|
+
key,
|
|
122
|
+
value,
|
|
123
|
+
"Must be a non-empty string.",
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Validates the `live` configuration, ensuring all nested properties
|
|
131
|
+
* conform to their expected types and ranges.
|
|
132
|
+
*
|
|
133
|
+
* @param value - The live reload configuration to validate.
|
|
134
|
+
*/
|
|
135
|
+
private validateLiveOptions(value: OptionsInterface["live"]): void {
|
|
136
|
+
if (value?.port && (value.port < 1 || value.port > 65535)) {
|
|
137
|
+
this.throwValidationError(
|
|
138
|
+
"live.port",
|
|
139
|
+
value.port,
|
|
140
|
+
"Port must be a number between 1 and 65535.",
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
if (value?.root && typeof value.root !== "string") {
|
|
144
|
+
this.throwValidationError(
|
|
145
|
+
"live.root",
|
|
146
|
+
value.root,
|
|
147
|
+
"Root must be a valid string path.",
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
if (value?.watchPaths && !Array.isArray(value.watchPaths)) {
|
|
151
|
+
this.throwValidationError(
|
|
152
|
+
"live.watchPaths",
|
|
153
|
+
value.watchPaths,
|
|
154
|
+
"Must be an array of paths.",
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
if (value?.ignoredPaths && !Array.isArray(value.ignoredPaths)) {
|
|
158
|
+
this.throwValidationError(
|
|
159
|
+
"live.ignoredPaths",
|
|
160
|
+
value.ignoredPaths,
|
|
161
|
+
"Must be an array of paths.",
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Checks if the given value is a valid object.
|
|
168
|
+
*
|
|
169
|
+
* @param value - The value to check.
|
|
170
|
+
* @returns True if the value is an object and not null or an array.
|
|
171
|
+
*/
|
|
172
|
+
private isValidObject(value: unknown): value is Record<string, unknown> {
|
|
173
|
+
return (
|
|
174
|
+
typeof value === "object" &&
|
|
175
|
+
value !== null &&
|
|
176
|
+
!Array.isArray(value)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Import
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
import { StageInterface } from "../../interface/StageInterface";
|
|
6
|
+
import { AbstractValidator } from "../abstract/AbstractValidator";
|
|
7
|
+
import { StepValidator } from "./StepValidator";
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Class
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* StageValidator ensures that stages within the configuration meet the required criteria.
|
|
15
|
+
* It validates the stage properties, dependencies, and steps for correctness.
|
|
16
|
+
*/
|
|
17
|
+
export class StageValidator extends AbstractValidator<StageInterface> {
|
|
18
|
+
// Parameters
|
|
19
|
+
// ========================================================================
|
|
20
|
+
|
|
21
|
+
private stageNames: Set<string>;
|
|
22
|
+
private stepValidator: StepValidator;
|
|
23
|
+
|
|
24
|
+
// Constructor
|
|
25
|
+
// ========================================================================
|
|
26
|
+
|
|
27
|
+
constructor() {
|
|
28
|
+
super();
|
|
29
|
+
this.stageNames = new Set();
|
|
30
|
+
this.stepValidator = new StepValidator();
|
|
31
|
+
this.logInfo("StageValidator initialized.");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Methods
|
|
35
|
+
// ========================================================================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Validates an entire stage object.
|
|
39
|
+
*
|
|
40
|
+
* @param stage - The stage object to validate.
|
|
41
|
+
* @throws Error if the stage or any of its properties are invalid.
|
|
42
|
+
*/
|
|
43
|
+
public validate(stage: StageInterface): void {
|
|
44
|
+
this.logInfo(`Validating stage: "${stage.name}"`);
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
// Validate individual properties of the stage
|
|
48
|
+
this.validateProperty("name", stage.name);
|
|
49
|
+
this.validateProperty("dependsOn", stage.dependsOn);
|
|
50
|
+
this.validateProperty("steps", stage.steps);
|
|
51
|
+
|
|
52
|
+
this.logInfo(`Stage "${stage.name}" validated successfully.`);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
this.logError(
|
|
55
|
+
`Validation failed for stage "${stage.name}": ${(error as Error).message}`,
|
|
56
|
+
);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Validates individual properties of the stage.
|
|
63
|
+
*
|
|
64
|
+
* @param key - The property name to validate.
|
|
65
|
+
* @param value - The property value to validate.
|
|
66
|
+
* @throws Error if the property value is invalid.
|
|
67
|
+
*/
|
|
68
|
+
public validateProperty<K extends keyof StageInterface>(
|
|
69
|
+
key: K,
|
|
70
|
+
value: StageInterface[K],
|
|
71
|
+
): void {
|
|
72
|
+
switch (key) {
|
|
73
|
+
case "name":
|
|
74
|
+
this.validateName(value as string);
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
case "dependsOn":
|
|
78
|
+
this.validateDependencies(value as string[]);
|
|
79
|
+
break;
|
|
80
|
+
|
|
81
|
+
case "steps":
|
|
82
|
+
this.validateSteps(value as StageInterface["steps"]);
|
|
83
|
+
break;
|
|
84
|
+
|
|
85
|
+
default:
|
|
86
|
+
this.throwValidationError(
|
|
87
|
+
key,
|
|
88
|
+
value,
|
|
89
|
+
"Unknown property provided for validation.",
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Log validation success with the property name and value
|
|
94
|
+
this.logValidationSuccess(key, value);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Validates the name of the stage.
|
|
99
|
+
*
|
|
100
|
+
* @param name - The name of the stage.
|
|
101
|
+
* @throws Error if the name is invalid.
|
|
102
|
+
*/
|
|
103
|
+
private validateName(name: string): void {
|
|
104
|
+
if (!name || typeof name !== "string") {
|
|
105
|
+
this.throwValidationError(
|
|
106
|
+
"name",
|
|
107
|
+
name,
|
|
108
|
+
"Stage must have a valid 'name' property.",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (this.stageNames.has(name)) {
|
|
113
|
+
this.throwValidationError(
|
|
114
|
+
"name",
|
|
115
|
+
name,
|
|
116
|
+
`Duplicate stage name found: "${name}".`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
this.stageNames.add(name);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Validates the stage dependencies.
|
|
125
|
+
*
|
|
126
|
+
* @param dependencies - The dependencies to validate.
|
|
127
|
+
* @throws Error if any dependency is invalid.
|
|
128
|
+
*/
|
|
129
|
+
private validateDependencies(dependencies: string[] | undefined): void {
|
|
130
|
+
if (dependencies && !Array.isArray(dependencies)) {
|
|
131
|
+
throw new Error("Stage dependencies must be an array.");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
dependencies?.forEach((dependency) => {
|
|
135
|
+
if (!this.stageNames.has(dependency)) {
|
|
136
|
+
this.throwValidationError(
|
|
137
|
+
"dependsOn",
|
|
138
|
+
[dependency], // Wrap dependency in an array to match the expected type
|
|
139
|
+
`Undefined dependency: "${dependency}". Ensure it references a valid stage.`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Validates the steps within the stage.
|
|
147
|
+
*
|
|
148
|
+
* @param steps - The steps array to validate.
|
|
149
|
+
* @throws Error if any step is invalid.
|
|
150
|
+
*/
|
|
151
|
+
private validateSteps(steps: StageInterface["steps"]): void {
|
|
152
|
+
if (!Array.isArray(steps) || steps.length === 0) {
|
|
153
|
+
this.throwValidationError(
|
|
154
|
+
"steps",
|
|
155
|
+
steps,
|
|
156
|
+
"Each stage must contain at least one step.",
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const stepNames = new Set<string>();
|
|
161
|
+
steps.forEach((step) => {
|
|
162
|
+
if (stepNames.has(step.name)) {
|
|
163
|
+
this.throwValidationError(
|
|
164
|
+
"steps",
|
|
165
|
+
steps, // Pass the full steps array for context
|
|
166
|
+
`Duplicate step name found in stage: "${step.name}".`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
stepNames.add(step.name);
|
|
170
|
+
|
|
171
|
+
// Validate each step using StepValidator
|
|
172
|
+
this.stepValidator.validate(step);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|