@tixyel/cli 2.4.0 → 2.6.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/dist/index.js CHANGED
@@ -39,15 +39,38 @@ program
39
39
  },
40
40
  ]);
41
41
  if (installPackages) {
42
- const { packageManager } = await inquirer.prompt([
43
- {
44
- type: 'select',
45
- name: 'packageManager',
46
- message: 'Select your package manager:',
47
- choices: ['npm', 'yarn', 'pnpm', 'bun'],
48
- default: 'npm',
49
- },
50
- ]);
42
+ const availablesManagers = [];
43
+ // check if npm is available
44
+ const checkManager = async (manager) => {
45
+ try {
46
+ await execPromise(`${manager} --version`);
47
+ availablesManagers.push(manager);
48
+ }
49
+ catch {
50
+ // not available
51
+ }
52
+ };
53
+ await Promise.all(['npm', 'yarn', 'pnpm', 'bun'].map((mgr) => checkManager(mgr)));
54
+ var packageManager;
55
+ if (availablesManagers.length === 0) {
56
+ console.error('❌ No package managers found (npm, yarn, pnpm, bun). Please install one and try again.');
57
+ return;
58
+ }
59
+ else if (availablesManagers.length === 1) {
60
+ packageManager = availablesManagers[0];
61
+ }
62
+ else {
63
+ const response = await inquirer.prompt([
64
+ {
65
+ type: 'select',
66
+ name: 'packageManager',
67
+ message: 'Select your package manager:',
68
+ choices: availablesManagers,
69
+ default: 'npm',
70
+ },
71
+ ]);
72
+ packageManager = response.packageManager;
73
+ }
51
74
  console.log(`📦 Installing packages using ${packageManager} ...`);
52
75
  let installCommand = '';
53
76
  const packages = ['@tixyel/cli', '@tixyel/streamelements', 'comfy.js', 'motion', 'typescript', '@types/node', '@types/jquery', 'lottie-web'];
@@ -0,0 +1,7 @@
1
+ import { WidgetInfo } from '../widget';
2
+ export declare var logo: string;
3
+ export declare const watermark: {
4
+ html(widget: WidgetInfo): string;
5
+ css(widget: WidgetInfo): string;
6
+ script(widget: WidgetInfo): string;
7
+ };
@@ -0,0 +1,71 @@
1
+ export var logo = ` ____ _ _ _
2
+ / __ \\ | |_ (_) __ __ _ _ ___ | |
3
+ / / _\` | | __| | | \\ \\/ / | | | | / _ \\ | |
4
+ | | (_| | | |_ | | > < | |_| | | __/ | |
5
+ \\ \\__,_| \\__| |_| /_/\\_\\ \\__, | \\___| |_|
6
+ \\____/ |___/\n`;
7
+ export const watermark = {
8
+ html(widget) {
9
+ return [
10
+ `<!---`,
11
+ logo,
12
+ `Generated by Tixyel Widgets SDK`,
13
+ `Widget name: ${widget.config.name}`,
14
+ `Version: ${widget.config.version}`,
15
+ `Description: ${widget.config.description}`,
16
+ `Tags: ${widget.config.metadata?.tags?.join(', ')}`,
17
+ `Made by: ${widget.config.metadata?.author}`,
18
+ widget.config.metadata?.clientId ? `Made for: ${widget.config.metadata?.clientId}` : undefined,
19
+ ...Object.entries(widget.config.metadata || {})
20
+ .filter(([key]) => !['tags', 'author', 'clientId'].includes(key))
21
+ .map(([key, value]) => `${key}: ${value}`),
22
+ ' ',
23
+ 'DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR',
24
+ `--->`,
25
+ ]
26
+ .filter(Boolean)
27
+ .join('\n');
28
+ },
29
+ css(widget) {
30
+ return [
31
+ `/**`,
32
+ logo,
33
+ `Generated by Tixyel Widgets SDK`,
34
+ `Widget name: ${widget.config.name}`,
35
+ `Version: ${widget.config.version}`,
36
+ `Description: ${widget.config.description}`,
37
+ `Tags: ${widget.config.metadata?.tags?.join(', ')}`,
38
+ `Made by: ${widget.config.metadata?.author}`,
39
+ widget.config.metadata?.clientId ? `Made for: ${widget.config.metadata?.clientId}` : undefined,
40
+ ...Object.entries(widget.config.metadata || {})
41
+ .filter(([key]) => !['tags', 'author', 'clientId'].includes(key))
42
+ .map(([key, value]) => `${key}: ${value}`),
43
+ ' ',
44
+ 'DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR',
45
+ `*/`,
46
+ ]
47
+ .filter(Boolean)
48
+ .join('\n');
49
+ },
50
+ script(widget) {
51
+ return [
52
+ `/**`,
53
+ logo,
54
+ `Generated by Tixyel Widgets SDK`,
55
+ `Widget name: ${widget.config.name}`,
56
+ `Version: ${widget.config.version}`,
57
+ `Description: ${widget.config.description}`,
58
+ `Tags: ${widget.config.metadata?.tags?.join(', ')}`,
59
+ `Made by: ${widget.config.metadata?.author}`,
60
+ widget.config.metadata?.clientId ? `Made for: ${widget.config.metadata?.clientId}` : undefined,
61
+ ...Object.entries(widget.config.metadata || {})
62
+ .filter(([key]) => !['tags', 'author', 'clientId'].includes(key))
63
+ .map(([key, value]) => `${key}: ${value}`),
64
+ ' ',
65
+ 'DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR',
66
+ `*/`,
67
+ ]
68
+ .filter(Boolean)
69
+ .join('\n');
70
+ },
71
+ };
package/dist/widget.js CHANGED
@@ -15,6 +15,7 @@ import postcss from 'postcss';
15
15
  import cssnano from 'cssnano';
16
16
  import JSZip from 'jszip';
17
17
  import { transformSync } from 'esbuild';
18
+ import { watermark } from './utils/watermark';
18
19
  export async function createWidget(path, metadata, config, root) {
19
20
  try {
20
21
  console.log(`📁 Creating ${metadata?.name} at: ${path}`);
@@ -287,81 +288,17 @@ export async function processBuild(widget, workspaceConfig, verbose = false) {
287
288
  }
288
289
  return contents;
289
290
  };
290
- // watermark for the files
291
- var ref = ` ____ _ _ _
292
- / __ \\ | |_ (_) __ __ _ _ ___ | |
293
- / / _\` | | __| | | \\ \\/ / | | | | / _ \\ | |
294
- | | (_| | | |_ | | > < | |_| | | __/ | |
295
- \\ \\__,_| \\__| |_| /_/\\_\\ \\__, | \\___| |_|
296
- \\____/ |___/\n`;
297
- var watermark = {
298
- html: [
299
- `<!---`,
300
- ref,
301
- `Generated by Tixyel Widgets SDK`,
302
- `Widget name: ${widget.config.name}`,
303
- `Version: ${widget.config.version}`,
304
- `Description: ${widget.config.description}`,
305
- `Tags: ${widget.config.metadata?.tags?.join(', ')}`,
306
- `Made by: ${widget.config.metadata?.author}`,
307
- widget.config.metadata?.clientId ? `Made for: ${widget.config.metadata?.clientId}` : undefined,
308
- ...Object.entries(widget.config.metadata || {})
309
- .filter(([key]) => !['tags', 'author', 'clientId'].includes(key))
310
- .map(([key, value]) => `${key}: ${value}`),
311
- ' ',
312
- 'DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR',
313
- `--->`,
314
- ]
315
- .filter(Boolean)
316
- .join('\n'),
317
- css: [
318
- `/**`,
319
- ref,
320
- `Generated by Tixyel Widgets SDK`,
321
- `Widget name: ${widget.config.name}`,
322
- `Version: ${widget.config.version}`,
323
- `Description: ${widget.config.description}`,
324
- `Tags: ${widget.config.metadata?.tags?.join(', ')}`,
325
- `Made by: ${widget.config.metadata?.author}`,
326
- widget.config.metadata?.clientId ? `Made for: ${widget.config.metadata?.clientId}` : undefined,
327
- ...Object.entries(widget.config.metadata || {})
328
- .filter(([key]) => !['tags', 'author', 'clientId'].includes(key))
329
- .map(([key, value]) => `${key}: ${value}`),
330
- ' ',
331
- 'DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR',
332
- `*/`,
333
- ]
334
- .filter(Boolean)
335
- .join('\n'),
336
- script: [
337
- `/**`,
338
- ref,
339
- `Generated by Tixyel Widgets SDK`,
340
- `Widget name: ${widget.config.name}`,
341
- `Version: ${widget.config.version}`,
342
- `Description: ${widget.config.description}`,
343
- `Tags: ${widget.config.metadata?.tags?.join(', ')}`,
344
- `Made by: ${widget.config.metadata?.author}`,
345
- widget.config.metadata?.clientId ? `Made for: ${widget.config.metadata?.clientId}` : undefined,
346
- ...Object.entries(widget.config.metadata || {})
347
- .filter(([key]) => !['tags', 'author', 'clientId'].includes(key))
348
- .map(([key, value]) => `${key}: ${value}`),
349
- ' ',
350
- 'DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR',
351
- `*/`,
352
- ]
353
- .filter(Boolean)
354
- .join('\n'),
355
- };
291
+ const usedWatermarks = new Set();
356
292
  const results = Object.fromEntries(await Promise.all(Object.entries(findPatterns).map(async ([key, patterns]) => {
357
293
  let result = '';
358
294
  const list = normalizeList(patterns);
359
- if (list.length === 0) {
295
+ if (!list.length)
360
296
  return [key, ''];
361
- }
362
297
  // Process HTML
363
- if (['html', 'HTML'].some((k) => key === k)) {
364
- result += watermark.html + '\n';
298
+ if (['html', 'HTML'].some((k) => key === k) || list.some((p) => p.toLowerCase().endsWith('.html'))) {
299
+ if (!usedWatermarks.has('html'))
300
+ result += watermark.html(widget) + '\n';
301
+ usedWatermarks.add('html');
365
302
  if (verbose)
366
303
  console.log(` - Processing HTML...`);
367
304
  const files = findAndRead(entryDir, list);
@@ -388,8 +325,10 @@ export async function processBuild(widget, workspaceConfig, verbose = false) {
388
325
  const minified = await minifyHTML(mergedHTML, workspaceConfig.build?.obfuscation?.html);
389
326
  result += minified.trim();
390
327
  }
391
- else if (['css', 'style', 'styles'].some((k) => key === k)) {
392
- result += watermark.css + '\n';
328
+ else if (['css', 'style', 'styles'].some((k) => key === k) || list.some((p) => p.toLowerCase().endsWith('.css'))) {
329
+ if (!usedWatermarks.has('css'))
330
+ result += watermark.css(widget) + '\n';
331
+ usedWatermarks.add('css');
393
332
  if (verbose)
394
333
  console.log(` - Processing CSS...`);
395
334
  const files = findAndRead(entryDir, list);
@@ -410,8 +349,10 @@ export async function processBuild(widget, workspaceConfig, verbose = false) {
410
349
  }
411
350
  result += mergedCSS.trim();
412
351
  }
413
- else if (['script', 'js', 'javascript'].some((k) => key === k)) {
414
- result += watermark.script + '\n';
352
+ else if (['script', 'js', 'javascript'].some((k) => key === k) || list.some((p) => p.toLowerCase().endsWith('.js'))) {
353
+ if (!usedWatermarks.has('script'))
354
+ result += watermark.script(widget) + '\n';
355
+ usedWatermarks.add('script');
415
356
  if (verbose)
416
357
  console.log(` - Processing JavaScript...`);
417
358
  const files = findAndRead(entryDir, list);
@@ -422,8 +363,10 @@ export async function processBuild(widget, workspaceConfig, verbose = false) {
422
363
  }
423
364
  result += mergedJS.trim();
424
365
  }
425
- else if (['typescript', 'ts'].some((k) => key === k)) {
426
- result += watermark.script + '\n';
366
+ else if (['typescript', 'ts'].some((k) => key === k) || list.some((p) => p.toLowerCase().endsWith('.ts'))) {
367
+ if (!usedWatermarks.has('script'))
368
+ result += watermark.script(widget) + '\n';
369
+ usedWatermarks.add('script');
427
370
  if (verbose)
428
371
  console.log(` - Processing TypeScript...`);
429
372
  const files = findAndRead(entryDir, list);
@@ -446,7 +389,7 @@ export async function processBuild(widget, workspaceConfig, verbose = false) {
446
389
  const obfuscated = JavaScriptObfuscator.obfuscate(mergedTS.trim(), workspaceConfig.build?.obfuscation?.javascript);
447
390
  result += obfuscated.getObfuscatedCode();
448
391
  }
449
- else if (['fields', 'FIELDS', 'fielddata', 'fieldData'].some((k) => key === k)) {
392
+ else if (['fields', 'FIELDS', 'fielddata', 'fieldData'].some((k) => key === k) || list.some((p) => p.toLowerCase().endsWith('.json'))) {
450
393
  if (verbose)
451
394
  console.log(` - Processing Json...`);
452
395
  const files = findAndRead(entryDir, list);
@@ -455,10 +398,7 @@ export async function processBuild(widget, workspaceConfig, verbose = false) {
455
398
  try {
456
399
  const noComments = parse(content);
457
400
  const parsed = JSON.parse(JSON.stringify(noComments));
458
- mergedFields = {
459
- ...mergedFields,
460
- ...parsed,
461
- };
401
+ Object.assign(mergedFields, parsed);
462
402
  }
463
403
  catch (error) {
464
404
  console.warn(` ⚠️ Failed to parse fields JSON: ${error}`);
@@ -475,7 +415,19 @@ export async function processBuild(widget, workspaceConfig, verbose = false) {
475
415
  return [key, result];
476
416
  })));
477
417
  for await (const [filename, key] of Object.entries(resultMapping)) {
478
- const content = results[key];
418
+ let content = '';
419
+ if (typeof key === 'string')
420
+ content = results[key];
421
+ else if (Array.isArray(key)) {
422
+ for await (const k of key) {
423
+ const part = results[k];
424
+ if (part) {
425
+ content += '\n' + part;
426
+ if (verbose)
427
+ console.log(` ✓ Merged part for: ${k}`);
428
+ }
429
+ }
430
+ }
479
431
  if (content) {
480
432
  const outPath = join(outDir, filename);
481
433
  writeFileSync(outPath, content, 'utf-8');
@@ -487,7 +439,19 @@ export async function processBuild(widget, workspaceConfig, verbose = false) {
487
439
  try {
488
440
  const zip = new JSZip();
489
441
  for await (const [filename, key] of Object.entries(compactedMapping)) {
490
- const content = results[key];
442
+ let content = '';
443
+ if (typeof key === 'string')
444
+ content = results[key];
445
+ else if (Array.isArray(key)) {
446
+ for await (const k of key) {
447
+ const part = results[k];
448
+ if (part) {
449
+ content += '\n' + part;
450
+ if (verbose)
451
+ console.log(` ✓ Merged part for ZIP: ${k}`);
452
+ }
453
+ }
454
+ }
491
455
  if (content) {
492
456
  zip.file(filename, content);
493
457
  if (verbose)
@@ -104,7 +104,7 @@ export interface WorkspaceConfig<Find extends BuildFindMap = BuildFindMap> {
104
104
  };
105
105
  }
106
106
  type BuildFindMap = Record<string, string[]>;
107
- type BuildResultMap<Find extends BuildFindMap> = Record<string, keyof Find>;
107
+ type BuildResultMap<Find extends BuildFindMap> = Record<string, keyof Find | (keyof Find)[]>;
108
108
  export declare function defineWorkspaceConfig<const Find extends BuildFindMap>(config: WorkspaceConfig<Find>): WorkspaceConfig<Find>;
109
109
  export declare function resolveConfig(path: string): Promise<WorkspaceConfig>;
110
110
  export declare function findWorkspaceRoot(startPath?: string): Promise<string | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tixyel/cli",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "CLI tool for streamelements widgets",
5
5
  "keywords": [
6
6
  "cli",
@@ -77,7 +77,8 @@
77
77
  "@types/inquirer": "^9.0.9",
78
78
  "@types/react": "^19.2.7",
79
79
  "@types/react-dom": "^19.2.3",
80
- "@types/ws": "^8.5.12"
80
+ "@types/ws": "^8.5.12",
81
+ "typescript": "^5.9.3"
81
82
  },
82
83
  "publishConfig": {
83
84
  "access": "public",