@tixyel/cli 3.0.0 → 3.1.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/api.d.mts +17 -1
- package/dist/api.mjs +1 -1
- package/dist/index.mjs +4 -2
- package/dist/workspace-BnA15bR0.mjs +33 -0
- package/package.json +2 -1
- package/dist/workspace-Dp9KM2gK.mjs +0 -34
package/dist/api.d.mts
CHANGED
|
@@ -57,6 +57,10 @@ interface WorkspaceConfig<Find extends BuildFindMap = BuildFindMap> {
|
|
|
57
57
|
*/
|
|
58
58
|
output?: string;
|
|
59
59
|
/**
|
|
60
|
+
* Directory where shared files for multiple widgets will be located, supports glob patterns
|
|
61
|
+
*/
|
|
62
|
+
shared?: string;
|
|
63
|
+
/**
|
|
60
64
|
* Directory where compacted widget files will be output, supports glob patterns
|
|
61
65
|
*/
|
|
62
66
|
extension?: string;
|
|
@@ -64,7 +68,10 @@ interface WorkspaceConfig<Find extends BuildFindMap = BuildFindMap> {
|
|
|
64
68
|
/**
|
|
65
69
|
* Scaffold structure to create when generating a new widget, defines the files and folders to create with their content (string or JSX.Element)
|
|
66
70
|
*/
|
|
67
|
-
scaffold?:
|
|
71
|
+
scaffold?: {
|
|
72
|
+
single?: WorkspaceScaffold.Item[];
|
|
73
|
+
multiple?: WorkspaceScaffold.Item[];
|
|
74
|
+
};
|
|
68
75
|
/**
|
|
69
76
|
* Build configuration for widget builds, including options for parallel builds, verbose logging, file finding patterns, build results mapping, and obfuscation settings for JavaScript, CSS, and HTML
|
|
70
77
|
*/
|
|
@@ -82,6 +89,10 @@ interface WorkspaceConfig<Find extends BuildFindMap = BuildFindMap> {
|
|
|
82
89
|
*/
|
|
83
90
|
find?: Find;
|
|
84
91
|
/**
|
|
92
|
+
* Directory for shared files used in multiple widget builds, allowing for common assets or code to be shared across widgets without duplication in each widget's build output
|
|
93
|
+
*/
|
|
94
|
+
shared?: Find;
|
|
95
|
+
/**
|
|
85
96
|
* Mapping of output files to find keys, defines how the found widget files should be mapped to output file names, allowing for flexible naming conventions and organization of built widget files
|
|
86
97
|
*/
|
|
87
98
|
result?: BuildResultMap<Find>;
|
|
@@ -119,6 +130,11 @@ interface WorkspaceConfig<Find extends BuildFindMap = BuildFindMap> {
|
|
|
119
130
|
*/
|
|
120
131
|
javascript?: ObfuscatorOptions;
|
|
121
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* Optional regular expression for matching HTML files during the build process, allowing for more flexible identification of HTML files beyond just file extensions, such as matching specific naming conventions or patterns in the file names to determine which files should be treated as HTML during the build
|
|
135
|
+
* The result should be match[1] containing the HTML content to be processed, typically by extracting the content within the <body> tags for further processing and building of the widget
|
|
136
|
+
*/
|
|
137
|
+
htmlRegex?: RegExp;
|
|
122
138
|
};
|
|
123
139
|
}
|
|
124
140
|
//#endregion
|
package/dist/api.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./workspace-
|
|
1
|
+
import{t as e}from"./workspace-BnA15bR0.mjs";function t(t){return e.Service.mergeConfig(t)}export{t as default,t as defineConfig};
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e,t}from"./workspace-
|
|
2
|
+
import{n as e,t}from"./workspace-BnA15bR0.mjs";import{Command as n}from"commander";import{createRequire as r}from"module";import{existsSync as i,readFileSync as a,readdirSync as o,unlink as s}from"fs";import c,{basename as l,join as u,relative as d,resolve as f}from"path";import{writeFile as p}from"fs/promises";import m from"inquirer";import{exec as h}from"child_process";import g from"ora";import _ from"cli-spinners";const v=new n;v.name(`tixyel cli`).description(`CLI tool for streamelements widgets made by Tixyel`).version((()=>{try{let{version:e}=r(import.meta.url)(`../package.json`);return e??`dev`}catch{return`dev`}})());const y=[`@tixyel/cli`,`@tixyel/streamelements`,`comfy.js`,`motion`,`typescript`,`@types/node`,`@types/jquery`,`lottie-web`],b={npm:(e,t)=>`npm install ${e.join(` `)}${t?` --no-cache`:``}`,yarn:(e,t)=>`yarn add ${e.join(` `)}${t?` --no-cache`:``}`,pnpm:(e,t)=>`pnpm add ${e.join(` `)}${t?` --no-cache`:``}`,bun:(e,t)=>`bun add ${e.join(` `)}${t?` --no-cache`:``}`};function x(){let e=process.env.npm_config_user_agent;if(e){if(e.includes(`yarn`))return`yarn`;if(e.includes(`pnpm`))return`pnpm`;if(e.includes(`bun`))return`bun`}return`npm`}v.command(`init`).aliases([`initialize`,`start`,`i`,`setup`]).description(`Initialize a new workspace for widget development`).option(`-f --force`,`Force initialization by overwriting existing configuration without confirmation`).action(async(e={})=>{let n=g({color:`magenta`,text:`Checking for existing workspace configuration...`,spinner:_.dotsCircle}).start(),r=await new t.Service({path:process.cwd(),spinner:n}).loadConfig().catch(e=>{n.fail(`Failed to load workspace configuration`),process.exit(1)});if(r&&!e.force){n.stop();let{force:t}=await m.prompt({type:`confirm`,name:`force`,message:`A workspace configuration already exists. Do you want to overwrite it?`,default:!1});if(!t){console.log(`Existing workspace configuration found. Initialization aborted.`);return}e.force=!0,n.start()}if(!r||r&&e.force){let t=f(process.cwd(),`tixyel.config.ts`),a=`import { defineConfig } from '@tixyel/cli/api';
|
|
3
3
|
|
|
4
4
|
export default defineConfig({
|
|
5
5
|
search: {
|
|
@@ -82,6 +82,8 @@ export default defineConfig({
|
|
|
82
82
|
'fields.txt': 'fields',
|
|
83
83
|
},
|
|
84
84
|
|
|
85
|
+
htmlRegex: /<body[^>]*>([\\s\\S]*?)<\\/body>/i,
|
|
86
|
+
|
|
85
87
|
obfuscation: {
|
|
86
88
|
javascript: {
|
|
87
89
|
compact: true,
|
|
@@ -112,4 +114,4 @@ export default defineConfig({
|
|
|
112
114
|
},
|
|
113
115
|
},
|
|
114
116
|
},
|
|
115
|
-
});`;i(t)&&r&&e.force?(
|
|
117
|
+
});`;i(t)&&r&&e.force?(s(r.path,e=>{if(e){console.error(`Failed to remove existing configuration: ${e}`);return}}),await p(t,a),n.text=`Existing configuration overwritten. Creating new workspace configuration...`):(await p(t,a),n.text=`Workspace configuration created.`)}n.succeed(`Workspace initialization complete!`);let{install:a}=await m.prompt({type:`confirm`,name:`install`,message:`Do you want to install the default dependencies now?`,default:!0});if(a){n.start(`Installing default dependencies...`);let e=x(),t=b[e](y,!1);n.text=`Installing dependencies using ${e}... It might take a few moments.`;try{await new Promise(e=>{h(t,(t,r,i)=>{if(t){n.fail(`Failed to install dependencies: ${t.message}`);return}n.succeed(`Dependencies installed successfully!`),e(r)})})}catch(e){n.fail(`Failed to execute install command: ${e}`)}}console.log(``),console.log(`🎉 Workspace setup is complete!`),console.log(` Edit ${r?.file??`tixyel.config.ts`} to customize your widget development experience.`),console.log(` Run 'tixyel generate' to create your first widget!`),console.log(` Run 'tixyel build' to build your widgets for use!`),console.log(``)});async function S(e){try{if(!i(e))return`01`;let t=o(e).filter(e=>/^\d+\s*-\s*/.test(e)).map(e=>parseInt(e.split(`-`)[0],10)).filter(e=>!isNaN(e)),n=t.length>0?Math.max(...t):0;return String(n+1).padStart(2,`0`)}catch{return`01`}}v.command(`generate [path] [name] [description] [tags]`).aliases([`new`,`create`,`g`,`c`,`widget`]).description(`Generate a new widget in the current workspace`).option(`-t, --type <type>`,`Widget type (single | multiple)`).action(async(e,n,r,i,a)=>{let o=g({color:`magenta`,text:`Loading workspace configuration...`,spinner:_.aesthetic}).start(),s=new t.Service({path:process.cwd(),spinner:o});await s.loadConfig().catch(e=>{o.fail(`Failed to load workspace configuration`),process.exit(1)})||(o.color=`red`,o.fail(`No workspace configuration found. Please run "tixyel init" to initialize a workspace before generating a widget.`),process.exit(1)),o.text=`Generating widget...`,o.color=`green`;let c=e?f(s.root,e.replace(/[/\\]$/,``)):s.root,d=e?e.endsWith(`/`)||e.endsWith(`\\`):!1,p=n;if(d)p=l(c),e?.slice(0,-1);else if(!p){o.stop();let e=`${await S(s.root)} - Custom Widget`,{name:t}=await m.prompt({name:`name`,type:`input`,message:`Enter a name for the widget:`,default:e});t||(console.log(`Widget name is required. Widget generation aborted.`),process.exit(1)),p=t}if(!r){o.stop();let{description:e}=await m.prompt({name:`description`,type:`input`,message:`Enter a description for the widget:`});r=e??``}if(!i){o.stop();let{tags:e}=await m.prompt({name:`tags`,type:`input`,message:`Enter tags for the widget (comma separated):`});i=e??``}let h=a?.type;if(!h){o.stop();let{type:e}=await m.prompt({name:`type`,type:`select`,message:`Select the widget type:`,choices:[{name:`Single (one widget per folder, scaffold defined in "scaffold.single")`,value:`single`},{name:`Multiple (multiple widgets per folder, scaffold defined in "scaffold.multiple")`,value:`multiple`}],default:`single`});h=e}let v=[];if(h===`multiple`){o.stop();let{widgets:e}=await m.prompt({name:`widgets`,type:`input`,message:`Enter the names of the widgets to create (comma separated):`,default:`main`});v=e?e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0):[],v.length||(console.log(`At least one widget name is required for multiple widget type. Widget generation aborted.`),process.exit(1))}let y=d?c:u(s.root,p);o.start(),o.text=`📂 Creating widget ${p} at ${y}`;let b=await s.createWidget(y,{name:p.replace(/^\d+\s*-\s*/,``),description:r,tags:i?i.split(`,`).map(e=>e.trim()):[]},{type:h,widgets:v});o.succeed(`Widget "${p}" generated successfully at ${y}`),console.log(``),b.config.description.length&&console.log(` - Description: ${b.config.description}`),b.config.metadata?.tags?.length&&console.log(` - Tags: ${b.config.metadata?.tags.join(`, `)}`),b.config.type&&console.log(` - Type: ${b.config.type}`),b.config.widgets?.length&&console.log(` - Widgets: ${b.config.widgets.join(`, `)}`),(b.content.files||b.content.folders)&&console.log(` - Scaffold created with ${b.content.folders} folders and ${b.content.files} files`),b.config.config&&console.log(` - Config path: ${b.config.config}`),console.log(``)}),v.command(`build`).aliases([`b`,`compact`,`compie`,`bundle`]).description(`Build the widgets in the current workspace`).option(`-p --parallel`,`Build widgets in parallel`).option(`-d --depth <number>`,`Maximum directory depth to search for widget files`,parseInt).option(`-v --verbose`,`Enable verbose logging during the build process`).option(`-w --widgets <names...>`,`Specify which widgets to build by name`,e=>e===`*`?`*`:String(e??``).split(`,`).map(e=>e.trim())).option(`-b --bump <type>`,`Bump version of built widgets (none, patch, minor, major)`).action(async n=>{let r=g({text:`Loading workspace configuration...`,color:`magenta`,spinner:_.dotsCircle}),o=new t.Service({spinner:r});if(i(`.tixyel`)&&!i(`.tixyel/`)){let t=JSON.parse(a(`.tixyel`,`utf-8`)),n=new e.Service({relativePath:d(process.cwd(),t.path),config:t,path:process.cwd(),workspace:o});n.config.config||(r.fail(`Invalid widget configuration found in .tixyel file`),process.exit(1)),o.root=c.join(process.cwd(),n.config.config),n.relativePath=d(o.root,n.path),r.succeed(`Loaded widget configuration from .tixyel file`)}r.start();let s=await o.loadConfig().catch(e=>{console.error(`Failed to load workspace configuration:`,e),process.exit(1)});s||(r.fail(`No workspace configuration found. Please run "tixyel init" to create a workspace configuration before building.`),process.exit(1));let l=s.data.search?.maxDepth;r.start(`🔎 Searching for widgets (max depth: ${l})...`);let u=await o.findWidgets(n.depth??void 0);u.length||(r.fail(`No widgets found in the workspace. Please ensure you have widgets configured correctly.`),process.exit(1));let f=[];if(n.widgets?.length&&n.widgets&&n.widgets!==void 0)n.widgets===`*`?(f=u.map(e=>e.path),r.succeed(`Auto-selected widgets for build (${f.length} widgets)`),await new Promise(e=>setTimeout(e,1e3))):(f=u.filter(e=>n.widgets.some(t=>e.config.name===t||e.path.includes(t))).map(e=>e.path),f.length||(r.fail(`No widgets matched the specified names. Please check the --widgets option and try again.`),process.exit(1)),r.text=`Selected widgets for build (${f.length} widgets)`);else if(u.length===1)f=[u[0].path],r.start(),r.succeed(`Auto-selected single widget for build: ${u[0].config.name}`);else{r.stop();let e=Math.max(...u.map(e=>e.config.name.length))+2,t=u.map(t=>({name:`${t.config.name.padEnd(e,` `)} (${t.relativePath.startsWith(`.`)?t.relativePath.replace(/\\/g,`/`):`./${t.relativePath}`.replace(/\\/g,`/`)})`,value:t.path,checked:!1})),{selected:n}=await m.prompt({type:`checkbox`,name:`selected`,message:`Select which widgets to build:`,choices:t,pageSize:10,loop:!1,theme:{checkbox:{on:`[x]`,off:`[ ]`}}});f=n,r.start()}f.length||(r.isSpinning?r.fail(`No widgets selected for build. Please select at least one widget to build.`):console.log(`❌ No widgets selected for build. Please select at least one widget to build.`));let p=`none`;if(n.bump){r.start();let e=[`none`,`patch`,`minor`,`major`];e.includes(n.bump)||(r.fail(`Invalid bump type "${n.bump}". Valid options are: ${e.join(`, `)}. Defaulting to "none".`),process.exit(1)),p=n.bump,r.succeed(`Version bump: ${p}`)}else{r.stop();let{version:e}=await m.prompt({type:`select`,name:`version`,message:`Select version bump type for built widgets:`,choices:[{name:`None (keep current version)`,value:`none`},{name:`Patch (x.x.1)`,value:`patch`},{name:`Minor (x.1.0)`,value:`minor`},{name:`Major (1.0.0)`,value:`major`}],default:`none`,loop:!1,pageSize:4});p=e}let h=n.parallel??o.config.data.build?.parallel??!1,v=n.verbose??o.config.data.build?.verbose??!1;if(r.start(),r.text=`🚀 Starting build for ${f.length} widget(s) with${h?` parallel`:``} build and${v?` verbose logging`:``}...`,h)await Promise.all(f.map(async e=>new Promise(async t=>{let n=u.find(t=>t.path===e);return n&&await n.build(v,p).catch(t=>{r.fail(`Failed to build widget at '${e}': ${t}`)}),t(n),n})));else for await(let e of f){let t=u.find(t=>t.path===e);t&&(r.text=`🚀 Building widget: ${t.config.name} (${t.relativePath})...`,await t.build(v,p).catch(t=>{r.fail(`Failed to build widget at '${e}': ${t}`)}))}r.succeed(`Build process complete!`)}),process.on(`unhandledRejection`,(e,t)=>{process.exit(0)}).on(`uncaughtException`,e=>{if(e instanceof Error&&e.name===`ExitPromptError`)console.log(`👋 until next time!`);else throw e}).on(`SIGINT`,()=>{process.exit(0)}),v.parse();export{};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import{existsSync as e,mkdirSync as t,readFileSync as n,readdirSync as r,unlinkSync as i,writeFileSync as a}from"fs";import{basename as o,dirname as s,extname as c,join as l,relative as u,resolve as d}from"path";import{mkdir as f,readFile as p,writeFile as m}from"fs/promises";import{transform as h,transformSync as g}from"esbuild";import{renderToStaticMarkup as _}from"react-dom/server";import{isValidElement as v}from"react";import{parse as y}from"jsonc-parser";import b from"postcss";import x from"cssnano";import S from"jszip";import C from"postcss-nested";import w from"autoprefixer";import{minify as T}from"html-minifier-terser";import E from"javascript-obfuscator";import D from"fast-glob";const O={entry:`development`,output:`finished`,shared:`shared`,extension:`widgetIO`},k=[`tixyel.config.ts`,`tixyel.config.tsx`,`tixyel.config.js`,`tixyel.config.mjs`,`tixyel.config.cjs`,`tixyel.config.json`,`tixyel.config.jsonc`,`.tixyelrc`,`.tixyelrc.json`,`.tixyelrc.jsonc`,`.tixyelrc.js`,`.tixyelrc.ts`,`.tixyelrc.mjs`,`.tixyelrc.cjs`],A=[`node_modules`,`dist`,`build`,`out`,`coverage`,`.git`,`.svn`,`.hg`],j=[{name:`development`,type:`folder`,content:[{name:`index.html`,type:`file`,content:``},{name:`style.css`,type:`file`,content:``},{name:`script.js`,type:`file`,content:``},{name:`fields.json`,type:`file`,content:`{}`},{name:`data.json`,type:`file`,content:`{}`}]},{name:`finished`,type:`folder`},{name:`resources`,type:`folder`}],M={search:{maxDepth:3,ignore:A},dirs:O,scaffold:{single:j,multiple:j},build:{parallel:!0,verbose:!1,find:{html:[`index.html`],css:[`style.css`],script:[`script.js`],fields:[`fields.json`]},result:{"HTML.html":`html`,"CSS.css":`css`,"SCRIPT.js":`script`,"FIELDS.json":`fields`},widgetIO:{"html.txt":`html`,"css.txt":`css`,"js.txt":`script`,"fields.txt":`fields`},obfuscation:{html:{},css:{removeNesting:!0,autoprefixer:{overrideBrowserslist:[`Chrome 127`]},cssnano:{}},javascript:{}},htmlRegex:/<body[^>]*>([\s\S]*?)<\/body>/i}};var N=` ____ _ _ _
|
|
2
|
+
/ __ \\ | |_ (_) __ __ _ _ ___ | |
|
|
3
|
+
/ / _\` | | __| | | \\ \\/ / | | | | / _ \\ | |
|
|
4
|
+
| | (_| | | |_ | | > < | |_| | | __/ | |
|
|
5
|
+
\\ \\__,_| \\__| |_| /_/\\_\\ \\__, | \\___| |_|
|
|
6
|
+
\\____/ |___/
|
|
7
|
+
`;const P={html(e){return[`<!---`,N,`Generated by @Tixyel Widgets SDK`,`Widget name: ${e.config.name}`,`Version: ${e.config.version}`,`Description: ${e.config.description}`,`Tags: ${e.config.metadata?.tags?.join(`, `)}`,`Made by: ${e.config.metadata?.author}`,e.config.metadata?.clientId?`Made for: ${e.config.metadata?.clientId}`:void 0,...Object.entries(e.config.metadata||{}).filter(([e])=>![`tags`,`author`,`clientId`].includes(e)).map(([e,t])=>`${e}: ${t}`),` `,`DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR`,`--->`].filter(Boolean).join(`
|
|
8
|
+
`)},css(e){return[`/**`,N,`Generated by @Tixyel Widgets SDK`,`Widget name: ${e.config.name}`,`Version: ${e.config.version}`,`Description: ${e.config.description}`,`Tags: ${e.config.metadata?.tags?.join(`, `)}`,`Made by: ${e.config.metadata?.author}`,e.config.metadata?.clientId?`Made for: ${e.config.metadata?.clientId}`:void 0,...Object.entries(e.config.metadata||{}).filter(([e])=>![`tags`,`author`,`clientId`].includes(e)).map(([e,t])=>`${e}: ${t}`),` `,`DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR`,`*/`].filter(Boolean).join(`
|
|
9
|
+
`)},script(e){return[`/**`,N,`Generated by @Tixyel Widgets SDK`,`Widget name: ${e.config.name}`,`Version: ${e.config.version}`,`Description: ${e.config.description}`,`Tags: ${e.config.metadata?.tags?.join(`, `)}`,`Made by: ${e.config.metadata?.author}`,e.config.metadata?.clientId?`Made for: ${e.config.metadata?.clientId}`:void 0,...Object.entries(e.config.metadata||{}).filter(([e])=>![`tags`,`author`,`clientId`].includes(e)).map(([e,t])=>`${e}: ${t}`),` `,`DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR`,`*/`].filter(Boolean).join(`
|
|
10
|
+
`)}};let F;(function(i){class s{constructor(e){this.content={folders:0,files:0},this.path=e.path,this.config=e.config,this.workspace=e.workspace,this.spinner=this.workspace.spinner,this.relativePath=e.relativePath,this.content=e.content??{folders:0,files:0}}async build(i=this.workspace.config.data.build?.verbose??!1,s=`none`){if(s!==`none`){let e=await this.bumpVersion(s);this.spinner&&this.spinner.isSpinning&&i&&(this.spinner.text=`Building widget ${this.config.name} (version bumped to ${e})...`)}try{let s=l(this.path,this.config.dirs?.entry??this.workspace.config.data.dirs?.entry??`development`),c=l(this.path,this.config.dirs?.output??this.workspace.config.data.dirs?.output??`finished`),u=l(this.path,this.config.dirs?.shared??this.workspace.config.data.dirs?.shared??`shared`),d=l(this.path,this.config.dirs?.extension??this.workspace.config.data.dirs?.extension??`widgetIO`);if(!e(s))throw Error(`Entry directory does not exist: ${s}`);t(c,{recursive:!0}),t(d,{recursive:!0});let f=this.config.build?.find??this.workspace.config.data.build?.find??M.build?.find,p=this.config.build?.shared??this.workspace.config.data.build?.shared??M.build?.shared,m=this.config.build?.result??this.workspace.config.data.build?.result??M.build?.result,h=this.config.build?.widgetIO??this.workspace.config.data.build?.widgetIO??M.build?.widgetIO,_=e=>Array.isArray(e)?e.filter(Boolean):[],v=(t,r)=>{let i={};for(let a of r){let r=l(t,a);e(r)&&(i[a]=n(r,`utf-8`))}return i},D=Object.entries(p).reduce((e,[t,n])=>(e[t]=n.map(e=>`../../${o(u)}/${e}`),e),{}),O=async(e,n,r)=>{let o=new Set,s=new Set,c=Object.fromEntries(await Promise.all(Object.entries({...f,...D}).map(async([t,n])=>{let r=``,a=_(n.filter(e=>!s.has(e)));if(!a.length)return[t,``];let o=(e,n)=>(!Array.isArray(e)&&(e=[e]),!Array.isArray(n)&&(n=[n]),e.some(e=>t.toLowerCase().includes(e.toLowerCase()))||a.some(e=>n.some(t=>e.toLowerCase().endsWith(t.toLowerCase())))),c=new Set;if(o(`html`,`.html`)){let n=a.filter(e=>e.endsWith(`.html`)&&!s.has(e));if(n.length){i&&console.log(` - Processing HTML for ${this.config.name} [${t}, ${n.join(`, `)}]...`);let a=v(e,n),o=``;for await(let[e,t]of Object.entries(a)){let n=t.match(this.workspace.config.data.build?.htmlRegex??M.build?.htmlRegex);n&&n[1]&&(o+=n[1].trim()+`
|
|
11
|
+
`,s.add(e))}let l=await T(o,this.workspace.config.data.build?.obfuscation?.html);r+=l.trim(),c.add(`html`)}}if(o([`css`,`style`,`styles`],`.css`)){let n=a.filter(e=>e.endsWith(`.css`)&&!s.has(e));if(n.length){i&&console.log(` - Processing CSS for ${this.config.name} [${t}, ${n.join(`, `)}]...`);let a=v(e,n),o=Object.values(a).filter(Boolean),l=``;for await(let e of o){let t=[w({overrideBrowserslist:[`Chrome 127`],...this.workspace.config.data.build?.obfuscation?.css?.autoprefixer}),x(this.workspace.config.data.build?.obfuscation?.css?.cssnano)];this.workspace.config.data.build?.obfuscation?.css?.removeNesting&&t.unshift(C());let n=await b(t).process(e,{from:void 0});l+=n.css+`
|
|
12
|
+
`}for(let e of Object.keys(a))s.add(e);c.has(`html`)?r=r+=`<style>${l.trim()}</style>`:r+=l.trim(),c.add(`css`)}}if(o([`typescript`,`ts`],[`.ts`,`.tsx`,`.cts`,`.mts`])){let n=a.filter(e=>e.endsWith(`.ts`)&&!s.has(e));if(n.length){i&&console.log(` - Processing TypeScript for ${this.config.name} [${t}, ${n.join(`, `)}]...`);let a=v(e,n),o=``;for await(let[e,t]of Object.entries(a))try{let e=g(t,{loader:`ts`,target:`es2020`,format:`cjs`});o+=e.code+`
|
|
13
|
+
`}catch(e){throw console.warn(` ⚠️ Failed to compile TypeScript: ${e}`),e}finally{s.add(e)}let l=E.obfuscate(o.trim(),this.workspace.config.data.build?.obfuscation?.javascript);c.has(`html`)?r=r+=`<script>${l.getObfuscatedCode()}<\/script>\n`:r+=l.getObfuscatedCode()+`
|
|
14
|
+
`,c.add(`typescript`)}}if(o([`script`,`js`,`javascript`],[`.js`,`.mjs`,`.cjs`,`.jsx`])){let n=a.filter(e=>e.endsWith(`.js`)&&!s.has(e));if(n.length){i&&console.log(` - Processing JavaScript for ${this.config.name} [${t}, ${n.join(`, `)}]...`);let a=v(e,n),o=``;for await(let[e,t]of Object.entries(a)){let n=E.obfuscate(t,this.workspace.config.data.build?.obfuscation?.javascript);o+=n.getObfuscatedCode()+`
|
|
15
|
+
`,s.add(e)}c.has(`html`)?r=r+=`<script>${o.trim()}<\/script>`:r+=o.trim(),c.add(`script`)}}if(o([`fields`,`fielddata`,`fieldData`,`cf`,`customfields`],[`.json`,`.jsonc`])){let n=a.filter(e=>(e.endsWith(`.json`)||e.endsWith(`.jsonc`))&&!s.has(e));if(n.length){i&&console.log(` - Processing JSON for ${this.config.name} [${t}, ${n.join(`, `)}]...`);let a=v(e,n),o={};for await(let[e,t]of Object.entries(a)){try{let e=y(t),n=JSON.parse(JSON.stringify(e));Object.assign(o,n)}catch(e){throw console.warn(` ⚠️ Failed to parse fields JSON: ${e}`),e}s.add(e)}!c.has(`fields`)&&Object.keys(o).length&&(r+=JSON.stringify(o,null,2)),c.add(`fields`)}}return r.length||(i&&console.log(` - Unknown build key: ${t}, the available keys are html, css, script and fields.`),r+=``),[t,r]})));for await(let[e,t]of Object.entries(m)){let r=``,s=Array.isArray(t)?t:[t];if(s.some(e=>e.includes(`script`))?(o.has(`script`)||(r+=P.script(this)+`
|
|
16
|
+
`),o.add(`script`)):s.some(e=>e.includes(`css`))?(o.has(`css`)||(r+=P.css(this)+`
|
|
17
|
+
`),o.add(`css`)):s.some(e=>e.includes(`html`))&&(o.has(`html`)||(r+=P.html(this)+`
|
|
18
|
+
`),o.add(`html`)),typeof t==`string`)r=c[t];else if(Array.isArray(t))for await(let e of t){let t=c[e];if(t&&t.trim().length){if([`fields`,`customfields`,`cf`,`fielddata`,`fieldData`,`data`].some(t=>e.toLowerCase().includes(t.toLowerCase()))){let e=JSON.parse(r||`{}`),n=JSON.parse(t);r=JSON.stringify({...e,...n},null,2)}else r+=`
|
|
19
|
+
`+t.trim();i&&console.log(` ✓ Merged part for: ${e}`)}}if(r=r.trim(),r){let t=l(n,e);a(t,r,`utf-8`),i&&console.log(` ✓ Written: ${t}`)}}try{let e=new S;for await(let[t,n]of Object.entries(h)){let r=``;if(typeof n==`string`)r=c[n];else if(Array.isArray(n))for await(let e of n){let t=c[e];t&&t.trim().length&&(r+=`
|
|
20
|
+
`+t.trim(),i&&console.log(` ✓ Merged part for ZIP: ${e}`))}r&&(e.file(t,r),i&&console.log(` ✓ Added to ZIP: ${t}`))}e.file(`widget.ini`,`[HTML]
|
|
21
|
+
path = "html.txt"
|
|
22
|
+
|
|
23
|
+
[CSS]
|
|
24
|
+
path = "css.txt"
|
|
25
|
+
|
|
26
|
+
[JS]
|
|
27
|
+
path = "js.txt"
|
|
28
|
+
|
|
29
|
+
[FIELDS]
|
|
30
|
+
path = "fields.txt"
|
|
31
|
+
|
|
32
|
+
[DATA]
|
|
33
|
+
path = "data.txt"`);let n=c.data||`{}`;e.file(`data.txt`,n);let o=await e.generateInternalStream({type:`base64`}).accumulate().then(e=>e),s=l(d+`/`+(this.config.version||`0.0.0`),`${r??this.config.name}.zip`);t(d+`/`+(this.config.version||`0.0.0`),{recursive:!0}),a(s,o,`base64`)}catch(e){throw Error(`Failed to create ZIP archive: ${e}`)}};if(this.config.type===`multiple`){let n=(this.config.widgets??[]).filter(Boolean),a=r(s,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name),o=n.length?n:a;if(!o.length)throw Error(`No widgets found in multiple widget entry directory: ${s}. Make sure to create subfolders for each widget or configure the "widgets" property in the widget configuration with the names of the widget folders.`);let u=0;for await(let n of o){let r=l(s,n),a=l(c,n);if(!e(r)&&i){console.warn(` ⚠️ Skipping widget "${n}" because the entry directory does not exist: ${r}`);continue}t(a,{recursive:!0}),await O(r,a,`${this.config.name}-${n}`),u++}if(!u)throw Error(`No valid widgets were built for multiple widget configuration. Please check the entry directory and configuration.`)}else await O(s,c,this.config.name)}catch(e){throw Error(`Failed to build widget: ${e}`)}}async bumpVersion(e){let t=d(this.path,`.tixyel`),n=this.config;n.version||=`0.0.0`;let[r,i,a]=n.version.split(`.`).map(Number),o;switch(e){case`major`:o=`${r+1}.0.0`;break;case`minor`:o=`${r}.${i+1}.0`;break;case`patch`:o=`${r}.${i}.${a+1}`;break}return n.version=o,await m(t,JSON.stringify(n,null,2),`utf-8`),o}static async readConfig(t){try{let n=d(t,`.tixyel`);if(!e(n))return null;let r=y(await p(n,`utf-8`));return typeof r!=`object`||!r||r===null||!r?.name||typeof r.name!=`string`||!r.name.trim().length?null:s.mergeConfig(r)}catch{}return null}static async mergeConfig(e){let t=e.type===`multiple`?Array.isArray(e.widgets)?e.widgets.filter(Boolean):[]:void 0,n={entry:e.dirs?.entry??`development`,output:e.dirs?.output??`finished`,shared:e.dirs?.shared??`widgetIO`,extension:e.dirs?.extension??`widgetIO`};return{...e,widgets:t,type:e.type??`single`,version:e.version??`0.0.0`,description:e.description??``,metadata:e.metadata??{},dirs:n}}}i.Service=s})(F||={});let I;(function(t){class r{constructor(e){this.root=e?.path??process.cwd(),this.config=e?.config??{data:M,path:this.root,file:`tixyel.config.ts`},this.spinner=e?.spinner}async loadConfig(){let t=k.find(t=>e(d(this.root,t)));if(!t)return null;let i,a=d(this.root,t);try{if(t.endsWith(`.ts`)||t.endsWith(`.tsx`))i=await r.loadTsConfig(this.root,a);else if(t.endsWith(`.js`)||t.endsWith(`.mjs`)||t.endsWith(`.cjs`)){let e=await import(a);i=e.default??e.config}else if(t.endsWith(`.json`)||t.endsWith(`.jsonc`)||t===`.tixyelrc`){let e=n(a,`utf-8`);i=JSON.parse(e)}else throw Error(`Unsupported configuration file format: ${t}`)}catch(e){throw Error(`Failed to load workspace configuration: ${e}`)}finally{if(!i)return null;i=r.mergeConfig(i);let e={data:i,path:a,file:t};return this.config=e,e}}async createWidget(e,t,n){try{await f(e,{recursive:!0});let r=u(e,this.config.path).replace(/\\/g,`/`),i={type:n?.type??`single`,widgets:n?.type===`multiple`?(n?.widgets??[]).map(e=>e.trim()).filter(e=>!!e.length):void 0,name:t?.name,description:t?.description,version:`0.0.0`,config:r.startsWith(`.`)?r:`./${r}`,metadata:{...this.config.data.metadata,...t,name:void 0,description:void 0},dirs:this.config.data.dirs??{entry:`development`,output:`finished`,shared:`shared`,extension:`widgetIO`}};await m(d(e,`.tixyel`),JSON.stringify(i,null,2),`utf-8`);let{single:a=this.config.data.scaffold?.single??[],multiple:o=this.config.data.scaffold?.multiple??[]}=this.config.data.scaffold??{},s={files:0,folders:0};async function c(e,t){let n=d(t,e.name);if(e.type===`folder`){if(await f(n,{recursive:!0}),s.folders++,!e.content||!Array.isArray(e.content)||!e.content.length)return;i.type===`multiple`&&e.name===(i.dirs?.entry??`development`)&&i.widgets?.length?await Promise.all(i.widgets.map(t=>new Promise(async r=>{let i=d(n,t);await f(i,{recursive:!0}),s.folders++,await Promise.all(e.content.map(e=>c(e,i))),r(i)}))):await Promise.all(e.content.map(e=>c(e,n)))}else if(e.type===`file`){let t=e.content;t===void 0||t===void 0||!t?t=``:typeof t==`string`?t=t:v(t)&&(t=_(t)),await m(n,String(t??``),`utf-8`),s.files++}}return await Promise.all((i.type===`single`?a:o).map(t=>c(t,e))),new F.Service({relativePath:u(this.root,e),config:i,content:s,path:e,workspace:this})}catch(e){throw Error(`Failed to create widget: ${e}`)}}async findWidgets(e=this.config.data.search?.maxDepth??5,t=this.config.data.search?.ignore??[]){let n=await D(`{${Array.from({length:e},(e,t)=>`*`.repeat(t+1)).join(`,`)}}/.tixyel`,{cwd:this.root,absolute:!0,onlyFiles:!0,ignore:[`node_modules`,`.git`,`dist`,...t]});return(await Promise.all(n.map(e=>new Promise(async t=>{let n=s(e),r=await F.Service.readConfig(n);if(!r||r===null)return t(null),null;let i=new F.Service({path:n,config:r,relativePath:u(this.root,n),workspace:this});return t(i),i})))).filter(e=>e!==null)}static mergeConfig(e){let t=M;return{...e||{},search:{...t.search,...e?.search||{}},metadata:{...t.metadata,...e?.metadata||{}},dirs:{...t.dirs,...e?.dirs||{}},scaffold:{...t.scaffold,...e?.scaffold},build:{...t.build,...e?.build||{},obfuscation:{...t.build?.obfuscation,...e?.build?.obfuscation||{}}}}}static async loadTsConfig(e,t){let r=d(e,`.temp.tixyel.config.mjs`),o=n(t,`utf-8`),s=c(t).toLowerCase(),l=s===`.tsx`?`tsx`:s===`.jsx`?`jsx`:`ts`,{code:u}=await h(o,{loader:l,format:`esm`,target:`es2022`,...l===`tsx`||l===`jsx`?{jsx:`automatic`}:{}});a(r,u,`utf-8`);try{let e=await import(`file://${r}?t=${Date.now()}`);try{i(r)}catch(e){throw Error(`Failed to clean up temporary configuration file: ${e}`)}return e.default??e.config}catch(e){throw Error(`Failed to load TypeScript workspace configuration: ${e}`)}}}t.Service=r})(I||={});export{F as n,I as t};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tixyel/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "CLI tool for streamelements widgets",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"autoprefixer": "^10.4.22",
|
|
59
|
+
"chalk": "^5.6.2",
|
|
59
60
|
"chokidar": "^3.6.0",
|
|
60
61
|
"cli-spinners": "^3.4.0",
|
|
61
62
|
"commander": "^14.0.2",
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import{existsSync as e,mkdirSync as t,readFileSync as n,unlinkSync as r,writeFileSync as i}from"fs";import{dirname as a,extname as o,join as s,relative as c,resolve as l}from"path";import{mkdir as u,readFile as d,writeFile as f}from"fs/promises";import{transform as p,transformSync as m}from"esbuild";import{renderToStaticMarkup as h}from"react-dom/server";import{isValidElement as g}from"react";import{parse as _}from"jsonc-parser";import v from"postcss";import y from"cssnano";import b from"jszip";import x from"postcss-nested";import S from"autoprefixer";import{minify as C}from"html-minifier-terser";import w from"javascript-obfuscator";import T from"fast-glob";const E={entry:`development`,output:`finished`,extension:`widgetIO`},D=[`tixyel.config.ts`,`tixyel.config.tsx`,`tixyel.config.js`,`tixyel.config.mjs`,`tixyel.config.cjs`,`tixyel.config.json`,`tixyel.config.jsonc`,`.tixyelrc`,`.tixyelrc.json`,`.tixyelrc.jsonc`,`.tixyelrc.js`,`.tixyelrc.ts`,`.tixyelrc.mjs`,`.tixyelrc.cjs`],O={search:{maxDepth:3,ignore:[`node_modules`,`dist`,`build`,`out`,`coverage`,`.git`,`.svn`,`.hg`]},dirs:E,scaffold:[{name:`development`,type:`folder`,content:[{name:`index.html`,type:`file`,content:``},{name:`style.css`,type:`file`,content:``},{name:`script.js`,type:`file`,content:``},{name:`fields.json`,type:`file`,content:`{}`},{name:`data.json`,type:`file`,content:`{}`}]},{name:`finished`,type:`folder`},{name:`resources`,type:`folder`}],build:{parallel:!0,verbose:!1,find:{html:[`index.html`],css:[`style.css`],script:[`script.js`],fields:[`fields.json`]},result:{"HTML.html":`html`,"CSS.css":`css`,"SCRIPT.js":`script`,"FIELDS.json":`fields`},widgetIO:{"html.txt":`html`,"css.txt":`css`,"js.txt":`script`,"fields.txt":`fields`},obfuscation:{html:{},css:{removeNesting:!0,autoprefixer:{overrideBrowserslist:[`Chrome 127`]},cssnano:{}},javascript:{}}}};var k=` ____ _ _ _
|
|
2
|
-
/ __ \\ | |_ (_) __ __ _ _ ___ | |
|
|
3
|
-
/ / _\` | | __| | | \\ \\/ / | | | | / _ \\ | |
|
|
4
|
-
| | (_| | | |_ | | > < | |_| | | __/ | |
|
|
5
|
-
\\ \\__,_| \\__| |_| /_/\\_\\ \\__, | \\___| |_|
|
|
6
|
-
\\____/ |___/
|
|
7
|
-
`;const A={html(e){return[`<!---`,k,`Generated by @Tixyel Widgets SDK`,`Widget name: ${e.config.name}`,`Version: ${e.config.version}`,`Description: ${e.config.description}`,`Tags: ${e.config.metadata?.tags?.join(`, `)}`,`Made by: ${e.config.metadata?.author}`,e.config.metadata?.clientId?`Made for: ${e.config.metadata?.clientId}`:void 0,...Object.entries(e.config.metadata||{}).filter(([e])=>![`tags`,`author`,`clientId`].includes(e)).map(([e,t])=>`${e}: ${t}`),` `,`DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR`,`--->`].filter(Boolean).join(`
|
|
8
|
-
`)},css(e){return[`/**`,k,`Generated by @Tixyel Widgets SDK`,`Widget name: ${e.config.name}`,`Version: ${e.config.version}`,`Description: ${e.config.description}`,`Tags: ${e.config.metadata?.tags?.join(`, `)}`,`Made by: ${e.config.metadata?.author}`,e.config.metadata?.clientId?`Made for: ${e.config.metadata?.clientId}`:void 0,...Object.entries(e.config.metadata||{}).filter(([e])=>![`tags`,`author`,`clientId`].includes(e)).map(([e,t])=>`${e}: ${t}`),` `,`DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR`,`*/`].filter(Boolean).join(`
|
|
9
|
-
`)},script(e){return[`/**`,k,`Generated by @Tixyel Widgets SDK`,`Widget name: ${e.config.name}`,`Version: ${e.config.version}`,`Description: ${e.config.description}`,`Tags: ${e.config.metadata?.tags?.join(`, `)}`,`Made by: ${e.config.metadata?.author}`,e.config.metadata?.clientId?`Made for: ${e.config.metadata?.clientId}`:void 0,...Object.entries(e.config.metadata||{}).filter(([e])=>![`tags`,`author`,`clientId`].includes(e)).map(([e,t])=>`${e}: ${t}`),` `,`DO NOT EDIT, SHARE OR DISTRIBUTE THIS CODE WITHOUT PERMISSION FROM THE AUTHOR`,`*/`].filter(Boolean).join(`
|
|
10
|
-
`)}};let j;(function(r){class a{constructor(e){this.content={folders:0,files:0},this.path=e.path,this.config=e.config,this.workspace=e.workspace,this.spinner=this.workspace.spinner,this.relativePath=e.relativePath,this.content=e.content??{folders:0,files:0}}async build(r=this.workspace.config.data.build?.verbose??!1,a=`none`){a!==`none`&&await this.bumpVersion(a);try{let a=s(this.path,this.config.dirs?.entry??this.workspace.config.data.dirs?.entry??`development`),o=s(this.path,this.config.dirs?.output??this.workspace.config.data.dirs?.output??`finished`),c=s(this.path,this.config.dirs?.extension??this.workspace.config.data.dirs?.extension??`widgetIO`);if(!e(a))throw Error(`Entry directory does not exist: ${a}`);t(o,{recursive:!0});let l=this.config.build?.find??this.workspace.config.data.build?.find??{html:[`index.html`],script:[`script.js`],typescript:[`script.ts`],css:[`styles.css`],fields:[`fields.json`]},u=this.config.build?.result??this.workspace.config.data.build?.result??{"HTML.html":`html`,"SCRIPT.js":`script`,"CSS.css":`css`,"FIELDS.json":`fields`},d=this.config.build?.widgetIO??this.workspace.config.data.build?.widgetIO??{"html.txt":`html`,"js.txt":`script`,"css.txt":`css`,"fields.txt":`fields`},f=e=>Array.isArray(e)?e.filter(Boolean):[],p=(t,r)=>{let i={};for(let a of r){let r=s(t,a);e(r)&&(i[a]=n(r,`utf-8`))}return i},h=new Set,g=new Set,T=Object.fromEntries(await Promise.all(Object.entries(l).map(async([e,t])=>{let n=``,i=f(t.filter(e=>!g.has(e)));if(!i.length)return[e,``];let o=(t,n)=>(!Array.isArray(t)&&(t=[t]),!Array.isArray(n)&&(n=[n]),t.some(t=>e.toLowerCase()===t.toLowerCase())||i.some(e=>n.some(t=>e.toLowerCase().endsWith(t.toLowerCase())))),s=new Set;if(o(`html`,`.html`)){h.has(`html`)||(n+=A.html(this)+`
|
|
11
|
-
`),h.add(`html`);let t=i.filter(e=>e.endsWith(`.html`)&&!g.has(e));r&&console.log(` - Processing HTML for ${this.config.name} [${e}, ${t.join(`, `)}]...`);let o=p(a,t),c=``;for await(let[e,t]of Object.entries(o)){let n=t.match(/<body[^>]*>([\s\S]*?)<\/body>/i);n&&n[1]&&(c+=n[1].trim()+`
|
|
12
|
-
`,g.add(e))}let l=await C(c,this.workspace.config.data.build?.obfuscation?.html);n+=l.trim(),s.add(`html`)}if(o([`css`,`style`,`styles`],`.css`)){h.has(`css`)||(n+=A.css(this)+`
|
|
13
|
-
`),h.add(`css`);let t=i.filter(e=>e.endsWith(`.css`)&&!g.has(e));r&&console.log(` - Processing CSS for ${this.config.name} [${e}, ${t.join(`, `)}]...`);let o=p(a,t),c=``;for await(let[e,t]of Object.entries(o)){let n=[S({overrideBrowserslist:[`Chrome 127`],...this.workspace.config.data.build?.obfuscation?.css?.autoprefixer}),y(this.workspace.config.data.build?.obfuscation?.css?.cssnano)];this.workspace.config.data.build?.obfuscation?.css?.removeNesting&&n.unshift(x());let r=await v(n).process(t,{from:void 0});c+=r.css+`
|
|
14
|
-
`,g.add(e)}s.has(`html`)?n=n+=`<style>${c.trim()}</style>`:n+=c.trim(),s.add(`css`)}if(o([`typescript`,`ts`],`.ts`)){h.has(`script`)||(n+=A.script(this)+`
|
|
15
|
-
`),h.add(`script`);let t=i.filter(e=>e.endsWith(`.ts`)&&!g.has(e));r&&console.log(` - Processing TypeScript for ${this.config.name} [${e}, ${t.join(`, `)}]...`);let o=p(a,t),c=``;for await(let[e,t]of Object.entries(o))try{let e=m(t,{loader:`ts`,target:`es2020`,format:`cjs`});c+=e.code+`
|
|
16
|
-
`}catch(e){throw console.warn(` ⚠️ Failed to compile TypeScript: ${e}`),e}finally{g.add(e)}let l=w.obfuscate(c.trim(),this.workspace.config.data.build?.obfuscation?.javascript);s.has(`html`)?n=n+=`<script>${l.getObfuscatedCode()}<\/script>\n`:n+=l.getObfuscatedCode()+`
|
|
17
|
-
`,s.add(`typescript`)}if(o([`script`,`js`,`javascript`],`.js`)){h.has(`script`)||(n+=A.script(this)+`
|
|
18
|
-
`),h.add(`script`);let t=i.filter(e=>e.endsWith(`.js`)&&!g.has(e));r&&console.log(` - Processing JavaScript for ${this.config.name} [${e}, ${t.join(`, `)}]...`);let o=p(a,t),c=``;for await(let[e,t]of Object.entries(o)){let n=w.obfuscate(t,this.workspace.config.data.build?.obfuscation?.javascript);c+=n.getObfuscatedCode()+`
|
|
19
|
-
`,g.add(e)}s.has(`html`)?n=n+=`<script>${c.trim()}<\/script>`:n+=c.trim(),s.add(`script`)}if(o([`fields`,`fielddata`,`fieldData`,`cf`,`customfields`],`.json`)){let t=i.filter(e=>e.endsWith(`.json`)&&!g.has(e));r&&console.log(` - Processing JSON for ${this.config.name} [${e}, ${t.join(`, `)}]...`);let o=p(a,t),c={};for await(let[e,t]of Object.entries(o))try{let e=_(t),n=JSON.parse(JSON.stringify(e));Object.assign(c,n)}catch(e){throw console.warn(` ⚠️ Failed to parse fields JSON: ${e}`),e}s.size||(n+=JSON.stringify(c,null,2)),s.add(`fields`)}return n.length||(r&&console.log(` - Unknown build key: ${e}, the available keys are html, css, script and fields.`),n+=``),[e,n]})));for await(let[e,t]of Object.entries(u)){let n=``;if(typeof t==`string`)n=T[t];else if(Array.isArray(t))for await(let e of t){let t=T[e];t&&(n+=`
|
|
20
|
-
`+t,r&&console.log(` ✓ Merged part for: ${e}`))}if(n){let t=s(o,e);i(t,n,`utf-8`),r&&console.log(` ✓ Written: ${t}`)}}try{let e=new b;for await(let[t,n]of Object.entries(d)){let i=``;if(typeof n==`string`)i=T[n];else if(Array.isArray(n))for await(let e of n){let t=T[e];t&&(i+=`
|
|
21
|
-
`+t,r&&console.log(` ✓ Merged part for ZIP: ${e}`))}i&&(e.file(t,i),r&&console.log(` ✓ Added to ZIP: ${t}`))}e.file(`widget.ini`,`[HTML]
|
|
22
|
-
path = "html.txt"
|
|
23
|
-
|
|
24
|
-
[CSS]
|
|
25
|
-
path = "css.txt"
|
|
26
|
-
|
|
27
|
-
[JS]
|
|
28
|
-
path = "js.txt"
|
|
29
|
-
|
|
30
|
-
[FIELDS]
|
|
31
|
-
path = "fields.txt"
|
|
32
|
-
|
|
33
|
-
[DATA]
|
|
34
|
-
path = "data.txt"`);let n=T.data||`{}`;e.file(`data.txt`,n);let a=await e.generateInternalStream({type:`base64`}).accumulate().then(e=>e),o=s(c+`/`+(this.config.version||`0.0.0`),`${this.config.name}.zip`);t(c+`/`+(this.config.version||`0.0.0`),{recursive:!0}),i(o,a,`base64`)}catch(e){throw Error(`Failed to create ZIP archive: ${e}`)}}catch(e){throw Error(`Failed to build widget: ${e}`)}}async bumpVersion(e){let t=l(this.path,`.tixyel`),n=this.config;n.version||=`0.0.0`;let[r,i,a]=n.version.split(`.`).map(Number),o;switch(e){case`major`:o=`${r+1}.0.0`;break;case`minor`:o=`${r}.${i+1}.0`;break;case`patch`:o=`${r}.${i}.${a+1}`;break}return n.version=o,await f(t,JSON.stringify(n,null,2),`utf-8`),o}static async readConfig(t){try{let n=l(t,`.tixyel`);if(!e(n))return null;let r=_(await d(n,`utf-8`));return typeof r!=`object`||!r||r===null||!r?.name||typeof r.name!=`string`||!r.name.trim().length?null:a.mergeConfig(r)}catch{}return null}static async mergeConfig(e){return{...e,version:e.version??`0.0.0`,description:e.description??``,metadata:{...e.metadata},dirs:{entry:e.dirs?.entry??`development`,output:e.dirs?.output??`finished`,extension:e.dirs?.extension??`widgetIO`}}}}r.Service=a})(j||={});let M;(function(t){class s{constructor(e){this.root=e?.path??process.cwd(),this.config=e?.config??{data:O,path:this.root,file:`tixyel.config.ts`},this.spinner=e?.spinner}async loadConfig(){let t=D.find(t=>e(l(this.root,t)));if(!t)return null;let r,i=l(this.root,t);try{if(t.endsWith(`.ts`)||t.endsWith(`.tsx`))r=await s.loadTsConfig(this.root,i);else if(t.endsWith(`.js`)||t.endsWith(`.mjs`)||t.endsWith(`.cjs`)){let e=await import(i);r=e.default??e.config}else if(t.endsWith(`.json`)||t.endsWith(`.jsonc`)||t===`.tixyelrc`){let e=n(i,`utf-8`);r=JSON.parse(e)}else throw Error(`Unsupported configuration file format: ${t}`)}catch(e){throw Error(`Failed to load workspace configuration: ${e}`)}finally{if(!r)return null;r=s.mergeConfig(r);let e={data:r,path:i,file:t};return this.config=e,e}}async createWidget(e,t){try{await u(e,{recursive:!0});let n=c(e,this.config.path).replace(/\\/g,`/`),r={name:t?.name,description:t?.description,version:`0.0.0`,config:n.startsWith(`.`)?n:`./${n}`,metadata:{...this.config.data.metadata,...t,name:void 0,description:void 0},dirs:this.config.data.dirs??{entry:`development`,output:`finished`,extension:`widgetIO`}};await f(l(e,`.tixyel`),JSON.stringify(r,null,2),`utf-8`);let i=this.config.data.scaffold??[],a={files:0,folders:0};async function o(e){return e===void 0||e===void 0||!e?``:typeof e==`string`?e:g(e)?h(e):String(e??``)}async function s(e,t){let n=l(t,e.name);e.type===`folder`?(await u(n,{recursive:!0}),a.folders++,e.content&&Array.isArray(e.content)&&e.content.length&&await Promise.all(e.content.map(e=>s(e,n)))):e.type===`file`&&(await f(n,await o(e.content),`utf-8`),a.files++)}return await Promise.all(i.map(t=>s(t,e))),new j.Service({relativePath:c(this.root,e),config:r,content:a,path:e,workspace:this})}catch(e){throw Error(`Failed to create widget: ${e}`)}}async findWidgets(e=this.config.data.search?.maxDepth??5,t=this.config.data.search?.ignore??[]){let n=await T(`{${Array.from({length:e},(e,t)=>`*`.repeat(t+1)).join(`,`)}}/.tixyel`,{cwd:this.root,absolute:!0,onlyFiles:!0,ignore:[`node_modules`,`.git`,`dist`,...t]});return(await Promise.all(n.map(e=>new Promise(async t=>{let n=a(e),r=await j.Service.readConfig(n);if(!r||r===null)return t(null),null;let i=new j.Service({path:n,config:r,relativePath:c(this.root,n),workspace:this});return t(i),i})))).filter(e=>e!==null)}static mergeConfig(e){let t=O;return{...e||{},search:{...t.search,...e?.search||{}},metadata:{...t.metadata,...e?.metadata||{}},dirs:{...t.dirs,...e?.dirs||{}},scaffold:e?.scaffold||t.scaffold,build:{...t.build,...e?.build||{},obfuscation:{...t.build?.obfuscation,...e?.build?.obfuscation||{}}}}}static async loadTsConfig(e,t){let a=l(e,`.temp.tixyel.config.mjs`),s=n(t,`utf-8`),c=o(t).toLowerCase(),u=c===`.tsx`?`tsx`:c===`.jsx`?`jsx`:`ts`,{code:d}=await p(s,{loader:u,format:`esm`,target:`es2022`,...u===`tsx`||u===`jsx`?{jsx:`automatic`}:{}});i(a,d,`utf-8`);try{let e=await import(`file://${a}?t=${Date.now()}`);try{r(a)}catch(e){throw Error(`Failed to clean up temporary configuration file: ${e}`)}return e.default??e.config}catch(e){throw Error(`Failed to load TypeScript workspace configuration: ${e}`)}}}t.Service=s})(M||={});export{j as n,M as t};
|