sommark 4.0.1 → 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 +1 -1
- package/cli/commands/help.js +2 -1
- package/cli/commands/show.js +20 -10
- package/cli/helpers/transpile.js +9 -4
- package/core/helpers/config-loader.js +28 -12
- package/core/validator.js +17 -8
- package/package.json +1 -1
package/cli/cli.mjs
CHANGED
package/cli/commands/help.js
CHANGED
|
@@ -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
|
|
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:$>",
|
package/cli/commands/show.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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
|
|
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
|
}
|
package/cli/helpers/transpile.js
CHANGED
|
@@ -31,10 +31,15 @@ export async function transpile({ src, format, filename = null, mapperFile = "",
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// Custom Mapper (String Path)
|
|
34
|
-
if (typeof finalMapper === "string" && finalMapper !== ""
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
|
|
34
|
+
if (typeof finalMapper === "string" && finalMapper !== "") {
|
|
35
|
+
const baseDir = finalConfig.resolvedConfigPath ? path.dirname(finalConfig.resolvedConfigPath) : process.cwd();
|
|
36
|
+
const absoluteMapperPath = path.resolve(baseDir, finalMapper);
|
|
37
|
+
|
|
38
|
+
if (await isExist(absoluteMapperPath)) {
|
|
39
|
+
const mapperFileURL = `${pathToFileURL(absoluteMapperPath).href}?t=${Date.now()}`;
|
|
40
|
+
const loadedMapper = await import(mapperFileURL);
|
|
41
|
+
finalMapper = loadedMapper.default;
|
|
42
|
+
}
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
|
|
@@ -31,31 +31,47 @@ 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
|
-
|
|
34
|
+
const cwd = process.cwd();
|
|
35
35
|
let configPath = null;
|
|
36
|
+
let startDir = cwd;
|
|
36
37
|
|
|
37
|
-
// 1.
|
|
38
|
+
// 1. Resolve Target Directory
|
|
38
39
|
if (targetPath) {
|
|
39
40
|
try {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
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() ?
|
|
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
|
|
55
|
+
// 2. Check the Target Directory (Highest Priority)
|
|
52
56
|
if (!configPath) {
|
|
53
|
-
const
|
|
57
|
+
const targetConfig = path.join(startDir, CONFIG_FILE_NAME);
|
|
58
|
+
try {
|
|
59
|
+
await fs.access(targetConfig);
|
|
60
|
+
configPath = targetConfig;
|
|
61
|
+
} catch {
|
|
62
|
+
// No config found in target dir
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
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);
|
|
54
70
|
try {
|
|
55
|
-
await fs.access(
|
|
56
|
-
configPath =
|
|
71
|
+
await fs.access(cwdConfig);
|
|
72
|
+
configPath = cwdConfig;
|
|
57
73
|
} catch {
|
|
58
|
-
// No
|
|
74
|
+
// No config found in CWD
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
77
|
|
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 &&
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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