mikel-cli 0.31.0 → 0.32.0

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 (3) hide show
  1. package/README.md +1 -0
  2. package/index.js +64 -47
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -34,6 +34,7 @@ $ mikel <template> [options]
34
34
  | `--help` | `-h` | Display help information |
35
35
  | `--data <file>` | `-D` | Path to JSON data file |
36
36
  | `--output <file>` | `-o` | Output file path |
37
+ | `--plugin <module>` | `-L` | Load a Mikel plugin from a JavaScript module (can be used multiple times) |
37
38
  | `--partial <file>` | `-P` | Register a partial template (supports glob patterns, can be used multiple times) |
38
39
  | `--helper <file>` | `-H` | Register helper functions from a JavaScript module (supports glob patterns, can be used multiple times) |
39
40
  | `--function <file>` | `-F` | Register functions from a JavaScript module (supports glob patterns, can be used multiple times) |
package/index.js CHANGED
@@ -55,44 +55,14 @@ const loadData = async (file = null) => {
55
55
  }
56
56
  };
57
57
 
58
- // @description load partials
59
- const loadPartials = async (patterns = []) => {
60
- const partials = {}; // output partials object
61
- const files = await expandGlobPatterns(patterns);
62
-
63
- // load all files
64
- for (let i = 0; i < files.length; i++) {
65
- const file = files[i]; // path.resolve(process.cwd(), uniqueFiles[i]);
66
- if (!existsSync(file)) {
67
- throw new Error(`Partial file '${file}' was not found.`);
68
- }
69
-
70
- // check if it's a file (not a directory)
71
- const stats = await fs.stat(file);
72
- if (!stats.isFile()) {
73
- continue; // skip directories
74
- }
75
-
76
- // load the file and save it as a partial
77
- try {
78
- partials[path.basename(file)] = await fs.readFile(file, "utf8");
79
- } catch (error) {
80
- throw new Error(`Failed to read partial file '${file}': ${error.message}`);
81
- }
82
- }
83
-
84
- return partials;
85
- };
86
-
87
58
  // @description load javascript modules
88
- const loadModules = async (patterns = []) => {
89
- const result = {};
59
+ const loadModules = async (patterns = [], callback) => {
90
60
  const files = await expandGlobPatterns(patterns);
91
61
 
92
62
  for (let i = 0; i < files.length; i++) {
93
63
  const file = files[i]; // path.resolve(process.cwd(), uniqueFiles[i]);
94
64
  if (!existsSync(file)) {
95
- throw new Error(`Module '${file}' was not found.`);
65
+ throw new Error(`File '${file}' was not found.`);
96
66
  }
97
67
 
98
68
  // Check if it's a file (not a directory)
@@ -101,21 +71,13 @@ const loadModules = async (patterns = []) => {
101
71
  continue; // Skip directories
102
72
  }
103
73
 
104
- const extension = path.extname(file);
105
- if (extension !== ".js" && extension !== ".mjs") {
106
- throw new Error(`Module '${file}' is not supported. Only ESM JavaScript (.js or .mjs) files are supported.`);
107
- }
108
74
  // import the module
109
75
  try {
110
- const content = (await import(file)) || {};
111
- if (typeof content === "object" && !!content) {
112
- Object.assign(result, content);
113
- }
76
+ await callback(file);
114
77
  } catch (error) {
115
- throw new Error(`Failed to import module '${file}': ${error.message}`);
78
+ throw new Error(`Failed to load '${file}': ${error.message}`);
116
79
  }
117
80
  }
118
- return result;
119
81
  };
120
82
 
121
83
  // print the help of the tool
@@ -129,6 +91,7 @@ const printHelp = () => {
129
91
  console.log(" -P, --partial <file> Register a partial (supports glob patterns, can be used multiple times)");
130
92
  console.log(" -H, --helper <file> Register a helper (supports glob patterns, can be used multiple times)");
131
93
  console.log(" -F, --function <file> Register a function (supports glob patterns, can be used multiple times)");
94
+ console.log(" -L, --plugin <file> Load a plugin from node_modules (can be used multiple times)");
132
95
  console.log(" -D, --data <file> Path to the data file to use (JSON)");
133
96
  console.log(" -o, --output <file> Output file");
134
97
  console.log("");
@@ -165,16 +128,65 @@ const main = async (input = "", options = {}) => {
165
128
  throw new Error(`Failed to read template file '${inputPath}': ${error.message}`);
166
129
  }
167
130
 
168
- // load additional data
131
+ // initialize the template engine
132
+ const mikelInstance = mikel.create({});
169
133
  const data = await loadData(options.data);
170
- const partials = await loadPartials(options.partial);
171
- const helpers = await loadModules(options.helper);
172
- const functions = await loadModules(options.function);
134
+
135
+ // load plugins
136
+ for (let i = 0; i < (options.plugin || []).length; i++) {
137
+ const pluginName = options.plugin[i];
138
+ let pluginModule;
139
+ try {
140
+ // try to import the plugin from node_modules
141
+ pluginModule = (await import(pluginName))?.default;
142
+ if (typeof pluginModule !== "function") {
143
+ throw new Error(`Plugin '${pluginName}' does not export a valid plugin function.`);
144
+ }
145
+ mikelInstance.use(pluginModule());
146
+ } catch (error) {
147
+ throw new Error(`Failed to load plugin '${pluginName}': ${error.message}`);
148
+ }
149
+ }
150
+
151
+ // load additional partials, helpers, and functions
152
+ await loadModules(options.partial, async (file) => {
153
+ try {
154
+ mikelInstance.addPartial(path.basename(file), await fs.readFile(file, "utf8"));
155
+ } catch (error) {
156
+ throw new Error(`Failed to read partial file '${file}': ${error.message}`);
157
+ }
158
+ });
159
+ await loadModules(options.helper, async (file) => {
160
+ const extension = path.extname(file);
161
+ if (extension !== ".js" && extension !== ".mjs") {
162
+ throw new Error(`Module '${file}' is not supported. Only ESM JavaScript (.js or .mjs) files are supported.`);
163
+ }
164
+ // import the module
165
+ const content = (await import(file)) || {};
166
+ if (typeof content === "object" && !!content) {
167
+ Object.keys(content).forEach(helperName => {
168
+ mikelInstance.addHelper(helperName, content[helperName]);
169
+ });
170
+ }
171
+ });
172
+ await loadModules(options.function, async (file) => {
173
+ const extension = path.extname(file);
174
+ if (extension !== ".js" && extension !== ".mjs") {
175
+ throw new Error(`Module '${file}' is not supported. Only ESM JavaScript (.js or .mjs) files are supported.`);
176
+ }
177
+ // import the module
178
+ const content = (await import(file)) || {};
179
+ if (typeof content === "object" && !!content) {
180
+ Object.keys(content).forEach(functionName => {
181
+ mikelInstance.addFunction(functionName, content[functionName]);
182
+ });
183
+ }
184
+ });
173
185
 
174
186
  // compile the template
175
187
  let result;
176
188
  try {
177
- result = mikel(template, data || {}, { helpers, functions, partials });
189
+ result = mikelInstance(template, data || {});
178
190
  } catch (error) {
179
191
  throw new Error(`Template compilation failed: ${error.message}`);
180
192
  }
@@ -233,6 +245,11 @@ const { positionals, values } = parseArgs({
233
245
  short: "P",
234
246
  multiple: true,
235
247
  },
248
+ plugin: {
249
+ type: "string",
250
+ short: "L",
251
+ multiple: true,
252
+ },
236
253
  help: {
237
254
  type: "boolean",
238
255
  short: "h",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mikel-cli",
3
3
  "description": "The cli tool for mikel templating.",
4
- "version": "0.31.0",
4
+ "version": "0.32.0",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": {
@@ -22,7 +22,7 @@
22
22
  "mikel": "index.js"
23
23
  },
24
24
  "peerDependencies": {
25
- "mikel": "^0.31.0"
25
+ "mikel": "^0.32.0"
26
26
  },
27
27
  "files": [
28
28
  "README.md",