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.
Files changed (236) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +298 -3
  3. package/js/actions/CoreActions.d.ts +6 -0
  4. package/js/actions/CoreActions.js +47 -0
  5. package/js/actions/DirectoryCleanAction/DirectoryCleanAction.d.ts +36 -0
  6. package/js/actions/DirectoryCleanAction/DirectoryCleanAction.js +123 -0
  7. package/js/actions/DirectoryCleanAction/index.d.ts +2 -0
  8. package/js/actions/DirectoryCleanAction/index.js +8 -0
  9. package/js/actions/DirectoryCopyAction/DirectoryCopyAction.d.ts +42 -0
  10. package/js/actions/DirectoryCopyAction/DirectoryCopyAction.js +118 -0
  11. package/js/actions/DirectoryCopyAction/index.d.ts +2 -0
  12. package/js/actions/DirectoryCopyAction/index.js +8 -0
  13. package/js/actions/DirectoryCreateAction/DirectoryCreateAction.d.ts +30 -0
  14. package/js/actions/DirectoryCreateAction/DirectoryCreateAction.js +85 -0
  15. package/js/actions/DirectoryCreateAction/index.d.ts +2 -0
  16. package/js/actions/DirectoryCreateAction/index.js +8 -0
  17. package/js/actions/DocumentationAction/DocumentationAction.d.ts +23 -0
  18. package/js/actions/DocumentationAction/DocumentationAction.js +88 -0
  19. package/js/actions/DocumentationAction/index.d.ts +2 -0
  20. package/js/actions/DocumentationAction/index.js +8 -0
  21. package/js/actions/FileCopyAction/FileCopyAction.d.ts +42 -0
  22. package/js/actions/FileCopyAction/FileCopyAction.js +127 -0
  23. package/js/actions/FileCopyAction/index.d.ts +2 -0
  24. package/js/actions/FileCopyAction/index.js +8 -0
  25. package/js/actions/FileRenameAction/FileRenameAction.d.ts +30 -0
  26. package/js/actions/FileRenameAction/FileRenameAction.js +84 -0
  27. package/js/actions/FileRenameAction/index.d.ts +2 -0
  28. package/js/actions/FileRenameAction/index.js +8 -0
  29. package/js/actions/JavaScriptMinifyAction/JavaScriptMinifyAction.d.ts +31 -0
  30. package/js/actions/JavaScriptMinifyAction/JavaScriptMinifyAction.js +98 -0
  31. package/js/actions/JavaScriptMinifyAction/index.d.ts +2 -0
  32. package/js/actions/JavaScriptMinifyAction/index.js +8 -0
  33. package/js/actions/JavaScriptMinifyAction/terser.config.d.ts +27 -0
  34. package/js/actions/JavaScriptMinifyAction/terser.config.js +119 -0
  35. package/js/actions/LintAction/LintAction.d.ts +17 -0
  36. package/js/actions/LintAction/LintAction.js +63 -0
  37. package/js/actions/LintAction/index.d.ts +2 -0
  38. package/js/actions/LintAction/index.js +8 -0
  39. package/js/actions/PackageManagerAction/PackageManagerAction.d.ts +57 -0
  40. package/js/actions/PackageManagerAction/PackageManagerAction.js +161 -0
  41. package/js/actions/PackageManagerAction/index.d.ts +2 -0
  42. package/js/actions/PackageManagerAction/index.js +8 -0
  43. package/js/actions/PackageManagerAction/package.config.d.ts +16 -0
  44. package/js/actions/PackageManagerAction/package.config.js +91 -0
  45. package/js/actions/StyleProcessingAction/StyleProcessingAction.d.ts +34 -0
  46. package/js/actions/StyleProcessingAction/StyleProcessingAction.js +164 -0
  47. package/js/actions/StyleProcessingAction/index.d.ts +2 -0
  48. package/js/actions/StyleProcessingAction/index.js +8 -0
  49. package/js/actions/StyleProcessingAction/postcss.config.compressed.d.ts +10 -0
  50. package/js/actions/StyleProcessingAction/postcss.config.compressed.js +31 -0
  51. package/js/actions/StyleProcessingAction/postcss.config.expanded.d.ts +16 -0
  52. package/js/actions/StyleProcessingAction/postcss.config.expanded.js +45 -0
  53. package/js/actions/SvgPackagerAction/SvgPackagerAction.d.ts +68 -0
  54. package/js/actions/SvgPackagerAction/SvgPackagerAction.js +186 -0
  55. package/js/actions/SvgPackagerAction/index.d.ts +2 -0
  56. package/js/actions/SvgPackagerAction/index.js +8 -0
  57. package/js/actions/SvgReaderAction/SvgReaderAction.d.ts +32 -0
  58. package/js/actions/SvgReaderAction/SvgReaderAction.js +87 -0
  59. package/js/actions/SvgReaderAction/index.d.ts +2 -0
  60. package/js/actions/SvgReaderAction/index.js +8 -0
  61. package/js/actions/SvgSpriteAction/SvgSpriteAction.d.ts +37 -0
  62. package/js/actions/SvgSpriteAction/SvgSpriteAction.js +114 -0
  63. package/js/actions/SvgSpriteAction/index.d.ts +2 -0
  64. package/js/actions/SvgSpriteAction/index.js +8 -0
  65. package/js/actions/SvgSpriteAction/svgsprite.config.d.ts +3 -0
  66. package/js/actions/SvgSpriteAction/svgsprite.config.js +117 -0
  67. package/js/actions/SvgToPngAction/SvgToPngAction.d.ts +28 -0
  68. package/js/actions/SvgToPngAction/SvgToPngAction.js +108 -0
  69. package/js/actions/SvgToPngAction/index.d.ts +2 -0
  70. package/js/actions/SvgToPngAction/index.js +8 -0
  71. package/js/actions/TypeScriptCompilerAction/TypeScriptCompilerAction.d.ts +28 -0
  72. package/js/actions/TypeScriptCompilerAction/TypeScriptCompilerAction.js +96 -0
  73. package/js/actions/TypeScriptCompilerAction/index.d.ts +2 -0
  74. package/js/actions/TypeScriptCompilerAction/index.js +8 -0
  75. package/js/actions/VersionWriteAction/VersionWriteAction.d.ts +45 -0
  76. package/js/actions/VersionWriteAction/VersionWriteAction.js +147 -0
  77. package/js/actions/VersionWriteAction/index.d.ts +2 -0
  78. package/js/actions/VersionWriteAction/index.js +8 -0
  79. package/js/cli/ArgumentParser.d.ts +62 -0
  80. package/js/cli/ArgumentParser.js +118 -0
  81. package/js/cli.d.ts +6 -0
  82. package/js/cli.js +58 -0
  83. package/js/core/abstract/AbstractProcess.d.ts +62 -0
  84. package/js/core/abstract/AbstractProcess.js +96 -0
  85. package/js/core/abstract/AbstractValidator.d.ts +72 -0
  86. package/js/core/abstract/AbstractValidator.js +128 -0
  87. package/js/core/config/ConfigLoader.d.ts +47 -0
  88. package/js/core/config/ConfigLoader.js +130 -0
  89. package/js/core/config/ConfigStore.d.ts +69 -0
  90. package/js/core/config/ConfigStore.js +168 -0
  91. package/js/core/config/defaultConfig.d.ts +5 -0
  92. package/js/core/config/defaultConfig.js +131 -0
  93. package/js/core/pipeline/Action.d.ts +60 -0
  94. package/js/core/pipeline/Action.js +77 -0
  95. package/js/core/pipeline/ActionRegistry.d.ts +80 -0
  96. package/js/core/pipeline/ActionRegistry.js +180 -0
  97. package/js/core/pipeline/Pipeline.d.ts +42 -0
  98. package/js/core/pipeline/Pipeline.js +107 -0
  99. package/js/core/pipeline/PipelineManager.d.ts +55 -0
  100. package/js/core/pipeline/PipelineManager.js +164 -0
  101. package/js/core/pipeline/Stage.d.ts +45 -0
  102. package/js/core/pipeline/Stage.js +110 -0
  103. package/js/core/pipeline/Step.d.ts +26 -0
  104. package/js/core/pipeline/Step.js +85 -0
  105. package/js/core/validation/OptionsValidator.d.ts +43 -0
  106. package/js/core/validation/OptionsValidator.js +123 -0
  107. package/js/index.d.ts +3 -0
  108. package/js/index.js +36 -0
  109. package/js/interface/ActionInterface.d.ts +57 -0
  110. package/js/interface/ActionInterface.js +5 -0
  111. package/js/interface/ActionPlugin.d.ts +4 -0
  112. package/js/interface/ActionPlugin.js +5 -0
  113. package/js/interface/ConfigInterface.d.ts +43 -0
  114. package/js/interface/ConfigInterface.js +5 -0
  115. package/js/interface/LiveOptionsInterface.d.ts +42 -0
  116. package/js/interface/LiveOptionsInterface.js +2 -0
  117. package/js/interface/MetadataInterface.d.ts +95 -0
  118. package/js/interface/MetadataInterface.js +2 -0
  119. package/js/interface/OptionsInterface.d.ts +45 -0
  120. package/js/interface/OptionsInterface.js +5 -0
  121. package/js/interface/PipelineOptionsInterface.d.ts +66 -0
  122. package/js/interface/PipelineOptionsInterface.js +5 -0
  123. package/js/interface/StageInterface.d.ts +79 -0
  124. package/js/interface/StageInterface.js +5 -0
  125. package/js/interface/StepInterface.d.ts +66 -0
  126. package/js/interface/StepInterface.js +5 -0
  127. package/js/interface/StepOptionsInterface.d.ts +38 -0
  128. package/js/interface/StepOptionsInterface.js +21 -0
  129. package/js/interface/index.d.ts +7 -0
  130. package/js/interface/index.js +3 -0
  131. package/js/kist.d.ts +58 -0
  132. package/js/kist.js +145 -0
  133. package/js/live/LiveServer.d.ts +95 -0
  134. package/js/live/LiveServer.js +233 -0
  135. package/js/live/LiveWatcher.d.ts +45 -0
  136. package/js/live/LiveWatcher.js +140 -0
  137. package/js/logger/Logger.d.ts +94 -0
  138. package/js/logger/Logger.js +151 -0
  139. package/js/logger/LoggerStyles.d.ts +23 -0
  140. package/js/logger/LoggerStyles.js +30 -0
  141. package/js/types/ActionOptionsType.d.ts +8 -0
  142. package/js/types/ActionOptionsType.js +2 -0
  143. package/js/types/index.d.ts +1 -0
  144. package/js/types/index.js +3 -0
  145. package/package.json +93 -7
  146. package/ts/actions/CoreActions.ts +64 -0
  147. package/ts/actions/DirectoryCleanAction/DirectoryCleanAction.ts +121 -0
  148. package/ts/actions/DirectoryCleanAction/index.ts +11 -0
  149. package/ts/actions/DirectoryCopyAction/DirectoryCopyAction.ts +118 -0
  150. package/ts/actions/DirectoryCopyAction/index.ts +11 -0
  151. package/ts/actions/DirectoryCreateAction/DirectoryCreateAction.ts +81 -0
  152. package/ts/actions/DirectoryCreateAction/index.ts +11 -0
  153. package/ts/actions/DocumentationAction/DocumentationAction.ts +100 -0
  154. package/ts/actions/DocumentationAction/index.ts +11 -0
  155. package/ts/actions/FileCopyAction/FileCopyAction.ts +125 -0
  156. package/ts/actions/FileCopyAction/index.ts +11 -0
  157. package/ts/actions/FileRenameAction/FileRenameAction.ts +82 -0
  158. package/ts/actions/FileRenameAction/index.ts +11 -0
  159. package/ts/actions/JavaScriptMinifyAction/JavaScriptMinifyAction.ts +109 -0
  160. package/ts/actions/JavaScriptMinifyAction/index.ts +11 -0
  161. package/ts/actions/JavaScriptMinifyAction/terser.config.ts +177 -0
  162. package/ts/actions/LintAction/LintAction.ts +67 -0
  163. package/ts/actions/LintAction/index.ts +11 -0
  164. package/ts/actions/PackageManagerAction/PackageManagerAction.ts +176 -0
  165. package/ts/actions/PackageManagerAction/index.ts +11 -0
  166. package/ts/actions/PackageManagerAction/package.config.ts +94 -0
  167. package/ts/actions/SassDocAction/SassDocAction.ts +66 -0
  168. package/ts/actions/SassDocAction/index.ts +11 -0
  169. package/ts/actions/StyleProcessingAction/StyleProcessingAction.ts +142 -0
  170. package/ts/actions/StyleProcessingAction/index.ts +11 -0
  171. package/ts/actions/StyleProcessingAction/postcss.config.compressed.ts +31 -0
  172. package/ts/actions/StyleProcessingAction/postcss.config.expanded.ts +47 -0
  173. package/ts/actions/SvgPackagerAction/SvgPackagerAction.ts +187 -0
  174. package/ts/actions/SvgPackagerAction/index.ts +11 -0
  175. package/ts/actions/SvgReaderAction/SvgReaderAction.ts +77 -0
  176. package/ts/actions/SvgReaderAction/index.ts +11 -0
  177. package/ts/actions/SvgSpriteAction/SvgSpriteAction.ts +127 -0
  178. package/ts/actions/SvgSpriteAction/index.ts +11 -0
  179. package/ts/actions/SvgSpriteAction/svgsprite.config.ts +123 -0
  180. package/ts/actions/SvgToPngAction/SvgToPngAction.ts +113 -0
  181. package/ts/actions/SvgToPngAction/index.ts +11 -0
  182. package/ts/actions/TypeScriptCompilerAction/TypeScriptCompilerAction.ts +117 -0
  183. package/ts/actions/TypeScriptCompilerAction/index.ts +11 -0
  184. package/ts/actions/VersionWriteAction/VersionWriteAction.ts +174 -0
  185. package/ts/actions/VersionWriteAction/index.ts +11 -0
  186. package/ts/actions/index.ts +0 -0
  187. package/ts/cli/ArgumentParser.ts +150 -0
  188. package/ts/cli/index.ts +1 -0
  189. package/ts/cli.ts +56 -0
  190. package/ts/core/abstract/AbstractProcess.ts +109 -0
  191. package/ts/core/abstract/AbstractSingleton.ts +46 -0
  192. package/ts/core/abstract/AbstractValidator.ts +167 -0
  193. package/ts/core/abstract/index.ts +0 -0
  194. package/ts/core/config/ConfigLoader.ts +141 -0
  195. package/ts/core/config/ConfigStore.ts +201 -0
  196. package/ts/core/config/defaultConfig.ts +154 -0
  197. package/ts/core/config/index.ts +0 -0
  198. package/ts/core/index.ts +34 -0
  199. package/ts/core/pipeline/Action.ts +101 -0
  200. package/ts/core/pipeline/ActionRegistry.ts +216 -0
  201. package/ts/core/pipeline/Pipeline.ts +121 -0
  202. package/ts/core/pipeline/PipelineManager.ts +170 -0
  203. package/ts/core/pipeline/Stage.ts +131 -0
  204. package/ts/core/pipeline/Step.ts +96 -0
  205. package/ts/core/pipeline/index.ts +0 -0
  206. package/ts/core/validation/ActionValidator.ts +97 -0
  207. package/ts/core/validation/ConfigValidator.ts +103 -0
  208. package/ts/core/validation/OptionsValidator.ts +179 -0
  209. package/ts/core/validation/StageValidator.ts +175 -0
  210. package/ts/core/validation/StepValidator.ts +203 -0
  211. package/ts/core/validation/index.ts +0 -0
  212. package/ts/index.ts +26 -0
  213. package/ts/interface/ActionInterface.ts +70 -0
  214. package/ts/interface/ActionPlugin.ts +14 -0
  215. package/ts/interface/ConfigInterface.ts +55 -0
  216. package/ts/interface/File.ts +24 -0
  217. package/ts/interface/LiveOptionsInterface.ts +46 -0
  218. package/ts/interface/MetadataInterface.ts +105 -0
  219. package/ts/interface/OptionsInterface.ts +58 -0
  220. package/ts/interface/PackageJson.ts +171 -0
  221. package/ts/interface/PipelineOptionsInterface.ts +74 -0
  222. package/ts/interface/SVG.ts +84 -0
  223. package/ts/interface/StageInterface.ts +96 -0
  224. package/ts/interface/StepInterface.ts +83 -0
  225. package/ts/interface/StepOptionsInterface.ts +57 -0
  226. package/ts/interface/index.ts +9 -0
  227. package/ts/kist.ts +161 -0
  228. package/ts/live/LiveServer.ts +311 -0
  229. package/ts/live/LiveWatcher.ts +150 -0
  230. package/ts/live/index.ts +11 -0
  231. package/ts/logger/Logger.ts +187 -0
  232. package/ts/logger/LoggerStyles.ts +28 -0
  233. package/ts/logger/index.ts +0 -0
  234. package/ts/types/ActionOptionsType.ts +10 -0
  235. package/ts/types/index.ts +3 -0
  236. package/index.js +0 -3
@@ -0,0 +1,142 @@
1
+ // ============================================================================
2
+ // Import
3
+ // ============================================================================
4
+
5
+ import { promises as fs } from "fs";
6
+ import path from "path";
7
+ import postcss from "postcss";
8
+ import * as sass from "sass";
9
+
10
+ import { Action } from "../../core/pipeline/Action.js";
11
+ import { ActionOptionsType } from "../../types/ActionOptionsType.js";
12
+
13
+ // Assuming the PostCSS configurations are available at the given paths
14
+ import postcssConfigCompressed from "./postcss.config.compressed.js";
15
+ import postcssConfigExpanded from "./postcss.config.expanded.js";
16
+
17
+ // ============================================================================
18
+ // Classes
19
+ // ============================================================================
20
+
21
+ /**
22
+ * StyleProcessingAction is a step action responsible for processing styles,
23
+ * including compiling SCSS and applying PostCSS transformations. It supports
24
+ * expanded and compressed output styles based on the provided configuration.
25
+ */
26
+ export class StyleProcessingAction extends Action {
27
+ // Parameters
28
+ // ========================================================================
29
+
30
+ // Constructor
31
+ // ========================================================================
32
+
33
+ // Methods
34
+ // ========================================================================
35
+
36
+ /**
37
+ * Executes the style processing action.
38
+ * @param options - The options specific to style processing, including
39
+ * input/output file paths and style format.
40
+ * @returns A Promise that resolves when the styles are processed
41
+ * successfully, or rejects with an error if the action fails.
42
+ */
43
+ async execute(options: ActionOptionsType): Promise<void> {
44
+ const inputFile = options.inputFile as string;
45
+ const outputFile = options.outputFile as string;
46
+ const styleOption = options.styleOption as "expanded" | "compressed";
47
+
48
+ if (!inputFile || !outputFile || !styleOption) {
49
+ throw new Error(
50
+ "Missing required options: inputFile, outputFile, or styleOption.",
51
+ );
52
+ }
53
+
54
+ this.logInfo(
55
+ `Processing styles from ${inputFile} to ${outputFile} with ${styleOption} style.`,
56
+ );
57
+
58
+ try {
59
+ // Ensure the output directory exists
60
+ const outputDir = path.dirname(outputFile);
61
+ await this.ensureDirectoryExists(outputDir);
62
+
63
+ // Compile SCSS to CSS
64
+ const result = await sass.compileAsync(inputFile, {
65
+ style: styleOption,
66
+ importers: [new sass.NodePackageImporter()],
67
+ });
68
+
69
+ // Process the compiled CSS with PostCSS
70
+ const processedCss = await this.processPostCSS(
71
+ result.css,
72
+ styleOption,
73
+ );
74
+
75
+ // Write the processed CSS to a file
76
+ await fs.writeFile(outputFile, processedCss, "utf-8");
77
+
78
+ this.logInfo(
79
+ `Styles processed successfully from ${inputFile} to ${outputFile}.`,
80
+ );
81
+ } catch (error) {
82
+ this.logError(
83
+ `Error processing styles from ${inputFile}: ${error}`,
84
+ );
85
+ throw error;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Processes the given CSS with PostCSS based on the provided style option.
91
+ * @param css - The CSS string to process.
92
+ * @param styleOption - The style option, either "expanded" or "compressed".
93
+ * @returns Processed CSS string.
94
+ */
95
+ private async processPostCSS(
96
+ css: string,
97
+ styleOption: "expanded" | "compressed",
98
+ ): Promise<string> {
99
+ const config =
100
+ styleOption === "expanded"
101
+ ? postcssConfigExpanded
102
+ : postcssConfigCompressed;
103
+ const result = await postcss(config.plugins).process(css, {
104
+ from: undefined,
105
+ map: { inline: false },
106
+ });
107
+ return result.css;
108
+ }
109
+
110
+ /**
111
+ * Ensures that the given directory exists, creating it if it does not.
112
+ * @param dirPath - The path of the directory to check and create.
113
+ */
114
+ private async ensureDirectoryExists(dirPath: string): Promise<void> {
115
+ try {
116
+ await fs.mkdir(dirPath, { recursive: true });
117
+ } catch (error) {
118
+ if (error instanceof Error) {
119
+ const nodeError = error as NodeJS.ErrnoException;
120
+ if (nodeError.code !== "EEXIST") {
121
+ throw nodeError;
122
+ }
123
+ } else {
124
+ throw error;
125
+ }
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Provides a description of the action.
131
+ * @returns A string description of the action.
132
+ */
133
+ describe(): string {
134
+ return "Processes SCSS files into CSS, applying PostCSS transformations for expanded or compressed outputs.";
135
+ }
136
+ }
137
+
138
+ // ============================================================================
139
+ // Export
140
+ // ============================================================================
141
+
142
+ // export default StyleProcessingAction;
@@ -0,0 +1,11 @@
1
+ // ============================================================================
2
+ // Import
3
+ // ============================================================================
4
+
5
+ import { StyleProcessingAction } from "./StyleProcessingAction";
6
+
7
+ // ============================================================================
8
+ // Export
9
+ // ============================================================================
10
+
11
+ export { StyleProcessingAction };
@@ -0,0 +1,31 @@
1
+ // ============================================================================
2
+ // Import
3
+ // ============================================================================
4
+
5
+ import autoprefixer from "autoprefixer"; // Handles CSS vendor prefixing automatically
6
+ import cssnano from "cssnano"; // A PostCSS plugin for CSS minimization
7
+
8
+ // ============================================================================
9
+ // Constants
10
+ // ============================================================================
11
+
12
+ /**
13
+ * Configuration object for PostCSS that includes plugins for optimization and compression
14
+ * of CSS. This setup is typically used for production builds where minimized CSS is preferred
15
+ * to reduce file size and improve loading times.
16
+ */
17
+ const postcssConfigCompressed = {
18
+ plugins: [
19
+ autoprefixer, // Automatically adds vendor prefixes to CSS rules
20
+ cssnano({
21
+ // Compresses CSS output
22
+ preset: "default", // Uses the default settings for compression
23
+ }),
24
+ ],
25
+ };
26
+
27
+ // ============================================================================
28
+ // Export
29
+ // ============================================================================
30
+
31
+ export default postcssConfigCompressed;
@@ -0,0 +1,47 @@
1
+ // ============================================================================
2
+ // Import
3
+ // ============================================================================
4
+
5
+ import autoprefixer from "autoprefixer"; // Automatically adds vendor prefixes to CSS rules
6
+ import cssnano from "cssnano";
7
+ // import postcssSimpleVars from 'postcss-simple-vars'; // Plugin to handle CSS variables
8
+ // import postcssNested from 'postcss-nested'; // Plugin to allow nesting of CSS rules
9
+ // import postcssImport from 'postcss-import'; // Plugin to inline import CSS files into a single CSS
10
+
11
+ // ============================================================================
12
+ // Constants
13
+ // ============================================================================
14
+
15
+ /**
16
+ * Configuration object for PostCSS that focuses on generating expanded, readable CSS
17
+ * for development environments. Includes plugins that enhance CSS handling like nesting,
18
+ * variable support, and import inlining, alongside autoprefixer for browser compatibility.
19
+ */
20
+ const postcssConfigExpanded = {
21
+ plugins: [
22
+ autoprefixer,
23
+ // Include other plugins suited for the expanded output
24
+ ],
25
+ // plugins: [
26
+ // postcssImport(), // Allows importing of other CSS files within a CSS file
27
+ // autoprefixer(), // Adds vendor prefixes to CSS, using data from Can I Use
28
+ // postcssSimpleVars(), // Enables the use of Sass-like variables in CSS
29
+ // postcssNested(), // Process nested rules, which is similar to how Sass handles nesting
30
+ // // cssnano({
31
+ // // preset: 'default', // Optionally include for light compression or reformatting
32
+ // // }),
33
+ // ]
34
+ };
35
+
36
+ // ============================================================================
37
+ // Export
38
+ // ============================================================================
39
+
40
+ export default postcssConfigExpanded;
41
+
42
+ /**
43
+ * Note: This configuration is intended for development use where extended readability
44
+ * and ease of debugging are critical. The cssnano plugin is commented out by default
45
+ * to keep the output CSS as clean and readable as possible; it can be enabled for
46
+ * environments that require slightly more optimized output without full minification.
47
+ */
@@ -0,0 +1,187 @@
1
+ // ============================================================================
2
+ // Imports
3
+ // ============================================================================
4
+
5
+ import * as fs from "fs/promises";
6
+ import * as glob from "glob";
7
+ import * as path from "path";
8
+ import SVGO, { loadConfig } from "svgo";
9
+ import { Action } from "../../core/pipeline/Action";
10
+ import { ActionOptionsType } from "../../types/ActionOptionsType";
11
+
12
+ // ============================================================================
13
+ // Classes
14
+ // ============================================================================
15
+
16
+ /**
17
+ * SvgPackagerAction is responsible for optimizing and packaging SVG files.
18
+ * It reads SVG files from a specified directory, optimizes them using SVGO,
19
+ * and then outputs them as TypeScript files and JSON indexes.
20
+ */
21
+ export class SvgPackagerAction extends Action {
22
+ // Methods
23
+ // ========================================================================
24
+
25
+ /**
26
+ * Executes the SVG processing action.
27
+ * @param options - The options specifying input and output directories.
28
+ * @returns A Promise that resolves when the action completes successfully.
29
+ */
30
+ async execute(options: ActionOptionsType): Promise<void> {
31
+ const {
32
+ svgoConfigPath = "./config/svgo.config.js",
33
+ inputDirectory = "src/icons",
34
+ outputDirectory = "dist/icons",
35
+ tsOutputDirectory = "dist/ts",
36
+ jsonOutputDirectory = "dist",
37
+ } = options;
38
+
39
+ this.logInfo(`Processing SVG files from ${inputDirectory}...`);
40
+ const iconNames: string[] = [];
41
+
42
+ try {
43
+ const svgFiles = glob.sync(`${inputDirectory}/**/*.svg`);
44
+
45
+ for (const file of svgFiles) {
46
+ const iconName = this.sanitizeFileName(
47
+ path.basename(file, ".svg"),
48
+ );
49
+ iconNames.push(iconName);
50
+
51
+ const svgContent = await this.readSvgFile(file);
52
+ const optimizedSvg = await this.optimizeSvg(
53
+ svgoConfigPath,
54
+ svgContent,
55
+ );
56
+
57
+ await this.writeFiles(
58
+ iconName,
59
+ optimizedSvg,
60
+ outputDirectory,
61
+ tsOutputDirectory,
62
+ );
63
+ }
64
+
65
+ await this.writeIconsJson(iconNames, jsonOutputDirectory);
66
+ this.logInfo(
67
+ `Successfully processed ${svgFiles.length} SVG files.`,
68
+ );
69
+ } catch (error) {
70
+ this.logError("Error processing SVG files.", error);
71
+ throw error;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Reads the content of an SVG file.
77
+ * @param filePath The path to the SVG file.
78
+ * @returns The content of the SVG file.
79
+ */
80
+ private async readSvgFile(filePath: string): Promise<string> {
81
+ return fs.readFile(filePath, "utf8");
82
+ }
83
+
84
+ /**
85
+ * Sanitizes a file name to be a valid TypeScript identifier.
86
+ * @param fileName The original file name.
87
+ * @returns A sanitized version of the file name.
88
+ */
89
+ private sanitizeFileName(fileName: string): string {
90
+ return fileName.replace(/[^a-zA-Z0-9_]/g, "_");
91
+ }
92
+
93
+ /**
94
+ * Optimizes SVG content using SVGO.
95
+ * @param svgoConfigPath Path to the SVGO configuration file.
96
+ * @param svgContent The raw SVG content.
97
+ * @returns The optimized SVG content.
98
+ */
99
+ private async optimizeSvg(
100
+ svgoConfigPath: string,
101
+ svgContent: string,
102
+ ): Promise<string> {
103
+ const config = await loadConfig(svgoConfigPath);
104
+ const result = await SVGO.optimize(svgContent, { ...config });
105
+ return result.data.trim();
106
+ }
107
+
108
+ /**
109
+ * Writes optimized SVG content to files (SVG & TypeScript).
110
+ * @param iconName The name of the icon.
111
+ * @param svgContent The optimized SVG content.
112
+ * @param outputDirectory The directory for SVG output.
113
+ * @param tsOutputDirectory The directory for TypeScript output.
114
+ */
115
+ private async writeFiles(
116
+ iconName: string,
117
+ svgContent: string,
118
+ outputDirectory: string,
119
+ tsOutputDirectory: string,
120
+ ): Promise<void> {
121
+ await this.writeSvgFile(iconName, svgContent, outputDirectory);
122
+ await this.writeTypeScriptFile(
123
+ iconName,
124
+ svgContent,
125
+ tsOutputDirectory,
126
+ );
127
+ }
128
+
129
+ /**
130
+ * Writes the optimized SVG content to an output file.
131
+ * @param iconName The name of the icon.
132
+ * @param svgContent The SVG content to be written.
133
+ * @param outputDirectory The directory to output the SVG file.
134
+ */
135
+ private async writeSvgFile(
136
+ iconName: string,
137
+ svgContent: string,
138
+ outputDirectory: string,
139
+ ): Promise<void> {
140
+ const outputPath = path.join(outputDirectory, `${iconName}.svg`);
141
+ await fs.writeFile(outputPath, svgContent);
142
+ }
143
+
144
+ /**
145
+ * Creates a TypeScript file from the optimized SVG content.
146
+ * @param iconName The name of the icon.
147
+ * @param svgContent The optimized SVG content.
148
+ * @param tsOutputDirectory The directory for TypeScript output.
149
+ */
150
+ private async writeTypeScriptFile(
151
+ iconName: string,
152
+ svgContent: string,
153
+ tsOutputDirectory: string,
154
+ ): Promise<void> {
155
+ const tsContent = `export const icon_${iconName} = \`${svgContent}\`;\n`;
156
+ const outputPath = path.join(tsOutputDirectory, `${iconName}.ts`);
157
+ await fs.writeFile(outputPath, tsContent);
158
+ }
159
+
160
+ /**
161
+ * Writes a JSON file containing the names of processed icons.
162
+ * @param iconNames An array of processed icon names.
163
+ * @param jsonOutputDirectory The directory to output the JSON file.
164
+ */
165
+ private async writeIconsJson(
166
+ iconNames: string[],
167
+ jsonOutputDirectory: string,
168
+ ): Promise<void> {
169
+ const jsonContent = JSON.stringify(iconNames, null, 2);
170
+ const outputPath = path.join(jsonOutputDirectory, "icons.json");
171
+ await fs.writeFile(outputPath, jsonContent);
172
+ }
173
+
174
+ /**
175
+ * Provides a description of the action.
176
+ * @returns A string description of the action.
177
+ */
178
+ describe(): string {
179
+ return "Optimizes and packages SVG files into multiple formats (SVG, TypeScript, JSON).";
180
+ }
181
+ }
182
+
183
+ // ============================================================================
184
+ // Export
185
+ // ============================================================================
186
+
187
+ export default SvgPackagerAction;
@@ -0,0 +1,11 @@
1
+ // ============================================================================
2
+ // Import
3
+ // ============================================================================
4
+
5
+ import { SvgPackagerAction } from "./SvgPackagerAction";
6
+
7
+ // ============================================================================
8
+ // Export
9
+ // ============================================================================
10
+
11
+ export { SvgPackagerAction };
@@ -0,0 +1,77 @@
1
+ // ============================================================================
2
+ // Imports
3
+ // ============================================================================
4
+
5
+ import { promises as fs } from "fs";
6
+ import path from "path";
7
+ import { Action } from "../../core/pipeline/Action";
8
+ import { ActionOptionsType } from "../../types/ActionOptionsType";
9
+
10
+ // ============================================================================
11
+ // Classes
12
+ // ============================================================================
13
+
14
+ /**
15
+ * SvgReaderAction is responsible for reading SVG file contents and
16
+ * making them available for further processing in the pipeline.
17
+ */
18
+ export class SvgReaderAction extends Action {
19
+ private svgContent: string = "";
20
+
21
+ // Methods
22
+ // ========================================================================
23
+
24
+ /**
25
+ * Executes the SVG reading action.
26
+ * @param options - The options specifying the SVG file path.
27
+ * @returns A Promise that resolves when the SVG file is successfully read.
28
+ */
29
+ async execute(options: ActionOptionsType): Promise<void> {
30
+ const { filePath } = options;
31
+
32
+ if (!filePath) {
33
+ throw new Error("Missing required option: 'filePath'.");
34
+ }
35
+
36
+ this.logInfo(`Reading SVG file: ${filePath}`);
37
+
38
+ try {
39
+ this.svgContent = await this.readSvg(filePath);
40
+ this.logInfo(`Successfully read SVG file: ${filePath}`);
41
+ } catch (error) {
42
+ this.logError(`Error reading SVG file: ${filePath}`, error);
43
+ throw error;
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Reads the content of an SVG file asynchronously.
49
+ * @param filePath The path to the SVG file.
50
+ * @returns A promise that resolves to the SVG file content.
51
+ */
52
+ private async readSvg(filePath: string): Promise<string> {
53
+ return fs.readFile(path.resolve(filePath), "utf-8");
54
+ }
55
+
56
+ /**
57
+ * Retrieves the last read SVG content.
58
+ * @returns The last read SVG content.
59
+ */
60
+ getSvgContent(): string {
61
+ return this.svgContent;
62
+ }
63
+
64
+ /**
65
+ * Provides a description of the action.
66
+ * @returns A string description of the action.
67
+ */
68
+ describe(): string {
69
+ return "Reads an SVG file and stores its content for further processing.";
70
+ }
71
+ }
72
+
73
+ // ============================================================================
74
+ // Export
75
+ // ============================================================================
76
+
77
+ export default SvgReaderAction;
@@ -0,0 +1,11 @@
1
+ // ============================================================================
2
+ // Import
3
+ // ============================================================================
4
+
5
+ import { SvgReaderAction } from "./SvgReaderAction";
6
+
7
+ // ============================================================================
8
+ // Export
9
+ // ============================================================================
10
+
11
+ export { SvgReaderAction };
@@ -0,0 +1,127 @@
1
+ // ============================================================================
2
+ // Imports
3
+ // ============================================================================
4
+
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import svgSprite from "svg-sprite";
8
+ import { Action } from "../../core/pipeline/Action";
9
+ import { ActionOptionsType } from "../../types/ActionOptionsType";
10
+ import svgspriteConfig from "./svgsprite.config.js";
11
+
12
+ // ============================================================================
13
+ // Classes
14
+ // ============================================================================
15
+
16
+ /**
17
+ * SvgSpriteAction compiles multiple SVG files into a single sprite sheet,
18
+ * making it more efficient to manage and use SVG assets in web applications.
19
+ */
20
+ export class SvgSpriteAction extends Action {
21
+ // Parameters
22
+ // ========================================================================
23
+
24
+ private config: svgSprite.Config;
25
+
26
+ /**
27
+ * Default configuration for SVG sprite generation.
28
+ */
29
+ private static defaultConfig: svgSprite.Config = svgspriteConfig;
30
+
31
+ // Constructor
32
+ // ========================================================================
33
+
34
+ /**
35
+ * Constructs an instance with merged default and custom configurations.
36
+ * @param {svgSprite.Config} customConfig - Optional custom configuration
37
+ * for svg-sprite.
38
+ */
39
+ constructor(customConfig: svgSprite.Config = {}) {
40
+ super();
41
+ this.config = { ...SvgSpriteAction.defaultConfig, ...customConfig };
42
+ }
43
+
44
+ // Methods
45
+ // ========================================================================
46
+
47
+ /**
48
+ * Executes the SVG sprite generation process.
49
+ * @param options - Options including source directory and output directory.
50
+ */
51
+ async execute(options: ActionOptionsType): Promise<void> {
52
+ const { sourceDir, outputDir } = options;
53
+
54
+ if (!sourceDir || !outputDir) {
55
+ throw new Error(
56
+ "Both 'sourceDir' and 'outputDir' must be specified.",
57
+ );
58
+ }
59
+
60
+ this.logInfo(`Generating SVG sprite from: ${sourceDir}`);
61
+
62
+ try {
63
+ await this.generateSprite(sourceDir, outputDir);
64
+ this.logInfo(`SVG sprite successfully generated in: ${outputDir}`);
65
+ } catch (error) {
66
+ this.logError("Error generating SVG sprite:", error);
67
+ throw error;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Generates an SVG sprite from all SVG files in the specified directory.
73
+ * @param sourceDir - Directory containing source SVG files.
74
+ * @param outputDir - Directory where the generated sprite will be saved.
75
+ */
76
+ private async generateSprite(
77
+ sourceDir: string,
78
+ outputDir: string,
79
+ ): Promise<void> {
80
+ const files = fs.readdirSync(sourceDir);
81
+ const sprite = new svgSprite(this.config);
82
+
83
+ for (const file of files) {
84
+ if (path.extname(file) === ".svg") {
85
+ const svgPath = path.resolve(sourceDir, file);
86
+ const content = fs.readFileSync(svgPath, "utf8");
87
+ sprite.add(svgPath, null, content);
88
+ }
89
+ }
90
+
91
+ sprite.compile((error, result) => {
92
+ if (error) {
93
+ throw error;
94
+ }
95
+
96
+ for (const mode in result) {
97
+ for (const resource in result[mode]) {
98
+ const outputPath = path.resolve(
99
+ outputDir,
100
+ result[mode][resource].path,
101
+ );
102
+ fs.mkdirSync(path.dirname(outputPath), {
103
+ recursive: true,
104
+ });
105
+ fs.writeFileSync(
106
+ outputPath,
107
+ result[mode][resource].contents,
108
+ );
109
+ }
110
+ }
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Provides a description of the action.
116
+ * @returns A string description of the action.
117
+ */
118
+ describe(): string {
119
+ return "Generates an SVG sprite from a directory of SVG files.";
120
+ }
121
+ }
122
+
123
+ // ============================================================================
124
+ // Export
125
+ // ============================================================================
126
+
127
+ export default SvgSpriteAction;
@@ -0,0 +1,11 @@
1
+ // ============================================================================
2
+ // Import
3
+ // ============================================================================
4
+
5
+ import { SvgSpriteAction } from "./SvgSpriteAction";
6
+
7
+ // ============================================================================
8
+ // Export
9
+ // ============================================================================
10
+
11
+ export { SvgSpriteAction };