kist 0.1.33 → 0.1.36

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.
@@ -2,7 +2,7 @@ import { Action } from "../../core/pipeline/Action";
2
2
  import { ActionOptionsType } from "../../types/ActionOptionsType";
3
3
  /**
4
4
  * SvgToPngAction converts SVG content to PNG format.
5
- * Uses `sharp` for conversion and `jsdom` for SVG element manipulation.
5
+ * Uses `resvg-js` for conversion and `jsdom` for SVG element manipulation.
6
6
  */
7
7
  export declare class SvgToPngAction extends Action {
8
8
  /**
@@ -16,17 +16,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.SvgToPngAction = void 0;
19
+ const resvg_js_1 = require("@resvg/resvg-js");
19
20
  const fs_1 = __importDefault(require("fs"));
20
21
  const jsdom_1 = require("jsdom");
21
22
  const path_1 = __importDefault(require("path"));
22
- const sharp_1 = __importDefault(require("sharp"));
23
23
  const Action_1 = require("../../core/pipeline/Action");
24
24
  // ============================================================================
25
25
  // Classes
26
26
  // ============================================================================
27
27
  /**
28
28
  * SvgToPngAction converts SVG content to PNG format.
29
- * Uses `sharp` for conversion and `jsdom` for SVG element manipulation.
29
+ * Uses `resvg-js` for conversion and `jsdom` for SVG element manipulation.
30
30
  */
31
31
  class SvgToPngAction extends Action_1.Action {
32
32
  // Methods
@@ -68,25 +68,25 @@ class SvgToPngAction extends Action_1.Action {
68
68
  if (!fs_1.default.existsSync(outputDir)) {
69
69
  fs_1.default.mkdirSync(outputDir, { recursive: true });
70
70
  }
71
- // Create a JSDOM instance to parse the SVG
71
+ // Parse SVG and apply width/height
72
72
  const dom = new jsdom_1.JSDOM(svgContent);
73
73
  const svgElement = dom.window.document.querySelector("svg");
74
74
  if (!svgElement) {
75
75
  throw new Error("Invalid SVG content");
76
76
  }
77
- if (width) {
77
+ if (width)
78
78
  svgElement.setAttribute("width", width.toString());
79
- }
80
- if (height) {
79
+ if (height)
81
80
  svgElement.setAttribute("height", height.toString());
82
- }
83
- // Serialize the updated SVG content
84
81
  const updatedSvgContent = svgElement.outerHTML;
85
- // Convert SVG to PNG using Sharp
86
- const pngBuffer = yield (0, sharp_1.default)(Buffer.from(updatedSvgContent))
87
- .png()
88
- .toBuffer();
89
- yield (0, sharp_1.default)(pngBuffer).toFile(outputPath);
82
+ // Render using Resvg
83
+ const resvg = new resvg_js_1.Resvg(updatedSvgContent, {
84
+ fitTo: width && height
85
+ ? { mode: "width", value: width }
86
+ : undefined,
87
+ });
88
+ const pngBuffer = resvg.render().asPng();
89
+ fs_1.default.writeFileSync(outputPath, pngBuffer);
90
90
  }
91
91
  catch (error) {
92
92
  throw new Error(`Error converting SVG to PNG: ${error.message}`);
@@ -98,7 +98,7 @@ class SvgToPngAction extends Action_1.Action {
98
98
  * @returns A string description of the action.
99
99
  */
100
100
  describe() {
101
- return "Converts SVG content to PNG format with optional resizing.";
101
+ return "Converts SVG content to PNG format with optional resizing using resvg-js.";
102
102
  }
103
103
  }
104
104
  exports.SvgToPngAction = SvgToPngAction;
@@ -1,25 +1,8 @@
1
1
  import { Action } from "../../core/pipeline/Action";
2
2
  import { ActionOptionsType } from "../../types/ActionOptionsType";
3
- /**
4
- * TemplateRenderAction is responsible for rendering and writing multiple files
5
- * from Nunjucks templates in a single action. It allows batch generation of
6
- * output files based on a shared template context.
7
- */
8
3
  export declare class TemplateRenderAction extends Action {
9
- /**
10
- * Executes the template rendering process for multiple templates.
11
- *
12
- * @param options - The options specifying the template directory,
13
- * template-output mapping, and rendering context.
14
- * @returns A Promise that resolves when all templates have been rendered.
15
- * @throws {Error} Throws an error if template processing fails.
16
- */
17
4
  execute(options: ActionOptionsType): Promise<void>;
18
- /**
19
- * Provides a description of the action.
20
- *
21
- * @returns A string description of the action.
22
- */
5
+ private renderTemplate;
23
6
  describe(): string;
24
7
  }
25
8
  export default TemplateRenderAction;
@@ -17,6 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.TemplateRenderAction = void 0;
19
19
  const promises_1 = require("fs/promises");
20
+ const glob_1 = require("glob");
20
21
  const nunjucks_1 = __importDefault(require("nunjucks"));
21
22
  const path_1 = __importDefault(require("path"));
22
23
  const Action_1 = require("../../core/pipeline/Action");
@@ -24,50 +25,32 @@ const nunjucks_config_js_1 = __importDefault(require("./nunjucks.config.js"));
24
25
  // ============================================================================
25
26
  // Classes
26
27
  // ============================================================================
27
- /**
28
- * TemplateRenderAction is responsible for rendering and writing multiple files
29
- * from Nunjucks templates in a single action. It allows batch generation of
30
- * output files based on a shared template context.
31
- */
32
28
  class TemplateRenderAction extends Action_1.Action {
33
- /**
34
- * Executes the template rendering process for multiple templates.
35
- *
36
- * @param options - The options specifying the template directory,
37
- * template-output mapping, and rendering context.
38
- * @returns A Promise that resolves when all templates have been rendered.
39
- * @throws {Error} Throws an error if template processing fails.
40
- */
41
29
  execute(options) {
42
30
  return __awaiter(this, void 0, void 0, function* () {
43
- const { templatesDir = "./templates", templates = [], context = {}, customConfig = {}, } = options;
44
- if (!Array.isArray(templates) || templates.length === 0) {
45
- throw new Error("Invalid options: 'templates' must be an array containing template-output pairs.");
46
- }
47
- this.logInfo(`Rendering ${templates.length} templates...`);
31
+ const { templatesDir = "./templates", outputDir = "./dist", templates = [], context = {}, renderAllFromDir = false, customConfig = {}, } = options;
32
+ const config = Object.assign(Object.assign({}, nunjucks_config_js_1.default), customConfig);
33
+ nunjucks_1.default.configure(templatesDir, config);
48
34
  try {
49
- // Merge Nunjucks configurations
50
- const config = Object.assign(Object.assign({}, nunjucks_config_js_1.default), customConfig);
51
- nunjucks_1.default.configure(templatesDir, config);
52
- // Render each template and save to its corresponding output path
53
- for (const { template, outputFile } of templates) {
54
- if (!template || !outputFile) {
55
- throw new Error(`Invalid template entry: ${JSON.stringify({
56
- template,
57
- outputFile,
58
- })}`);
35
+ if (renderAllFromDir) {
36
+ this.logInfo(`Auto-rendering all templates from ${templatesDir}...`);
37
+ const templateFiles = yield (0, glob_1.glob)("**/*.jinja", {
38
+ cwd: templatesDir,
39
+ });
40
+ for (const templateRelPath of templateFiles) {
41
+ const outputFile = path_1.default.join(outputDir, templateRelPath.replace(/\.jinja$/, ""));
42
+ yield this.renderTemplate(templateRelPath, outputFile, context, templatesDir);
43
+ }
44
+ }
45
+ else {
46
+ if (!Array.isArray(templates) || templates.length === 0) {
47
+ throw new Error("Option 'templates' must be provided if 'renderAllFromDir' is false.");
48
+ }
49
+ for (const { template, outputFile } of templates) {
50
+ yield this.renderTemplate(template, outputFile, context, templatesDir);
59
51
  }
60
- this.logInfo(`Rendering: ${template} → ${outputFile}`);
61
- // Render template content
62
- const content = nunjucks_1.default.render(template, context);
63
- // Ensure the output directory exists
64
- const dir = path_1.default.dirname(outputFile);
65
- yield (0, promises_1.mkdir)(dir, { recursive: true });
66
- // Write the rendered template to file
67
- yield (0, promises_1.writeFile)(outputFile, content, "utf-8");
68
- this.logInfo(`✓ Successfully rendered: ${outputFile}`);
69
52
  }
70
- this.logInfo("All templates rendered successfully.");
53
+ this.logInfo("All templates rendered successfully.");
71
54
  }
72
55
  catch (error) {
73
56
  this.logError("Error rendering templates.", error);
@@ -75,13 +58,18 @@ class TemplateRenderAction extends Action_1.Action {
75
58
  }
76
59
  });
77
60
  }
78
- /**
79
- * Provides a description of the action.
80
- *
81
- * @returns A string description of the action.
82
- */
61
+ renderTemplate(template, outputFile, context, templatesDir) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ this.logInfo(`Rendering: ${template} → ${outputFile}`);
64
+ const content = nunjucks_1.default.render(template, context);
65
+ const dir = path_1.default.dirname(outputFile);
66
+ yield (0, promises_1.mkdir)(dir, { recursive: true });
67
+ yield (0, promises_1.writeFile)(outputFile, content, "utf-8");
68
+ this.logInfo(`✓ Rendered: ${outputFile}`);
69
+ });
70
+ }
83
71
  describe() {
84
- return "Renders multiple Nunjucks templates into files using a shared context.";
72
+ return "Renders one or many Nunjucks templates using a shared context. Supports folder-wide auto-rendering.";
85
73
  }
86
74
  }
87
75
  exports.TemplateRenderAction = TemplateRenderAction;
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Configuration options for Nunjucks to ensure safe and efficient template rendering.
3
- * This setup is ideal for both development and production environments, providing a balance
4
- * between performance optimizations and security best practices.
2
+ * Configuration options for Nunjucks to ensure safe and efficient template
3
+ * rendering. This setup is ideal for both development and production
4
+ * environments, providing a balance between performance optimizations and
5
+ * security best practices.
5
6
  */
6
7
  declare const nunjucksConfig: {
7
8
  autoescape: boolean;
@@ -3,18 +3,28 @@
3
3
  // according to your caching strategy for production environments to optimize performance.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  // ============================================================================
6
+ // Import
7
+ // ============================================================================
8
+ // Importing path for potential future use in specifying template directories
9
+ // or other file paths
10
+ // ============================================================================
6
11
  // Constants
7
12
  // ============================================================================
8
13
  /**
9
- * Configuration options for Nunjucks to ensure safe and efficient template rendering.
10
- * This setup is ideal for both development and production environments, providing a balance
11
- * between performance optimizations and security best practices.
14
+ * Configuration options for Nunjucks to ensure safe and efficient template
15
+ * rendering. This setup is ideal for both development and production
16
+ * environments, providing a balance between performance optimizations and
17
+ * security best practices.
12
18
  */
13
19
  const nunjucksConfig = {
14
- autoescape: true, // Controls if output with dangerous characters are escaped automatically
15
- throwOnUndefined: false, // Throw errors when outputting a null/undefined value
16
- trimBlocks: true, // Automatically remove trailing newlines from a block/tag
17
- lstripBlocks: true, // Automatically remove leading whitespace from a block/tag
20
+ // Controls if output with dangerous characters are escaped automatically
21
+ autoescape: true,
22
+ // Throw errors when outputting a null/undefined value
23
+ throwOnUndefined: false,
24
+ // Automatically remove trailing newlines from a block/tag
25
+ trimBlocks: true,
26
+ // Automatically remove leading whitespace from a block/tag
27
+ lstripBlocks: true,
18
28
  noCache: true,
19
29
  };
20
30
  // ============================================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kist",
3
- "version": "0.1.33",
3
+ "version": "0.1.36",
4
4
  "description": "Package Pipeline Processor",
5
5
  "keywords": [
6
6
  "kist",
@@ -60,6 +60,7 @@
60
60
  "@babel/core": "^7.23.6",
61
61
  "@babel/preset-env": "^7.23.6",
62
62
  "@babel/preset-typescript": "^7.23.3",
63
+ "@resvg/resvg-js": "^2.6.2",
63
64
  "@types/fs-extra": "^11.0.4",
64
65
  "@types/glob": "^8.1.0",
65
66
  "@types/jsdom": "^21.1.6",
@@ -67,13 +68,13 @@
67
68
  "@types/node": "^22.13.0",
68
69
  "@types/nunjucks": "^3.2.6",
69
70
  "@types/svg-sprite": "^0.0.39",
70
- "autoprefixer": "^10.4.16",
71
+ "autoprefixer": "^10.4.21",
71
72
  "chokidar": "^4.0.0",
72
73
  "cssnano": "^7.0.4",
73
74
  "del": "^8.0.0",
74
75
  "eslint": "^9.9.0",
75
76
  "eslint-config-prettier": "^10.0.1",
76
- "express": "^4.21.0",
77
+ "express": "^5.1.0",
77
78
  "express-rate-limit": "^7.5.0",
78
79
  "fantasticon": "^3.0.0",
79
80
  "fs-extra": "^11.2.0",
@@ -88,7 +89,6 @@
88
89
  "sass": "^1.69.7",
89
90
  "sassdoc": "^2.7.4",
90
91
  "semver": "^7.5.4",
91
- "sharp": "^0.34.0",
92
92
  "svg-sprite": "^2.0.2",
93
93
  "svgo": "^3.1.0",
94
94
  "terser": "^5.26.0",
@@ -2,10 +2,10 @@
2
2
  // Imports
3
3
  // ============================================================================
4
4
 
5
+ import { Resvg } from "@resvg/resvg-js";
5
6
  import fs from "fs";
6
7
  import { JSDOM } from "jsdom";
7
8
  import path from "path";
8
- import sharp from "sharp";
9
9
  import { Action } from "../../core/pipeline/Action";
10
10
  import { ActionOptionsType } from "../../types/ActionOptionsType";
11
11
 
@@ -15,7 +15,7 @@ import { ActionOptionsType } from "../../types/ActionOptionsType";
15
15
 
16
16
  /**
17
17
  * SvgToPngAction converts SVG content to PNG format.
18
- * Uses `sharp` for conversion and `jsdom` for SVG element manipulation.
18
+ * Uses `resvg-js` for conversion and `jsdom` for SVG element manipulation.
19
19
  */
20
20
  export class SvgToPngAction extends Action {
21
21
  // Methods
@@ -66,7 +66,7 @@ export class SvgToPngAction extends Action {
66
66
  fs.mkdirSync(outputDir, { recursive: true });
67
67
  }
68
68
 
69
- // Create a JSDOM instance to parse the SVG
69
+ // Parse SVG and apply width/height
70
70
  const dom = new JSDOM(svgContent);
71
71
  const svgElement = dom.window.document.querySelector("svg");
72
72
 
@@ -74,22 +74,22 @@ export class SvgToPngAction extends Action {
74
74
  throw new Error("Invalid SVG content");
75
75
  }
76
76
 
77
- if (width) {
78
- svgElement.setAttribute("width", width.toString());
79
- }
80
-
81
- if (height) {
82
- svgElement.setAttribute("height", height.toString());
83
- }
77
+ if (width) svgElement.setAttribute("width", width.toString());
78
+ if (height) svgElement.setAttribute("height", height.toString());
84
79
 
85
- // Serialize the updated SVG content
86
80
  const updatedSvgContent = svgElement.outerHTML;
87
81
 
88
- // Convert SVG to PNG using Sharp
89
- const pngBuffer = await sharp(Buffer.from(updatedSvgContent))
90
- .png()
91
- .toBuffer();
92
- await sharp(pngBuffer).toFile(outputPath);
82
+ // Render using Resvg
83
+ const resvg = new Resvg(updatedSvgContent, {
84
+ fitTo:
85
+ width && height
86
+ ? { mode: "width", value: width }
87
+ : undefined,
88
+ });
89
+
90
+ const pngBuffer = resvg.render().asPng();
91
+
92
+ fs.writeFileSync(outputPath, pngBuffer);
93
93
  } catch (error) {
94
94
  throw new Error(
95
95
  `Error converting SVG to PNG: ${(error as Error).message}`,
@@ -102,7 +102,7 @@ export class SvgToPngAction extends Action {
102
102
  * @returns A string description of the action.
103
103
  */
104
104
  describe(): string {
105
- return "Converts SVG content to PNG format with optional resizing.";
105
+ return "Converts SVG content to PNG format with optional resizing using resvg-js.";
106
106
  }
107
107
  }
108
108
 
@@ -3,6 +3,7 @@
3
3
  // ============================================================================
4
4
 
5
5
  import { mkdir, writeFile } from "fs/promises";
6
+ import { glob } from "glob";
6
7
  import nunjucks from "nunjucks";
7
8
  import path from "path";
8
9
  import { Action } from "../../core/pipeline/Action";
@@ -13,81 +14,83 @@ import nunjucksConfig from "./nunjucks.config.js";
13
14
  // Classes
14
15
  // ============================================================================
15
16
 
16
- /**
17
- * TemplateRenderAction is responsible for rendering and writing multiple files
18
- * from Nunjucks templates in a single action. It allows batch generation of
19
- * output files based on a shared template context.
20
- */
21
17
  export class TemplateRenderAction extends Action {
22
- /**
23
- * Executes the template rendering process for multiple templates.
24
- *
25
- * @param options - The options specifying the template directory,
26
- * template-output mapping, and rendering context.
27
- * @returns A Promise that resolves when all templates have been rendered.
28
- * @throws {Error} Throws an error if template processing fails.
29
- */
30
18
  async execute(options: ActionOptionsType): Promise<void> {
31
19
  const {
32
20
  templatesDir = "./templates",
21
+ outputDir = "./dist",
33
22
  templates = [],
34
23
  context = {},
24
+ renderAllFromDir = false,
35
25
  customConfig = {},
36
26
  } = options;
37
27
 
38
- if (!Array.isArray(templates) || templates.length === 0) {
39
- throw new Error(
40
- "Invalid options: 'templates' must be an array containing template-output pairs."
41
- );
42
- }
43
-
44
- this.logInfo(`Rendering ${templates.length} templates...`);
28
+ const config = { ...nunjucksConfig, ...customConfig };
29
+ nunjucks.configure(templatesDir, config);
45
30
 
46
31
  try {
47
- // Merge Nunjucks configurations
48
- const config = { ...nunjucksConfig, ...customConfig };
49
- nunjucks.configure(templatesDir, config);
50
-
51
- // Render each template and save to its corresponding output path
52
- for (const { template, outputFile } of templates) {
53
- if (!template || !outputFile) {
32
+ if (renderAllFromDir) {
33
+ this.logInfo(
34
+ `Auto-rendering all templates from ${templatesDir}...`,
35
+ );
36
+ const templateFiles = await glob("**/*.jinja", {
37
+ cwd: templatesDir,
38
+ });
39
+
40
+ for (const templateRelPath of templateFiles) {
41
+ const outputFile = path.join(
42
+ outputDir,
43
+ templateRelPath.replace(/\.jinja$/, ""),
44
+ );
45
+ await this.renderTemplate(
46
+ templateRelPath,
47
+ outputFile,
48
+ context,
49
+ templatesDir,
50
+ );
51
+ }
52
+ } else {
53
+ if (!Array.isArray(templates) || templates.length === 0) {
54
54
  throw new Error(
55
- `Invalid template entry: ${JSON.stringify({
56
- template,
57
- outputFile,
58
- })}`
55
+ "Option 'templates' must be provided if 'renderAllFromDir' is false.",
59
56
  );
60
57
  }
61
58
 
62
- this.logInfo(`Rendering: ${template} ${outputFile}`);
63
-
64
- // Render template content
65
- const content = nunjucks.render(template, context);
66
-
67
- // Ensure the output directory exists
68
- const dir = path.dirname(outputFile);
69
- await mkdir(dir, { recursive: true });
70
-
71
- // Write the rendered template to file
72
- await writeFile(outputFile, content, "utf-8");
73
-
74
- this.logInfo(`✓ Successfully rendered: ${outputFile}`);
59
+ for (const { template, outputFile } of templates) {
60
+ await this.renderTemplate(
61
+ template,
62
+ outputFile,
63
+ context,
64
+ templatesDir,
65
+ );
66
+ }
75
67
  }
76
68
 
77
- this.logInfo("All templates rendered successfully.");
69
+ this.logInfo("All templates rendered successfully.");
78
70
  } catch (error) {
79
71
  this.logError("Error rendering templates.", error);
80
72
  throw error;
81
73
  }
82
74
  }
83
75
 
84
- /**
85
- * Provides a description of the action.
86
- *
87
- * @returns A string description of the action.
88
- */
76
+ private async renderTemplate(
77
+ template: string,
78
+ outputFile: string,
79
+ context: Record<string, any>,
80
+ templatesDir: string,
81
+ ): Promise<void> {
82
+ this.logInfo(`Rendering: ${template} → ${outputFile}`);
83
+
84
+ const content = nunjucks.render(template, context);
85
+ const dir = path.dirname(outputFile);
86
+ await mkdir(dir, { recursive: true });
87
+ await writeFile(outputFile, content, "utf-8");
88
+
89
+ this.logInfo(`✓ Rendered: ${outputFile}`);
90
+ }
91
+
89
92
  describe(): string {
90
- return "Renders multiple Nunjucks templates into files using a shared context.";
93
+ return "Renders one or many Nunjucks templates using a shared context. Supports folder-wide auto-rendering.";
91
94
  }
92
95
  }
93
96
 
@@ -5,23 +5,28 @@
5
5
  // Import
6
6
  // ============================================================================
7
7
 
8
- // Importing path for potential future use in specifying template directories or other file paths
9
- import path from "node:path";
8
+ // Importing path for potential future use in specifying template directories
9
+ // or other file paths
10
10
 
11
11
  // ============================================================================
12
12
  // Constants
13
13
  // ============================================================================
14
14
 
15
15
  /**
16
- * Configuration options for Nunjucks to ensure safe and efficient template rendering.
17
- * This setup is ideal for both development and production environments, providing a balance
18
- * between performance optimizations and security best practices.
16
+ * Configuration options for Nunjucks to ensure safe and efficient template
17
+ * rendering. This setup is ideal for both development and production
18
+ * environments, providing a balance between performance optimizations and
19
+ * security best practices.
19
20
  */
20
21
  const nunjucksConfig = {
21
- autoescape: true, // Controls if output with dangerous characters are escaped automatically
22
- throwOnUndefined: false, // Throw errors when outputting a null/undefined value
23
- trimBlocks: true, // Automatically remove trailing newlines from a block/tag
24
- lstripBlocks: true, // Automatically remove leading whitespace from a block/tag
22
+ // Controls if output with dangerous characters are escaped automatically
23
+ autoescape: true,
24
+ // Throw errors when outputting a null/undefined value
25
+ throwOnUndefined: false,
26
+ // Automatically remove trailing newlines from a block/tag
27
+ trimBlocks: true,
28
+ // Automatically remove leading whitespace from a block/tag
29
+ lstripBlocks: true,
25
30
  noCache: true,
26
31
  };
27
32