@tixyel/cli 2.7.0 → 3.0.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 DELETED
@@ -1,416 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command as Commander } from 'commander';
3
- import { basename, join, resolve } from 'path';
4
- import { writeFile } from 'fs/promises';
5
- import { createRequire } from 'module';
6
- const program = new Commander();
7
- program
8
- .name('tixyel')
9
- .description('CLI tool for streamelements widgets')
10
- .version((() => {
11
- try {
12
- const require = createRequire(import.meta.url);
13
- const { version } = require('../package.json');
14
- return version ?? 'dev';
15
- }
16
- catch {
17
- return process.env.TIXYEL_VERSION ?? 'dev';
18
- }
19
- })());
20
- program
21
- .command('init')
22
- .aliases(['initialize', 'i', 'setup', 'start'])
23
- .description('Initialize a new widget workspace.')
24
- .action(async () => {
25
- const { workspace_config } = await import('./templates/workspace.js');
26
- const root = process.cwd();
27
- const config = resolve(root, 'tixyel.config.ts');
28
- // Pergunta se o usuário quer instalar pacotes npm
29
- const inquirer = (await import('inquirer')).default;
30
- const { exec } = await import('child_process');
31
- const util = await import('util');
32
- const execPromise = util.promisify(exec);
33
- const { installPackages } = await inquirer.prompt([
34
- {
35
- type: 'confirm',
36
- name: 'installPackages',
37
- message: 'You want to install essential npm/bun packages?',
38
- default: true,
39
- },
40
- ]);
41
- if (installPackages) {
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
- }
74
- console.log(`📦 Installing packages using ${packageManager} ...`);
75
- let installCommand = '';
76
- const packages = ['@tixyel/cli', '@tixyel/streamelements', 'comfy.js', 'motion', 'typescript', '@types/node', '@types/jquery', 'lottie-web'];
77
- switch (packageManager) {
78
- case 'npm': {
79
- installCommand = `npm install ${packages.join(' ')}`;
80
- break;
81
- }
82
- case 'yarn': {
83
- installCommand = `yarn add ${packages.join(' ')}`;
84
- break;
85
- }
86
- case 'pnpm': {
87
- installCommand = `pnpm add ${packages.join(' ')}`;
88
- break;
89
- }
90
- case 'bun': {
91
- installCommand = `bun add ${packages.join(' ')}`;
92
- break;
93
- }
94
- }
95
- if (!installCommand) {
96
- console.error('❌ Invalid package manager selected.');
97
- return;
98
- }
99
- try {
100
- const { stdout, stderr } = await execPromise(installCommand, { cwd: root });
101
- if (stdout)
102
- process.stdout.write(stdout);
103
- if (stderr)
104
- process.stderr.write(stderr);
105
- console.log('✅ Packages installed successfully.');
106
- }
107
- catch (error) {
108
- console.error('❌ Error installing packages:', error);
109
- }
110
- }
111
- console.log('🚀 Initializing new workspace...');
112
- console.log(`📁 Workspace root: ${root}`);
113
- const content = workspace_config;
114
- try {
115
- await writeFile(config, content, 'utf-8');
116
- console.log(`✅ Created tixyel.config.ts`);
117
- console.log(' Edit it to customize your workspace settings.');
118
- console.log('\n🎉 All set! Start building your widgets!');
119
- console.log(' - Use "tixyel generate" to create new widgets.');
120
- console.log(' - Use "tixyel build" to build your widgets for publish.');
121
- }
122
- catch (error) {
123
- throw error;
124
- }
125
- });
126
- program
127
- .command('generate [path] [name] [description] [tags]')
128
- .aliases(['new', 'g', 'create', 'widget'])
129
- .description('Generate a new widget.')
130
- .action(async (path, name, description, tags) => {
131
- try {
132
- const { validateWorkspace, loadWorkspace } = await import('./workspace.js');
133
- const { createWidget, getNextWidgetNumber } = await import('./widget.js');
134
- // Validate if the workspace is initialized
135
- const validWorkspacePath = await validateWorkspace();
136
- const rootPath = process.cwd();
137
- // Load the workspace config
138
- const workspaceConfig = await loadWorkspace(validWorkspacePath);
139
- // Default to current dir if the path wasn't provided
140
- const resolvedPath = path ? resolve(rootPath, path.replace(/[/\\]$/, '')) : rootPath;
141
- const isTarget = path ? path.endsWith('/') || path.endsWith('\\') : false;
142
- console.log('🎨 Generating widget...\n');
143
- if (isTarget) {
144
- // Path ends with / -> use as target directory
145
- const folderName = basename(resolvedPath);
146
- await createWidget(resolvedPath, {
147
- name: folderName,
148
- description,
149
- tags: tags ? tags.split(',').map((t) => t.trim()) : undefined,
150
- }, workspaceConfig, validWorkspacePath);
151
- }
152
- else {
153
- // Path without / -> use as parent directory
154
- let finalWidgetName = name;
155
- if (!finalWidgetName) {
156
- // Get next number and ask for name
157
- const nextNum = await getNextWidgetNumber(resolvedPath);
158
- const defaultName = `${nextNum} - Widget`;
159
- const inquirer = (await import('inquirer')).default;
160
- const answers = await inquirer.prompt([
161
- {
162
- type: 'input',
163
- name: 'name',
164
- message: 'Widget name:',
165
- default: defaultName,
166
- },
167
- ]);
168
- finalWidgetName = answers.name;
169
- }
170
- const widgetPath = join(resolvedPath, finalWidgetName);
171
- await createWidget(widgetPath, {
172
- name: finalWidgetName.replace(/^\d+\s*-\s*/, ''),
173
- description,
174
- tags: tags ? tags.split(',').map((t) => t.trim()) : undefined,
175
- }, workspaceConfig, validWorkspacePath);
176
- }
177
- console.log('\n✨ Generation complete!');
178
- }
179
- catch (error) {
180
- throw error;
181
- }
182
- });
183
- program
184
- .command('build')
185
- .aliases(['b', 'compact', 'compile'])
186
- .description('Build widgets in the workspace. Supports interactive selection and version bumping.')
187
- .option('-d --depth <number>', 'Maximum search depth for widgets', '3')
188
- .option('-p --parallel', 'Build widgets in parallel')
189
- .option('-v --verbose', 'Show verbose output')
190
- .option('-w --widgets <names>', 'Widget names or paths to build (comma-separated, or * for all)')
191
- .option('-b --bump <type>', 'Version bump type (none, patch, minor, major)')
192
- .action(async (options = {}) => {
193
- try {
194
- const { validateWorkspace, loadWorkspace } = await import('./workspace.js');
195
- const { build, findWidgets } = await import('./widget.js');
196
- let inquirer = null;
197
- const getInquirer = async () => (inquirer ??= (await import('inquirer')).default);
198
- // Validate if the workspace is initialized
199
- const validWorkspacePath = await validateWorkspace();
200
- const rootPath = process.cwd();
201
- // Load the workspace config
202
- const workspaceConfig = await loadWorkspace(validWorkspacePath);
203
- const maxDepth = options.depth ? parseInt(options.depth, 10) : workspaceConfig.search?.maxDepth || 3;
204
- console.log(`🔍 Searching for widgets (max depth: ${maxDepth})...\n`);
205
- // Find all widgets on the workspace
206
- const widgets = await findWidgets(rootPath, maxDepth, workspaceConfig.search?.ignore || []);
207
- let selectedPaths = [];
208
- if (widgets.length === 0) {
209
- console.log('❌ No widgets found with .tixyel configuration files.');
210
- return;
211
- }
212
- // Handle --widgets option
213
- if (options.widgets) {
214
- if (options.widgets === '*') {
215
- // Select all widgets
216
- selectedPaths = widgets.map((w) => w.path);
217
- console.log(`✅ Auto-selected all ${widgets.length} widget(s)\n`);
218
- }
219
- else {
220
- // Parse comma-separated widget names or paths
221
- const widgetSelectors = options.widgets.split(',').map((s) => s.trim());
222
- selectedPaths = widgets.filter((w) => widgetSelectors.some((sel) => w.config.name === sel || w.path.includes(sel))).map((w) => w.path);
223
- if (selectedPaths.length === 0) {
224
- console.log(`❌ No widgets matched the provided names/paths: ${options.widgets}`);
225
- return;
226
- }
227
- console.log(`✅ Selected ${selectedPaths.length} widget(s)\n`);
228
- }
229
- }
230
- else {
231
- // Interactive mode
232
- const choices = widgets.map((widget) => ({
233
- name: `${widget.config.name} (${widget.relativePath})`,
234
- value: widget.path,
235
- checked: false,
236
- }));
237
- if (widgets.length === 1) {
238
- selectedPaths = [choices[0].value];
239
- console.log(`🔒 Only one widget found, auto-selected: ${choices[0].name}\n`);
240
- }
241
- else {
242
- console.log(`✅ Found ${widgets.length} widget(s)\n`);
243
- const inquirerInstance = await getInquirer();
244
- const answers = await inquirerInstance.prompt([
245
- {
246
- type: 'checkbox',
247
- name: 'selectedWidgets',
248
- message: 'Select widgets to build:',
249
- choices,
250
- pageSize: 10,
251
- loop: false,
252
- },
253
- ]);
254
- selectedPaths = answers.selectedWidgets;
255
- }
256
- }
257
- if (selectedPaths.length === 0) {
258
- console.log('❌ No widgets selected for build. Exiting.');
259
- return;
260
- }
261
- // Handle version bump
262
- let versionBump = 'none';
263
- if (options.bump) {
264
- const validBumps = ['none', 'patch', 'minor', 'major'];
265
- if (!validBumps.includes(options.bump)) {
266
- console.log(`❌ Invalid version bump type: ${options.bump}. Valid options: ${validBumps.join(', ')}`);
267
- return;
268
- }
269
- versionBump = options.bump;
270
- console.log(`📌 Version bump: ${versionBump}\n`);
271
- }
272
- else {
273
- // Interactive mode
274
- const inquirerInstance = await getInquirer();
275
- const versionAnswers = await inquirerInstance.prompt([
276
- {
277
- type: 'select',
278
- name: 'versionBump',
279
- message: 'Select version bump type:',
280
- choices: [
281
- { name: 'No version bump', value: 'none' },
282
- { name: 'Patch (x.x.1)', value: 'patch' },
283
- { name: 'Minor (x.1.x)', value: 'minor' },
284
- { name: 'Major (1.x.x)', value: 'major' },
285
- ],
286
- default: 'none',
287
- loop: false,
288
- pageSize: 4,
289
- },
290
- ]);
291
- versionBump = versionAnswers.versionBump;
292
- }
293
- // Resolve parallel option (CLI option overrides config)
294
- const buildInParallel = options.parallel ?? workspaceConfig.build?.parallel ?? false;
295
- const verboseOutput = options.verbose ?? workspaceConfig.build?.verbose ?? false;
296
- console.log(`\n⚙️ Building ${selectedPaths.length} widget(s)${buildInParallel ? ' in parallel' : ''}...\n`);
297
- if (buildInParallel) {
298
- await Promise.all(selectedPaths.map(async (path) => {
299
- const widget = widgets.find((w) => w.path === path);
300
- if (widget) {
301
- await build(widget, versionBump, verboseOutput, workspaceConfig);
302
- }
303
- }));
304
- }
305
- else {
306
- for (const widgetPath of selectedPaths) {
307
- const widget = widgets.find((w) => w.path === widgetPath);
308
- if (widget) {
309
- await build(widget, versionBump, verboseOutput, workspaceConfig);
310
- }
311
- }
312
- }
313
- console.log('\n🎉 Build process complete!');
314
- }
315
- catch (error) {
316
- throw error;
317
- }
318
- });
319
- program
320
- .command('update')
321
- .aliases(['upgrade', 'u'])
322
- .description('Update Tixyel packages to the latest version.')
323
- .option('-f --force', 'Force update even if already on latest version', false)
324
- .option('-nc --no-cache', 'Disable package manager cache during installation', false)
325
- .action(async (options) => {
326
- const root = process.cwd();
327
- const inquirer = (await import('inquirer')).default;
328
- const { exec } = await import('child_process');
329
- const util = await import('util');
330
- const execPromise = util.promisify(exec);
331
- const availablesManagers = [];
332
- // check if npm is available
333
- const checkManager = async (manager) => {
334
- try {
335
- await execPromise(`${manager} --version`);
336
- availablesManagers.push(manager);
337
- }
338
- catch {
339
- // not available
340
- }
341
- };
342
- await Promise.all(['npm', 'yarn', 'pnpm', 'bun'].map((mgr) => checkManager(mgr)));
343
- var packageManager;
344
- if (availablesManagers.length === 0) {
345
- console.error('❌ No package managers found (npm, yarn, pnpm, bun). Please install one and try again.');
346
- return;
347
- }
348
- else if (availablesManagers.length === 1) {
349
- packageManager = availablesManagers[0];
350
- }
351
- else {
352
- const response = await inquirer.prompt([
353
- {
354
- type: 'select',
355
- name: 'packageManager',
356
- message: 'Select your package manager:',
357
- choices: availablesManagers,
358
- default: 'npm',
359
- },
360
- ]);
361
- packageManager = response.packageManager;
362
- }
363
- console.log(`📦 Installing packages using ${packageManager} ...`);
364
- let installCommand = '';
365
- const packages = ['@tixyel/cli@latest', '@tixyel/streamelements@latest'];
366
- switch (packageManager) {
367
- case 'npm': {
368
- installCommand = `npm install ${packages.join(' ')}`;
369
- if (options.noCache)
370
- installCommand += ' --no-cache';
371
- if (options.force)
372
- installCommand += ' --force';
373
- break;
374
- }
375
- case 'yarn': {
376
- installCommand = `yarn add ${packages.join(' ')}`;
377
- if (options.noCache)
378
- installCommand += ' --no-cache';
379
- if (options.force)
380
- installCommand += ' --force';
381
- break;
382
- }
383
- case 'pnpm': {
384
- installCommand = `pnpm add ${packages.join(' ')}`;
385
- if (options.noCache)
386
- installCommand += ' --no-cache';
387
- if (options.force)
388
- installCommand += ' --force';
389
- break;
390
- }
391
- case 'bun': {
392
- installCommand = `bun add ${packages.join(' ')}`;
393
- if (options.noCache)
394
- installCommand += ' --no-cache';
395
- if (options.force)
396
- installCommand += ' --force';
397
- break;
398
- }
399
- }
400
- if (!installCommand) {
401
- console.error('❌ Invalid package manager selected.');
402
- return;
403
- }
404
- try {
405
- const { stdout, stderr } = await execPromise(installCommand, { cwd: root });
406
- if (stdout)
407
- process.stdout.write(stdout);
408
- if (stderr)
409
- process.stderr.write(stderr);
410
- console.log('✅ Packages updated successfully.');
411
- }
412
- catch (error) {
413
- console.error('❌ Error installing packages:', error);
414
- }
415
- });
416
- program.parse();
@@ -1 +0,0 @@
1
- export declare const workspace_config: string;
@@ -1,111 +0,0 @@
1
- export const workspace_config = `
2
- import { defineWorkspaceConfig } from '@tixyel/cli/api';
3
-
4
- export default defineWorkspaceConfig({
5
- search: {
6
- maxDepth: 3,
7
- ignore: ['node_modules', 'dist', 'build', '.git'],
8
- },
9
-
10
- metadata: {
11
- author: 'Your Name',
12
- clientId: 'your-client-id',
13
- },
14
-
15
- scaffold: [
16
- {
17
- name: 'development',
18
- type: 'folder',
19
- content: [
20
- {
21
- name: 'index.html',
22
- type: 'file',
23
- content: \`\`,
24
- },
25
- {
26
- name: 'style.css',
27
- type: 'file',
28
- content: \`\`,
29
- },
30
- {
31
- name: 'script.js',
32
- type: 'file',
33
- content: \`\`,
34
- },
35
- {
36
- name: 'fields.json',
37
- type: 'file',
38
- content: '{}',
39
- },
40
- {
41
- name: 'data.json',
42
- type: 'file',
43
- content: '{}',
44
- },
45
- ],
46
- },
47
- {
48
- name: 'finished',
49
- type: 'folder',
50
- },
51
- {
52
- name: 'widgetIO',
53
- type: 'folder',
54
- },
55
- ],
56
-
57
- build: {
58
- parallel: true,
59
- verbose: false,
60
-
61
- find: {
62
- html: ['index.html'],
63
- script: ['script.js'],
64
- css: ['style.css'],
65
- fields: ['fields.json', 'fields.jsonc'],
66
- },
67
- result: {
68
- 'HTML.html': 'html',
69
- 'SCRIPT.js': 'script',
70
- 'CSS.css': 'css',
71
- 'FIELDS.json': 'fields',
72
- },
73
- widgetIO: {
74
- 'html.txt': 'html',
75
- 'js.txt': 'script',
76
- 'css.txt': 'css',
77
- 'fields.txt': 'fields',
78
- },
79
-
80
- obfuscation: {
81
- javascript: {
82
- compact: true,
83
- log: false,
84
- debugProtection: false,
85
- selfDefending: false,
86
- deadCodeInjection: false,
87
- controlFlowFlattening: false,
88
- stringArray: false,
89
- simplify: false,
90
- identifierNamesGenerator: 'mangled',
91
- },
92
- css: {
93
- removeNesting: true,
94
- autoprefixer: {
95
- overrideBrowserslist: ['Chrome 127'],
96
- },
97
- cssnano: {
98
- preset: 'default',
99
- },
100
- },
101
- html: {
102
- removeComments: true,
103
- collapseWhitespace: true,
104
- minifyCSS: true,
105
- minifyJS: true,
106
- removeAttributeQuotes: false,
107
- },
108
- },
109
- },
110
- });
111
- `.trim();
@@ -1,7 +0,0 @@
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
- };
@@ -1,71 +0,0 @@
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.d.ts DELETED
@@ -1,31 +0,0 @@
1
- import { WorkspaceConfig } from './workspace';
2
- export interface DotTixyel {
3
- name: string;
4
- description: string;
5
- version: string;
6
- config?: string;
7
- metadata: WorkspaceConfig['metadata'];
8
- dirs: WorkspaceConfig['dirs'];
9
- }
10
- export declare function createWidget(path: string, metadata: WorkspaceConfig['metadata'], config: WorkspaceConfig, root: string): Promise<void>;
11
- export declare function getNextWidgetNumber(parentPath: string): Promise<string>;
12
- export declare function validateDotTixyel(config: DotTixyel): boolean;
13
- export type WidgetInfo = {
14
- /**
15
- * Absolute path to the widget directory
16
- */
17
- path: string;
18
- /**
19
- * Relative path from the root directory
20
- */
21
- relativePath: string;
22
- /**
23
- * Parsed .tixyel configuration
24
- */
25
- config: DotTixyel;
26
- };
27
- export declare function readDotTixyel(path: string): Promise<DotTixyel | null>;
28
- export declare function findWidgets(root: string, depth: number, ignore: string[]): Promise<WidgetInfo[]>;
29
- export declare function build(widget: WidgetInfo, versionBump: 'none' | 'patch' | 'minor' | 'major', verbose: boolean | undefined, workspaceConfig: WorkspaceConfig): Promise<void>;
30
- export declare function processBuild(widget: WidgetInfo, workspaceConfig: WorkspaceConfig, verbose?: boolean): Promise<void>;
31
- export declare function bumpVersion(widgetPath: string, bumpType?: 'major' | 'minor' | 'patch'): Promise<string | null>;