@allior/wmake-cli 0.0.6 → 0.0.7
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/dist/bin.d.ts +1 -1
- package/dist/bin.js +27 -65
- package/dist/generate-fields.d.ts +9 -17
- package/dist/generate-fields.d.ts.map +1 -1
- package/dist/generate-fields.js +68 -75
- package/dist/vite-config.d.ts +20 -12
- package/dist/vite-config.d.ts.map +1 -1
- package/dist/vite-config.js +109 -104
- package/dist/widget.d.ts +6 -2
- package/dist/widget.d.ts.map +1 -1
- package/dist/widget.js +124 -168
- package/package.json +3 -4
- package/src/bin.ts +28 -66
- package/src/generate-fields.ts +104 -117
- package/src/vite-config.ts +113 -117
- package/src/widget.ts +155 -216
package/dist/widget.js
CHANGED
|
@@ -1,182 +1,138 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Сборка виджета: html.txt, js.txt, css.txt, fields.txt, data.txt и архив .zip.
|
|
3
|
-
* Все пути относительно текущей папки (откуда вызывается скрипт).
|
|
4
|
-
*/
|
|
5
1
|
import fs from "node:fs";
|
|
6
2
|
import path from "node:path";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
import { build } from "vite";
|
|
4
|
+
import { getRawWmakeGlobals, getWmakeDeps, getWmakeDepsWithVersions } from "./vite-config.js";
|
|
5
|
+
import { generateMergedFields } from "./generate-fields.js";
|
|
6
|
+
import admZip from "adm-zip";
|
|
7
|
+
/** Builds project for StreamElements widget using CDN mode */
|
|
8
|
+
export async function buildWidget(options = {}) {
|
|
9
|
+
const { full = false, seDir } = options;
|
|
10
|
+
const projectDir = process.cwd();
|
|
11
|
+
await build({
|
|
12
|
+
configFile: path.resolve(projectDir, "vite.widget.config.ts"),
|
|
13
|
+
build: {
|
|
14
|
+
emptyOutDir: true,
|
|
15
|
+
minify: true,
|
|
16
|
+
}
|
|
19
17
|
});
|
|
20
|
-
return r.status === 0;
|
|
21
|
-
}
|
|
22
|
-
function getPackageManager() {
|
|
23
|
-
const userAgent = process.env.npm_config_user_agent || "";
|
|
24
|
-
if (userAgent.includes("bun"))
|
|
25
|
-
return "bun";
|
|
26
|
-
if (userAgent.includes("pnpm"))
|
|
27
|
-
return "pnpm";
|
|
28
|
-
if (userAgent.includes("yarn"))
|
|
29
|
-
return "yarn";
|
|
30
|
-
return "npm";
|
|
31
|
-
}
|
|
32
|
-
export async function buildWidget(options) {
|
|
33
|
-
const projectDir = getProjectDir();
|
|
34
18
|
const distDir = path.join(projectDir, "dist");
|
|
35
|
-
const buildDir = path.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
runGenerateFields({
|
|
43
|
-
fieldsDir: projectDir,
|
|
44
|
-
testMessages: mod.testMessages,
|
|
45
|
-
testAlerts: mod.testAlerts,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
else if (fs.existsSync(fieldsTsPath)) {
|
|
49
|
-
runGenerateFieldsFromModule(fieldsTsPath);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
console.log("No fields.base.json or fields.ts found, skipping fields generation");
|
|
53
|
-
}
|
|
54
|
-
console.log("Building...");
|
|
55
|
-
const buildEnv = options.full ? { BUILD_FULL: "1" } : {};
|
|
56
|
-
if (!run(getPackageManager(), ["run", "build"], projectDir, buildEnv)) {
|
|
57
|
-
throw new Error("Build failed.");
|
|
58
|
-
}
|
|
59
|
-
if (!fs.existsSync(distDir)) {
|
|
60
|
-
throw new Error("dist not found. Run build first.");
|
|
61
|
-
}
|
|
62
|
-
fs.mkdirSync(buildDir, { recursive: true });
|
|
63
|
-
const html = fs.readFileSync(path.join(distDir, "index.html"), "utf-8");
|
|
64
|
-
fs.writeFileSync(path.join(buildDir, "html.txt"), html);
|
|
65
|
-
const assetsDir = path.join(distDir, "assets");
|
|
66
|
-
const findFiles = (dir, ext) => {
|
|
67
|
-
const found = [];
|
|
68
|
-
const walk = (d) => {
|
|
69
|
-
if (!fs.existsSync(d))
|
|
70
|
-
return;
|
|
71
|
-
for (const e of fs.readdirSync(d)) {
|
|
72
|
-
const full = path.join(d, e);
|
|
73
|
-
const stat = fs.statSync(full);
|
|
74
|
-
if (stat.isDirectory())
|
|
75
|
-
walk(full);
|
|
76
|
-
else if (e.endsWith(ext))
|
|
77
|
-
found.push(full);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
walk(dir);
|
|
81
|
-
return found;
|
|
82
|
-
};
|
|
83
|
-
const jsFiles = findFiles(assetsDir, ".js");
|
|
84
|
-
const cssFiles = findFiles(assetsDir, ".css");
|
|
85
|
-
if (jsFiles.length === 0 || cssFiles.length === 0) {
|
|
86
|
-
throw new Error("Expected .js and .css in dist/assets");
|
|
87
|
-
}
|
|
88
|
-
let finalJs = fs.readFileSync(jsFiles[0], "utf-8");
|
|
89
|
-
// Если мы НЕ в FULL режиме, оборачиваем в проверку готовности глобалов
|
|
90
|
-
if (!options.full) {
|
|
91
|
-
const { getRawWmakeGlobals } = await import("./vite-config.js");
|
|
19
|
+
const buildDir = path.join(projectDir, "build");
|
|
20
|
+
if (!fs.existsSync(buildDir))
|
|
21
|
+
fs.mkdirSync(buildDir, { recursive: true });
|
|
22
|
+
let html = fs.readFileSync(path.join(distDir, "index.html"), "utf-8");
|
|
23
|
+
let css = fs.readFileSync(path.join(distDir, "assets/style.css"), "utf-8");
|
|
24
|
+
let js = fs.readFileSync(path.join(distDir, "assets/index.js"), "utf-8");
|
|
25
|
+
if (!full) {
|
|
92
26
|
const rawGlobals = getRawWmakeGlobals(projectDir);
|
|
93
27
|
const requiredGlobals = JSON.stringify(Array.from(new Set(Object.values(rawGlobals))));
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
run();
|
|
113
|
-
} else {
|
|
114
|
-
if (window.__WMAKE_LOG_MISSING !== missing.join(",")) {
|
|
115
|
-
console.warn("[WMAKE] Waiting for dependencies: " + missing.join(", "));
|
|
116
|
-
window.__WMAKE_LOG_MISSING = missing.join(",");
|
|
117
|
-
}
|
|
118
|
-
setTimeout(check, 100);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
console.log("[WMAKE] Initializing dependency check...");
|
|
122
|
-
check();
|
|
123
|
-
})();`;
|
|
28
|
+
const wmakeDepsWithVersions = getWmakeDepsWithVersions(projectDir);
|
|
29
|
+
const wmakeDeps = getWmakeDeps(projectDir);
|
|
30
|
+
const globalsInOrder = Array.from(new Set(Object.values(rawGlobals)));
|
|
31
|
+
const loaderJs = `(function() {
|
|
32
|
+
var req = ${requiredGlobals};
|
|
33
|
+
var wmakeDeps = ${JSON.stringify(wmakeDeps)};
|
|
34
|
+
var wmakeFallbacks = ${JSON.stringify(wmakeDepsWithVersions)};
|
|
35
|
+
|
|
36
|
+
for (var i = 0; i < req.length; i++) {
|
|
37
|
+
if (!window.hasOwnProperty(req[i])) window[req[i]] = undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function check() {
|
|
41
|
+
var missing = [];
|
|
42
|
+
for (var i = 0; i < req.length; i++) {
|
|
43
|
+
if (!window[req[i]]) { missing.push(req[i]); }
|
|
124
44
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
45
|
+
if (missing.length === 0) {
|
|
46
|
+
console.log("[WMAKE] All context dependencies initialized");
|
|
47
|
+
var run = function() {
|
|
48
|
+
${globalsInOrder.map(g => `var ${g} = window.${g};`).join(" ")}
|
|
49
|
+
try {
|
|
50
|
+
${js.trim()}
|
|
51
|
+
} catch (e) {
|
|
52
|
+
console.error("[WMAKE] Runtime error:", e);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
run();
|
|
56
|
+
} else {
|
|
57
|
+
setTimeout(check, 100);
|
|
130
58
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
})();
|
|
142
|
-
const dataPath = path.join(projectDir, "data.json");
|
|
143
|
-
const data = fs.existsSync(dataPath)
|
|
144
|
-
? JSON.parse(fs.readFileSync(dataPath, "utf-8"))
|
|
145
|
-
: {};
|
|
146
|
-
if (wmakeVersion) {
|
|
147
|
-
data.wmakeVersion = wmakeVersion;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function injectScripts(fieldData) {
|
|
62
|
+
var CDN_BASE = "https://cdn.jsdelivr.net/npm";
|
|
63
|
+
var head = document.getElementsByTagName("head")[0];
|
|
64
|
+
|
|
65
|
+
var queue = [];
|
|
66
|
+
for (var i = 0; i < wmakeDeps.length; i++) {
|
|
67
|
+
queue.push({ pkg: wmakeDeps[i], entry: "root" });
|
|
68
|
+
queue.push({ pkg: wmakeDeps[i], entry: "react" });
|
|
148
69
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
cwd: buildDir,
|
|
154
|
-
stdio: "pipe",
|
|
155
|
-
});
|
|
156
|
-
if (zip.status === 0) {
|
|
157
|
-
console.log("Archive:", zipPath);
|
|
70
|
+
|
|
71
|
+
function loadNext(qIdx) {
|
|
72
|
+
if (qIdx >= queue.length) {
|
|
73
|
+
check();
|
|
158
74
|
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
var item = queue[qIdx];
|
|
78
|
+
var pkg = item.pkg;
|
|
79
|
+
var name = pkg.replace("@allior/wmake-", "");
|
|
80
|
+
var pascalName = name.split("-").map(function(w) { return w.charAt(0).toUpperCase() + w.slice(1); }).join("");
|
|
81
|
+
var fieldKey = "wmake" + pascalName + "Version";
|
|
82
|
+
var version = (fieldData && fieldData[fieldKey]) || wmakeFallbacks[pkg] || "latest";
|
|
83
|
+
|
|
84
|
+
var src = CDN_BASE + "/" + pkg + "@" + version + "/dist/" + item.entry + "/index.iife.js";
|
|
85
|
+
var script = document.createElement("script");
|
|
86
|
+
script.src = src;
|
|
87
|
+
script.onload = function() { loadNext(qIdx + 1); };
|
|
88
|
+
script.onerror = function() { loadNext(qIdx + 1); };
|
|
89
|
+
head.appendChild(script);
|
|
159
90
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (fs.existsSync(fp))
|
|
172
|
-
archive.addLocalFile(fp, "", f);
|
|
173
|
-
}
|
|
174
|
-
archive.writeZip(zipPath);
|
|
175
|
-
console.log("Archive (adm-zip):", zipPath);
|
|
91
|
+
|
|
92
|
+
loadNext(0);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
window.addEventListener("onWidgetLoad", function(obj) {
|
|
96
|
+
var detail = obj.detail;
|
|
97
|
+
window.__WMAKE_INIT_DATA__ = detail;
|
|
98
|
+
injectScripts(detail && detail.fieldData);
|
|
99
|
+
});
|
|
100
|
+
})();`;
|
|
101
|
+
js = loaderJs;
|
|
176
102
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
103
|
+
fs.writeFileSync(path.join(buildDir, "html.txt"), html, "utf-8");
|
|
104
|
+
fs.writeFileSync(path.join(buildDir, "css.txt"), css, "utf-8");
|
|
105
|
+
fs.writeFileSync(path.join(buildDir, "js.txt"), js, "utf-8");
|
|
106
|
+
const fields = generateMergedFields(projectDir, seDir, {
|
|
107
|
+
skipWmakeVersions: options.skipWmakeVersions,
|
|
108
|
+
skipTestAlerts: options.skipTestAlerts,
|
|
109
|
+
skipTestMessages: options.skipTestMessages,
|
|
110
|
+
});
|
|
111
|
+
fs.writeFileSync(path.join(buildDir, "fields.txt"), JSON.stringify(fields, null, 2), "utf-8");
|
|
112
|
+
const dataPath = seDir
|
|
113
|
+
? path.join(projectDir, seDir, "data.json")
|
|
114
|
+
: path.join(projectDir, "data.json");
|
|
115
|
+
let dataFilename = "";
|
|
116
|
+
if (fs.existsSync(dataPath)) {
|
|
117
|
+
dataFilename = "data.txt";
|
|
118
|
+
fs.writeFileSync(path.join(buildDir, dataFilename), fs.readFileSync(dataPath, "utf-8"), "utf-8");
|
|
181
119
|
}
|
|
120
|
+
const iniContent = `[HTML]
|
|
121
|
+
path = "html.txt"
|
|
122
|
+
|
|
123
|
+
[CSS]
|
|
124
|
+
path = "css.txt"
|
|
125
|
+
|
|
126
|
+
[JS]
|
|
127
|
+
path = "js.txt"
|
|
128
|
+
|
|
129
|
+
[FIELDS]
|
|
130
|
+
path = "fields.txt"
|
|
131
|
+
${dataFilename ? `\n[DATA]\npath = "${dataFilename}"` : ""}
|
|
132
|
+
`;
|
|
133
|
+
fs.writeFileSync(path.join(buildDir, "widget.ini"), iniContent, "utf-8");
|
|
134
|
+
const zip = new admZip();
|
|
135
|
+
zip.addLocalFolder(buildDir);
|
|
136
|
+
const zipPath = path.join(distDir, "widget.zip");
|
|
137
|
+
zip.writeZip(zipPath);
|
|
182
138
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allior/wmake-cli",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.7",
|
|
4
|
+
"description": "WMake CLI: build widgets, base64 encode assets, generate fields",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./dist/index.js",
|
|
9
|
-
"./vite
|
|
10
|
-
"./vite-plugin": "./dist/vite-config.js"
|
|
9
|
+
"./vite": "./dist/vite-config.js"
|
|
11
10
|
},
|
|
12
11
|
"bin": {
|
|
13
12
|
"wmake-cli": "dist/bin.js",
|
package/src/bin.ts
CHANGED
|
@@ -1,82 +1,44 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import fs from "node:fs";
|
|
1
|
+
#!/usr/bin/env bun
|
|
4
2
|
import { Command } from "commander";
|
|
5
|
-
import { processPath } from "./base64.js";
|
|
6
3
|
import { buildWidget } from "./widget.js";
|
|
7
4
|
import { runGenerateFields } from "./generate-fields.js";
|
|
8
|
-
import {
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const pkg = JSON.parse(readFileSync(path.join(__dirname, "../package.json"), "utf8"));
|
|
9
11
|
|
|
10
12
|
const program = new Command();
|
|
11
13
|
|
|
12
|
-
program
|
|
14
|
+
program
|
|
15
|
+
.name("wmake")
|
|
16
|
+
.description("Build tool for @allior/wmake components")
|
|
17
|
+
.version(pkg.version);
|
|
13
18
|
|
|
14
19
|
program
|
|
15
20
|
.command("widget")
|
|
16
|
-
.description("Build
|
|
17
|
-
.option("--full", "
|
|
18
|
-
.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
.description("Build a StreamElements widget")
|
|
22
|
+
.option("-f, --full", "Build a full bundle without CDN deps")
|
|
23
|
+
.option("-s, --se-dir <dir>", "Directory containing StreamElements files (fields.json, data.json)")
|
|
24
|
+
.option("--no-wmake-versions", "Do not include wmake versions in fields")
|
|
25
|
+
.option("--no-test-alerts", "Do not include test alerts in fields")
|
|
26
|
+
.option("--no-test-messages", "Do not include test messages in fields")
|
|
27
|
+
.action(async (options) => {
|
|
28
|
+
await buildWidget({
|
|
29
|
+
full: options.full,
|
|
30
|
+
seDir: options.seDir,
|
|
31
|
+
skipWmakeVersions: !options.wmakeVersions,
|
|
32
|
+
skipTestAlerts: !options.testAlerts,
|
|
33
|
+
skipTestMessages: !options.testMessages
|
|
34
|
+
});
|
|
25
35
|
});
|
|
26
36
|
|
|
27
37
|
program
|
|
28
38
|
.command("generate-fields")
|
|
29
|
-
.description("Generate fields.json from fields.base.json
|
|
30
|
-
.action(
|
|
31
|
-
|
|
32
|
-
const fieldsDir = process.env.WMAKE_FIELDS_DIR;
|
|
33
|
-
if (!fieldsDir?.trim()) {
|
|
34
|
-
throw new Error("WMAKE_FIELDS_DIR must be set.");
|
|
35
|
-
}
|
|
36
|
-
const mod = (await import("@allior/wmake-streamelements-events")) as unknown as {
|
|
37
|
-
testMessages: Record<string, unknown>;
|
|
38
|
-
testAlerts: Record<string, unknown>;
|
|
39
|
-
};
|
|
40
|
-
runGenerateFields({
|
|
41
|
-
fieldsDir: path.resolve(fieldsDir),
|
|
42
|
-
testMessages: mod.testMessages,
|
|
43
|
-
testAlerts: mod.testAlerts,
|
|
44
|
-
});
|
|
45
|
-
} catch (e) {
|
|
46
|
-
console.error((e as Error).message);
|
|
47
|
-
process.exit(1);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
program
|
|
52
|
-
.command("extract-test-data")
|
|
53
|
-
.description("No-op: test data lives in streamelements/src/assets as TS objects")
|
|
54
|
-
.action(async () => {
|
|
55
|
-
try {
|
|
56
|
-
await runExtractTestData();
|
|
57
|
-
} catch (e) {
|
|
58
|
-
console.error((e as Error).message);
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
program
|
|
64
|
-
.command("base64")
|
|
65
|
-
.description("Convert images, videos, SVG to base64 for browsers")
|
|
66
|
-
.argument("<path>", "File or directory path")
|
|
67
|
-
.option("-o, --output <path>", "Output file or directory")
|
|
68
|
-
.option("-f, --full", "Output with additional info")
|
|
69
|
-
.action(async (inputPath: string, options: { output?: string; full?: boolean }) => {
|
|
70
|
-
if (!fs.existsSync(inputPath)) {
|
|
71
|
-
console.error("Error: Path does not exist");
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
try {
|
|
75
|
-
await processPath(inputPath, options.output ?? null, options.full ?? false);
|
|
76
|
-
} catch (e) {
|
|
77
|
-
console.error("Error:", (e as Error).message);
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}
|
|
39
|
+
.description("Generate fields.json from fields.base.json (manual source update)")
|
|
40
|
+
.action(() => {
|
|
41
|
+
runGenerateFields(process.cwd());
|
|
80
42
|
});
|
|
81
43
|
|
|
82
44
|
program.parse();
|