@tixyel/cli 1.0.0 → 2.0.1
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/README.md +31 -31
- package/dist/index.d.ts +1 -1
- package/dist/index.js +188 -33
- package/dist/templates/workspace.d.ts +1 -0
- package/dist/templates/workspace.js +111 -0
- package/dist/widget.d.ts +31 -0
- package/dist/widget.js +499 -0
- package/dist/workspace.d.ts +111 -0
- package/dist/workspace.js +225 -0
- package/package.json +70 -62
- package/dist/commands/base.d.ts +0 -24
- package/dist/commands/base.js +0 -15
- package/dist/commands/build.d.ts +0 -15
- package/dist/commands/build.js +0 -155
- package/dist/commands/generate-new.d.ts +0 -11
- package/dist/commands/generate-new.js +0 -146
- package/dist/commands/generate.d.ts +0 -11
- package/dist/commands/generate.js +0 -198
- package/dist/commands/init.d.ts +0 -9
- package/dist/commands/init.js +0 -140
- package/dist/types/tixyel-cli-config.d.ts +0 -149
- package/dist/types/tixyel-cli-config.js +0 -162
- package/dist/types/tixyel-config.d.ts +0 -83
- package/dist/types/tixyel-config.js +0 -43
- package/dist/utils/build-processor.d.ts +0 -12
- package/dist/utils/build-processor.js +0 -156
- package/dist/utils/config.d.ts +0 -23
- package/dist/utils/config.js +0 -34
- package/dist/utils/find-widgets.d.ts +0 -19
- package/dist/utils/find-widgets.js +0 -35
- package/dist/utils/load-cli-config.d.ts +0 -5
- package/dist/utils/load-cli-config.js +0 -66
- package/dist/utils/version.d.ts +0 -12
- package/dist/utils/version.js +0 -49
- package/dist/utils/workspace.d.ts +0 -13
- package/dist/utils/workspace.js +0 -43
package/README.md
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
# @tixyel/cli
|
|
2
|
-
|
|
3
|
-
CLI tool for Tixyel widgets.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g @tixyel/cli
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
tixyel --help
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Development
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm run dev
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Build
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npm run build
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## License
|
|
30
|
-
|
|
31
|
-
Apache-2.0
|
|
1
|
+
# @tixyel/cli
|
|
2
|
+
|
|
3
|
+
CLI tool for Tixyel widgets.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @tixyel/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
tixyel --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Development
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm run dev
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Build
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm run build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## License
|
|
30
|
+
|
|
31
|
+
Apache-2.0
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export
|
|
2
|
+
export * from './workspace.js';
|
package/dist/index.js
CHANGED
|
@@ -1,39 +1,194 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
2
|
+
import { build, createWidget, findWidgets, getNextWidgetNumber } from './widget.js';
|
|
3
|
+
import { loadWorkspace, validateWorkspace } from './workspace.js';
|
|
4
|
+
import { workspace_config } from './templates/workspace.js';
|
|
5
|
+
import { Command as Commander } from 'commander';
|
|
6
|
+
import { basename, join, resolve } from 'path';
|
|
7
|
+
import { writeFile } from 'fs/promises';
|
|
8
|
+
import { createRequire } from 'module';
|
|
9
|
+
import inquirer from 'inquirer';
|
|
10
|
+
const program = new Commander();
|
|
11
|
+
program
|
|
12
|
+
.name('tixyel')
|
|
13
|
+
.description('CLI tool for streamelements widgets')
|
|
14
|
+
.version((() => {
|
|
15
|
+
try {
|
|
16
|
+
const require = createRequire(import.meta.url);
|
|
17
|
+
const { version } = require('../package.json');
|
|
18
|
+
return version ?? 'dev';
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return process.env.TIXYEL_VERSION ?? 'dev';
|
|
22
|
+
}
|
|
23
|
+
})());
|
|
24
|
+
program
|
|
25
|
+
.command('init')
|
|
26
|
+
.aliases(['initialize', 'i', 'setup', 'start'])
|
|
27
|
+
.description('Initialize a new widget workspace.')
|
|
28
|
+
.action(async () => {
|
|
29
|
+
const root = process.cwd();
|
|
30
|
+
const config = resolve(root, 'tixyel.config.ts');
|
|
31
|
+
console.log('🚀 Initializing new workspace...');
|
|
32
|
+
console.log(`📁 Workspace root: ${root}`);
|
|
33
|
+
const content = workspace_config;
|
|
34
|
+
try {
|
|
35
|
+
await writeFile(config, content, 'utf-8');
|
|
36
|
+
console.log(`✅ Created tixyel.config.ts`);
|
|
37
|
+
console.log(' Edit it to customize your workspace settings.');
|
|
38
|
+
console.log('\n🎉 All set! Start building your widgets!');
|
|
39
|
+
console.log(' - Use "tixyel generate" to create new widgets.');
|
|
40
|
+
console.log(' - Use "tixyel build" to build your widgets for publish.');
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
program
|
|
47
|
+
.command('generate [path] [name] [description] [tags]')
|
|
48
|
+
.aliases(['new', 'g', 'create', 'widget'])
|
|
49
|
+
.description('Generate a new widget.')
|
|
50
|
+
.action(async (path, name, description, tags) => {
|
|
51
|
+
try {
|
|
52
|
+
// Validate if the workspace is initialized
|
|
53
|
+
const validWorkspacePath = await validateWorkspace();
|
|
54
|
+
const rootPath = process.cwd();
|
|
55
|
+
// Load the workspace config
|
|
56
|
+
const workspaceConfig = await loadWorkspace(validWorkspacePath);
|
|
57
|
+
// Default to current dir if the path wasn't provided
|
|
58
|
+
const resolvedPath = path ? resolve(rootPath, path.replace(/[/\\]$/, '')) : rootPath;
|
|
59
|
+
const isTarget = path ? path.endsWith('/') || path.endsWith('\\') : false;
|
|
60
|
+
console.log('🎨 Generating widget...\n');
|
|
61
|
+
if (isTarget) {
|
|
62
|
+
// Path ends with / -> use as target directory
|
|
63
|
+
const folderName = basename(resolvedPath);
|
|
64
|
+
await createWidget(resolvedPath, {
|
|
65
|
+
name: folderName,
|
|
66
|
+
description,
|
|
67
|
+
tags: tags ? tags.split(',').map((t) => t.trim()) : undefined,
|
|
68
|
+
}, workspaceConfig, validWorkspacePath);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Path without / -> use as parent directory
|
|
72
|
+
let finalWidgetName = name;
|
|
73
|
+
if (!finalWidgetName) {
|
|
74
|
+
// Get next number and ask for name
|
|
75
|
+
const nextNum = await getNextWidgetNumber(resolvedPath);
|
|
76
|
+
const defaultName = `${nextNum} - Widget`;
|
|
77
|
+
const answers = await inquirer.prompt([
|
|
78
|
+
{
|
|
79
|
+
type: 'input',
|
|
80
|
+
name: 'name',
|
|
81
|
+
message: 'Widget name:',
|
|
82
|
+
default: defaultName,
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
85
|
+
finalWidgetName = answers.name;
|
|
30
86
|
}
|
|
87
|
+
const widgetPath = join(resolvedPath, finalWidgetName);
|
|
88
|
+
await createWidget(widgetPath, {
|
|
89
|
+
name: finalWidgetName,
|
|
90
|
+
description,
|
|
91
|
+
tags: tags ? tags.split(',').map((t) => t.trim()) : undefined,
|
|
92
|
+
}, workspaceConfig, validWorkspacePath);
|
|
93
|
+
}
|
|
94
|
+
console.log('\n✨ Generation complete!');
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
program
|
|
101
|
+
.command('build')
|
|
102
|
+
.aliases(['b', 'compact', 'compile'])
|
|
103
|
+
.description('Build widgets in the workspace. Supports interactive selection and version bumping.')
|
|
104
|
+
.option('-d --depth <number>', 'Maximum search depth for widgets', '3')
|
|
105
|
+
.option('-p --parallel', 'Build widgets in parallel')
|
|
106
|
+
.option('-v --verbose', 'Show verbose output')
|
|
107
|
+
.action(async (options = {}) => {
|
|
108
|
+
try {
|
|
109
|
+
// Validate if the workspace is initialized
|
|
110
|
+
const validWorkspacePath = await validateWorkspace();
|
|
111
|
+
const rootPath = process.cwd();
|
|
112
|
+
// Load the workspace config
|
|
113
|
+
const workspaceConfig = await loadWorkspace(validWorkspacePath);
|
|
114
|
+
const maxDepth = options.depth ? parseInt(options.depth, 10) : workspaceConfig.search?.maxDepth || 3;
|
|
115
|
+
console.log(`🔍 Searching for widgets (max depth: ${maxDepth})...\n`);
|
|
116
|
+
// Find all widgets on the workspace
|
|
117
|
+
const widgets = await findWidgets(rootPath, maxDepth, workspaceConfig.search?.ignore || []);
|
|
118
|
+
const choices = widgets.map((widget) => ({
|
|
119
|
+
name: `${widget.config.name} (${widget.relativePath})`,
|
|
120
|
+
value: widget.path,
|
|
121
|
+
checked: false,
|
|
122
|
+
}));
|
|
123
|
+
let selectedPaths = [];
|
|
124
|
+
if (widgets.length === 0) {
|
|
125
|
+
console.log('❌ No widgets found with .tixyel configuration files.');
|
|
126
|
+
return;
|
|
31
127
|
}
|
|
32
|
-
|
|
33
|
-
|
|
128
|
+
else if (widgets.length === 1) {
|
|
129
|
+
selectedPaths = [choices[0].value];
|
|
130
|
+
console.log(`🔒 Only one widget found, auto-selected: ${choices[0].name}\n`);
|
|
34
131
|
}
|
|
132
|
+
else {
|
|
133
|
+
console.log(`✅ Found ${widgets.length} widget(s)\n`);
|
|
134
|
+
const answers = await inquirer.prompt([
|
|
135
|
+
{
|
|
136
|
+
type: 'checkbox',
|
|
137
|
+
name: 'selectedWidgets',
|
|
138
|
+
message: 'Select widgets to build:',
|
|
139
|
+
choices,
|
|
140
|
+
pageSize: 10,
|
|
141
|
+
loop: false,
|
|
142
|
+
},
|
|
143
|
+
]);
|
|
144
|
+
selectedPaths = answers.selectedWidgets;
|
|
145
|
+
}
|
|
146
|
+
if (selectedPaths.length === 0) {
|
|
147
|
+
console.log('❌ No widgets selected for build. Exiting.');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const versionAnswers = await inquirer.prompt([
|
|
151
|
+
{
|
|
152
|
+
type: 'select',
|
|
153
|
+
name: 'versionBump',
|
|
154
|
+
message: 'Select version bump type:',
|
|
155
|
+
choices: [
|
|
156
|
+
{ name: 'No version bump', value: 'none' },
|
|
157
|
+
{ name: 'Patch (x.x.1)', value: 'patch' },
|
|
158
|
+
{ name: 'Minor (x.1.x)', value: 'minor' },
|
|
159
|
+
{ name: 'Major (1.x.x)', value: 'major' },
|
|
160
|
+
],
|
|
161
|
+
default: 'none',
|
|
162
|
+
loop: false,
|
|
163
|
+
pageSize: 4,
|
|
164
|
+
},
|
|
165
|
+
]);
|
|
166
|
+
const versionBump = versionAnswers.versionBump;
|
|
167
|
+
// Resolve parallel option (CLI option overrides config)
|
|
168
|
+
const buildInParallel = options.parallel ?? workspaceConfig.build?.parallel ?? false;
|
|
169
|
+
const verboseOutput = options.verbose ?? workspaceConfig.build?.verbose ?? false;
|
|
170
|
+
console.log(`\n⚙️ Building ${selectedPaths.length} widget(s)${buildInParallel ? ' in parallel' : ''}...\n`);
|
|
171
|
+
if (buildInParallel) {
|
|
172
|
+
await Promise.all(selectedPaths.map(async (path) => {
|
|
173
|
+
const widget = widgets.find((w) => w.path === path);
|
|
174
|
+
if (widget) {
|
|
175
|
+
await build(widget, versionBump, verboseOutput, workspaceConfig);
|
|
176
|
+
}
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
for (const widgetPath of selectedPaths) {
|
|
181
|
+
const widget = widgets.find((w) => w.path === widgetPath);
|
|
182
|
+
if (widget) {
|
|
183
|
+
await build(widget, versionBump, verboseOutput, workspaceConfig);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
console.log('\n🎉 Build process complete!');
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
throw error;
|
|
35
191
|
}
|
|
36
|
-
}
|
|
37
|
-
// Load commands and parse
|
|
38
|
-
await loadCommands();
|
|
192
|
+
});
|
|
39
193
|
program.parse();
|
|
194
|
+
export * from './workspace.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const workspace_config: string;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export const workspace_config = `
|
|
2
|
+
import { defineWorkspaceConfig } from '@tixyel/cli';
|
|
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();
|
package/dist/widget.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
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>;
|