@tixyel/cli 3.1.1 → 3.2.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.mjs CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./workspace-CsM91FG0.mjs";function t(t){return e.Service.mergeConfig(t)}export{t as default,t as defineConfig};
1
+ import"./widget-DjRl-Wmr.mjs";import{t as e}from"./workspace-BBnu5Ngx.mjs";function t(t){return e.Service.mergeConfig(t)}export{t as default,t as defineConfig};
@@ -0,0 +1 @@
1
+ import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"./constants.workspace-D4p5DQV4.mjs";const c=`.tixyel`,l=[`npm`,`yarn`,`pnpm`,`bun`],u=[`@tixyel/cli`,`@tixyel/streamelements`,`comfy.js`,`motion`,`typescript`,`@types/node`,`@types/jquery`,`lottie-web`],d=[`@tixyel/cli@latest`,`@tixyel/streamelements@latest`],f={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`:``}`};export{s as DEFAULT_WORKSPACE_CONFIG,u as INITIAL_PACKAGES,f as INSTALL_COMMANDS,l as PACKAGE_MANAGERS,d as UPDATE_PACKAGES,c as WIDGET_MARKET_FILE,r as WORKSPACE_CONFIG_FILES,a as WORKSPACE_DEFAULT_IGNORE_PATTERNS,n as WORKSPACE_DEFAULT_MAX_DEPTH,e as WORKSPACE_DEFAULT_MULTIPLE_SCAFFOLD,i as WORKSPACE_DEFAULT_SCAFFOLD,o as WORKSPACE_DEFAULT_WIDGET_DIRS,t as WORKSPACE_SEARCH_LIMIT};
@@ -0,0 +1 @@
1
+ const e=3,t=50,n={entry:`development`,output:`finished`,shared:`shared`,extension:`widgetIO`},r=[`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`],i=[`node_modules`,`dist`,`build`,`out`,`coverage`,`.git`,`.svn`,`.hg`],a=[{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`}],o=[{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:`shared`,type:`folder`,content:[{name:`style.css`,type:`file`,content:``},{name:`script.js`,type:`file`,content:``}]},{name:`finished`,type:`folder`},{name:`widgetIO`,type:`folder`}],s={search:{maxDepth:3,ignore:i},dirs:n,scaffold:{single:a,multiple:a},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}};export{o as a,t as c,e as i,r as n,a as o,i as r,n as s,s as t};
package/dist/index.mjs CHANGED
@@ -1,117 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{n as e,t}from"./workspace-CsM91FG0.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
-
4
- export default defineConfig({
5
- search: {
6
- maxDepth: 3,
7
- ignore: ['node_modules', 'dist', 'build', '.git'],
8
- },
9
-
10
- metadata: {
11
- author: 'Your Name',
12
- },
13
-
14
- dirs: {
15
- entry: 'development',
16
- output: 'finished',
17
- extension: 'widgetIO',
18
- },
19
-
20
- scaffold: [
21
- {
22
- name: 'development',
23
- type: 'folder',
24
- content: [
25
- {
26
- name: 'index.html',
27
- type: 'file',
28
- content: \`\`,
29
- },
30
- {
31
- name: 'style.css',
32
- type: 'file',
33
- content: \`\`,
34
- },
35
- {
36
- name: 'script.js',
37
- type: 'file',
38
- content: \`\`,
39
- },
40
- {
41
- name: 'fields.json',
42
- type: 'file',
43
- content: '{}',
44
- },
45
- {
46
- name: 'data.json',
47
- type: 'file',
48
- content: '{}',
49
- },
50
- ],
51
- },
52
- {
53
- name: 'finished',
54
- type: 'folder',
55
- },
56
- {
57
- name: 'widgetIO',
58
- type: 'folder',
59
- },
60
- ],
61
-
62
- build: {
63
- parallel: true,
64
- verbose: false,
65
-
66
- find: {
67
- html: ['index.html'],
68
- script: ['script.js'],
69
- css: ['style.css'],
70
- fields: ['fields.json', 'fields.jsonc'],
71
- },
72
- result: {
73
- 'HTML.html': 'html',
74
- 'SCRIPT.js': 'script',
75
- 'CSS.css': 'css',
76
- 'FIELDS.json': 'fields',
77
- },
78
- widgetIO: {
79
- 'html.txt': 'html',
80
- 'js.txt': 'script',
81
- 'css.txt': 'css',
82
- 'fields.txt': 'fields',
83
- },
84
-
85
- htmlRegex: /<body[^>]*>([\\s\\S]*?)<\\/body>/i,
86
-
87
- obfuscation: {
88
- javascript: {
89
- compact: true,
90
- log: false,
91
- debugProtection: false,
92
- selfDefending: false,
93
- deadCodeInjection: false,
94
- controlFlowFlattening: false,
95
- stringArray: false,
96
- simplify: false,
97
- identifierNamesGenerator: 'mangled',
98
- },
99
- css: {
100
- removeNesting: true,
101
- autoprefixer: {
102
- overrideBrowserslist: ['Chrome 127'],
103
- },
104
- cssnano: {
105
- preset: 'default',
106
- },
107
- },
108
- html: {
109
- removeComments: true,
110
- collapseWhitespace: true,
111
- minifyCSS: true,
112
- minifyJS: true,
113
- removeAttributeQuotes: false,
114
- },
115
- },
116
- },
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{};
2
+ import{Command as e}from"commander";import{createRequire as t}from"module";import{existsSync as n,readFileSync as r,unlink as i}from"fs";import{writeFile as a}from"fs/promises";import{exec as o}from"child_process";import s,{basename as c,join as l,relative as u,resolve as d}from"path";const f=new e;f.name(`tixyel cli`).description(`CLI tool for streamelements widgets made by Tixyel`).version((()=>{try{let{version:e}=t(import.meta.url)(`../package.json`);return e??`dev`}catch{return`dev`}})()),f.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[{Workspace:t},{default:r},{default:s},{INITIAL_PACKAGES:c,INSTALL_COMMANDS:l},{WORKSPACE_CONFIG_TEMPLATE:u},{default:f},{detectPackageManager:p}]=await Promise.all([import(`./workspace-BBnu5Ngx.mjs`).then(e=>e.n),import(`ora`),import(`cli-spinners`),import(`./constants-VFBMIWoM.mjs`),import(`./workspaceConfig-BMR2fvy0.mjs`),import(`inquirer`),import(`./pm-DLnTwBIj.mjs`)]),m=r({color:`magenta`,text:`Checking for existing workspace configuration...`,spinner:s.dotsCircle}).start(),h=await new t.Service({path:process.cwd(),spinner:m}).loadConfig().catch(e=>{m.fail(`Failed to load workspace configuration`),process.exit(1)});if(h&&!e.force){m.stop();let{force:t}=await f.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,m.start()}if(!h||h&&e.force){let t=d(process.cwd(),`tixyel.config.ts`),r=u;n(t)&&h&&e.force?(i(h.path,e=>{if(e){console.error(`Failed to remove existing configuration: ${e}`);return}}),await a(t,r),m.text=`Existing configuration overwritten. Creating new workspace configuration...`):(await a(t,r),m.text=`Workspace configuration created.`)}m.succeed(`Workspace initialization complete!`);let{install:g}=await f.prompt({type:`confirm`,name:`install`,message:`Do you want to install the default dependencies now?`,default:!0});if(g){m.start(`Installing default dependencies...`);let e=p(),t=l[e](c,!1);m.text=`Installing dependencies using ${e}... It might take a few moments.`;try{await new Promise(e=>{o(t,(t,n,r)=>{if(t){m.fail(`Failed to install dependencies: ${t.message}`);return}m.succeed(`Dependencies installed successfully!`),e(n)})})}catch(e){m.fail(`Failed to execute install command: ${e}`)}}console.log(``),console.log(`🎉 Workspace setup is complete!`),console.log(` Edit ${h?.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(``)}),f.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,t,n,r,i)=>{let[{Workspace:a},{default:o},{default:s},{getNextWidgetNumber:u},{default:f}]=await Promise.all([import(`./workspace-BBnu5Ngx.mjs`).then(e=>e.n),import(`ora`),import(`cli-spinners`),import(`./widget-B5-QuDQ2.mjs`),import(`inquirer`)]),p=o({color:`magenta`,text:`Loading workspace configuration...`,spinner:s.aesthetic}).start(),m=new a.Service({path:process.cwd(),spinner:p});await m.loadConfig().catch(e=>{p.fail(`Failed to load workspace configuration`),process.exit(1)})||(p.color=`red`,p.fail(`No workspace configuration found. Please run "tixyel init" to initialize a workspace before generating a widget.`),process.exit(1)),p.text=`Generating widget...`,p.color=`green`;let h=e?d(m.root,e.replace(/[/\\]$/,``)):m.root,g=e?e.endsWith(`/`)||e.endsWith(`\\`):!1,_=t;if(g)_=c(h),h=d(h,`..`),e?.slice(0,-1);else if(!_){p.stop();let e=`${await u(h)} - Custom Widget`,{name:t}=await f.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)),_=t}if(!n){p.stop();let{description:e}=await f.prompt({name:`description`,type:`input`,message:`Enter a description for the widget:`});n=e??``}if(!r){p.stop();let{tags:e}=await f.prompt({name:`tags`,type:`input`,message:`Enter tags for the widget (comma separated):`});r=e??``}let v=i?.type;if(!v){p.stop();let{type:e}=await f.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`});v=e}let y=[];if(v===`multiple`){p.stop();let{widgets:e}=await f.prompt({name:`widgets`,type:`input`,message:`Enter the names of the widgets to create (comma separated):`,default:`main`});y=e?e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0):[],y.length||(console.log(`At least one widget name is required for multiple widget type. Widget generation aborted.`),process.exit(1))}let b=g?h:l(h,_);p.start(),p.text=`📂 Creating widget ${_} at ${b}`;let x=await m.createWidget(b,{name:_.replace(/^\d+\s*-\s*/,``),description:n,tags:r?r.split(`,`).map(e=>e.trim()):[]},{type:v,widgets:y});p.succeed(`Widget "${_}" generated successfully at ${b}`),console.log(``),x.config.description.length&&console.log(` - Description: ${x.config.description}`),x.config.metadata?.tags?.length&&console.log(` - Tags: ${x.config.metadata?.tags.join(`, `)}`),x.config.type&&console.log(` - Type: ${x.config.type}`),x.config.widgets?.length&&console.log(` - Widgets: ${x.config.widgets.join(`, `)}`),(x.content.files||x.content.folders)&&console.log(` - Scaffold created with ${x.content.folders} folders and ${x.content.files} files`),x.config.config&&console.log(` - Config path: ${x.config.config}`),console.log(``)}),f.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 e=>{let[{Workspace:t},{default:i},{default:a},{default:o},{Widget:c}]=await Promise.all([import(`./workspace-BBnu5Ngx.mjs`).then(e=>e.n),import(`ora`),import(`cli-spinners`),import(`inquirer`),import(`./widget-DjRl-Wmr.mjs`).then(e=>e.n)]),l=i({text:`Loading workspace configuration...`,color:`magenta`,spinner:a.dotsCircle}),d=new t.Service({spinner:l});if(n(`.tixyel`)&&!n(`.tixyel/`)){let e=JSON.parse(r(`.tixyel`,`utf-8`)),t=new c.Service({relativePath:u(process.cwd(),e.path),config:e,path:process.cwd(),workspace:d});t.config.config||(l.fail(`Invalid widget configuration found in .tixyel file`),process.exit(1)),d.root=s.join(process.cwd(),t.config.config),t.relativePath=u(d.root,t.path),l.succeed(`Loaded widget configuration from .tixyel file`)}l.start();let f=await d.loadConfig().catch(e=>{console.error(`Failed to load workspace configuration:`,e),process.exit(1)});f||(l.fail(`No workspace configuration found. Please run "tixyel init" to create a workspace configuration before building.`),process.exit(1));let p=f.data.search?.maxDepth;l.start(`🔎 Searching for widgets (max depth: ${p})...`);let m=await d.findWidgets(e.depth??void 0);m.length||(l.fail(`No widgets found in the workspace. Please ensure you have widgets configured correctly.`),process.exit(1));let h=[];if(e.widgets?.length&&e.widgets&&e.widgets!==void 0)e.widgets===`*`?(h=m.map(e=>e.path),l.succeed(`Auto-selected widgets for build (${h.length} widgets)`),await new Promise(e=>setTimeout(e,1e3))):(h=m.filter(t=>e.widgets.some(e=>t.config.name===e||t.path.includes(e))).map(e=>e.path),h.length||(l.fail(`No widgets matched the specified names. Please check the --widgets option and try again.`),process.exit(1)),l.text=`Selected widgets for build (${h.length} widgets)`);else if(m.length===1)h=[m[0].path],l.start(),l.succeed(`Auto-selected single widget for build: ${m[0].config.name}`);else{l.stop();let e=Math.max(...m.map(e=>e.config.name.length))+2,t=m.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 o.prompt({type:`checkbox`,name:`selected`,message:`Select which widgets to build:`,choices:t,pageSize:10,loop:!1,theme:{checkbox:{on:`[x]`,off:`[ ]`}}});h=n,l.start()}h.length||(l.isSpinning?l.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 g=`none`;if(e.bump){l.start();let t=[`none`,`patch`,`minor`,`major`];t.includes(e.bump)||(l.fail(`Invalid bump type "${e.bump}". Valid options are: ${t.join(`, `)}. Defaulting to "none".`),process.exit(1)),g=e.bump,l.succeed(`Version bump: ${g}`)}else{l.stop();let{version:e}=await o.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});g=e}let _=e.parallel??d.config.data.build?.parallel??!1,v=e.verbose??d.config.data.build?.verbose??!1;if(l.start(),l.text=`🚀 Starting build for ${h.length} widget(s) with${_?` parallel`:``} build and${v?` verbose logging`:``}...`,_)await Promise.all(h.map(async e=>new Promise(async t=>{let n=m.find(t=>t.path===e);return n&&await n.build(v,g).catch(t=>{l.fail(`Failed to build widget at '${e}': ${t}`)}),t(n),n})));else for await(let e of h){let t=m.find(t=>t.path===e);t&&(l.text=`🚀 Building widget: ${t.config.name} (${t.relativePath})...`,await t.build(v,g).catch(t=>{l.fail(`Failed to build widget at '${e}': ${t}`)}))}l.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)}),f.parse();export{};
@@ -0,0 +1 @@
1
+ function e(){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`}export{e as detectPackageManager};
@@ -0,0 +1 @@
1
+ var e=Object.defineProperty,t=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r};export{t};
@@ -0,0 +1 @@
1
+ import{existsSync as e,readdirSync as t}from"fs";async function n(n){try{if(!e(n))return`01`;let r=t(n).filter(e=>/^\d+\s*-\s*/.test(e)).map(e=>parseInt(e.split(`-`)[0],10)).filter(e=>!isNaN(e)),i=r.length>0?Math.max(...r):0;return String(i+1).padStart(2,`0`)}catch{return`01`}}export{n as getNextWidgetNumber};
@@ -0,0 +1,33 @@
1
+ import{t as e}from"./rolldown-runtime-DR3Ue2cl.mjs";import{t}from"./constants.workspace-D4p5DQV4.mjs";import{existsSync as n,mkdirSync as r,readFileSync as i,readdirSync as a,writeFileSync as o}from"fs";import{readFile as s,writeFile as c}from"fs/promises";import{basename as l,join as u,resolve as d}from"path";import{transformSync as f}from"esbuild";import{parse as p}from"jsonc-parser";import m from"postcss";import h from"cssnano";import g from"jszip";import _ from"postcss-nested";import v from"autoprefixer";import{minify as y}from"html-minifier-terser";import b from"javascript-obfuscator";var x=` ____ _ _ _
2
+ / __ \\ | |_ (_) __ __ _ _ ___ | |
3
+ / / _\` | | __| | | \\ \\/ / | | | | / _ \\ | |
4
+ | | (_| | | |_ | | > < | |_| | | __/ | |
5
+ \\ \\__,_| \\__| |_| /_/\\_\\ \\__, | \\___| |_|
6
+ \\____/ |___/
7
+ `;const S={html(e){return[`<!---`,x,`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[`/**`,x,`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[`/**`,x,`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
+ `)}};var C=e({Widget:()=>w});let w;(function(e){class x{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(e=this.workspace.config.data.build?.verbose??!1,s=`none`){if(s!==`none`){let t=await this.bumpVersion(s);this.spinner&&this.spinner.isSpinning&&e&&(this.spinner.text=`Building widget ${this.config.name} (version bumped to ${t})...`)}try{let s=u(this.path,this.config.dirs?.entry??this.workspace.config.data.dirs?.entry??`development`),c=u(this.path,this.config.dirs?.output??this.workspace.config.data.dirs?.output??`finished`),d=u(this.path,this.config.dirs?.shared??this.workspace.config.data.dirs?.shared??`shared`),x=u(this.path,this.config.dirs?.extension??this.workspace.config.data.dirs?.extension??`widgetIO`);if(!n(s))throw Error(`Entry directory does not exist: ${s}`);r(c,{recursive:!0}),r(x,{recursive:!0});let C=this.config.build?.find??this.workspace.config.data.build?.find??t.build?.find,w=this.config.build?.shared??this.workspace.config.data.build?.shared??t.build?.shared,T=this.config.build?.result??this.workspace.config.data.build?.result??t.build?.result,E=this.config.build?.widgetIO??this.workspace.config.data.build?.widgetIO??t.build?.widgetIO,D=e=>Array.isArray(e)?e.filter(Boolean):[],O=(e,t)=>{let r={};for(let a of t){let t=u(e,a);n(t)&&(r[a]=i(t,`utf-8`))}return r},k=Object.entries(w).reduce((e,[t,n])=>(e[t]=n.map(e=>`../../${l(d)}/${e}`),e),{}),A=async(n,i,a)=>{let s=new Set,c=new Set,l=Object.fromEntries(await Promise.all(Object.entries({...C,...k}).map(async([r,i])=>{let a=``,o=D(i.filter(e=>!c.has(e)));if(!o.length)return[r,``];let s=(e,t)=>(!Array.isArray(e)&&(e=[e]),!Array.isArray(t)&&(t=[t]),e.some(e=>r.toLowerCase().includes(e.toLowerCase()))||o.some(e=>t.some(t=>e.toLowerCase().endsWith(t.toLowerCase())))),l=new Set;if(s(`html`,`.html`)){let i=o.filter(e=>e.endsWith(`.html`)&&!c.has(e));if(i.length){e&&console.log(` - Processing HTML for ${this.config.name} [${r}, ${i.join(`, `)}]...`);let o=O(n,i),s=``;for await(let[e,n]of Object.entries(o)){let r=n.match(this.workspace.config.data.build?.htmlRegex??t.build?.htmlRegex);r&&r[1]&&(s+=r[1].trim()+`
11
+ `,c.add(e))}let u=await y(s,this.workspace.config.data.build?.obfuscation?.html);a+=u.trim(),l.add(`html`)}}if(s([`css`,`style`,`styles`],`.css`)){let t=o.filter(e=>e.endsWith(`.css`)&&!c.has(e));if(t.length){e&&console.log(` - Processing CSS for ${this.config.name} [${r}, ${t.join(`, `)}]...`);let i=O(n,t),o=Object.values(i).filter(Boolean),s=``;for await(let e of o){let t=[v({overrideBrowserslist:[`Chrome 127`],...this.workspace.config.data.build?.obfuscation?.css?.autoprefixer}),h(this.workspace.config.data.build?.obfuscation?.css?.cssnano)];this.workspace.config.data.build?.obfuscation?.css?.removeNesting&&t.unshift(_());let n=await m(t).process(e,{from:void 0});s+=n.css+`
12
+ `}for(let e of Object.keys(i))c.add(e);l.has(`html`)?a=a+=`<style>${s.trim()}</style>`:a+=s.trim(),l.add(`css`)}}if(s([`typescript`,`ts`],[`.ts`,`.tsx`,`.cts`,`.mts`])){let t=o.filter(e=>e.endsWith(`.ts`)&&!c.has(e));if(t.length){e&&console.log(` - Processing TypeScript for ${this.config.name} [${r}, ${t.join(`, `)}]...`);let i=O(n,t),o=``;for await(let[e,t]of Object.entries(i))try{let e=f(t,{loader:`ts`,target:`es2020`,format:`cjs`});o+=e.code+`
13
+ `}catch(e){throw console.warn(` ⚠️ Failed to compile TypeScript: ${e}`),e}finally{c.add(e)}let s=b.obfuscate(o.trim(),this.workspace.config.data.build?.obfuscation?.javascript);l.has(`html`)?a=a+=`<script>${s.getObfuscatedCode()}<\/script>\n`:a+=s.getObfuscatedCode()+`
14
+ `,l.add(`typescript`)}}if(s([`script`,`js`,`javascript`],[`.js`,`.mjs`,`.cjs`,`.jsx`])){let t=o.filter(e=>e.endsWith(`.js`)&&!c.has(e));if(t.length){e&&console.log(` - Processing JavaScript for ${this.config.name} [${r}, ${t.join(`, `)}]...`);let i=O(n,t),o=``;for await(let[e,t]of Object.entries(i)){let n=b.obfuscate(t,this.workspace.config.data.build?.obfuscation?.javascript);o+=n.getObfuscatedCode()+`
15
+ `,c.add(e)}l.has(`html`)?a=a+=`<script>${o.trim()}<\/script>`:a+=o.trim(),l.add(`script`)}}if(s([`fields`,`fielddata`,`fieldData`,`cf`,`customfields`],[`.json`,`.jsonc`])){let t=o.filter(e=>(e.endsWith(`.json`)||e.endsWith(`.jsonc`))&&!c.has(e));if(t.length){e&&console.log(` - Processing JSON for ${this.config.name} [${r}, ${t.join(`, `)}]...`);let i=O(n,t),o={};for await(let[e,t]of Object.entries(i)){try{let e=p(t),n=JSON.parse(JSON.stringify(e));Object.assign(o,n)}catch(e){throw console.warn(` ⚠️ Failed to parse fields JSON: ${e}`),e}c.add(e)}l.has(`fields`)||(a+=JSON.stringify(o,null,2)),l.add(`fields`)}}return a.length||(e&&console.log(` - Unknown build key: ${r}, the available keys are html, css, script and fields.`),a+=``),[r,a]})));for await(let[t,n]of Object.entries(T)){let r=``,a=Array.isArray(n)?n:[n];if(a.some(e=>e.includes(`script`))?(s.has(`script`)||(r+=S.script(this)+`
16
+ `),s.add(`script`)):a.some(e=>e.includes(`css`))?(s.has(`css`)||(r+=S.css(this)+`
17
+ `),s.add(`css`)):a.some(e=>e.includes(`html`))&&(s.has(`html`)||(r+=S.html(this)+`
18
+ `),s.add(`html`)),typeof n==`string`)r=l[n];else if(Array.isArray(n))for await(let t of n){let n=l[t];if(n&&n.trim().length){if([`fields`,`customfields`,`cf`,`fielddata`,`fieldData`,`data`].some(e=>t.toLowerCase().includes(e.toLowerCase()))){let e=JSON.parse(r||`{}`),t=JSON.parse(n);r=JSON.stringify({...e,...t},null,2)}else r+=`
19
+ `+n.trim();e&&console.log(` ✓ Merged part for: ${t}`)}}if(r=r.trim(),r){let n=u(i,t);o(n,r,`utf-8`),e&&console.log(` ✓ Written: ${n}`)}}try{let t=new g;for await(let[n,r]of Object.entries(E)){let i=``;if(typeof r==`string`)i=l[r];else if(Array.isArray(r))for await(let t of r){let n=l[t];n&&n.trim().length&&(i+=`
20
+ `+n.trim(),e&&console.log(` ✓ Merged part for ZIP: ${t}`))}i&&(t.file(n,i),e&&console.log(` ✓ Added to ZIP: ${n}`))}t.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=l.data||`{}`;t.file(`data.txt`,n);let i=await t.generateInternalStream({type:`base64`}).accumulate().then(e=>e),s=u(x+`/`+(this.config.version||`0.0.0`),`${a??this.config.name}.zip`);r(x+`/`+(this.config.version||`0.0.0`),{recursive:!0}),o(s,i,`base64`)}catch(e){throw Error(`Failed to create ZIP archive: ${e}`)}};if(this.config.type===`multiple`){let t=(this.config.widgets??[]).filter(Boolean),i=a(s,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name),o=t.length?t:i;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 l=0;for await(let t of o){let i=u(s,t),a=u(c,t);if(!n(i)&&e){console.warn(` ⚠️ Skipping widget "${t}" because the entry directory does not exist: ${i}`);continue}r(a,{recursive:!0}),await A(i,a,`${this.config.name}-${t}`),l++}if(!l)throw Error(`No valid widgets were built for multiple widget configuration. Please check the entry directory and configuration.`)}else await A(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 c(t,JSON.stringify(n,null,2),`utf-8`),o}static async readConfig(e){try{let t=d(e,`.tixyel`);if(!n(t))return null;let r=p(await s(t,`utf-8`));return typeof r!=`object`||!r||r===null||!r?.name||typeof r.name!=`string`||!r.name.trim().length?null:x.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}}}e.Service=x})(w||={});export{C as n,w as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./rolldown-runtime-DR3Ue2cl.mjs";import{n as t,t as n}from"./constants.workspace-D4p5DQV4.mjs";import{t as r}from"./widget-DjRl-Wmr.mjs";import{existsSync as i,readFileSync as a,unlinkSync as o,writeFileSync as s}from"fs";import{mkdir as c,writeFile as l}from"fs/promises";import{dirname as u,extname as d,relative as f,resolve as p}from"path";import{transform as m}from"esbuild";import{renderToStaticMarkup as h}from"react-dom/server";import{isValidElement as g}from"react";import _ from"fast-glob";var v=e({Workspace:()=>y});let y;(function(e){class v{constructor(e){this.root=e?.path??process.cwd(),this.config=e?.config??{data:n,path:this.root,file:`tixyel.config.ts`},this.spinner=e?.spinner}async loadConfig(){let e=t.find(e=>i(p(this.root,e)));if(!e)return null;let n,r=p(this.root,e);try{if(e.endsWith(`.ts`)||e.endsWith(`.tsx`))n=await v.loadTsConfig(this.root,r);else if(e.endsWith(`.js`)||e.endsWith(`.mjs`)||e.endsWith(`.cjs`)){let e=await import(r);n=e.default??e.config}else if(e.endsWith(`.json`)||e.endsWith(`.jsonc`)||e===`.tixyelrc`){let e=a(r,`utf-8`);n=JSON.parse(e)}else throw Error(`Unsupported configuration file format: ${e}`)}catch(e){throw Error(`Failed to load workspace configuration: ${e}`)}finally{if(!n)return null;n=v.mergeConfig(n);let t={data:n,path:r,file:e};return this.config=t,t}}async createWidget(e,t,n){try{await c(e,{recursive:!0});let i=f(e,this.config.path).replace(/\\/g,`/`),a={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:i.startsWith(`.`)?i:`./${i}`,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 l(p(e,`.tixyel`),JSON.stringify(a,null,2),`utf-8`);let{single:o=this.config.data.scaffold?.single??[],multiple:s=this.config.data.scaffold?.multiple??[]}=this.config.data.scaffold??{},u={files:0,folders:0};async function d(e,t){let n=p(t,e.name);if(e.type===`folder`){if(await c(n,{recursive:!0}),u.folders++,!e.content||!Array.isArray(e.content)||!e.content.length)return;a.type===`multiple`&&e.name===(a.dirs?.entry??`development`)&&a.widgets?.length?await Promise.all(a.widgets.map(t=>new Promise(async r=>{let i=p(n,t);await c(i,{recursive:!0}),u.folders++,await Promise.all(e.content.map(e=>d(e,i))),r(i)}))):await Promise.all(e.content.map(e=>d(e,n)))}else if(e.type===`file`){let t=e.content;t===void 0||t===void 0||!t?t=``:typeof t==`string`?t=t:g(t)&&(t=h(t)),await l(n,String(t??``),`utf-8`),u.files++}}return await Promise.all((a.type===`single`?o:s).map(t=>d(t,e))),new r.Service({relativePath:f(this.root,e),config:a,content:u,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 _(`{${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=u(e),i=await r.Service.readConfig(n);if(!i||i===null)return t(null),null;let a=new r.Service({path:n,config:i,relativePath:f(this.root,n),workspace:this});return t(a),a})))).filter(e=>e!==null)}static mergeConfig(e){let t=n;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 n=p(e,`.temp.tixyel.config.mjs`),r=a(t,`utf-8`),i=d(t).toLowerCase(),c=i===`.tsx`?`tsx`:i===`.jsx`?`jsx`:`ts`,{code:l}=await m(r,{loader:c,format:`esm`,target:`es2022`,...c===`tsx`||c===`jsx`?{jsx:`automatic`}:{}});s(n,l,`utf-8`);try{let e=await import(`file://${n}?t=${Date.now()}`);try{o(n)}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}`)}}}e.Service=v})(y||={});export{v as n,y as t};
@@ -0,0 +1,116 @@
1
+ const e=`import { defineConfig } from '@tixyel/cli/api';
2
+
3
+ export default defineConfig({
4
+ search: {
5
+ maxDepth: 3,
6
+ ignore: ['node_modules', 'dist', 'build', '.git'],
7
+ },
8
+
9
+ metadata: {
10
+ author: 'Your Name',
11
+ },
12
+
13
+ dirs: {
14
+ entry: 'development',
15
+ output: 'finished',
16
+ extension: 'widgetIO',
17
+ },
18
+
19
+ scaffold: [
20
+ {
21
+ name: 'development',
22
+ type: 'folder',
23
+ content: [
24
+ {
25
+ name: 'index.html',
26
+ type: 'file',
27
+ content: \`\`,
28
+ },
29
+ {
30
+ name: 'style.css',
31
+ type: 'file',
32
+ content: \`\`,
33
+ },
34
+ {
35
+ name: 'script.js',
36
+ type: 'file',
37
+ content: \`\`,
38
+ },
39
+ {
40
+ name: 'fields.json',
41
+ type: 'file',
42
+ content: '{}',
43
+ },
44
+ {
45
+ name: 'data.json',
46
+ type: 'file',
47
+ content: '{}',
48
+ },
49
+ ],
50
+ },
51
+ {
52
+ name: 'finished',
53
+ type: 'folder',
54
+ },
55
+ {
56
+ name: 'widgetIO',
57
+ type: 'folder',
58
+ },
59
+ ],
60
+
61
+ build: {
62
+ parallel: true,
63
+ verbose: false,
64
+
65
+ find: {
66
+ html: ['index.html'],
67
+ script: ['script.js'],
68
+ css: ['style.css'],
69
+ fields: ['fields.json', 'fields.jsonc'],
70
+ },
71
+ result: {
72
+ 'HTML.html': 'html',
73
+ 'SCRIPT.js': 'script',
74
+ 'CSS.css': 'css',
75
+ 'FIELDS.json': 'fields',
76
+ },
77
+ widgetIO: {
78
+ 'html.txt': 'html',
79
+ 'js.txt': 'script',
80
+ 'css.txt': 'css',
81
+ 'fields.txt': 'fields',
82
+ },
83
+
84
+ htmlRegex: /<body[^>]*>([\\s\\S]*?)<\\/body>/i,
85
+
86
+ obfuscation: {
87
+ javascript: {
88
+ compact: true,
89
+ log: false,
90
+ debugProtection: false,
91
+ selfDefending: false,
92
+ deadCodeInjection: false,
93
+ controlFlowFlattening: false,
94
+ stringArray: false,
95
+ simplify: false,
96
+ identifierNamesGenerator: 'mangled',
97
+ },
98
+ css: {
99
+ removeNesting: true,
100
+ autoprefixer: {
101
+ overrideBrowserslist: ['Chrome 127'],
102
+ },
103
+ cssnano: {
104
+ preset: 'default',
105
+ },
106
+ },
107
+ html: {
108
+ removeComments: true,
109
+ collapseWhitespace: true,
110
+ minifyCSS: true,
111
+ minifyJS: true,
112
+ removeAttributeQuotes: false,
113
+ },
114
+ },
115
+ },
116
+ });`;export{e as WORKSPACE_CONFIG_TEMPLATE};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tixyel/cli",
3
- "version": "3.1.1",
3
+ "version": "3.2.0",
4
4
  "description": "CLI tool for streamelements widgets",
5
5
  "keywords": [
6
6
  "cli",
@@ -1,33 +0,0 @@
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`)||(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};