@tixyel/cli 1.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/README.md +31 -0
- package/dist/commands/base.d.ts +24 -0
- package/dist/commands/base.js +15 -0
- package/dist/commands/build.d.ts +15 -0
- package/dist/commands/build.js +155 -0
- package/dist/commands/generate-new.d.ts +11 -0
- package/dist/commands/generate-new.js +146 -0
- package/dist/commands/generate.d.ts +11 -0
- package/dist/commands/generate.js +198 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.js +140 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +39 -0
- package/dist/types/tixyel-cli-config.d.ts +149 -0
- package/dist/types/tixyel-cli-config.js +162 -0
- package/dist/types/tixyel-config.d.ts +83 -0
- package/dist/types/tixyel-config.js +43 -0
- package/dist/utils/build-processor.d.ts +12 -0
- package/dist/utils/build-processor.js +156 -0
- package/dist/utils/config.d.ts +23 -0
- package/dist/utils/config.js +34 -0
- package/dist/utils/find-widgets.d.ts +19 -0
- package/dist/utils/find-widgets.js +35 -0
- package/dist/utils/load-cli-config.d.ts +5 -0
- package/dist/utils/load-cli-config.js +66 -0
- package/dist/utils/version.d.ts +12 -0
- package/dist/utils/version.js +49 -0
- package/dist/utils/workspace.d.ts +13 -0
- package/dist/utils/workspace.js +43 -0
- package/package.json +62 -0
|
@@ -0,0 +1,140 @@
|
|
|
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
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command as CommanderCommand } from 'commander';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import { readdirSync } from 'fs';
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
const program = new CommanderCommand();
|
|
9
|
+
program.name('tixyel').description('CLI tool for Tixyel widgets').version('1.0.0');
|
|
10
|
+
/**
|
|
11
|
+
* Auto-discover and load command classes from the commands directory
|
|
12
|
+
*/
|
|
13
|
+
async function loadCommands() {
|
|
14
|
+
const commandsDir = join(__dirname, 'commands');
|
|
15
|
+
const files = readdirSync(commandsDir).filter((file) => file.endsWith('.js') && file !== 'base.js');
|
|
16
|
+
for (const file of files) {
|
|
17
|
+
try {
|
|
18
|
+
const modulePath = join(commandsDir, file);
|
|
19
|
+
const module = await import(`file://${modulePath}`);
|
|
20
|
+
// Look for class exports
|
|
21
|
+
for (const key in module) {
|
|
22
|
+
const exported = module[key];
|
|
23
|
+
// Check if it's a class that extends Command
|
|
24
|
+
if (typeof exported === 'function' && exported.prototype && exported.prototype.register) {
|
|
25
|
+
const CommandClass = exported;
|
|
26
|
+
const instance = new CommandClass();
|
|
27
|
+
instance.register(program);
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.error(`Failed to load command from ${file}:`, error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Load commands and parse
|
|
38
|
+
await loadCommands();
|
|
39
|
+
program.parse();
|
|
@@ -0,0 +1,149 @@
|
|
|
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;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default CLI configuration
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_CLI_CONFIG = {
|
|
5
|
+
search: {
|
|
6
|
+
maxDepth: 3,
|
|
7
|
+
ignore: ['node_modules', 'dist', '.git', '.turbo'],
|
|
8
|
+
},
|
|
9
|
+
generationDefaults: {
|
|
10
|
+
author: 'Tixyel',
|
|
11
|
+
minify: true,
|
|
12
|
+
platform: 'streamelements',
|
|
13
|
+
scaffold: [
|
|
14
|
+
{
|
|
15
|
+
name: 'development',
|
|
16
|
+
type: 'folder',
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
name: 'index.html',
|
|
20
|
+
type: 'file',
|
|
21
|
+
content: `<!DOCTYPE html>
|
|
22
|
+
<html lang="en">
|
|
23
|
+
<head>
|
|
24
|
+
<meta charset="UTF-8">
|
|
25
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
26
|
+
<title>Widget</title>
|
|
27
|
+
<link rel="stylesheet" href="style.css">
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<div id="widget">
|
|
31
|
+
<!-- Widget content here -->
|
|
32
|
+
</div>
|
|
33
|
+
<script src="script.js"></script>
|
|
34
|
+
</body>
|
|
35
|
+
</html>`,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'script.js',
|
|
39
|
+
type: 'file',
|
|
40
|
+
content: `// Widget script
|
|
41
|
+
console.log('Widget loaded');
|
|
42
|
+
`,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'fields.json',
|
|
46
|
+
type: 'file',
|
|
47
|
+
content: `{
|
|
48
|
+
"title": "Widget Fields",
|
|
49
|
+
"fields": []
|
|
50
|
+
}`,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'data.json',
|
|
54
|
+
type: 'file',
|
|
55
|
+
content: `{
|
|
56
|
+
"title": "Widget Data"
|
|
57
|
+
}`,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'style.css',
|
|
61
|
+
type: 'file',
|
|
62
|
+
content: `/* Widget styles */
|
|
63
|
+
body {
|
|
64
|
+
margin: 0;
|
|
65
|
+
padding: 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#widget {
|
|
69
|
+
/* Add your styles here */
|
|
70
|
+
}`,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'finished',
|
|
76
|
+
type: 'folder',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
build: {
|
|
81
|
+
parallel: false,
|
|
82
|
+
verbose: false,
|
|
83
|
+
find: {
|
|
84
|
+
html: ['index.html'],
|
|
85
|
+
css: ['style.css'],
|
|
86
|
+
script: ['resources.js', 'script.js'],
|
|
87
|
+
fields: ['cf.json', 'fields.json'],
|
|
88
|
+
},
|
|
89
|
+
finished: {
|
|
90
|
+
'HTML.html': 'html',
|
|
91
|
+
'CSS.css': 'css',
|
|
92
|
+
'SCRIPT.js': 'script',
|
|
93
|
+
'FIELDS.json': 'fields',
|
|
94
|
+
},
|
|
95
|
+
obfuscation: {
|
|
96
|
+
javascript: {
|
|
97
|
+
compact: true,
|
|
98
|
+
log: false,
|
|
99
|
+
debugProtection: false,
|
|
100
|
+
selfDefending: false,
|
|
101
|
+
deadCodeInjection: false,
|
|
102
|
+
controlFlowFlattening: false,
|
|
103
|
+
stringArray: false,
|
|
104
|
+
simplify: false,
|
|
105
|
+
identifierNamesGenerator: 'mangled',
|
|
106
|
+
},
|
|
107
|
+
css: {
|
|
108
|
+
removeNesting: true,
|
|
109
|
+
autoprefixer: {
|
|
110
|
+
overrideBrowserslist: ['Chrome 127'],
|
|
111
|
+
},
|
|
112
|
+
cssnano: {
|
|
113
|
+
preset: 'default',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
html: {
|
|
117
|
+
removeComments: true,
|
|
118
|
+
collapseWhitespace: true,
|
|
119
|
+
minifyCSS: true,
|
|
120
|
+
minifyJS: true,
|
|
121
|
+
removeAttributeQuotes: false,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Merges user config with defaults
|
|
128
|
+
*/
|
|
129
|
+
export function mergeCliConfig(userConfig) {
|
|
130
|
+
return {
|
|
131
|
+
search: {
|
|
132
|
+
maxDepth: userConfig?.search?.maxDepth ?? DEFAULT_CLI_CONFIG.search.maxDepth,
|
|
133
|
+
ignore: userConfig?.search?.ignore ?? DEFAULT_CLI_CONFIG.search.ignore,
|
|
134
|
+
},
|
|
135
|
+
generationDefaults: {
|
|
136
|
+
author: userConfig?.generationDefaults?.author ?? DEFAULT_CLI_CONFIG.generationDefaults.author,
|
|
137
|
+
minify: userConfig?.generationDefaults?.minify ?? DEFAULT_CLI_CONFIG.generationDefaults.minify,
|
|
138
|
+
platform: userConfig?.generationDefaults?.platform ?? DEFAULT_CLI_CONFIG.generationDefaults.platform,
|
|
139
|
+
scaffold: userConfig?.generationDefaults?.scaffold ?? DEFAULT_CLI_CONFIG.generationDefaults.scaffold,
|
|
140
|
+
},
|
|
141
|
+
build: {
|
|
142
|
+
parallel: userConfig?.build?.parallel ?? DEFAULT_CLI_CONFIG.build.parallel,
|
|
143
|
+
verbose: userConfig?.build?.verbose ?? DEFAULT_CLI_CONFIG.build.verbose,
|
|
144
|
+
find: {
|
|
145
|
+
html: userConfig?.build?.find?.html ?? DEFAULT_CLI_CONFIG.build.find.html,
|
|
146
|
+
css: userConfig?.build?.find?.css ?? DEFAULT_CLI_CONFIG.build.find.css,
|
|
147
|
+
script: userConfig?.build?.find?.script ?? DEFAULT_CLI_CONFIG.build.find.script,
|
|
148
|
+
fields: userConfig?.build?.find?.fields ?? DEFAULT_CLI_CONFIG.build.find.fields,
|
|
149
|
+
},
|
|
150
|
+
finished: userConfig?.build?.finished ?? DEFAULT_CLI_CONFIG.build.finished,
|
|
151
|
+
obfuscation: {
|
|
152
|
+
javascript: userConfig?.build?.obfuscation?.javascript ?? DEFAULT_CLI_CONFIG.build.obfuscation.javascript,
|
|
153
|
+
css: {
|
|
154
|
+
removeNesting: userConfig?.build?.obfuscation?.css?.removeNesting ?? DEFAULT_CLI_CONFIG.build.obfuscation.css.removeNesting,
|
|
155
|
+
autoprefixer: userConfig?.build?.obfuscation?.css?.autoprefixer ?? DEFAULT_CLI_CONFIG.build.obfuscation.css.autoprefixer,
|
|
156
|
+
cssnano: userConfig?.build?.obfuscation?.css?.cssnano ?? DEFAULT_CLI_CONFIG.build.obfuscation.css.cssnano,
|
|
157
|
+
},
|
|
158
|
+
html: userConfig?.build?.obfuscation?.html ?? DEFAULT_CLI_CONFIG.build.obfuscation.html,
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema for .tixyel configuration file
|
|
3
|
+
*/
|
|
4
|
+
export interface TixyelConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Widget name
|
|
7
|
+
*/
|
|
8
|
+
name: string;
|
|
9
|
+
/**
|
|
10
|
+
* Widget version (default: 1.0.0)
|
|
11
|
+
*/
|
|
12
|
+
version?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Widget description
|
|
15
|
+
*/
|
|
16
|
+
description?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Entry point directory (default: development)
|
|
19
|
+
*/
|
|
20
|
+
entry?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Output directory (default: finished)
|
|
23
|
+
*/
|
|
24
|
+
outDir?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Relative path to tixyel.config.ts from this file's directory
|
|
27
|
+
* Auto-calculated during widget generation
|
|
28
|
+
*/
|
|
29
|
+
configPath?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Additional build configuration
|
|
32
|
+
*/
|
|
33
|
+
build?: {
|
|
34
|
+
/**
|
|
35
|
+
* Minify output
|
|
36
|
+
*/
|
|
37
|
+
minify?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* File patterns to find and merge
|
|
40
|
+
*/
|
|
41
|
+
find?: {
|
|
42
|
+
html?: string[];
|
|
43
|
+
css?: string[];
|
|
44
|
+
script?: string[];
|
|
45
|
+
fields?: string[];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Output file mapping
|
|
49
|
+
*/
|
|
50
|
+
finished?: {
|
|
51
|
+
[key: string]: 'html' | 'css' | 'script' | 'fields';
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Widget metadata
|
|
56
|
+
*/
|
|
57
|
+
metadata?: {
|
|
58
|
+
author?: string;
|
|
59
|
+
tags?: string[];
|
|
60
|
+
/**
|
|
61
|
+
* Platform - currently only StreamElements is supported
|
|
62
|
+
*/
|
|
63
|
+
platform?: 'streamelements';
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Default configuration values
|
|
68
|
+
*/
|
|
69
|
+
export declare const DEFAULT_TIXYEL_CONFIG: {
|
|
70
|
+
readonly version: "1.0.0";
|
|
71
|
+
readonly entry: "development";
|
|
72
|
+
readonly outDir: "finished";
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Validates a Tixyel configuration object
|
|
76
|
+
*/
|
|
77
|
+
export declare function validateTixyelConfig(config: unknown): config is TixyelConfig;
|
|
78
|
+
/**
|
|
79
|
+
* Applies default values to a configuration object
|
|
80
|
+
*/
|
|
81
|
+
export declare function applyDefaults(config: TixyelConfig): Omit<Required<TixyelConfig>, 'configPath'> & {
|
|
82
|
+
configPath?: string;
|
|
83
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default configuration values
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_TIXYEL_CONFIG = {
|
|
5
|
+
version: '1.0.0',
|
|
6
|
+
entry: 'development',
|
|
7
|
+
outDir: 'finished',
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Validates a Tixyel configuration object
|
|
11
|
+
*/
|
|
12
|
+
export function validateTixyelConfig(config) {
|
|
13
|
+
if (typeof config !== 'object' || config === null) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
const cfg = config;
|
|
17
|
+
// Required fields
|
|
18
|
+
if (typeof cfg.name !== 'string' || !cfg.name) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Applies default values to a configuration object
|
|
25
|
+
*/
|
|
26
|
+
export function applyDefaults(config) {
|
|
27
|
+
return {
|
|
28
|
+
name: config.name,
|
|
29
|
+
version: config.version || DEFAULT_TIXYEL_CONFIG.version,
|
|
30
|
+
description: config.description ?? '',
|
|
31
|
+
entry: config.entry ?? DEFAULT_TIXYEL_CONFIG.entry,
|
|
32
|
+
outDir: config.outDir ?? DEFAULT_TIXYEL_CONFIG.outDir,
|
|
33
|
+
configPath: config.configPath,
|
|
34
|
+
build: config.build
|
|
35
|
+
? {
|
|
36
|
+
minify: config.build.minify ?? false,
|
|
37
|
+
find: config.build.find,
|
|
38
|
+
finished: config.build.finished,
|
|
39
|
+
}
|
|
40
|
+
: { minify: false },
|
|
41
|
+
metadata: config.metadata ?? { platform: 'streamelements' },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TixyelConfig } from '../types/tixyel-config.js';
|
|
2
|
+
import type { RequiredCliConfig } from '../types/tixyel-cli-config.js';
|
|
3
|
+
export interface BuildOptions {
|
|
4
|
+
widgetPath: string;
|
|
5
|
+
config: TixyelConfig;
|
|
6
|
+
cliConfig: RequiredCliConfig;
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Processes and builds a widget
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildWidget(options: BuildOptions): Promise<void>;
|