@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
|
@@ -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
|
-
}
|
|
@@ -1,198 +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
|
-
import { validateWorkspaceInit, getConfigPathFromWidget } from '../utils/workspace.js';
|
|
7
|
-
import { Command } from './base.js';
|
|
8
|
-
/**
|
|
9
|
-
* Generate command
|
|
10
|
-
*/
|
|
11
|
-
export class GenerateCommand extends Command {
|
|
12
|
-
constructor() {
|
|
13
|
-
super(...arguments);
|
|
14
|
-
this.name = 'generate';
|
|
15
|
-
this.description = 'Generate a new widget (path defaults to current directory)';
|
|
16
|
-
}
|
|
17
|
-
register(command) {
|
|
18
|
-
command
|
|
19
|
-
.command(`${this.name} [path] [name] [description] [tags]`)
|
|
20
|
-
.description(this.description)
|
|
21
|
-
.action((...args) => this.execute(...args));
|
|
22
|
-
}
|
|
23
|
-
async execute(targetPath, widgetName, description, tags) {
|
|
24
|
-
try {
|
|
25
|
-
// Validate workspace is initialized
|
|
26
|
-
const workspaceRoot = await validateWorkspaceInit();
|
|
27
|
-
const rootPath = process.cwd();
|
|
28
|
-
// Load CLI config from workspace root
|
|
29
|
-
const cliConfig = await loadCliConfig(workspaceRoot);
|
|
30
|
-
// Default to current directory if no path provided
|
|
31
|
-
const resolvedPath = targetPath ? resolve(rootPath, targetPath.replace(/[/\\]$/, '')) : rootPath;
|
|
32
|
-
const isTarget = targetPath ? isTargetDirectory(targetPath) : false;
|
|
33
|
-
console.log('šØ Generating widget...\n');
|
|
34
|
-
if (isTarget) {
|
|
35
|
-
// Path ends with / -> use as target directory
|
|
36
|
-
const folderName = basename(resolvedPath);
|
|
37
|
-
await createWidget(resolvedPath, folderName, description, tags, cliConfig, workspaceRoot);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
// Path without / -> use as parent directory
|
|
41
|
-
let finalWidgetName = widgetName;
|
|
42
|
-
if (!finalWidgetName) {
|
|
43
|
-
// Get next number and ask for name
|
|
44
|
-
const nextNum = await getNextWidgetNumber(resolvedPath);
|
|
45
|
-
const defaultName = `${nextNum} - Widget`;
|
|
46
|
-
const answers = await inquirer.prompt([
|
|
47
|
-
{
|
|
48
|
-
type: 'input',
|
|
49
|
-
name: 'name',
|
|
50
|
-
message: 'Widget name:',
|
|
51
|
-
default: defaultName,
|
|
52
|
-
},
|
|
53
|
-
]);
|
|
54
|
-
finalWidgetName = answers.name;
|
|
55
|
-
}
|
|
56
|
-
const widgetPath = join(resolvedPath, finalWidgetName);
|
|
57
|
-
await createWidget(widgetPath, finalWidgetName, description, tags, cliConfig, workspaceRoot);
|
|
58
|
-
}
|
|
59
|
-
console.log('\n⨠Generation complete!');
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
console.error(`${error}`);
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Determines if a path should be treated as a parent directory or target directory
|
|
69
|
-
* Paths ending with / are treated as target directories
|
|
70
|
-
*/
|
|
71
|
-
function isTargetDirectory(path) {
|
|
72
|
-
return path.endsWith('/') || path.endsWith('\\');
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Gets the next widget number in a parent directory
|
|
76
|
-
*/
|
|
77
|
-
async function getNextWidgetNumber(parentPath) {
|
|
78
|
-
try {
|
|
79
|
-
if (!existsSync(parentPath)) {
|
|
80
|
-
return '01';
|
|
81
|
-
}
|
|
82
|
-
// Check for existing widget folders
|
|
83
|
-
const { readdirSync } = await import('fs');
|
|
84
|
-
const entries = readdirSync(parentPath);
|
|
85
|
-
const widgetNumbers = entries
|
|
86
|
-
.filter((name) => /^\d+\s*-\s*/.test(name))
|
|
87
|
-
.map((name) => parseInt(name.split('-')[0], 10))
|
|
88
|
-
.filter((num) => !isNaN(num));
|
|
89
|
-
const maxNum = widgetNumbers.length > 0 ? Math.max(...widgetNumbers) : 0;
|
|
90
|
-
return String(maxNum + 1).padStart(2, '0');
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
return '01';
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Prompts for optional widget metadata
|
|
98
|
-
*/
|
|
99
|
-
async function promptMetadata(widgetName, initialDescription, initialTags) {
|
|
100
|
-
const answers = await inquirer.prompt([
|
|
101
|
-
{
|
|
102
|
-
type: 'input',
|
|
103
|
-
name: 'description',
|
|
104
|
-
message: 'Widget description:',
|
|
105
|
-
default: initialDescription || '',
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
type: 'input',
|
|
109
|
-
name: 'tags',
|
|
110
|
-
message: 'Widget tags (comma-separated):',
|
|
111
|
-
default: initialTags || '',
|
|
112
|
-
},
|
|
113
|
-
]);
|
|
114
|
-
const tagsArray = answers.tags
|
|
115
|
-
? answers.tags
|
|
116
|
-
.split(',')
|
|
117
|
-
.map((tag) => tag.trim())
|
|
118
|
-
.filter((tag) => tag.length > 0)
|
|
119
|
-
: [];
|
|
120
|
-
return {
|
|
121
|
-
description: answers.description,
|
|
122
|
-
tags: tagsArray,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Creates a widget with .tixyel configuration file
|
|
127
|
-
*/
|
|
128
|
-
async function createWidget(widgetPath, widgetName, description, tagsStr, cliConfig, workspaceRoot) {
|
|
129
|
-
try {
|
|
130
|
-
console.log(`š Creating widget: ${widgetName}`);
|
|
131
|
-
console.log(` Path: ${widgetPath}`);
|
|
132
|
-
// Create directory
|
|
133
|
-
await mkdir(widgetPath, { recursive: true });
|
|
134
|
-
// Calculate config path if workspace root is provided
|
|
135
|
-
const configPath = workspaceRoot ? getConfigPathFromWidget(widgetPath, workspaceRoot) : undefined;
|
|
136
|
-
// Prompt for metadata if not provided
|
|
137
|
-
const metadata = await promptMetadata(widgetName, description, tagsStr);
|
|
138
|
-
// Create .tixyel configuration
|
|
139
|
-
const tixyelConfig = {
|
|
140
|
-
name: widgetName,
|
|
141
|
-
description: metadata.description,
|
|
142
|
-
};
|
|
143
|
-
if (configPath) {
|
|
144
|
-
tixyelConfig.configPath = configPath;
|
|
145
|
-
}
|
|
146
|
-
tixyelConfig.metadata = {
|
|
147
|
-
author: cliConfig?.generationDefaults.author || 'Tixyel',
|
|
148
|
-
tags: metadata.tags,
|
|
149
|
-
platform: cliConfig?.generationDefaults.platform || 'streamelements',
|
|
150
|
-
};
|
|
151
|
-
const configFilePath = join(widgetPath, '.tixyel');
|
|
152
|
-
await writeFile(configFilePath, JSON.stringify(tixyelConfig, null, 2), 'utf-8');
|
|
153
|
-
// Create scaffold files from config
|
|
154
|
-
const scaffold = cliConfig?.generationDefaults.scaffold || [];
|
|
155
|
-
let createdFiles = 0;
|
|
156
|
-
let createdFolders = 0;
|
|
157
|
-
async function processScaffoldItem(item, basePath) {
|
|
158
|
-
const fullPath = join(basePath, item.name);
|
|
159
|
-
if (item.type === 'folder') {
|
|
160
|
-
await mkdir(fullPath, { recursive: true });
|
|
161
|
-
createdFolders++;
|
|
162
|
-
// Process folder contents if any
|
|
163
|
-
if (item.content && Array.isArray(item.content)) {
|
|
164
|
-
for (const child of item.content) {
|
|
165
|
-
await processScaffoldItem(child, fullPath);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else if (item.type === 'file') {
|
|
170
|
-
// Write file
|
|
171
|
-
await writeFile(fullPath, item.content || '', 'utf-8');
|
|
172
|
-
createdFiles++;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
for (const item of scaffold) {
|
|
176
|
-
await processScaffoldItem(item, widgetPath);
|
|
177
|
-
}
|
|
178
|
-
console.log(`ā Created ${widgetName} successfully`);
|
|
179
|
-
console.log(` - Name: ${widgetName}`);
|
|
180
|
-
if (metadata.description) {
|
|
181
|
-
console.log(` - Description: ${metadata.description}`);
|
|
182
|
-
}
|
|
183
|
-
if (metadata.tags.length > 0) {
|
|
184
|
-
console.log(` - Tags: ${metadata.tags.join(', ')}`);
|
|
185
|
-
}
|
|
186
|
-
if (configPath) {
|
|
187
|
-
console.log(` - Config path: ${configPath}`);
|
|
188
|
-
}
|
|
189
|
-
console.log(` - .tixyel configuration created`);
|
|
190
|
-
if (createdFiles > 0 || createdFolders > 0) {
|
|
191
|
-
console.log(` - Scaffold: ${createdFiles} file(s), ${createdFolders} folder(s)`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
catch (error) {
|
|
195
|
-
console.error(`ā Failed to create widget: ${error}`);
|
|
196
|
-
throw error;
|
|
197
|
-
}
|
|
198
|
-
}
|
package/dist/commands/init.d.ts
DELETED
package/dist/commands/init.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { writeFile } from 'fs/promises';
|
|
2
|
-
import { resolve } from 'path';
|
|
3
|
-
import { Command } from './base.js';
|
|
4
|
-
/**
|
|
5
|
-
* Init command - initializes a workspace
|
|
6
|
-
*/
|
|
7
|
-
export class InitCommand extends Command {
|
|
8
|
-
constructor() {
|
|
9
|
-
super(...arguments);
|
|
10
|
-
this.name = 'init';
|
|
11
|
-
this.description = 'Initialize a new Tixyel workspace';
|
|
12
|
-
}
|
|
13
|
-
async execute() {
|
|
14
|
-
const rootPath = process.cwd();
|
|
15
|
-
const configPath = resolve(rootPath, 'tixyel.config.ts');
|
|
16
|
-
console.log('š Initializing Tixyel workspace...\n');
|
|
17
|
-
console.log(`š Workspace root: ${rootPath}\n`);
|
|
18
|
-
// Create initial tixyel.config.ts
|
|
19
|
-
const configContent = `import type { TixyelCliConfig } from '@tixyel/cli';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Tixyel workspace configuration
|
|
23
|
-
*/
|
|
24
|
-
const config: TixyelCliConfig = {
|
|
25
|
-
// Search configuration
|
|
26
|
-
search: {
|
|
27
|
-
maxDepth: 3,
|
|
28
|
-
ignore: ['node_modules', 'dist', '.git', '.turbo', '.vscode'],
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
// Defaults for widget generation
|
|
32
|
-
generationDefaults: {
|
|
33
|
-
author: 'Your Name',
|
|
34
|
-
minify: true,
|
|
35
|
-
platform: 'streamelements',
|
|
36
|
-
|
|
37
|
-
// File structure to create when generating a widget
|
|
38
|
-
scaffold: [
|
|
39
|
-
{
|
|
40
|
-
name: 'development',
|
|
41
|
-
type: 'folder',
|
|
42
|
-
content: [
|
|
43
|
-
{
|
|
44
|
-
name: 'index.html',
|
|
45
|
-
type: 'file',
|
|
46
|
-
content: '',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: 'script.js',
|
|
50
|
-
type: 'file',
|
|
51
|
-
content: '',
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
name: 'fields.json',
|
|
55
|
-
type: 'file',
|
|
56
|
-
content: '{}',
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
name: 'data.json',
|
|
60
|
-
type: 'file',
|
|
61
|
-
content: '{}',
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
name: 'style.css',
|
|
65
|
-
type: 'file',
|
|
66
|
-
content: '',
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
name: 'finished',
|
|
72
|
-
type: 'folder',
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
// Build configuration
|
|
78
|
-
build: {
|
|
79
|
-
parallel: false,
|
|
80
|
-
verbose: false,
|
|
81
|
-
find: {
|
|
82
|
-
html: ['index.html'],
|
|
83
|
-
css: ['style.css'],
|
|
84
|
-
script: ['resources.js', 'script.js'],
|
|
85
|
-
fields: ['cf.json', 'fields.json'],
|
|
86
|
-
},
|
|
87
|
-
finished: {
|
|
88
|
-
'HTML.html': 'html',
|
|
89
|
-
'CSS.css': 'css',
|
|
90
|
-
'SCRIPT.js': 'script',
|
|
91
|
-
'FIELDS.json': 'fields',
|
|
92
|
-
},
|
|
93
|
-
obfuscation: {
|
|
94
|
-
javascript: {
|
|
95
|
-
compact: true,
|
|
96
|
-
log: false,
|
|
97
|
-
debugProtection: false,
|
|
98
|
-
selfDefending: false,
|
|
99
|
-
deadCodeInjection: false,
|
|
100
|
-
controlFlowFlattening: false,
|
|
101
|
-
stringArray: false,
|
|
102
|
-
simplify: false,
|
|
103
|
-
identifierNamesGenerator: 'mangled',
|
|
104
|
-
},
|
|
105
|
-
css: {
|
|
106
|
-
removeNesting: true,
|
|
107
|
-
autoprefixer: {
|
|
108
|
-
overrideBrowserslist: ['Chrome 127'],
|
|
109
|
-
},
|
|
110
|
-
cssnano: {
|
|
111
|
-
preset: 'default',
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
html: {
|
|
115
|
-
removeComments: true,
|
|
116
|
-
collapseWhitespace: true,
|
|
117
|
-
minifyCSS: true,
|
|
118
|
-
minifyJS: true,
|
|
119
|
-
removeAttributeQuotes: false,
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
export default config;
|
|
126
|
-
`;
|
|
127
|
-
try {
|
|
128
|
-
await writeFile(configPath, configContent, 'utf-8');
|
|
129
|
-
console.log('ā
Created tixyel.config.ts');
|
|
130
|
-
console.log(' Edit it to customize your workspace settings');
|
|
131
|
-
console.log('\n⨠Workspace initialized! You can now use:');
|
|
132
|
-
console.log(' - tixyel generate [path] - Generate new widgets');
|
|
133
|
-
console.log(' - tixyel build - Build selected widgets');
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
console.error(`ā Failed to initialize workspace: ${error}`);
|
|
137
|
-
throw error;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import type { Options as AutoprefixerOptions } from 'autoprefixer';
|
|
2
|
-
import type { Options as CssnanoOptions } from 'cssnano';
|
|
3
|
-
import type { ObfuscatorOptions } from 'javascript-obfuscator';
|
|
4
|
-
import type { Options as HtmlMinifierOptions } from 'html-minifier-terser';
|
|
5
|
-
/**
|
|
6
|
-
* Schema for tixyel.config.ts configuration file
|
|
7
|
-
*/
|
|
8
|
-
export interface TixyelCliConfig {
|
|
9
|
-
/**
|
|
10
|
-
* Search configuration
|
|
11
|
-
*/
|
|
12
|
-
search?: {
|
|
13
|
-
/**
|
|
14
|
-
* Maximum depth to search for .tixyel files
|
|
15
|
-
*/
|
|
16
|
-
maxDepth?: number;
|
|
17
|
-
/**
|
|
18
|
-
* Folders to ignore during search
|
|
19
|
-
*/
|
|
20
|
-
ignore?: string[];
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* Defaults for generating new widgets
|
|
24
|
-
*/
|
|
25
|
-
generationDefaults?: {
|
|
26
|
-
/**
|
|
27
|
-
* Default author for new widgets
|
|
28
|
-
*/
|
|
29
|
-
author?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Default minify setting
|
|
32
|
-
*/
|
|
33
|
-
minify?: boolean;
|
|
34
|
-
/**
|
|
35
|
-
* Default platform
|
|
36
|
-
*/
|
|
37
|
-
platform?: 'streamelements';
|
|
38
|
-
/**
|
|
39
|
-
* File/folder structure to create when generating a widget
|
|
40
|
-
*/
|
|
41
|
-
scaffold?: ScaffoldItem[];
|
|
42
|
-
};
|
|
43
|
-
/**
|
|
44
|
-
* Build configuration
|
|
45
|
-
*/
|
|
46
|
-
build?: {
|
|
47
|
-
/**
|
|
48
|
-
* Run builds in parallel
|
|
49
|
-
*/
|
|
50
|
-
parallel?: boolean;
|
|
51
|
-
/**
|
|
52
|
-
* Verbose output
|
|
53
|
-
*/
|
|
54
|
-
verbose?: boolean;
|
|
55
|
-
/**
|
|
56
|
-
* Default file patterns for widgets
|
|
57
|
-
*/
|
|
58
|
-
find?: {
|
|
59
|
-
html?: string[];
|
|
60
|
-
css?: string[];
|
|
61
|
-
script?: string[];
|
|
62
|
-
fields?: string[];
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* Default output file mapping
|
|
66
|
-
*/
|
|
67
|
-
finished?: {
|
|
68
|
-
[key: string]: 'html' | 'css' | 'script' | 'fields';
|
|
69
|
-
};
|
|
70
|
-
/**
|
|
71
|
-
* Obfuscation options per file type
|
|
72
|
-
*/
|
|
73
|
-
obfuscation?: {
|
|
74
|
-
/**
|
|
75
|
-
* JavaScript obfuscation options
|
|
76
|
-
*/
|
|
77
|
-
javascript?: ObfuscatorOptions;
|
|
78
|
-
/**
|
|
79
|
-
* CSS processing options
|
|
80
|
-
*/
|
|
81
|
-
css?: {
|
|
82
|
-
removeNesting?: boolean;
|
|
83
|
-
autoprefixer?: AutoprefixerOptions;
|
|
84
|
-
cssnano?: CssnanoOptions;
|
|
85
|
-
};
|
|
86
|
-
/**
|
|
87
|
-
* HTML minification options
|
|
88
|
-
*/
|
|
89
|
-
html?: HtmlMinifierOptions;
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Represents a file or folder in the scaffold
|
|
95
|
-
*/
|
|
96
|
-
export type ScaffoldItem = ScaffoldFile | ScaffoldFolder;
|
|
97
|
-
/**
|
|
98
|
-
* File in scaffold
|
|
99
|
-
*/
|
|
100
|
-
export interface ScaffoldFile {
|
|
101
|
-
name: string;
|
|
102
|
-
type: 'file';
|
|
103
|
-
content: string;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Folder in scaffold
|
|
107
|
-
*/
|
|
108
|
-
export interface ScaffoldFolder {
|
|
109
|
-
name: string;
|
|
110
|
-
type: 'folder';
|
|
111
|
-
content?: ScaffoldItem[];
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Required configuration with all defaults
|
|
115
|
-
*/
|
|
116
|
-
export interface RequiredCliConfig {
|
|
117
|
-
search: Required<NonNullable<TixyelCliConfig['search']>>;
|
|
118
|
-
generationDefaults: Required<NonNullable<TixyelCliConfig['generationDefaults']>>;
|
|
119
|
-
build: {
|
|
120
|
-
parallel: boolean;
|
|
121
|
-
verbose: boolean;
|
|
122
|
-
find: {
|
|
123
|
-
html: string[];
|
|
124
|
-
css: string[];
|
|
125
|
-
script: string[];
|
|
126
|
-
fields: string[];
|
|
127
|
-
};
|
|
128
|
-
finished: {
|
|
129
|
-
[key: string]: 'html' | 'css' | 'script' | 'fields';
|
|
130
|
-
};
|
|
131
|
-
obfuscation: {
|
|
132
|
-
javascript: ObfuscatorOptions;
|
|
133
|
-
css: {
|
|
134
|
-
removeNesting: boolean;
|
|
135
|
-
autoprefixer: AutoprefixerOptions;
|
|
136
|
-
cssnano: CssnanoOptions;
|
|
137
|
-
};
|
|
138
|
-
html: HtmlMinifierOptions;
|
|
139
|
-
};
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Default CLI configuration
|
|
144
|
-
*/
|
|
145
|
-
export declare const DEFAULT_CLI_CONFIG: RequiredCliConfig;
|
|
146
|
-
/**
|
|
147
|
-
* Merges user config with defaults
|
|
148
|
-
*/
|
|
149
|
-
export declare function mergeCliConfig(userConfig: TixyelCliConfig | undefined): RequiredCliConfig;
|