sommark 4.0.2 → 4.0.3

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/cli/cli.mjs CHANGED
@@ -61,7 +61,7 @@ async function main() {
61
61
 
62
62
  // 5. Show
63
63
  if (command === "show") {
64
- await runShow(args[1]);
64
+ await runShow(args[1], args[2]);
65
65
  return;
66
66
  }
67
67
 
@@ -19,7 +19,8 @@ export function getHelp(unknown_option = true) {
19
19
  "{N} <$green:-h, --help$> <$cyan: Show help message$>",
20
20
  "{N} <$green:-v, --version$> <$cyan: Show version information$>",
21
21
  "{N} <$green:init$> <$cyan: Initialize local SomMark configuration file (smark.config.js)$>",
22
- "{N} <$green:show config$> <$cyan: Display the absolute paths to the active SomMark configuration files$>",
22
+ "{N} <$green:show config [file]$> <$cyan: Display the configuration data (for a specific file or CWD)$>",
23
+ "{N} <$green:show --path-config [file]$> <$cyan: Display the absolute path to the active config file$>",
23
24
  "{N} <$green:color on|off$> <$cyan: Help on enabling colors via Environment Variables$>",
24
25
 
25
26
  "{N}{N}<$yellow:Transpilation Options:$>",
@@ -8,30 +8,40 @@ import { loadConfig, getResolvedConfigPath } from "../helpers/config.js";
8
8
  /**
9
9
  * Shows the configuration data or where the settings file is located.
10
10
  * @param {string} target - The target to show ('config' or '--path-config').
11
+ * @param {string|null} [filePath=null] - Optional file path to show config for.
11
12
  */
12
- export async function runShow(target) {
13
- const config = await loadConfig();
13
+ export async function runShow(target, filePath = null) {
14
+ const config = await loadConfig(filePath);
14
15
  const resolvedPath = getResolvedConfigPath();
16
+ const contextText = filePath ? ` for <$blue:'${filePath}'$>` : "";
15
17
 
16
18
  if (target === "config") {
17
19
  try {
18
- console.log(formatMessage(`{N}<$yellow:SomMark Configuration Data:$>{N}`));
20
+ console.log(formatMessage(`{N}<$yellow:SomMark Configuration Data$>${contextText}<$yellow::$>{N}`));
19
21
 
20
- // Format config for display (hide large objects)
22
+ // Format config for display (hide large objects and internal metadata)
21
23
  const displayConfig = { ...config };
22
- if (displayConfig.mappingFile && typeof displayConfig.mappingFile === "object") {
23
- displayConfig.mappingFile = "[Mapper Object]";
24
+ const configPath = displayConfig.resolvedConfigPath;
25
+ delete displayConfig.resolvedConfigPath;
26
+
27
+ if (displayConfig.mapperFile && typeof displayConfig.mapperFile === "object") {
28
+ displayConfig.mapperFile = "[Mapper Object]";
24
29
  }
25
30
 
26
31
  console.log(JSON.stringify(displayConfig, null, 4));
27
- console.log("");
32
+
33
+ if (configPath) {
34
+ console.log(formatMessage(`{N}<$yellow:Active Config Path:$> <$green:${configPath}$>{N}`));
35
+ } else {
36
+ console.log(formatMessage(`{N}<$yellow:Active Config Path:$> <$red:None (Using Defaults)$>{N}`));
37
+ }
28
38
  } catch (error) {
29
39
  cliError([
30
40
  `{line}<$red:Failed to retrieve configuration data:$> <$magenta:${error.message}$>{line}`
31
41
  ]);
32
42
  }
33
43
  } else if (target === "--path-config") {
34
- console.log(formatMessage(`{N}<$yellow:SomMark Configuration Path:$>{N}`));
44
+ console.log(formatMessage(`{N}<$yellow:SomMark Configuration Path$>${contextText}<$yellow::$>{N}`));
35
45
  if (resolvedPath) {
36
46
  console.log(formatMessage(` <$green:${resolvedPath}$>{N}`));
37
47
  } else {
@@ -40,8 +50,8 @@ export async function runShow(target) {
40
50
  } else {
41
51
  cliError([
42
52
  `{line}<$red:Invalid target for 'show' command:$> <$blue:'${target || ""}'$> `,
43
- `{N}<$yellow:Usage:$> {N} <$cyan:sommark show config$> - Displays configuration data`,
44
- ` <$cyan:sommark show --path-config$> - Displays configuration file path{line}`
53
+ `{N}<$yellow:Usage:$> {N} <$cyan:sommark show config [file]$> - Displays configuration data`,
54
+ ` <$cyan:sommark show --path-config [file]$> - Displays configuration file path{line}`
45
55
  ]);
46
56
  }
47
57
  }
@@ -31,37 +31,42 @@ async function loadConfigFile(configPath) {
31
31
  * @returns {Promise<Object>} - The final configuration merged with defaults.
32
32
  */
33
33
  export async function findAndLoadConfig(targetPath) {
34
- let startDir = process.cwd();
34
+ const cwd = process.cwd();
35
35
  let configPath = null;
36
+ let startDir = cwd;
36
37
 
37
- // 1. Check if targetPath is an explicit config file path
38
+ // 1. Resolve Target Directory
38
39
  if (targetPath) {
39
40
  try {
40
- const stats = await fs.stat(targetPath);
41
- if (stats.isFile() && targetPath.endsWith(".js")) {
42
- configPath = path.resolve(targetPath);
41
+ const absoluteTarget = path.resolve(cwd, targetPath);
42
+ const stats = await fs.stat(absoluteTarget);
43
+
44
+ // If target is a .js file, it might be an explicit config (legacy/internal support)
45
+ if (stats.isFile() && absoluteTarget.endsWith(".js") && !absoluteTarget.endsWith("smark.config.js")) {
46
+ configPath = absoluteTarget;
43
47
  } else {
44
- startDir = stats.isDirectory() ? targetPath : path.dirname(targetPath);
48
+ startDir = stats.isDirectory() ? absoluteTarget : path.dirname(absoluteTarget);
45
49
  }
46
50
  } catch {
47
- // Path doesn't exist
51
+ // Path doesn't exist, fallback to CWD
48
52
  }
49
53
  }
50
54
 
51
- // 2. Check the target directory
55
+ // 2. Check the Target Directory (Highest Priority)
52
56
  if (!configPath) {
53
- const localConfig = path.join(startDir, CONFIG_FILE_NAME);
57
+ const targetConfig = path.join(startDir, CONFIG_FILE_NAME);
54
58
  try {
55
- await fs.access(localConfig);
56
- configPath = localConfig;
59
+ await fs.access(targetConfig);
60
+ configPath = targetConfig;
57
61
  } catch {
58
- // No local config found in target dir
62
+ // No config found in target dir
59
63
  }
60
64
  }
61
65
 
62
- // 3. Check the current working directory (if different from target dir)
63
- if (!configPath && startDir !== process.cwd()) {
64
- const cwdConfig = path.join(process.cwd(), CONFIG_FILE_NAME);
66
+ // 3. Check the Current Working Directory (Fallback)
67
+ // We only check CWD if it's different from the Target Directory
68
+ if (!configPath && startDir !== cwd) {
69
+ const cwdConfig = path.join(cwd, CONFIG_FILE_NAME);
65
70
  try {
66
71
  await fs.access(cwdConfig);
67
72
  configPath = cwdConfig;
package/core/validator.js CHANGED
@@ -22,14 +22,23 @@ const runValidations = (node, target, instance) => {
22
22
  const context = instance ? { src: instance.src, range: node.range, filename: instance.filename } : null;
23
23
 
24
24
  // -- Structural Integrity (Self-Closing) ------------------------------ //
25
- if (rules.is_self_closing && (node.type === "Block" && (node.body && node.body.length > 0))) {
26
- transpilerError(
27
- [
28
- "<$red:Validation Error:$> ",
29
- `<$yellow:Identifier$> <$blue:'${id}'$> <$yellow:is self-closing and cannot have children (body).$>`
30
- ],
31
- context
32
- );
25
+ if (rules.is_self_closing && node.type === "Block" && node.body) {
26
+ const hasContent = node.body.some(child => {
27
+ if (child.type === "Text") {
28
+ return (child.text || "").trim().length > 0;
29
+ }
30
+ return true; // Any other node type (Block, Inline, etc.) counts as content
31
+ });
32
+
33
+ if (hasContent) {
34
+ transpilerError(
35
+ [
36
+ "<$red:Validation Error:$> ",
37
+ `<$yellow:Identifier$> <$blue:'${id}'$> <$yellow:is self-closing and cannot have children (body).$>`
38
+ ],
39
+ context
40
+ );
41
+ }
33
42
  }
34
43
  };
35
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sommark",
3
- "version": "4.0.2",
3
+ "version": "4.0.3",
4
4
  "description": "SomMark is a declarative, extensible markup language for structured content that can be converted to HTML, Markdown, MDX, JSON, XML, and more.",
5
5
  "main": "index.js",
6
6
  "files": [