sommark 4.3.0 → 4.4.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.
- package/cli/cli.mjs +9 -0
- package/cli/commands/bundle.js +144 -0
- package/cli/commands/help.js +4 -0
- package/cli/constants.js +1 -1
- package/core/evaluator.stub.js +44 -0
- package/core/helpers/lib.js +1 -1
- package/dist/sommark.browser.js +1 -1
- package/dist/sommark.browser.lite.js +13439 -0
- package/dist/sommark.lexer.js +1039 -0
- package/dist/sommark.parser.js +2521 -0
- package/package.json +7 -4
package/cli/cli.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import { printOutput, printLex, printParse } from "./commands/print.js";
|
|
|
12
12
|
import { runInit } from "./commands/init.js";
|
|
13
13
|
import { runShow } from "./commands/show.js";
|
|
14
14
|
import { runColor } from "./commands/color.js";
|
|
15
|
+
import { runBundle } from "./commands/bundle.js";
|
|
15
16
|
import { extensions } from "./constants.js";
|
|
16
17
|
|
|
17
18
|
// ========================================================================== //
|
|
@@ -57,6 +58,14 @@ async function main() {
|
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
// 4.5. Bundle
|
|
62
|
+
if (command === "bundle") {
|
|
63
|
+
const targetDir = args.find(a => !a.startsWith("--") && a !== "bundle");
|
|
64
|
+
const flags = args.filter(a => a.startsWith("--"));
|
|
65
|
+
await runBundle(targetDir, flags);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
60
69
|
|
|
61
70
|
|
|
62
71
|
// 5. Show
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { cliError, formatMessage } from "../../core/errors.js";
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
const DIST_SRC = path.resolve(__dirname, "../../dist");
|
|
9
|
+
|
|
10
|
+
const BUNDLES = {
|
|
11
|
+
"--lite": { file: "sommark.browser.lite.js", label: "Lite bundle", note: "no WASM — static/runtime blocks disabled" },
|
|
12
|
+
"--only-lexer": { file: "sommark.lexer.js", label: "Lexer bundle", note: "lexSync, lex, TOKEN_TYPES, labels only" },
|
|
13
|
+
"--only-parser": { file: "sommark.parser.js", label: "Parser bundle", note: "lexSync, lex, parseSync, parse, TOKEN_TYPES, labels only" },
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
async function copyDir(src, dest) {
|
|
17
|
+
await fs.mkdir(dest, { recursive: true });
|
|
18
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
const srcPath = path.join(src, entry.name);
|
|
21
|
+
const destPath = path.join(dest, entry.name);
|
|
22
|
+
if (entry.isDirectory()) {
|
|
23
|
+
await copyDir(srcPath, destPath);
|
|
24
|
+
} else {
|
|
25
|
+
await fs.copyFile(srcPath, destPath);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function getDirSize(dir) {
|
|
31
|
+
let total = 0;
|
|
32
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
const full = path.join(dir, entry.name);
|
|
35
|
+
if (entry.isDirectory()) {
|
|
36
|
+
total += await getDirSize(full);
|
|
37
|
+
} else {
|
|
38
|
+
const stat = await fs.stat(full);
|
|
39
|
+
total += stat.size;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return total;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function ensureDir(outDir) {
|
|
46
|
+
let exists = false;
|
|
47
|
+
try {
|
|
48
|
+
const stat = await fs.stat(outDir);
|
|
49
|
+
if (!stat.isDirectory()) {
|
|
50
|
+
cliError([
|
|
51
|
+
`{line}<$red:Target path$> <$yellow:'${outDir}'$> <$red:already exists but is a file, not a directory.$>{line}`
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
exists = true;
|
|
55
|
+
} catch (err) {
|
|
56
|
+
if (err.code !== "ENOENT") throw err;
|
|
57
|
+
}
|
|
58
|
+
if (!exists) {
|
|
59
|
+
try {
|
|
60
|
+
await fs.mkdir(outDir, { recursive: true });
|
|
61
|
+
} catch (err) {
|
|
62
|
+
cliError([
|
|
63
|
+
`{line}<$red:Could not create directory$> <$yellow:'${outDir}'$>{N}`,
|
|
64
|
+
`<$blue:${err.message}$>{line}`
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function runBundle(targetDir, flags = []) {
|
|
71
|
+
const outDir = targetDir ? path.resolve(process.cwd(), targetDir) : process.cwd();
|
|
72
|
+
|
|
73
|
+
// Partial bundle (--lite, --only-lexer, --only-parser)
|
|
74
|
+
const partialFlag = flags.find(f => BUNDLES[f]);
|
|
75
|
+
if (partialFlag) {
|
|
76
|
+
const { file, label, note } = BUNDLES[partialFlag];
|
|
77
|
+
const src = path.resolve(DIST_SRC, file);
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
await fs.access(src);
|
|
81
|
+
} catch {
|
|
82
|
+
cliError([
|
|
83
|
+
`{line}<$red:${label} not found at$> <$yellow:'${src}'$>{N}`,
|
|
84
|
+
`<$red:Your SomMark installation may be incomplete or corrupted.$>{line}`
|
|
85
|
+
]);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
await ensureDir(outDir);
|
|
89
|
+
|
|
90
|
+
const dest = path.join(outDir, file);
|
|
91
|
+
try {
|
|
92
|
+
await fs.copyFile(src, dest);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
cliError([
|
|
95
|
+
`{line}<$red:Failed to copy ${label.toLowerCase()} to$> <$yellow:'${dest}'$>{N}`,
|
|
96
|
+
`<$blue:${err.message}$>{line}`
|
|
97
|
+
]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const stats = await fs.stat(dest);
|
|
101
|
+
const date = new Date().toLocaleString();
|
|
102
|
+
console.log(formatMessage(
|
|
103
|
+
[
|
|
104
|
+
`{line}[<$yellow: STATUS$> : <$green: SUCCESS$>]{line}`,
|
|
105
|
+
`<$blue:${label}$> <$yellow:'${file}'$> <$blue:copied to$> <$yellow:'${outDir}'$>{N}`,
|
|
106
|
+
`<$blue:Size:$> <$yellow:${(stats.size / 1024).toFixed(1)} KB$> <$yellow:(${note})$>{N}`,
|
|
107
|
+
`<$blue:Date:$> <$yellow:${date}$>{line}`
|
|
108
|
+
].join("")
|
|
109
|
+
));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Full: copy entire dist folder
|
|
114
|
+
try {
|
|
115
|
+
await fs.access(DIST_SRC);
|
|
116
|
+
} catch {
|
|
117
|
+
cliError([
|
|
118
|
+
`{line}<$red:dist folder not found at$> <$yellow:'${DIST_SRC}'$>{N}`,
|
|
119
|
+
`<$red:Your SomMark installation may be incomplete or corrupted.$>{line}`
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
await ensureDir(outDir);
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
await copyDir(DIST_SRC, outDir);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
cliError([
|
|
129
|
+
`{line}<$red:Failed to copy bundle to$> <$yellow:'${outDir}'$>{N}`,
|
|
130
|
+
`<$blue:${err.message}$>{line}`
|
|
131
|
+
]);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const totalSize = await getDirSize(outDir);
|
|
135
|
+
const date = new Date().toLocaleString();
|
|
136
|
+
console.log(formatMessage(
|
|
137
|
+
[
|
|
138
|
+
`{line}[<$yellow: STATUS$> : <$green: SUCCESS$>]{line}`,
|
|
139
|
+
`<$blue:Bundle copied to$> <$yellow:'${outDir}'$>{N}`,
|
|
140
|
+
`<$blue:Total size:$> <$yellow:${(totalSize / 1024).toFixed(1)} KB$>{N}`,
|
|
141
|
+
`<$blue:Date:$> <$yellow:${date}$>{line}`
|
|
142
|
+
].join("")
|
|
143
|
+
));
|
|
144
|
+
}
|
package/cli/commands/help.js
CHANGED
|
@@ -22,6 +22,10 @@ export function getHelp(unknown_option = true) {
|
|
|
22
22
|
"{N} <$green:show config [file]$> <$cyan: Display the configuration data (for a specific file or CWD)$>",
|
|
23
23
|
"{N} <$green:show --path-config [file]$> <$cyan: Display the absolute path to the active config file$>",
|
|
24
24
|
"{N} <$green:color on|off$> <$cyan: Help on enabling colors via Environment Variables$>",
|
|
25
|
+
"{N} <$green:bundle [dir]$> <$cyan: Copy the full browser bundle (JS + WASM) to a directory$>",
|
|
26
|
+
"{N} <$green:bundle [dir] --lite$> <$cyan: Lite bundle — no WASM, static/runtime blocks disabled$>",
|
|
27
|
+
"{N} <$green:bundle [dir] --only-lexer$> <$cyan: Lexer only — lexSync, lex, TOKEN_TYPES, labels$>",
|
|
28
|
+
"{N} <$green:bundle [dir] --only-parser$> <$cyan: Parser only — lexSync, parseSync and above$>",
|
|
25
29
|
|
|
26
30
|
"{N}{N}<$yellow:Transpilation Options:$>",
|
|
27
31
|
"{N}<$yellow:Usage:$> <$blue:sommark [option] [targetFile] [option] [outputFile] [outputDir]$>",
|
package/cli/constants.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/** @type {Array<string>} List of recognized CLI flags and commands. */
|
|
7
|
-
export const options = ["-v", "--version", "-h", "--help", "--html", "--markdown", "--mdx", "--json", "--jsonc", "--text", "--xml", "--print", "-p", "--lex", "--parse", "list"];
|
|
7
|
+
export const options = ["-v", "--version", "-h", "--help", "--html", "--markdown", "--mdx", "--json", "--jsonc", "--text", "--xml", "--print", "-p", "--lex", "--parse", "list", "bundle"];
|
|
8
8
|
|
|
9
9
|
/** @type {Object<string, string>} Map of output formats to their respective file extensions. */
|
|
10
10
|
export const extensions = {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Lite-mode stub — same interface as evaluator.js but without QuickJS/WASM.
|
|
2
|
+
// Static and runtime blocks throw a clear error instead of executing.
|
|
3
|
+
|
|
4
|
+
const LITE_ERROR =
|
|
5
|
+
"[SomMark lite] static ${}$ and runtime ${}$ blocks are not supported in lite mode. " +
|
|
6
|
+
"Use the full SomMark bundle to enable JS evaluation.";
|
|
7
|
+
|
|
8
|
+
export function setCompilerClass(_cls) {}
|
|
9
|
+
|
|
10
|
+
class EvaluatorStub {
|
|
11
|
+
setDefaultFs(_fs) {}
|
|
12
|
+
|
|
13
|
+
get active() {
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async init(_baseDir, _security, _settings, _mapperFile) {}
|
|
18
|
+
|
|
19
|
+
destroy() {}
|
|
20
|
+
|
|
21
|
+
pushScope() {}
|
|
22
|
+
|
|
23
|
+
async popScope() {}
|
|
24
|
+
|
|
25
|
+
inject(_vars) {}
|
|
26
|
+
|
|
27
|
+
async execute(_code) {
|
|
28
|
+
throw new Error(LITE_ERROR);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
hasDynamicTag(_id) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getDynamicTagOptions(_id) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async executeDynamicTag(_id, _payload) {
|
|
40
|
+
throw new Error(LITE_ERROR);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default new EvaluatorStub();
|
package/core/helpers/lib.js
CHANGED