@tixyel/cli 1.0.0 ā 2.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/dev.d.ts +2 -0
- package/dist/dev.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +188 -33
- package/dist/templates/config.d.ts +1 -0
- package/dist/templates/config.js +12 -0
- package/dist/templates/workspace.d.ts +1 -0
- package/dist/templates/workspace.js +111 -0
- package/dist/types/workspace.d.ts +47 -0
- package/dist/types/workspace.js +4 -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 +19 -16
- 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
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
|
|
2
|
+
import { transform } from 'esbuild';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
const DEFAULT_WORKSPACE_CONFIG = {
|
|
5
|
+
search: {
|
|
6
|
+
maxDepth: 3,
|
|
7
|
+
ignore: ['node_modules', 'dist', '.git', '.turbo', '.vscode'],
|
|
8
|
+
},
|
|
9
|
+
dirs: {
|
|
10
|
+
entry: 'development',
|
|
11
|
+
output: 'finished',
|
|
12
|
+
compacted: 'widgetIO',
|
|
13
|
+
},
|
|
14
|
+
scaffold: [
|
|
15
|
+
{
|
|
16
|
+
name: 'development',
|
|
17
|
+
type: 'folder',
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
name: 'index.html',
|
|
21
|
+
type: 'file',
|
|
22
|
+
content: ``,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'style.css',
|
|
26
|
+
type: 'file',
|
|
27
|
+
content: ``,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'script.js',
|
|
31
|
+
type: 'file',
|
|
32
|
+
content: ``,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'fields.json',
|
|
36
|
+
type: 'file',
|
|
37
|
+
content: '{}',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'data.json',
|
|
41
|
+
type: 'file',
|
|
42
|
+
content: '{}',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'finished',
|
|
48
|
+
type: 'folder',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'widgetIO',
|
|
52
|
+
type: 'folder',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
build: {
|
|
56
|
+
parallel: true,
|
|
57
|
+
verbose: false,
|
|
58
|
+
find: {
|
|
59
|
+
html: ['index.html'],
|
|
60
|
+
script: ['script.js'],
|
|
61
|
+
css: ['style.css'],
|
|
62
|
+
fields: ['fields.json'],
|
|
63
|
+
},
|
|
64
|
+
result: {
|
|
65
|
+
'HTML.html': 'html',
|
|
66
|
+
'SCRIPT.js': 'script',
|
|
67
|
+
'CSS.css': 'css',
|
|
68
|
+
'FIELDS.json': 'fields',
|
|
69
|
+
},
|
|
70
|
+
widgetIO: {
|
|
71
|
+
'html.txt': 'html',
|
|
72
|
+
'js.txt': 'script',
|
|
73
|
+
'css.txt': 'css',
|
|
74
|
+
'fields.txt': 'fields',
|
|
75
|
+
},
|
|
76
|
+
obfuscation: {
|
|
77
|
+
javascript: {},
|
|
78
|
+
css: {
|
|
79
|
+
removeNesting: true,
|
|
80
|
+
autoprefixer: {
|
|
81
|
+
overrideBrowserslist: ['Chrome 127'],
|
|
82
|
+
},
|
|
83
|
+
cssnano: {},
|
|
84
|
+
},
|
|
85
|
+
html: {},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
// Helper to preserve literal keys for autocomplete in find/result
|
|
90
|
+
export function defineWorkspaceConfig(config) {
|
|
91
|
+
config.dirs = {
|
|
92
|
+
...DEFAULT_WORKSPACE_CONFIG.dirs,
|
|
93
|
+
...config.dirs,
|
|
94
|
+
};
|
|
95
|
+
config.build = {
|
|
96
|
+
...DEFAULT_WORKSPACE_CONFIG.build,
|
|
97
|
+
...config.build,
|
|
98
|
+
};
|
|
99
|
+
config.build.find = {
|
|
100
|
+
...DEFAULT_WORKSPACE_CONFIG.build.find,
|
|
101
|
+
...config.build.find,
|
|
102
|
+
};
|
|
103
|
+
config.build.result = {
|
|
104
|
+
...DEFAULT_WORKSPACE_CONFIG.build.result,
|
|
105
|
+
...config.build.result,
|
|
106
|
+
};
|
|
107
|
+
config.search = {
|
|
108
|
+
...DEFAULT_WORKSPACE_CONFIG.search,
|
|
109
|
+
...config.search,
|
|
110
|
+
};
|
|
111
|
+
config.scaffold = config.scaffold || DEFAULT_WORKSPACE_CONFIG.scaffold;
|
|
112
|
+
return config;
|
|
113
|
+
}
|
|
114
|
+
export async function findWorkspaceRoot(startPath = process.cwd()) {
|
|
115
|
+
let currentPath = resolve(startPath);
|
|
116
|
+
// Limit search to 10 levels up to avoid infinite loops
|
|
117
|
+
for (let i = 0; i < 10; i++) {
|
|
118
|
+
const configTs = resolve(currentPath, 'tixyel.config.ts');
|
|
119
|
+
const configJs = resolve(currentPath, 'tixyel.config.js');
|
|
120
|
+
const configPathMjs = resolve(currentPath, 'tixyel.config.mjs');
|
|
121
|
+
if (existsSync(configTs) || existsSync(configJs) || existsSync(configPathMjs)) {
|
|
122
|
+
return currentPath;
|
|
123
|
+
}
|
|
124
|
+
const parentPath = resolve(currentPath, '..');
|
|
125
|
+
if (parentPath === currentPath) {
|
|
126
|
+
// Reached filesystem root
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
currentPath = parentPath;
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
export async function validateWorkspace() {
|
|
134
|
+
const root = await findWorkspaceRoot();
|
|
135
|
+
if (!root) {
|
|
136
|
+
throw new Error('ā Your workspace is not initialized. Please run `tixyel init` in your workspace root first.');
|
|
137
|
+
}
|
|
138
|
+
return root;
|
|
139
|
+
}
|
|
140
|
+
async function loadTsConfig(path, root) {
|
|
141
|
+
const temp = resolve(root, '.tixyel.config.temp.mjs');
|
|
142
|
+
const tsContent = readFileSync(path, 'utf-8');
|
|
143
|
+
const { code } = await transform(tsContent, {
|
|
144
|
+
loader: 'ts',
|
|
145
|
+
format: 'esm',
|
|
146
|
+
target: 'es2022',
|
|
147
|
+
});
|
|
148
|
+
writeFileSync(temp, code, 'utf-8');
|
|
149
|
+
try {
|
|
150
|
+
const mod = await import(`file://${temp}?t=${Date.now()}`);
|
|
151
|
+
return mod.default ?? mod.config;
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
try {
|
|
155
|
+
unlinkSync(temp);
|
|
156
|
+
}
|
|
157
|
+
catch { }
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
export async function loadWorkspace(path) {
|
|
161
|
+
const configPathTs = resolve(path, 'tixyel.config.ts');
|
|
162
|
+
const configPathJs = resolve(path, 'tixyel.config.js');
|
|
163
|
+
const configPathMjs = resolve(path, 'tixyel.config.mjs');
|
|
164
|
+
let config;
|
|
165
|
+
try {
|
|
166
|
+
// Trying .mjs first (already ES module)
|
|
167
|
+
if (existsSync(configPathMjs)) {
|
|
168
|
+
const module = await import(`file://${configPathMjs}`);
|
|
169
|
+
config = module.default || module.config;
|
|
170
|
+
}
|
|
171
|
+
// Trying .js (if package.json has type: module)
|
|
172
|
+
else if (existsSync(configPathJs)) {
|
|
173
|
+
const module = await import(`file://${configPathJs}`);
|
|
174
|
+
config = module.default || module.config;
|
|
175
|
+
}
|
|
176
|
+
// Trying .ts file (compile on-the-fly)
|
|
177
|
+
else if (existsSync(configPathTs)) {
|
|
178
|
+
config = await loadTsConfig(configPathTs, path);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
console.warn(`ā ļø Failed to load tixyel.config: ${error}`);
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
return merge(config);
|
|
186
|
+
}
|
|
187
|
+
function merge(config) {
|
|
188
|
+
const merged = {
|
|
189
|
+
...config,
|
|
190
|
+
search: {
|
|
191
|
+
...DEFAULT_WORKSPACE_CONFIG.search,
|
|
192
|
+
...config?.search,
|
|
193
|
+
},
|
|
194
|
+
metadata: {
|
|
195
|
+
...DEFAULT_WORKSPACE_CONFIG.metadata,
|
|
196
|
+
...config?.metadata,
|
|
197
|
+
},
|
|
198
|
+
dirs: {
|
|
199
|
+
...DEFAULT_WORKSPACE_CONFIG.dirs,
|
|
200
|
+
...config?.dirs,
|
|
201
|
+
},
|
|
202
|
+
scaffold: config?.scaffold || DEFAULT_WORKSPACE_CONFIG.scaffold,
|
|
203
|
+
build: {
|
|
204
|
+
...DEFAULT_WORKSPACE_CONFIG.build,
|
|
205
|
+
...config?.build,
|
|
206
|
+
find: {
|
|
207
|
+
...DEFAULT_WORKSPACE_CONFIG.build.find,
|
|
208
|
+
...config?.build?.find,
|
|
209
|
+
},
|
|
210
|
+
result: {
|
|
211
|
+
...DEFAULT_WORKSPACE_CONFIG.build.result,
|
|
212
|
+
...config?.build?.result,
|
|
213
|
+
},
|
|
214
|
+
widgetIO: {
|
|
215
|
+
...DEFAULT_WORKSPACE_CONFIG.build.widgetIO,
|
|
216
|
+
...config?.build?.widgetIO,
|
|
217
|
+
},
|
|
218
|
+
obfuscation: {
|
|
219
|
+
...DEFAULT_WORKSPACE_CONFIG.build.obfuscation,
|
|
220
|
+
...config?.build?.obfuscation,
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
return merged;
|
|
225
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tixyel/cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "CLI tool for
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "CLI tool for streamelements widgets",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
7
7
|
"widgets",
|
|
8
|
-
"typescript"
|
|
8
|
+
"typescript",
|
|
9
|
+
"server",
|
|
10
|
+
"build"
|
|
9
11
|
],
|
|
10
|
-
"author":
|
|
12
|
+
"author": {
|
|
13
|
+
"name": "Tixyel",
|
|
14
|
+
"email": "tixyelpvd@gmail.com",
|
|
15
|
+
"url": "https://github.com/tixyel"
|
|
16
|
+
},
|
|
11
17
|
"license": "Apache-2.0",
|
|
12
18
|
"homepage": "https://github.com/Tixyel/widgets#readme",
|
|
13
19
|
"repository": {
|
|
@@ -33,30 +39,27 @@
|
|
|
33
39
|
}
|
|
34
40
|
},
|
|
35
41
|
"files": [
|
|
36
|
-
"dist"
|
|
42
|
+
"dist",
|
|
43
|
+
"package.json"
|
|
37
44
|
],
|
|
38
45
|
"scripts": {
|
|
39
|
-
"build": "tsc",
|
|
40
|
-
"dev": "tsc --watch",
|
|
46
|
+
"build": "cross-env TIXYEL_VERSION=$npm_package_version tsc",
|
|
47
|
+
"dev": "cross-env TIXYEL_VERSION=$npm_package_version tsc --watch",
|
|
41
48
|
"check-types": "tsc --noEmit"
|
|
42
49
|
},
|
|
43
|
-
"devDependencies": {
|
|
44
|
-
"@types/inquirer": "^9.0.9",
|
|
45
|
-
"@types/node": "^22.19.1",
|
|
46
|
-
"typescript": "^5.9.3"
|
|
47
|
-
},
|
|
48
50
|
"dependencies": {
|
|
49
|
-
"@types/html-minifier-terser": "^7.0.2",
|
|
50
51
|
"autoprefixer": "^10.4.22",
|
|
51
52
|
"commander": "^14.0.2",
|
|
53
|
+
"cross-env": "^10.1.0",
|
|
52
54
|
"cssnano": "^7.1.2",
|
|
53
55
|
"fast-glob": "^3.3.3",
|
|
54
|
-
"html-minifier": "^4.0.0",
|
|
55
56
|
"html-minifier-terser": "^7.2.0",
|
|
56
57
|
"inquirer": "^13.0.2",
|
|
57
58
|
"javascript-obfuscator": "^4.1.1",
|
|
58
59
|
"jsonc-parser": "^3.3.1",
|
|
59
|
-
"
|
|
60
|
-
|
|
60
|
+
"jszip": "^3.10.1"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/inquirer": "^9.0.9"
|
|
61
64
|
}
|
|
62
65
|
}
|
package/dist/commands/base.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Command as CommanderCommand } from 'commander';
|
|
2
|
-
/**
|
|
3
|
-
* Base class for all CLI commands
|
|
4
|
-
*/
|
|
5
|
-
export declare abstract class Command {
|
|
6
|
-
/**
|
|
7
|
-
* Command name (e.g., 'init', 'build', 'generate')
|
|
8
|
-
*/
|
|
9
|
-
abstract name: string;
|
|
10
|
-
/**
|
|
11
|
-
* Command description
|
|
12
|
-
*/
|
|
13
|
-
abstract description: string;
|
|
14
|
-
/**
|
|
15
|
-
* Register the command with commander
|
|
16
|
-
* Override to add custom arguments/options
|
|
17
|
-
*/
|
|
18
|
-
register(command: CommanderCommand): void;
|
|
19
|
-
/**
|
|
20
|
-
* Execute the command
|
|
21
|
-
* Implement in subclasses
|
|
22
|
-
*/
|
|
23
|
-
abstract execute(...args: unknown[]): Promise<void>;
|
|
24
|
-
}
|
package/dist/commands/base.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base class for all CLI commands
|
|
3
|
-
*/
|
|
4
|
-
export class Command {
|
|
5
|
-
/**
|
|
6
|
-
* Register the command with commander
|
|
7
|
-
* Override to add custom arguments/options
|
|
8
|
-
*/
|
|
9
|
-
register(command) {
|
|
10
|
-
command
|
|
11
|
-
.command(this.name)
|
|
12
|
-
.description(this.description)
|
|
13
|
-
.action((...args) => this.execute(...args));
|
|
14
|
-
}
|
|
15
|
-
}
|
package/dist/commands/build.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Command as CommanderCommand } from 'commander';
|
|
2
|
-
import { Command } from './base.js';
|
|
3
|
-
/**
|
|
4
|
-
* Build command
|
|
5
|
-
*/
|
|
6
|
-
export declare class BuildCommand extends Command {
|
|
7
|
-
name: string;
|
|
8
|
-
description: string;
|
|
9
|
-
register(command: CommanderCommand): void;
|
|
10
|
-
execute(options?: {
|
|
11
|
-
depth?: string;
|
|
12
|
-
parallel?: boolean;
|
|
13
|
-
verbose?: boolean;
|
|
14
|
-
}): Promise<void>;
|
|
15
|
-
}
|
package/dist/commands/build.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import inquirer from 'inquirer';
|
|
2
|
-
import { findWidgets } from '../utils/find-widgets.js';
|
|
3
|
-
import { bumpWidgetVersion } from '../utils/version.js';
|
|
4
|
-
import { loadCliConfig } from '../utils/load-cli-config.js';
|
|
5
|
-
import { validateWorkspaceInit } from '../utils/workspace.js';
|
|
6
|
-
import { buildWidget as processBuild } from '../utils/build-processor.js';
|
|
7
|
-
import { Command } from './base.js';
|
|
8
|
-
/**
|
|
9
|
-
* Build command
|
|
10
|
-
*/
|
|
11
|
-
export class BuildCommand extends Command {
|
|
12
|
-
constructor() {
|
|
13
|
-
super(...arguments);
|
|
14
|
-
this.name = 'build';
|
|
15
|
-
this.description = 'Build widgets from the workspace';
|
|
16
|
-
}
|
|
17
|
-
register(command) {
|
|
18
|
-
command
|
|
19
|
-
.command(this.name)
|
|
20
|
-
.description(this.description)
|
|
21
|
-
.option('-d, --depth <number>', 'Maximum depth to search for widgets', '3')
|
|
22
|
-
.option('-p, --parallel', 'Build widgets in parallel')
|
|
23
|
-
.option('-v, --verbose', 'Show verbose output')
|
|
24
|
-
.action((...args) => this.execute(...args));
|
|
25
|
-
}
|
|
26
|
-
async execute(options = {}) {
|
|
27
|
-
try {
|
|
28
|
-
// Validate workspace is initialized
|
|
29
|
-
const workspaceRoot = await validateWorkspaceInit();
|
|
30
|
-
const rootPath = process.cwd();
|
|
31
|
-
// Load CLI config from workspace root
|
|
32
|
-
const cliConfig = await loadCliConfig(workspaceRoot);
|
|
33
|
-
const maxDepth = options.depth ? parseInt(options.depth, 10) : cliConfig.search.maxDepth;
|
|
34
|
-
console.log(`š Searching for widgets (max depth: ${maxDepth})...\n`);
|
|
35
|
-
// Find all widgets
|
|
36
|
-
const widgets = await findWidgets(rootPath, maxDepth, cliConfig.search.ignore);
|
|
37
|
-
if (widgets.length === 0) {
|
|
38
|
-
console.log('ā No widgets found with .tixyel configuration files.');
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
console.log(`ā
Found ${widgets.length} widget(s)\n`);
|
|
42
|
-
// Create choices for selection
|
|
43
|
-
const choices = widgets.map((widget) => ({
|
|
44
|
-
name: `${widget.config.name} (${widget.relativePath})`,
|
|
45
|
-
value: widget.path,
|
|
46
|
-
checked: false,
|
|
47
|
-
}));
|
|
48
|
-
let selectedPaths = [];
|
|
49
|
-
if (choices.length === 1) {
|
|
50
|
-
selectedPaths = [choices[0].value];
|
|
51
|
-
console.log(`š Only one widget found, auto-selected: ${choices[0].name}\n`);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
// Prompt for widget selection
|
|
55
|
-
const answers = await inquirer.prompt([
|
|
56
|
-
{
|
|
57
|
-
type: 'checkbox',
|
|
58
|
-
name: 'selectedWidgets',
|
|
59
|
-
message: 'Select widgets to build:',
|
|
60
|
-
choices,
|
|
61
|
-
pageSize: 10,
|
|
62
|
-
loop: false,
|
|
63
|
-
},
|
|
64
|
-
]);
|
|
65
|
-
selectedPaths = answers.selectedWidgets;
|
|
66
|
-
}
|
|
67
|
-
if (selectedPaths.length === 0) {
|
|
68
|
-
console.log('\nā ļø No widgets selected. Exiting...');
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
// Prompt for version bump
|
|
72
|
-
const versionAnswers = await inquirer.prompt([
|
|
73
|
-
{
|
|
74
|
-
type: 'select',
|
|
75
|
-
name: 'versionBump',
|
|
76
|
-
message: 'Version bump type:',
|
|
77
|
-
choices: [
|
|
78
|
-
{ name: 'No version bump', value: 'none' },
|
|
79
|
-
{ name: 'Patch (x.x.1)', value: 'patch' },
|
|
80
|
-
{ name: 'Minor (x.1.0)', value: 'minor' },
|
|
81
|
-
{ name: 'Major (1.0.0)', value: 'major' },
|
|
82
|
-
],
|
|
83
|
-
default: 'none',
|
|
84
|
-
loop: false,
|
|
85
|
-
pageSize: 4,
|
|
86
|
-
},
|
|
87
|
-
]);
|
|
88
|
-
const versionBump = versionAnswers.versionBump;
|
|
89
|
-
// Resolve parallel setting (CLI option overrides config)
|
|
90
|
-
const useParallel = options.parallel ?? cliConfig.build.parallel;
|
|
91
|
-
const verbose = options.verbose ?? cliConfig.build.verbose;
|
|
92
|
-
console.log(`\nš Building ${selectedPaths.length} widget(s)${useParallel ? ' (parallel)' : ''}...\n`);
|
|
93
|
-
// Build each selected widget
|
|
94
|
-
if (useParallel) {
|
|
95
|
-
// Parallel execution
|
|
96
|
-
await Promise.all(selectedPaths.map(async (widgetPath) => {
|
|
97
|
-
const widget = widgets.find((w) => w.path === widgetPath);
|
|
98
|
-
if (widget) {
|
|
99
|
-
await buildWidget(widget.path, widget.config.name, versionBump !== 'none' ? versionBump : undefined, verbose, widget.config, cliConfig);
|
|
100
|
-
}
|
|
101
|
-
}));
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
// Sequential execution
|
|
105
|
-
for (const widgetPath of selectedPaths) {
|
|
106
|
-
const widget = widgets.find((w) => w.path === widgetPath);
|
|
107
|
-
if (widget) {
|
|
108
|
-
await buildWidget(widget.path, widget.config.name, versionBump !== 'none' ? versionBump : undefined, verbose, widget.config, cliConfig);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
console.log('\n⨠Build complete!');
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
console.error(`${error}`);
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Builds a single widget
|
|
122
|
-
*/
|
|
123
|
-
async function buildWidget(widgetPath, widgetName, versionBump, verbose, config, cliConfig) {
|
|
124
|
-
console.log(`š¦ Building ${widgetName}...`);
|
|
125
|
-
if (verbose) {
|
|
126
|
-
console.log(` Path: ${widgetPath}`);
|
|
127
|
-
}
|
|
128
|
-
// Bump version if requested
|
|
129
|
-
if (versionBump) {
|
|
130
|
-
const newVersion = await bumpWidgetVersion(widgetPath, versionBump);
|
|
131
|
-
if (newVersion) {
|
|
132
|
-
console.log(` š Version bumped to: ${newVersion}`);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
// Process build if config and cliConfig provided
|
|
136
|
-
if (config && cliConfig) {
|
|
137
|
-
try {
|
|
138
|
-
await processBuild({
|
|
139
|
-
widgetPath,
|
|
140
|
-
config,
|
|
141
|
-
cliConfig,
|
|
142
|
-
verbose,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
catch (error) {
|
|
146
|
-
console.error(` ā Build failed: ${error}`);
|
|
147
|
-
throw error;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
console.error(' ā Missing configuration for build process.');
|
|
152
|
-
throw new Error('Missing configuration for build process.');
|
|
153
|
-
}
|
|
154
|
-
console.log(`ā ${widgetName} built successfully\n`);
|
|
155
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate command handler
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* - `tixyel generate` -> creates widget in current directory (01 - Widget)
|
|
6
|
-
* - `tixyel generate widgets` -> creates widgets/01 - Widget/
|
|
7
|
-
* - `tixyel generate widgets myname` -> creates widgets/myname/
|
|
8
|
-
* - `tixyel generate widgets/` -> creates widget at widgets/
|
|
9
|
-
* - All parameters except path are optional and can be provided via prompts
|
|
10
|
-
*/
|
|
11
|
-
export declare function generateCommand(targetPath?: string, widgetName?: string, description?: string, tags?: string): Promise<void>;
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { resolve, basename, join } from 'path';
|
|
2
|
-
import { mkdir, writeFile } from 'fs/promises';
|
|
3
|
-
import { existsSync } from 'fs';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
|
-
import { loadCliConfig } from '../utils/load-cli-config.js';
|
|
6
|
-
/**
|
|
7
|
-
* Determines if a path should be treated as a parent directory or target directory
|
|
8
|
-
* Paths ending with / are treated as target directories
|
|
9
|
-
*/
|
|
10
|
-
function isTargetDirectory(path) {
|
|
11
|
-
return path.endsWith('/') || path.endsWith('\\');
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Gets the next widget number in a parent directory
|
|
15
|
-
*/
|
|
16
|
-
async function getNextWidgetNumber(parentPath) {
|
|
17
|
-
try {
|
|
18
|
-
if (!existsSync(parentPath)) {
|
|
19
|
-
return '01';
|
|
20
|
-
}
|
|
21
|
-
// Check for existing widget folders
|
|
22
|
-
const { readdirSync } = await import('fs');
|
|
23
|
-
const entries = readdirSync(parentPath);
|
|
24
|
-
const widgetNumbers = entries
|
|
25
|
-
.filter((name) => /^\d+\s*-\s*/.test(name))
|
|
26
|
-
.map((name) => parseInt(name.split('-')[0], 10))
|
|
27
|
-
.filter((num) => !isNaN(num));
|
|
28
|
-
const maxNum = widgetNumbers.length > 0 ? Math.max(...widgetNumbers) : 0;
|
|
29
|
-
return String(maxNum + 1).padStart(2, '0');
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
return '01';
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Generate command handler
|
|
37
|
-
*
|
|
38
|
-
* Usage:
|
|
39
|
-
* - `tixyel generate` -> creates widget in current directory (01 - Widget)
|
|
40
|
-
* - `tixyel generate widgets` -> creates widgets/01 - Widget/
|
|
41
|
-
* - `tixyel generate widgets myname` -> creates widgets/myname/
|
|
42
|
-
* - `tixyel generate widgets/` -> creates widget at widgets/
|
|
43
|
-
* - All parameters except path are optional and can be provided via prompts
|
|
44
|
-
*/
|
|
45
|
-
export async function generateCommand(targetPath, widgetName, description, tags) {
|
|
46
|
-
const rootPath = process.cwd();
|
|
47
|
-
// Load CLI config
|
|
48
|
-
const cliConfig = await loadCliConfig(rootPath);
|
|
49
|
-
// Default to current directory if no path provided
|
|
50
|
-
const resolvedPath = targetPath ? resolve(rootPath, targetPath.replace(/[/\\]$/, '')) : rootPath;
|
|
51
|
-
const isTarget = targetPath ? isTargetDirectory(targetPath) : false;
|
|
52
|
-
console.log('šØ Generating widget...\n');
|
|
53
|
-
if (isTarget) {
|
|
54
|
-
// Path ends with / -> use as target directory
|
|
55
|
-
const folderName = basename(resolvedPath);
|
|
56
|
-
await createWidget(resolvedPath, folderName, description, tags, cliConfig);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
// Path without / -> use as parent directory
|
|
60
|
-
let finalWidgetName = widgetName;
|
|
61
|
-
if (!finalWidgetName) {
|
|
62
|
-
// Get next number and ask for name
|
|
63
|
-
const nextNum = await getNextWidgetNumber(resolvedPath);
|
|
64
|
-
const defaultName = `${nextNum} - Widget`;
|
|
65
|
-
const answers = await inquirer.prompt([
|
|
66
|
-
{
|
|
67
|
-
type: 'input',
|
|
68
|
-
name: 'name',
|
|
69
|
-
message: 'Widget name:',
|
|
70
|
-
default: defaultName,
|
|
71
|
-
},
|
|
72
|
-
]);
|
|
73
|
-
finalWidgetName = answers.name;
|
|
74
|
-
}
|
|
75
|
-
const widgetPath = join(resolvedPath, finalWidgetName);
|
|
76
|
-
await createWidget(widgetPath, finalWidgetName, description, tags, cliConfig);
|
|
77
|
-
}
|
|
78
|
-
console.log('\n⨠Generation complete!');
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Prompts for optional widget metadata
|
|
82
|
-
*/
|
|
83
|
-
async function promptMetadata(widgetName, initialDescription, initialTags) {
|
|
84
|
-
const answers = await inquirer.prompt([
|
|
85
|
-
{
|
|
86
|
-
type: 'input',
|
|
87
|
-
name: 'description',
|
|
88
|
-
message: 'Widget description:',
|
|
89
|
-
default: initialDescription || '',
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
type: 'input',
|
|
93
|
-
name: 'tags',
|
|
94
|
-
message: 'Widget tags (comma-separated):',
|
|
95
|
-
default: initialTags || '',
|
|
96
|
-
},
|
|
97
|
-
]);
|
|
98
|
-
const tagsArray = answers.tags
|
|
99
|
-
? answers.tags
|
|
100
|
-
.split(',')
|
|
101
|
-
.map((tag) => tag.trim())
|
|
102
|
-
.filter((tag) => tag.length > 0)
|
|
103
|
-
: [];
|
|
104
|
-
return {
|
|
105
|
-
description: answers.description,
|
|
106
|
-
tags: tagsArray,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Creates a widget with .tixyel configuration file
|
|
111
|
-
*/
|
|
112
|
-
async function createWidget(widgetPath, widgetName, description, tagsStr, cliConfig) {
|
|
113
|
-
try {
|
|
114
|
-
console.log(`š Creating widget: ${widgetName}`);
|
|
115
|
-
console.log(` Path: ${widgetPath}`);
|
|
116
|
-
// Create directory
|
|
117
|
-
await mkdir(widgetPath, { recursive: true });
|
|
118
|
-
// Prompt for metadata if not provided
|
|
119
|
-
const metadata = await promptMetadata(widgetName, description, tagsStr);
|
|
120
|
-
// Create .tixyel configuration
|
|
121
|
-
const tixyelConfig = {
|
|
122
|
-
name: widgetName,
|
|
123
|
-
description: metadata.description,
|
|
124
|
-
metadata: {
|
|
125
|
-
author: cliConfig?.generationDefaults.author || 'Tixyel',
|
|
126
|
-
tags: metadata.tags,
|
|
127
|
-
platform: cliConfig?.generationDefaults.platform || 'streamelements',
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
const configPath = join(widgetPath, '.tixyel');
|
|
131
|
-
await writeFile(configPath, JSON.stringify(tixyelConfig, null, 2), 'utf-8');
|
|
132
|
-
console.log(`ā Created ${widgetName} successfully`);
|
|
133
|
-
console.log(` - Name: ${widgetName}`);
|
|
134
|
-
if (metadata.description) {
|
|
135
|
-
console.log(` - Description: ${metadata.description}`);
|
|
136
|
-
}
|
|
137
|
-
if (metadata.tags.length > 0) {
|
|
138
|
-
console.log(` - Tags: ${metadata.tags.join(', ')}`);
|
|
139
|
-
}
|
|
140
|
-
console.log(` - .tixyel configuration created`);
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
console.error(`ā Failed to create widget: ${error}`);
|
|
144
|
-
throw error;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Command as CommanderCommand } from 'commander';
|
|
2
|
-
import { Command } from './base.js';
|
|
3
|
-
/**
|
|
4
|
-
* Generate command
|
|
5
|
-
*/
|
|
6
|
-
export declare class GenerateCommand extends Command {
|
|
7
|
-
name: string;
|
|
8
|
-
description: string;
|
|
9
|
-
register(command: CommanderCommand): void;
|
|
10
|
-
execute(targetPath?: string, widgetName?: string, description?: string, tags?: string): Promise<void>;
|
|
11
|
-
}
|