@allior/wmake-cli 0.0.5 → 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 CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
2
  export {};
3
3
  //# sourceMappingURL=bin.d.ts.map
package/dist/bin.js CHANGED
@@ -1,76 +1,38 @@
1
- #!/usr/bin/env node
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 { runExtractTestData } from "./extract-test-data.js";
5
+ import { readFileSync } from "node:fs";
6
+ import { fileURLToPath } from "node:url";
7
+ import path from "node:path";
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const pkg = JSON.parse(readFileSync(path.join(__dirname, "../package.json"), "utf8"));
9
10
  const program = new Command();
10
- program.name("wmake").description("CLI for streamiby / wmake").version("1.0.0");
11
+ program
12
+ .name("wmake")
13
+ .description("Build tool for @allior/wmake components")
14
+ .version(pkg.version);
11
15
  program
12
16
  .command("widget")
13
- .description("Build chat-demo into widget files and zip in examples/chat-demo/dist")
14
- .option("--full", "Full bundle (no CDN external), like the old build")
15
- .action(async (opts) => {
16
- try {
17
- await buildWidget({ full: opts.full });
18
- }
19
- catch (e) {
20
- console.error(e.message);
21
- process.exit(1);
22
- }
17
+ .description("Build a StreamElements widget")
18
+ .option("-f, --full", "Build a full bundle without CDN deps")
19
+ .option("-s, --se-dir <dir>", "Directory containing StreamElements files (fields.json, data.json)")
20
+ .option("--no-wmake-versions", "Do not include wmake versions in fields")
21
+ .option("--no-test-alerts", "Do not include test alerts in fields")
22
+ .option("--no-test-messages", "Do not include test messages in fields")
23
+ .action(async (options) => {
24
+ await buildWidget({
25
+ full: options.full,
26
+ seDir: options.seDir,
27
+ skipWmakeVersions: !options.wmakeVersions,
28
+ skipTestAlerts: !options.testAlerts,
29
+ skipTestMessages: !options.testMessages
30
+ });
23
31
  });
24
32
  program
25
33
  .command("generate-fields")
26
- .description("Generate fields.json from fields.base.json and test data objects (WMAKE_FIELDS_DIR)")
27
- .action(async () => {
28
- try {
29
- const fieldsDir = process.env.WMAKE_FIELDS_DIR;
30
- if (!fieldsDir?.trim()) {
31
- throw new Error("WMAKE_FIELDS_DIR must be set.");
32
- }
33
- const mod = (await import("@allior/wmake-streamelements-events"));
34
- runGenerateFields({
35
- fieldsDir: path.resolve(fieldsDir),
36
- testMessages: mod.testMessages,
37
- testAlerts: mod.testAlerts,
38
- });
39
- }
40
- catch (e) {
41
- console.error(e.message);
42
- process.exit(1);
43
- }
44
- });
45
- program
46
- .command("extract-test-data")
47
- .description("No-op: test data lives in streamelements/src/assets as TS objects")
48
- .action(async () => {
49
- try {
50
- await runExtractTestData();
51
- }
52
- catch (e) {
53
- console.error(e.message);
54
- process.exit(1);
55
- }
56
- });
57
- program
58
- .command("base64")
59
- .description("Convert images, videos, SVG to base64 for browsers")
60
- .argument("<path>", "File or directory path")
61
- .option("-o, --output <path>", "Output file or directory")
62
- .option("-f, --full", "Output with additional info")
63
- .action(async (inputPath, options) => {
64
- if (!fs.existsSync(inputPath)) {
65
- console.error("Error: Path does not exist");
66
- process.exit(1);
67
- }
68
- try {
69
- await processPath(inputPath, options.output ?? null, options.full ?? false);
70
- }
71
- catch (e) {
72
- console.error("Error:", e.message);
73
- process.exit(1);
74
- }
34
+ .description("Generate fields.json from fields.base.json (manual source update)")
35
+ .action(() => {
36
+ runGenerateFields(process.cwd());
75
37
  });
76
38
  program.parse();
@@ -1,18 +1,10 @@
1
- /**
2
- * Генерирует fields.json из fields.base.json и ключей из объектов testMessages / testAlerts.
3
- * Путь к каталогу с fields.base.json задаётся WMAKE_FIELDS_DIR.
4
- * Данные сообщений и алертов передаются объектами (из скриптов streamelements).
5
- */
6
- export type MessagesRecord = Record<string, unknown>;
7
- export type AlertsRecord = Record<string, unknown>;
8
- export declare function runGenerateFields(options: {
9
- fieldsDir: string;
10
- testMessages: MessagesRecord;
11
- testAlerts: AlertsRecord;
12
- }): void;
13
- /**
14
- * Генерирует fields.json из TS/JS модуля, экспортирующего default AdvancedField[].
15
- * Использует tsx для загрузки .ts файлов.
16
- */
17
- export declare function runGenerateFieldsFromModule(fieldsModulePath: string): void;
1
+ export interface GenerateFieldsOptions {
2
+ skipWmakeVersions?: boolean;
3
+ skipTestAlerts?: boolean;
4
+ skipTestMessages?: boolean;
5
+ }
6
+ /** Merges base fields with dynamic WMake version fields and testing tools. */
7
+ export declare function generateMergedFields(cwd?: string, seDir?: string, options?: GenerateFieldsOptions): any;
8
+ /** Standalone command entry point */
9
+ export declare function runGenerateFields(cwd?: string): void;
18
10
  //# sourceMappingURL=generate-fields.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-fields.d.ts","sourceRoot":"","sources":["../src/generate-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgCH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,cAAc,CAAC;IAC7B,UAAU,EAAE,YAAY,CAAC;CAC1B,GAAG,IAAI,CAkDP;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAiB1E"}
1
+ {"version":3,"file":"generate-fields.d.ts","sourceRoot":"","sources":["../src/generate-fields.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAClC,GAAG,GAAE,MAAsB,EAC3B,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,GAAG,CA4EL;AAED,qCAAqC;AACrC,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,QAK5D"}
@@ -1,88 +1,81 @@
1
- /**
2
- * Генерирует fields.json из fields.base.json и ключей из объектов testMessages / testAlerts.
3
- * Путь к каталогу с fields.base.json задаётся WMAKE_FIELDS_DIR.
4
- * Данные сообщений и алертов передаются объектами (из скриптов streamelements).
5
- */
6
1
  import fs from "node:fs";
7
2
  import path from "node:path";
8
- import { spawnSync } from "node:child_process";
9
- const TEST_GROUP = "Tests / Тесты";
10
- function pascalCase(s) {
11
- return s.charAt(0).toUpperCase() + s.slice(1);
12
- }
13
- /** camelCase → sentence case (e.g. veryShort → "Very short", selfSub → "Self sub") */
14
- function keyToTitle(key) {
15
- const words = key
16
- .replace(/([A-Z])/g, " $1")
17
- .toLowerCase()
18
- .trim();
19
- return words.charAt(0).toUpperCase() + words.slice(1);
20
- }
21
- function messageLabel(key) {
22
- return `${keyToTitle(key)} message`;
23
- }
24
- function alertLabel(key) {
25
- return `${keyToTitle(key)} alert`;
26
- }
27
- export function runGenerateFields(options) {
28
- const { fieldsDir, testMessages: messages, testAlerts: alerts } = options;
29
- const basePath = path.join(fieldsDir, "fields.base.json");
30
- const outPath = path.join(fieldsDir, "fields.json");
31
- const base = JSON.parse(fs.readFileSync(basePath, "utf-8"));
32
- const messageKeys = Object.keys(messages);
33
- const alertKeys = Object.keys(alerts);
34
- const testMessageFields = {};
35
- for (const key of messageKeys) {
36
- const fieldId = "testMessage" + pascalCase(key);
37
- testMessageFields[fieldId] = {
3
+ import { getWmakeDepsWithVersions } from "./vite-config.js";
4
+ /** Merges base fields with dynamic WMake version fields and testing tools. */
5
+ export function generateMergedFields(cwd = process.cwd(), seDir, options = {}) {
6
+ const baseFieldsPath = seDir
7
+ ? path.join(cwd, seDir, "fields.json")
8
+ : path.join(cwd, "fields.json");
9
+ const legacyPath = path.join(cwd, "fields.base.json");
10
+ let finalBaseFieldsPath = baseFieldsPath;
11
+ if (!fs.existsSync(baseFieldsPath) && fs.existsSync(legacyPath)) {
12
+ finalBaseFieldsPath = legacyPath;
13
+ }
14
+ if (!fs.existsSync(finalBaseFieldsPath)) {
15
+ console.error(`Fields file not found at ${finalBaseFieldsPath}`);
16
+ return {};
17
+ }
18
+ const baseFields = JSON.parse(fs.readFileSync(finalBaseFieldsPath, "utf-8"));
19
+ const finalFields = { ...baseFields };
20
+ const mergedFields = {};
21
+ // 1. Prepare WMake versions
22
+ const wmakeFields = {};
23
+ if (!options.skipWmakeVersions) {
24
+ const wmakeVersions = getWmakeDepsWithVersions(cwd);
25
+ Object.keys(wmakeVersions).forEach(pkg => {
26
+ const name = pkg.replace("@allior/wmake-", "");
27
+ const pascalName = pascalCase(name);
28
+ const fieldKey = `wmake${pascalName}Version`;
29
+ wmakeFields[fieldKey] = {
30
+ type: "text",
31
+ label: `${pascalName} version`,
32
+ value: wmakeVersions[pkg],
33
+ group: "WMake"
34
+ };
35
+ });
36
+ }
37
+ // 2. Prepare Testing fields
38
+ const testFields = {};
39
+ if (!options.skipTestAlerts) {
40
+ testFields["testAlert"] = {
38
41
  type: "button",
39
- label: messageLabel(key),
40
- group: TEST_GROUP,
42
+ label: "Test Alert",
43
+ value: "testAlert",
44
+ group: "Testing"
41
45
  };
42
46
  }
43
- const testAlertFields = {};
44
- for (const key of alertKeys) {
45
- const fieldId = "testAlert" + pascalCase(key);
46
- testAlertFields[fieldId] = {
47
+ if (!options.skipTestMessages) {
48
+ testFields["testMessage"] = {
47
49
  type: "button",
48
- label: alertLabel(key),
49
- group: TEST_GROUP,
50
+ label: "Test Message",
51
+ value: "testMessage",
52
+ group: "Testing"
50
53
  };
51
54
  }
52
- const insertAfterKey = "blueFlowerAnimationDuration";
53
- const result = {};
54
- let inserted = false;
55
- for (const k of Object.keys(base)) {
56
- if (k.startsWith("_"))
57
- continue;
58
- result[k] = base[k];
59
- if (k === insertAfterKey) {
60
- Object.assign(result, testMessageFields, testAlertFields);
61
- inserted = true;
55
+ const dynamicFields = { ...wmakeFields, ...testFields };
56
+ const dynamicKeys = Object.keys(dynamicFields).sort();
57
+ const sortedDynamic = {};
58
+ dynamicKeys.forEach(k => sortedDynamic[k] = dynamicFields[k]);
59
+ let dynamicInserted = false;
60
+ for (const key in finalFields) {
61
+ if (key.startsWith("testMessage") && !dynamicInserted) {
62
+ Object.assign(mergedFields, sortedDynamic);
63
+ dynamicInserted = true;
62
64
  }
65
+ mergedFields[key] = finalFields[key];
63
66
  }
64
- if (!inserted) {
65
- Object.assign(result, testMessageFields, testAlertFields);
67
+ if (!dynamicInserted) {
68
+ Object.assign(mergedFields, sortedDynamic);
66
69
  }
67
- fs.writeFileSync(outPath, JSON.stringify(result, null, 2), "utf-8");
68
- console.log("Wrote", outPath);
69
- console.log("Test message buttons:", messageKeys.length);
70
- console.log("Test alert buttons:", alertKeys.length);
70
+ return mergedFields;
71
71
  }
72
- /**
73
- * Генерирует fields.json из TS/JS модуля, экспортирующего default AdvancedField[].
74
- * Использует tsx для загрузки .ts файлов.
75
- */
76
- export function runGenerateFieldsFromModule(fieldsModulePath) {
77
- const absPath = path.resolve(fieldsModulePath);
78
- const outPath = path.join(path.dirname(absPath), "fields.json");
79
- const runnerPath = path.join(__dirname, "..", "src", "generate-fields-from-module-runner.ts");
80
- const r = spawnSync("npx", ["tsx", runnerPath, absPath, outPath], {
81
- stdio: "inherit",
82
- shell: true,
83
- cwd: path.dirname(absPath),
84
- });
85
- if (r.status !== 0) {
86
- throw new Error(`Failed to generate fields from ${fieldsModulePath}`);
87
- }
72
+ /** Standalone command entry point */
73
+ export function runGenerateFields(cwd = process.cwd()) {
74
+ const fields = generateMergedFields(cwd);
75
+ const fieldsPath = path.join(cwd, "fields.json");
76
+ fs.writeFileSync(fieldsPath, JSON.stringify(fields, null, 2), "utf-8");
77
+ console.log(`Wrote ${fieldsPath}`);
78
+ }
79
+ function pascalCase(str) {
80
+ return str.split("-").map(w => w.charAt(0).toUpperCase() + w.slice(1)).join("");
88
81
  }
@@ -1,22 +1,25 @@
1
- import { PluginOption } from "vite";
2
- export declare const CDN_BASE = "https://cdn.jsdelivr.net/npm";
3
- export declare const REACT_VER = "19.0.0";
4
- export declare const WMAKE_VER = "1.0.0";
5
- export declare const EXTERNAL_FOR_CDN: Set<string>;
6
- export declare function wmakeImportMapPlugin(): PluginOption;
7
- export declare function getWmakeAliases(root: string): {
8
- "@allior/wmake-streamelements-events/react": string;
9
- "@allior/wmake-streamelements-events": string;
10
- "@allior/wmake-utils/react": string;
11
- "@allior/wmake-utils": string;
12
- "@allior/wmake-emotes/react": string;
13
- "@allior/wmake-emotes/7tv": string;
14
- "@allior/wmake-emotes": string;
15
- "@allior/wmake-streamelements/react": string;
16
- "@allior/wmake-streamelements/fields": string;
17
- "@allior/wmake-streamelements": string;
18
- };
19
- export declare function getWmakeOptimizeDeps(): {
20
- include: string[];
21
- };
1
+ import type { AliasOptions, PluginOption } from "vite";
2
+ export declare const BASE_GLOBALS: Record<string, string>;
3
+ /** Translates package name to global window variable name */
4
+ export declare function getWmakeGlobals(cwd?: string): Record<string, string>;
5
+ /** Translates package name to global window variable name (without React/ReactDOM) */
6
+ export declare function getRawWmakeGlobals(cwd?: string): Record<string, string>;
7
+ /** Generates Vite aliases for workspace development */
8
+ export declare function getWmakeAliases(root: string): AliasOptions;
9
+ /** Detects @allior/wmake-* dependencies in package.json and sorts them by hierarchy */
10
+ export declare function getWmakeDeps(cwd?: string): string[];
11
+ /** Detects dependencies and their current versions from package.json */
12
+ export declare function getWmakeDepsWithVersions(cwd?: string): Record<string, string>;
13
+ /** Checks if a dependency should be external in CDN mode */
14
+ export declare function isExternalForCdn(id: string, cwd?: string): boolean;
15
+ /** Legacy helper for external dependencies */
16
+ export declare function getExternalForCdn(cwd?: string): string[];
17
+ /** Provides list of dependencies for pre-optimization */
18
+ export declare function getWmakeOptimizeDeps(cwd?: string): string[];
19
+ /** Vite plugin to inject global window shims for widget development */
20
+ export declare function wmakeScriptCdnPlugin(options?: {
21
+ useCdn?: boolean;
22
+ }): PluginOption;
23
+ /** Sorts dependencies in correct loading order based on internals */
24
+ export declare function sortWmakeDeps(deps: string[]): string[];
22
25
  //# sourceMappingURL=vite-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../src/vite-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEpC,eAAO,MAAM,QAAQ,iCAAiC,CAAC;AACvD,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,eAAO,MAAM,SAAS,UAAU,CAAC;AAEjC,eAAO,MAAM,gBAAgB,aAW3B,CAAC;AA4CH,wBAAgB,oBAAoB,IAAI,YAAY,CAmDnD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;;EAa3C;AAED,wBAAgB,oBAAoB;;EASnC"}
1
+ {"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../src/vite-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEvD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK/C,CAAC;AAEF,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAanF;AAED,sFAAsF;AACtF,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAatF;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAgB1D;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,EAAE,CAOlE;AAED,wEAAwE;AACxE,wBAAgB,wBAAwB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY5F;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAcjF;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,EAAE,CAQvE;AAED,yDAAyD;AACzD,wBAAgB,oBAAoB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,EAAE,CAG1E;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,YAAY,CAerF;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAWtD"}
@@ -1,127 +1,142 @@
1
1
  import path from "node:path";
2
2
  import fs from "node:fs";
3
- export const CDN_BASE = "https://cdn.jsdelivr.net/npm";
4
- export const REACT_VER = "19.0.0";
5
- export const WMAKE_VER = "1.0.0";
6
- export const EXTERNAL_FOR_CDN = new Set([
7
- "react",
8
- "react/jsx-runtime",
9
- "react-dom",
10
- "react-dom/client",
11
- "@allior/wmake-utils",
12
- "@allior/wmake-utils/react",
13
- "@allior/wmake-streamelements-events",
14
- "@allior/wmake-streamelements-events/react",
15
- "@allior/wmake-emotes/7tv",
16
- "@allior/wmake-streamelements",
17
- ]);
18
- const BOOTSTRAP_PLACEHOLDER_SRC = "__MAIN_SCRIPT_SRC__";
19
- const BOOTSTRAP_PLACEHOLDER_VER = "__DEFAULT_WMAKE_VER__";
20
- const bootstrapScript = `
21
- (function(){
22
- var CDN_BASE='${CDN_BASE}';
23
- var REACT_VER='${REACT_VER}';
24
- var defaultVer='${BOOTSTRAP_PLACEHOLDER_VER}';
25
- var mainScriptSrc='${BOOTSTRAP_PLACEHOLDER_SRC}';
26
- function run(ver){
27
- var v=ver||defaultVer;
28
- var map={imports:{
29
- 'react':CDN_BASE+'/react@'+REACT_VER+'/+esm',
30
- 'react/jsx-runtime':CDN_BASE+'/react@'+REACT_VER+'/jsx-runtime.js',
31
- 'react-dom':CDN_BASE+'/react-dom@'+REACT_VER+'/+esm',
32
- 'react-dom/client':CDN_BASE+'/react-dom@'+REACT_VER+'/client.js',
33
- '@allior/wmake-utils':CDN_BASE+'/@allior/wmake-utils@'+v+'/dist/root/index.js',
34
- '@allior/wmake-utils/react':CDN_BASE+'/@allior/wmake-utils@'+v+'/dist/react/index.js',
35
- '@allior/wmake-streamelements-events':CDN_BASE+'/@allior/wmake-streamelements-events@'+v+'/dist/root/index.js',
36
- '@allior/wmake-streamelements-events/react':CDN_BASE+'/@allior/wmake-streamelements-events@'+v+'/dist/react/index.js',
37
- '@allior/wmake-emotes/7tv':CDN_BASE+'/@allior/wmake-emotes@'+v+'/dist/7tv/index.js',
38
- '@allior/wmake-streamelements':CDN_BASE+'/@allior/wmake-streamelements@'+v+'/dist/root/index.js'
39
- }};
40
- var s=document.createElement('script');
41
- s.type='importmap';
42
- s.textContent=JSON.stringify(map);
43
- document.head.appendChild(s);
44
- var m=document.createElement('script');
45
- m.type='module';
46
- m.src=mainScriptSrc;
47
- document.body.appendChild(m);
48
- }
49
- if(typeof window.addEventListener==='function'){
50
- window.addEventListener('onWidgetLoad',function(obj){
51
- var fd=obj.detail&&obj.detail.fieldData;
52
- run(fd&&fd.wmakeVersion);
53
- });
54
- setTimeout(function(){if(!document.querySelector('script[type="importmap"]'))run(defaultVer);},100);
55
- }else{run(defaultVer);}
56
- })();
57
- `;
58
- export function wmakeImportMapPlugin() {
59
- const imports = {
60
- react: `${CDN_BASE}/react@${REACT_VER}/+esm`,
61
- "react/jsx-runtime": `${CDN_BASE}/react@${REACT_VER}/jsx-runtime.js`,
62
- "react-dom": `${CDN_BASE}/react-dom@${REACT_VER}/+esm`,
63
- "react-dom/client": `${CDN_BASE}/react-dom@${REACT_VER}/client.js`,
64
- "@allior/wmake-utils": `${CDN_BASE}/@allior/wmake-utils@${WMAKE_VER}/dist/root/index.js`,
65
- "@allior/wmake-utils/react": `${CDN_BASE}/@allior/wmake-utils@${WMAKE_VER}/dist/react/index.js`,
66
- "@allior/wmake-streamelements-events": `${CDN_BASE}/@allior/wmake-streamelements-events@${WMAKE_VER}/dist/root/index.js`,
67
- "@allior/wmake-streamelements-events/react": `${CDN_BASE}/@allior/wmake-streamelements-events@${WMAKE_VER}/dist/react/index.js`,
68
- "@allior/wmake-emotes/7tv": `${CDN_BASE}/@allior/wmake-emotes@${WMAKE_VER}/dist/7tv/index.js`,
69
- "@allior/wmake-streamelements": `${CDN_BASE}/@allior/wmake-streamelements@${WMAKE_VER}/dist/root/index.js`,
70
- };
71
- const importMap = { imports };
72
- const staticImportMapScript = `<script type="importmap">${JSON.stringify(importMap)}</script>`;
73
- return {
74
- name: "importmap-cdn",
75
- transformIndexHtml: {
76
- order: "post",
77
- handler(html, ctx) {
78
- const isBuild = !ctx.server;
79
- if (isBuild) {
80
- const script = "<script>\n" + bootstrapScript.trim() + "\n</script>";
81
- return html.replace(/(<head[^>]*>)/i, "$1\n" + script);
82
- }
83
- return staticImportMapScript + "\n" + html;
84
- },
85
- },
86
- writeBundle(options) {
87
- const outDir = options.dir ?? "dist";
88
- const htmlPath = path.join(outDir, "index.html");
89
- if (!fs.existsSync(htmlPath))
90
- return;
91
- let html = fs.readFileSync(htmlPath, "utf-8");
92
- const scriptTagMatch = html.match(/<script(?=[^>]*type=["']module["'])(?=[^>]*src=)[^>]*src=["']([^"']+)["'][^>]*>\s*<\/script>/);
93
- if (!scriptTagMatch)
94
- return;
95
- const mainScriptSrc = scriptTagMatch[1];
96
- html = html
97
- .replace(BOOTSTRAP_PLACEHOLDER_VER, WMAKE_VER)
98
- .replace(BOOTSTRAP_PLACEHOLDER_SRC, mainScriptSrc)
99
- .replace(scriptTagMatch[0], "");
100
- fs.writeFileSync(htmlPath, html);
101
- },
102
- };
3
+ export const BASE_GLOBALS = {
4
+ react: "React",
5
+ "react-dom": "ReactDOM",
6
+ "react-dom/client": "ReactDOM",
7
+ "react/jsx-runtime": "React",
8
+ };
9
+ /** Translates package name to global window variable name */
10
+ export function getWmakeGlobals(cwd = process.cwd()) {
11
+ const deps = getWmakeDeps(cwd);
12
+ const res = { ...BASE_GLOBALS };
13
+ for (const pkg of deps) {
14
+ const name = pkg.replace("@allior/wmake-", "");
15
+ const pascalName = name
16
+ .split("-")
17
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
18
+ .join("");
19
+ res[pkg] = `Wmake${pascalName}`;
20
+ res[`${pkg}/react`] = `Wmake${pascalName}React`;
21
+ }
22
+ return res;
23
+ }
24
+ /** Translates package name to global window variable name (without React/ReactDOM) */
25
+ export function getRawWmakeGlobals(cwd = process.cwd()) {
26
+ const deps = getWmakeDeps(cwd);
27
+ const res = {};
28
+ for (const pkg of deps) {
29
+ const name = pkg.replace("@allior/wmake-", "");
30
+ const pascalName = name
31
+ .split("-")
32
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
33
+ .join("");
34
+ res[pkg] = `Wmake${pascalName}`;
35
+ res[`${pkg}/react`] = `Wmake${pascalName}React`;
36
+ }
37
+ return res;
103
38
  }
39
+ /** Generates Vite aliases for workspace development */
104
40
  export function getWmakeAliases(root) {
105
- return {
106
- "@allior/wmake-streamelements-events/react": path.join(root, "streamelements-events/dist/react/index.js"),
107
- "@allior/wmake-streamelements-events": path.join(root, "streamelements-events/dist/root/index.js"),
108
- "@allior/wmake-utils/react": path.join(root, "utils/dist/react/index.js"),
109
- "@allior/wmake-utils": path.join(root, "utils/dist/root/index.js"),
110
- "@allior/wmake-emotes/react": path.join(root, "emotes/dist/react/index.js"),
111
- "@allior/wmake-emotes/7tv": path.join(root, "emotes/dist/7tv/index.js"),
112
- "@allior/wmake-emotes": path.join(root, "emotes/dist/root/index.js"),
113
- "@allior/wmake-streamelements/react": path.join(root, "streamelements/dist/react/index.js"),
114
- "@allior/wmake-streamelements/fields": path.join(root, "streamelements/dist/fields/index.js"),
115
- "@allior/wmake-streamelements": path.join(root, "streamelements/dist/root/index.js"),
116
- };
41
+ const dirs = fs.readdirSync(root, { withFileTypes: true });
42
+ const aliases = {};
43
+ for (const dir of dirs) {
44
+ if (dir.isDirectory()) {
45
+ const pkgPath = path.join(root, dir.name, "package.json");
46
+ if (fs.existsSync(pkgPath)) {
47
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
48
+ if (pkg.name && pkg.name.startsWith("@allior/wmake-")) {
49
+ aliases[pkg.name] = path.resolve(root, dir.name, "dist/root/index.js");
50
+ aliases[`${pkg.name}/react`] = path.resolve(root, dir.name, "dist/react/index.js");
51
+ }
52
+ }
53
+ }
54
+ }
55
+ return aliases;
56
+ }
57
+ /** Detects @allior/wmake-* dependencies in package.json and sorts them by hierarchy */
58
+ export function getWmakeDeps(cwd = process.cwd()) {
59
+ const pkgPath = path.join(cwd, "package.json");
60
+ if (!fs.existsSync(pkgPath))
61
+ return [];
62
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
63
+ const deps = Object.keys(pkg.dependencies || {}).filter((d) => d.startsWith("@allior/wmake-"));
64
+ return sortWmakeDeps(deps);
65
+ }
66
+ /** Detects dependencies and their current versions from package.json */
67
+ export function getWmakeDepsWithVersions(cwd = process.cwd()) {
68
+ const pkgPath = path.join(cwd, "package.json");
69
+ if (!fs.existsSync(pkgPath))
70
+ return {};
71
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
72
+ const res = {};
73
+ const deps = pkg.dependencies || {};
74
+ for (const d in deps) {
75
+ if (d.startsWith("@allior/wmake-")) {
76
+ res[d] = deps[d].replace(/[\^~]/, "");
77
+ }
78
+ }
79
+ return res;
80
+ }
81
+ /** Checks if a dependency should be external in CDN mode */
82
+ export function isExternalForCdn(id, cwd = process.cwd()) {
83
+ const normId = id.replace(/\\/g, "/");
84
+ if (Object.keys(BASE_GLOBALS).some(base => id === base || id.startsWith(base + "/")))
85
+ return true;
86
+ if (id.startsWith("@allior/wmake-") && id !== "@allior/wmake-cli")
87
+ return true;
88
+ const WMAKE_LIBS = ["utils", "streamelements", "streamelements-events", "emotes"];
89
+ for (const lib of WMAKE_LIBS) {
90
+ if (normId.includes(`/${lib}/dist/`))
91
+ return true;
92
+ }
93
+ if (normId.includes("/@allior/wmake-") || normId.includes("/wmake-")) {
94
+ if (!normId.includes("/wmake-cli/"))
95
+ return true;
96
+ }
97
+ return false;
98
+ }
99
+ /** Legacy helper for external dependencies */
100
+ export function getExternalForCdn(cwd = process.cwd()) {
101
+ const deps = getWmakeDeps(cwd);
102
+ const res = [...Object.keys(BASE_GLOBALS)];
103
+ for (const pkg of deps) {
104
+ res.push(pkg);
105
+ res.push(`${pkg}/react`);
106
+ }
107
+ return res;
117
108
  }
118
- export function getWmakeOptimizeDeps() {
109
+ /** Provides list of dependencies for pre-optimization */
110
+ export function getWmakeOptimizeDeps(cwd = process.cwd()) {
111
+ const deps = getWmakeDeps(cwd);
112
+ return [...deps, ...deps.map((d) => `${d}/react`)];
113
+ }
114
+ /** Vite plugin to inject global window shims for widget development */
115
+ export function wmakeScriptCdnPlugin(options = {}) {
116
+ const { useCdn = true } = options;
117
+ if (!useCdn)
118
+ return { name: "wmake-script-cdn-plugin" };
119
119
  return {
120
- include: [
121
- "@allior/wmake-streamelements-events",
122
- "@allior/wmake-utils",
123
- "@allior/wmake-emotes/7tv",
124
- "@allior/wmake-streamelements",
125
- ],
120
+ name: "wmake-script-cdn-plugin",
121
+ transformIndexHtml(html) {
122
+ return html.replace("</head>", `<script src="https://cdn.jsdelivr.net/bundle/npm/react@18.2.0/umd/react.production.min.js"></script>
123
+ <script src="https://cdn.jsdelivr.net/bundle/npm/react-dom@18.2.0/umd/react-dom.production.min.js"></script>
124
+ </head>`);
125
+ },
126
126
  };
127
127
  }
128
+ /** Sorts dependencies in correct loading order based on internals */
129
+ export function sortWmakeDeps(deps) {
130
+ const order = ["utils", "streamelements-events", "emotes", "streamelements"];
131
+ return [...deps].sort((a, b) => {
132
+ const aName = a.replace("@allior/wmake-", "");
133
+ const bName = b.replace("@allior/wmake-", "");
134
+ let aIdx = order.indexOf(aName);
135
+ let bIdx = order.indexOf(bName);
136
+ if (aIdx === -1)
137
+ aIdx = 999;
138
+ if (bIdx === -1)
139
+ bIdx = 999;
140
+ return aIdx - bIdx;
141
+ });
142
+ }
package/dist/widget.d.ts CHANGED
@@ -1,4 +1,8 @@
1
- export declare function buildWidget(options: {
1
+ import { GenerateFieldsOptions } from "./generate-fields.js";
2
+ export interface BuildWidgetOptions extends GenerateFieldsOptions {
2
3
  full?: boolean;
3
- }): Promise<void>;
4
+ seDir?: string;
5
+ }
6
+ /** Builds project for StreamElements widget using CDN mode */
7
+ export declare function buildWidget(options?: BuildWidgetOptions): Promise<void>;
4
8
  //# sourceMappingURL=widget.d.ts.map