@terrymooreii/sia 2.3.0 → 2.3.1

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/lib/build.js CHANGED
@@ -236,6 +236,7 @@ export async function build(options = {}) {
236
236
  // Load plugins
237
237
  let plugins = [];
238
238
  try {
239
+ console.log('🔌 Loading plugins...');
239
240
  plugins = await loadPlugins(config);
240
241
 
241
242
  // Register plugin hooks
package/lib/plugins.js CHANGED
@@ -45,13 +45,21 @@ export function validatePlugin(plugin, pluginPath) {
45
45
  export async function loadPlugin(pluginPath, config) {
46
46
  try {
47
47
  // Support both .js and .mjs files
48
+ // Add cache busting query parameter to ensure fresh reloads during dev
49
+ // This prevents Node.js from using cached versions of plugins during hot reload
50
+ const cacheBuster = `?t=${Date.now()}`;
48
51
  let module;
49
52
 
50
- if (pluginPath.endsWith('.mjs')) {
51
- module = await import(`file://${pluginPath}`);
52
- } else {
53
- module = await import(pluginPath);
54
- }
53
+ // Normalize path to use file:// protocol for consistent cache busting
54
+ // All plugin paths from discovery are absolute, so we can safely use file://
55
+ const normalizedPath = pluginPath.startsWith('file://')
56
+ ? pluginPath
57
+ : pluginPath.startsWith('/') || /^[A-Za-z]:/.test(pluginPath) // Unix absolute or Windows drive
58
+ ? `file://${pluginPath}`
59
+ : pluginPath; // Relative path (shouldn't happen, but handle it)
60
+
61
+ // Import with cache busting to ensure fresh reloads during dev
62
+ module = await import(`${normalizedPath}${cacheBuster}`);
55
63
 
56
64
  // Support both default export and named export
57
65
  const plugin = module.default || module;
@@ -86,18 +94,31 @@ export function discoverLocalPlugins(rootDir) {
86
94
 
87
95
  try {
88
96
  const items = readdirSync(pluginsDir);
97
+ console.log(`🔍 Scanning _plugins directory: found ${items.length} item(s)`);
89
98
 
90
99
  for (const item of items) {
91
100
  const itemPath = join(pluginsDir, item);
92
101
  const stat = statSync(itemPath);
93
102
 
94
- // Only process .js and .mjs files
95
- if (stat.isFile() && (item.endsWith('.js') || item.endsWith('.mjs'))) {
103
+ // Check extension case-insensitively
104
+ const lowerItem = item.toLowerCase();
105
+ const isJsFile = lowerItem.endsWith('.js') || lowerItem.endsWith('.mjs');
106
+
107
+ // Debug: log what we found
108
+ if (stat.isFile()) {
109
+ console.log(` 📄 Found file: ${item} (${isJsFile ? 'plugin candidate' : 'skipped - not .js/.mjs'})`);
110
+ } else if (stat.isDirectory()) {
111
+ console.log(` 📁 Found directory: ${item} (skipped - plugins must be files)`);
112
+ }
113
+
114
+ // Only process .js and .mjs files (case-insensitive)
115
+ if (stat.isFile() && isJsFile) {
96
116
  plugins.push({
97
117
  type: 'local',
98
118
  path: itemPath,
99
- name: item.replace(/\.(js|mjs)$/, '')
119
+ name: item.replace(/\.(js|mjs)$/i, '') // Case-insensitive replacement
100
120
  });
121
+ console.log(` ✓ Added plugin: ${item}`);
101
122
  }
102
123
  }
103
124
  } catch (err) {
@@ -250,9 +271,15 @@ export async function discoverPlugins(config) {
250
271
 
251
272
  // Filter by explicit plugin list if provided
252
273
  const explicitPlugins = config.plugins?.plugins;
253
- if (explicitPlugins && Array.isArray(explicitPlugins)) {
274
+ if (explicitPlugins && Array.isArray(explicitPlugins) && explicitPlugins.length > 0) {
275
+ console.log(`🔍 Filtering plugins: only loading ${explicitPlugins.join(', ')}`);
254
276
  const explicitSet = new Set(explicitPlugins);
255
- return discovered.filter(p => explicitSet.has(p.name));
277
+ const filtered = discovered.filter(p => explicitSet.has(p.name));
278
+ const filteredOut = discovered.filter(p => !explicitSet.has(p.name));
279
+ if (filteredOut.length > 0) {
280
+ console.log(` ⚠️ Filtered out ${filteredOut.length} plugin(s): ${filteredOut.map(p => p.name).join(', ')}`);
281
+ }
282
+ return filtered;
256
283
  }
257
284
 
258
285
  return discovered;
@@ -262,9 +289,24 @@ export async function discoverPlugins(config) {
262
289
  * Load all discovered plugins
263
290
  */
264
291
  export async function loadPlugins(config) {
292
+ // Check if plugins are disabled
293
+ if (config.plugins?.enabled === false) {
294
+ console.log('🔌 Plugins are disabled in config');
295
+ return [];
296
+ }
297
+
298
+ const rootDir = config.rootDir || process.cwd();
265
299
  const discovered = await discoverPlugins(config);
266
300
 
267
301
  if (discovered.length === 0) {
302
+ // Log that we checked but found nothing (helps with debugging)
303
+ const pluginsDir = join(rootDir, '_plugins');
304
+ const hasPluginsDir = existsSync(pluginsDir);
305
+ if (hasPluginsDir) {
306
+ console.log('🔌 No plugins discovered (directory exists but no valid plugins found)');
307
+ } else {
308
+ console.log('🔌 No plugins directory found, skipping plugin discovery');
309
+ }
268
310
  return [];
269
311
  }
270
312
 
package/lib/server.js CHANGED
@@ -166,7 +166,8 @@ function setupWatcher(config, wss) {
166
166
  config.includesDir,
167
167
  join(config.rootDir, '_config.yml'),
168
168
  join(config.rootDir, '_config.json'),
169
- join(config.rootDir, 'styles')
169
+ join(config.rootDir, 'styles'),
170
+ join(config.rootDir, '_plugins')
170
171
  ].filter(p => existsSync(p));
171
172
 
172
173
  const watcher = chokidar.watch(watchPaths, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terrymooreii/sia",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "description": "A simple, powerful static site generator with markdown, front matter, and Nunjucks templates",
5
5
  "main": "lib/index.js",
6
6
  "bin": {