phala 0.0.1-alpha
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/LICENSE +13 -0
- package/README.md +762 -0
- package/dist/chunk-A4IAJHG6.js +2 -0
- package/dist/chunk-A4IAJHG6.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +114 -0
- package/dist/index.js.map +1 -0
- package/dist/logger-LBGFMBSV.js +2 -0
- package/dist/logger-LBGFMBSV.js.map +1 -0
- package/package.json +73 -0
@@ -0,0 +1,2 @@
|
|
1
|
+
var B=Object.defineProperty;var I=(e,r,c)=>r in e?B(e,r,{enumerable:!0,configurable:!0,writable:!0,value:c}):e[r]=c;var N=(e,r,c)=>(I(e,typeof r!="symbol"?r+"":r,c),c);import y from"chalk";function A(e,r){if(!e)return[""];if(e.length<=r)return[e];let c=[],a="",m=e.split(/(\s+)/).filter(u=>u.trim().length>0);for(let u of m){if(u.length>r){a&&(c.push(a),a="");for(let l=0;l<u.length;l+=r)c.push(u.slice(l,l+r));continue}a.length+u.length+1>r?(c.push(a),a=u):a=a?`${a} ${u}`:u}return a&&c.push(a),c}var _={error:(e,...r)=>{console.error(y.red("\u2717"),y.red(e),...r)},warn:(e,...r)=>{console.log(y.yellow("\u26A0"),y.yellow(e),...r)},info:(e,...r)=>{console.log(y.blue("\u2139"),y.blue(e),...r)},success:(e,...r)=>{console.log(y.green("\u2713"),y.green(e),...r)},debug:(e,...r)=>{process.env.DEBUG&&console.log(y.gray("\u{1F50D}"),y.gray(e),...r)},table:(e,r)=>{if(e.length===0){console.log(y.yellow("No data to display"));return}if(r)if(typeof r[0]=="string"){let c=r.map(a=>({key:a,header:a.charAt(0).toUpperCase()+a.slice(1)}));E(e,{columns:c,borderStyle:"rounded",headerStyle:a=>y.cyan.bold(a)})}else E(e,{columns:r,borderStyle:"rounded",headerStyle:c=>y.cyan.bold(c)});else E(e,{borderStyle:"rounded",headerStyle:c=>y.cyan.bold(c)})},keyValueTable:(e,r)=>{let a={...{keyHeader:"Property",valueHeader:"Value",borderStyle:"rounded",enableTextWrapping:!0,maxDepth:2,formatKeys:!0,keyFormatter:f=>{let T=["URL","ID","API","UI","URI","CPU","GPU","RAM","JSON","XML","HTML","HTTP","HTTPS","SSH","FTP","IP","TCP","UDP","DNS","SSL","TLS","SQL","VCPU","CVM","TEE","IO"],W={teepod:"TEEPod",dstack:"Dstack"},w;f.includes("_")?w=f.split("_").map($=>$.charAt(0).toUpperCase()+$.slice(1).toLowerCase()).join(" "):f.includes("-")?w=f.split("-").map($=>$.charAt(0).toUpperCase()+$.slice(1).toLowerCase()).join(" "):w=f.charAt(0).toUpperCase()+f.slice(1).replace(/([a-z])([A-Z])/g,"$1 $2");for(let $ of T){let L=new RegExp(`\\b${$.toLowerCase()}\\b`,"gi");w=w.replace(L,$)}for(let[$,L]of Object.entries(W)){let j=new RegExp(`\\b${$}\\b`,"gi");w=w.replace(j,L)}return w},valueFormatter:f=>String(f??"")},...r},{include:m,exclude:u,keyFormatter:l,valueFormatter:S,formatKeys:x,keyHeader:b,valueHeader:v,keyWidth:C,valueWidth:o,borderStyle:n,enableTextWrapping:i,maxDepth:s}=a,d=Object.keys(e);if(m&&(d=d.filter(f=>m.includes(f))),u&&(d=d.filter(f=>!u.includes(f))),d.length===0){console.log(y.yellow("No properties to display"));return}let t=d.map(f=>{let T=e[f],W;return T==null?W="":typeof T=="object"&&!Array.isArray(T)?W=z(T,0,s):Array.isArray(T)?T.length===0?W="[]":typeof T[0]=="object"?W=`[${T.length} items]`:W=`[${T.join(", ")}]`:W=String(T),S&&(W=S(T,f)),{key:x&&l?l(f):f,value:W}}),g=H(),p=C,k=o;p||(p=Math.max(b.length,...t.map(f=>f.key.length),10),p=Math.min(p,Math.floor(g/3))),k||(k=g-p-7);let h=D(n),R=`${h.topLeft}${h.horizontal.repeat(p+2)}${h.topT}${h.horizontal.repeat(k+2)}${h.topRight}`,U=`${h.vertical} ${y.bold(b.padEnd(p))} ${h.vertical} ${y.bold(v.padEnd(k))} ${h.vertical}`,O=`${h.leftT}${h.horizontal.repeat(p+2)}${h.cross}${h.horizontal.repeat(k+2)}${h.rightT}`;console.log(R),console.log(U),console.log(O),t.forEach((f,T)=>{let W=i?A(f.key,p):[f.key],w=i?A(f.value,k):[f.value],$=Math.max(W.length,w.length);for(let L=0;L<$;L++){let j=(W[L]||"").padEnd(p),P=(w[L]||"").padEnd(k);console.log(`${h.vertical} ${j} ${h.vertical} ${P} ${h.vertical}`)}T<t.length-1&&console.log(`${h.leftT}${h.horizontal.repeat(p+2)}${h.cross}${h.horizontal.repeat(k+2)}${h.rightT}`)});let V=`${h.bottomLeft}${h.horizontal.repeat(p+2)}${h.bottomT}${h.horizontal.repeat(k+2)}${h.bottomRight}`;console.log(V)},startSpinner:e=>(process.stdout.write(`${y.blue("\u27F3")} ${e}... `),{stop:(r=!0,c)=>{let a=r?y.green("\u2713"):y.red("\u2717"),m=c?`: ${c}`:"";console.log(`${a}${m}`)}}),break(){console.log("")}};function z(e,r,c){if(r>=c)return"[Nested Object]";if(e==null)return"";if(Array.isArray(e))return e.length===0?"[]":`[${e.length} items]`;let a=[];for(let[m,u]of Object.entries(e))u==null?a.push(`${m}: `):typeof u=="object"?a.push(`${m}: ${z(u,r+1,c)}`):a.push(`${m}: ${u}`);return a.join(", ")}function D(e="single"){return{single:{topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"},double:{topLeft:"\u2554",topRight:"\u2557",bottomLeft:"\u255A",bottomRight:"\u255D",horizontal:"\u2550",vertical:"\u2551",leftT:"\u2560",rightT:"\u2563",topT:"\u2566",bottomT:"\u2569",cross:"\u256C"},rounded:{topLeft:"\u256D",topRight:"\u256E",bottomLeft:"\u2570",bottomRight:"\u256F",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"}}[e]}function H(){return process.stdout.columns||80}function M(e,r,c={}){let a=H(),m=c.borderChars??3,l=(c.additionalBorderWidth??1)+r.length*m,S=a-l,x={},b=0,v=0;for(let n of r){let i=n.key;if(n.fixedWidth!==void 0){x[i]=n.fixedWidth,b+=n.fixedWidth;continue}let s=n.minWidth??n.header.length,d;n.getWidth?d=Math.max(s,n.header.length,...e.map(t=>n.getWidth(t))):n.getValue?d=Math.max(s,n.header.length,...e.map(t=>String(n.getValue(t)||"").length)):d=Math.max(s,n.header.length,...e.map(t=>String(t[n.key]||"").length)),x[i]=d,b+=d,v+=n.weight??1}let C=Math.max(0,S-b);if(C>0&&v>0)for(let n of r){let i=n.key;if(n.fixedWidth===void 0&&n.weight){let s=Math.floor(C*(n.weight/v));x[i]+=s}}let o=Object.values(x).reduce((n,i)=>n+i,0)+l;if(o>a){let n=S/(o-l),i={};for(let s of r){let d=s.key,t=s.minWidth??s.header.length;i[d]=Math.max(t,Math.floor(x[d]*n))}return i}return x}function G(e){return M(e,[{key:"name",header:"Name",minWidth:10},{key:"status",header:"Status",minWidth:6},{key:"appId",header:"App ID",minWidth:8,weight:1},{key:"appUrl",header:"App URL",minWidth:7,weight:2}],{borderChars:3,additionalBorderWidth:1})}function Z(e,r){let c=r.map((u,l)=>({key:`col_${l}`,header:u.header,minWidth:u.minWidth,weight:u.weight,getValue:u.accessor})),a=M(e,c,{borderChars:3,additionalBorderWidth:1}),m={};return r.forEach((u,l)=>{m[u.key]=a[`col_${l}`]}),m}function E(e,r={}){if(r.keyValueMode&&e.length===1){let o=e[0],n=[];r.columns||(r.columns=Object.keys(o).map(i=>({key:i,header:i.charAt(0).toUpperCase()+i.slice(1).replace(/([A-Z])/g," $1")})));for(let i of r.columns){let s=String(i.key),d;if(i.accessor)d=i.accessor(o);else if(typeof i.key=="string"&&i.key.includes(".")){let t=i.key.split("."),g=o;for(let p of t){if(g==null){d="";break}g=g[p]}d=g}else d=o[i.key];i.formatter&&(d=i.formatter(d)),n.push({key:i.header||s,value:d})}e=n,r.columns=[{key:"key",header:"Property",minWidth:15},{key:"value",header:"Value",minWidth:20}]}if(e.length===0){console.log(y.yellow("No data to display"));return}let a={...{includeHeaders:!0,border:!0,borderStyle:"single",headerStyle:o=>y.bold(o),cellStyle:o=>o,enableTextWrapping:!0},...r},m=a.columns;if(m)m=m.map(o=>({...o,enableTextWrapping:o.enableTextWrapping!==void 0?o.enableTextWrapping:a.enableTextWrapping}));else{let o=e[0];m=Object.keys(o).map(n=>({key:n,header:n.charAt(0).toUpperCase()+n.slice(1),enableTextWrapping:a.enableTextWrapping}))}let l={single:{topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"},double:{topLeft:"\u2554",topRight:"\u2557",bottomLeft:"\u255A",bottomRight:"\u255D",horizontal:"\u2550",vertical:"\u2551",leftT:"\u2560",rightT:"\u2563",topT:"\u2566",bottomT:"\u2569",cross:"\u256C"},rounded:{topLeft:"\u256D",topRight:"\u256E",bottomLeft:"\u2570",bottomRight:"\u256F",horizontal:"\u2500",vertical:"\u2502",leftT:"\u251C",rightT:"\u2524",topT:"\u252C",bottomT:"\u2534",cross:"\u253C"}}[a.borderStyle],S=m.map(o=>({key:o.key,header:o.header||String(o.key),minWidth:o.minWidth||3,weight:o.weight,enableTextWrapping:o.enableTextWrapping,getValue:o.accessor?n=>o.accessor(n):n=>{if(typeof o.key=="string"&&o.key.includes(".")){let i=o.key.split("."),s=n;for(let d of i){if(s==null)return"";s=s[d]}return s??""}return n[o.key]??""}})),x=M(e,S),b=m.map((o,n)=>({...o,width:x[S[n].key]})),v=b.map(o=>o.header||String(o.key)),C=(o,n)=>{let i=b.map(t=>{let g;if(t.accessor)g=t.accessor(o);else if(typeof t.key=="string"&&t.key.includes(".")){let k=t.key.split("."),h=o;for(let R of k){if(h==null){g="";break}h=h[R]}g=h??""}else g=o[t.key]??"";let p=t.formatter?t.formatter(g):String(g||"");return t.enableTextWrapping?{lines:A(p,t.width),key:String(t.key)}:{lines:[p.length>t.width?p.substring(0,t.width-1)+"\u2026":p],key:String(t.key)}}),s=Math.max(...i.map(t=>t.lines.length)),d=[];for(let t=0;t<s;t++){let g=i.map((p,k)=>{let h=p.lines[t]||"";return a.cellStyle(h.padEnd(b[k].width),n,p.key)});d.push(g)}return d};if(a.border){let o=l.topLeft+b.map(i=>l.horizontal.repeat(i.width+2)).join(l.topT)+l.topRight;if(console.log(o),a.includeHeaders){let i=b.map((t,g)=>({lines:t.enableTextWrapping?A(v[g],t.width):[v[g]],width:t.width})),s=Math.max(...i.map(t=>t.lines.length));for(let t=0;t<s;t++){let g=l.vertical+i.map(p=>{let k=p.lines[t]||"";return" "+a.headerStyle(k.padEnd(p.width))+" "}).join(l.vertical)+l.vertical;console.log(g)}let d=l.leftT+b.map(t=>l.horizontal.repeat(t.width+2)).join(l.cross)+l.rightT;console.log(d)}e.forEach((i,s)=>{let d=C(i,s);if(d.forEach(t=>{console.log(l.vertical+t.map(g=>` ${g} `).join(l.vertical)+l.vertical)}),s<e.length-1&&d.length>1){let t=l.leftT+b.map(g=>l.horizontal.repeat(g.width+2)).join(l.cross)+l.rightT;console.log(t)}});let n=l.bottomLeft+b.map(i=>l.horizontal.repeat(i.width+2)).join(l.bottomT)+l.bottomRight;console.log(n)}else{if(a.includeHeaders){let o=b.map((s,d)=>({lines:s.enableTextWrapping?A(v[d],s.width):[v[d]],width:s.width})),n=Math.max(...o.map(s=>s.lines.length));for(let s=0;s<n;s++){let d=o.map(t=>{let g=t.lines[s]||"";return a.headerStyle(g.padEnd(t.width))}).join(" ");console.log(d)}let i=b.map(s=>"\u2500".repeat(s.width)).join(" ");console.log(i)}e.forEach((o,n)=>{let i=C(o,n);i.forEach(s=>{console.log(s.join(" "))}),n<e.length-1&&i.length>1&&console.log("")})}console.log(`Total: ${e.length} rows`)}export{N as a,_ as b,M as c,G as d,Z as e,E as f};
|
2
|
+
//# sourceMappingURL=chunk-A4IAJHG6.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../src/utils/logger.ts"],"sourcesContent":["import chalk from \"chalk\"\n\n/**\n * Wraps text to fit within a specified width\n * @param text Text to wrap\n * @param maxWidth Maximum width for the text\n * @returns Array of lines of text\n */\nfunction wrapText(text: string, maxWidth: number): string[] {\n if (!text) return [''];\n \n // Handle case where a single word is longer than maxWidth\n if (text.length <= maxWidth) return [text];\n \n const lines: string[] = [];\n let currentLine = '';\n \n // Split by any whitespace and preserve URLs\n const words = text.split(/(\\s+)/).filter(word => word.trim().length > 0);\n \n for (const word of words) {\n // If the word itself is longer than maxWidth, split it\n if (word.length > maxWidth) {\n if (currentLine) {\n lines.push(currentLine);\n currentLine = '';\n }\n for (let i = 0; i < word.length; i += maxWidth) {\n lines.push(word.slice(i, i + maxWidth));\n }\n continue;\n }\n \n // If adding the word would exceed maxWidth\n if (currentLine.length + word.length + 1 > maxWidth) {\n lines.push(currentLine);\n currentLine = word;\n } else {\n // Add word to current line\n currentLine = currentLine ? `${currentLine} ${word}` : word;\n }\n }\n \n if (currentLine) {\n lines.push(currentLine);\n }\n \n return lines;\n}\n\nexport const logger = {\n error: (message: string, ...args: any[]) => {\n console.error(chalk.red('✗'), chalk.red(message), ...args)\n },\n warn: (message: string, ...args: any[]) => {\n console.log(chalk.yellow('⚠'), chalk.yellow(message), ...args)\n },\n info: (message: string, ...args: any[]) => {\n console.log(chalk.blue('ℹ'), chalk.blue(message), ...args)\n },\n success: (message: string, ...args: any[]) => {\n console.log(chalk.green('✓'), chalk.green(message), ...args)\n },\n debug: (message: string, ...args: any[]) => {\n if (process.env.DEBUG) {\n console.log(chalk.gray('🔍'), chalk.gray(message), ...args)\n }\n },\n table: <T>(\n data: T[], \n columns?: Array<string> | Array<{ key: keyof T | string, header?: string }> | Array<any>\n ) => {\n if (data.length === 0) {\n console.log(chalk.yellow('No data to display'));\n return;\n }\n \n // Support for old API with just column names\n if (columns) {\n if (typeof columns[0] === 'string') {\n // Convert simple string array to column config\n const columnConfig = (columns as string[]).map(col => ({\n key: col,\n header: col.charAt(0).toUpperCase() + col.slice(1) // Capitalize\n }));\n \n // Filter data to only include specified columns\n formatTable(data, { \n columns: columnConfig,\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n } else {\n // Using the new column config format\n formatTable(data, { \n columns: columns as Array<{ key: keyof T | string, header?: string }>,\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n }\n } else {\n // No columns specified, show all\n formatTable(data, {\n borderStyle: 'rounded',\n headerStyle: (text) => chalk.cyan.bold(text)\n });\n }\n },\n /**\n * Displays an object's properties in a key-value table format (vertical table)\n * @param data Object to display\n * @param options Table display options\n */\n keyValueTable: <T extends object>(\n data: T,\n options?: {\n include?: string[]; // Optional list of keys to include\n exclude?: string[]; // Optional list of keys to exclude\n keyFormatter?: (key: string) => string; // Optional formatter for keys\n valueFormatter?: (value: any, key: string) => string; // Optional formatter for values\n formatKeys?: boolean; // Whether to format keys (default: true)\n keyHeader?: string; // Optional header for the key column\n valueHeader?: string; // Optional header for the value column\n keyWidth?: number; // Optional fixed width for the key column\n valueWidth?: number; // Optional fixed width for the value column\n borderStyle?: 'single' | 'double' | 'rounded'; // Border style\n enableTextWrapping?: boolean; // Whether to wrap text\n maxDepth?: number; // Maximum depth for nested objects (default: 2)\n }\n ) => {\n // Default options\n const defaultOptions = {\n keyHeader: 'Property',\n valueHeader: 'Value',\n borderStyle: 'rounded' as const,\n enableTextWrapping: true,\n maxDepth: 2,\n formatKeys: true,\n // Improved key formatter with different formatting options\n keyFormatter: (key: string) => {\n // Common acronyms that should remain uppercase\n const commonAcronyms = [\n 'URL', 'ID', 'API', 'UI', 'URI', 'CPU', 'GPU', 'RAM', 'JSON', 'XML', 'HTML', \n 'HTTP', 'HTTPS', 'SSH', 'FTP', 'IP', 'TCP', 'UDP', 'DNS', 'SSL', 'TLS', 'SQL', \n 'VCPU', 'CVM', 'TEE', 'IO'\n ];\n \n // Phala-specific terms with custom capitalization\n const customTerms = {\n 'teepod': 'TEEPod',\n 'dstack': 'Dstack'\n };\n \n // Handle different cases\n let formatted;\n \n if (key.includes('_')) {\n // Handle snake_case: convert app_url to App Url\n formatted = key.split('_')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join(' ');\n } else if (key.includes('-')) {\n // Handle kebab-case: convert app-url to App Url\n formatted = key.split('-')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join(' ');\n } else {\n // Handle camelCase: convert appUrl to App Url\n formatted = key.charAt(0).toUpperCase() + \n key.slice(1).replace(/([a-z])([A-Z])/g, '$1 $2');\n }\n \n // Replace common acronyms in the formatted text, preserving case\n for (const acronym of commonAcronyms) {\n // Only uppercase the whole acronym if it appears as a whole word\n const regex = new RegExp(`\\\\b${acronym.toLowerCase()}\\\\b`, 'gi');\n formatted = formatted.replace(regex, acronym);\n }\n \n // Apply custom term formatting\n for (const [term, replacement] of Object.entries(customTerms)) {\n const regex = new RegExp(`\\\\b${term}\\\\b`, 'gi');\n formatted = formatted.replace(regex, replacement);\n }\n \n return formatted;\n },\n valueFormatter: (value: any) => String(value ?? '')\n };\n\n const mergedOptions = { ...defaultOptions, ...options };\n const { include, exclude, keyFormatter, valueFormatter, formatKeys, keyHeader, valueHeader, keyWidth, valueWidth, borderStyle, enableTextWrapping, maxDepth } = mergedOptions;\n\n // Extract keys based on include/exclude\n let keys = Object.keys(data);\n if (include) {\n keys = keys.filter(key => include.includes(key));\n }\n if (exclude) {\n keys = keys.filter(key => !exclude.includes(key));\n }\n\n // If no keys to display, show message and return\n if (keys.length === 0) {\n console.log(chalk.yellow('No properties to display'));\n return;\n }\n\n // Prepare the data array for the table formatter\n const tableData = keys.map(key => {\n const value = data[key as keyof T];\n \n // Format the value based on its type\n let formattedValue: string;\n if (value === null || value === undefined) {\n formattedValue = '';\n } else if (typeof value === 'object' && !Array.isArray(value)) {\n // Handle nested objects (but limit depth)\n formattedValue = formatNestedObject(value, 0, maxDepth);\n } else if (Array.isArray(value)) {\n // Handle arrays\n if (value.length === 0) {\n formattedValue = '[]';\n } else if (typeof value[0] === 'object') {\n // Array of objects\n formattedValue = `[${value.length} items]`;\n } else {\n // Array of primitives\n formattedValue = `[${value.join(', ')}]`;\n }\n } else {\n // Handle primitives\n formattedValue = String(value);\n }\n \n // Apply custom value formatter if provided\n if (valueFormatter) {\n formattedValue = valueFormatter(value, key);\n }\n \n return {\n key: formatKeys && keyFormatter ? keyFormatter(key) : key,\n value: formattedValue\n };\n });\n\n // Calculate column widths\n const terminalWidth = getTerminalWidth();\n let finalKeyWidth = keyWidth;\n let finalValueWidth = valueWidth;\n \n if (!finalKeyWidth) {\n // Calculate key column width based on content\n finalKeyWidth = Math.max(\n keyHeader.length,\n ...tableData.map(item => item.key.length),\n 10 // Minimum key width\n );\n // Limit to 1/3 of terminal width\n finalKeyWidth = Math.min(finalKeyWidth, Math.floor(terminalWidth / 3));\n }\n \n if (!finalValueWidth) {\n // Calculate value column width\n const borderChars = 7; // Typical border chars count\n finalValueWidth = terminalWidth - finalKeyWidth - borderChars;\n }\n\n // Configure border characters based on style\n const border = getBorderChars(borderStyle);\n\n // Header row\n const topBorder = `${border.topLeft}${border.horizontal.repeat(finalKeyWidth + 2)}${border.topT}${border.horizontal.repeat(finalValueWidth + 2)}${border.topRight}`;\n const headerRow = `${border.vertical} ${chalk.bold(keyHeader.padEnd(finalKeyWidth))} ${border.vertical} ${chalk.bold(valueHeader.padEnd(finalValueWidth))} ${border.vertical}`;\n const headerSeparator = `${border.leftT}${border.horizontal.repeat(finalKeyWidth + 2)}${border.cross}${border.horizontal.repeat(finalValueWidth + 2)}${border.rightT}`;\n \n console.log(topBorder);\n console.log(headerRow);\n console.log(headerSeparator);\n \n // Data rows\n tableData.forEach((row, index) => {\n const keyLines = enableTextWrapping ? wrapText(row.key, finalKeyWidth) : [row.key];\n const valueLines = enableTextWrapping ? wrapText(row.value, finalValueWidth) : [row.value];\n \n const maxLines = Math.max(keyLines.length, valueLines.length);\n \n for (let i = 0; i < maxLines; i++) {\n const keyContent = (keyLines[i] || '').padEnd(finalKeyWidth);\n const valueContent = (valueLines[i] || '').padEnd(finalValueWidth);\n console.log(`${border.vertical} ${keyContent} ${border.vertical} ${valueContent} ${border.vertical}`);\n }\n \n // Add a separator between rows, but not after the last row\n if (index < tableData.length - 1) {\n console.log(`${border.leftT}${border.horizontal.repeat(finalKeyWidth + 2)}${border.cross}${border.horizontal.repeat(finalValueWidth + 2)}${border.rightT}`);\n }\n });\n \n // Bottom border\n const bottomBorder = `${border.bottomLeft}${border.horizontal.repeat(finalKeyWidth + 2)}${border.bottomT}${border.horizontal.repeat(finalValueWidth + 2)}${border.bottomRight}`;\n console.log(bottomBorder);\n },\n startSpinner: (message: string) => {\n process.stdout.write(`${chalk.blue('⟳')} ${message}... `)\n return {\n stop: (success = true, result?: string) => {\n const icon = success ? chalk.green('✓') : chalk.red('✗')\n const resultText = result ? `: ${result}` : ''\n console.log(`${icon}${resultText}`)\n }\n }\n },\n break() {\n console.log(\"\")\n },\n}\n\n/**\n * Formats a nested object for display in the keyValueTable\n */\nfunction formatNestedObject(obj: any, currentDepth: number, maxDepth: number): string {\n if (currentDepth >= maxDepth) {\n return '[Nested Object]';\n }\n \n if (obj === null || obj === undefined) {\n return '';\n }\n \n if (Array.isArray(obj)) {\n if (obj.length === 0) return '[]';\n return `[${obj.length} items]`;\n }\n \n const lines: string[] = [];\n for (const [key, value] of Object.entries(obj)) {\n if (value === null || value === undefined) {\n lines.push(`${key}: `);\n } else if (typeof value === 'object') {\n lines.push(`${key}: ${formatNestedObject(value, currentDepth + 1, maxDepth)}`);\n } else {\n lines.push(`${key}: ${value}`);\n }\n }\n \n return lines.join(', ');\n}\n\n/**\n * Get border characters based on style\n */\nfunction getBorderChars(style: 'single' | 'double' | 'rounded' = 'single') {\n return {\n single: {\n topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',\n horizontal: '─', vertical: '│', \n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n },\n double: {\n topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',\n horizontal: '═', vertical: '║',\n leftT: '╠', rightT: '╣', topT: '╦', bottomT: '╩', cross: '╬'\n },\n rounded: {\n topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',\n horizontal: '─', vertical: '│',\n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n }\n }[style];\n}\n\nfunction getTerminalWidth(): number {\n return process.stdout.columns || 80; // Default to 80 if width cannot be determined\n}\n\n/**\n * Calculate column widths for tabular data display\n * @param data Array of objects to display in table\n * @param columns Configuration for each column to display\n * @param options Additional display options\n * @returns Object with calculated widths for each column\n */\nexport function calculateColumnWidths<T>(\n data: T[],\n columns: {\n key: keyof T;\n header: string;\n minWidth?: number;\n weight?: number; // Relative weight for distributing remaining space (default: 1)\n fixedWidth?: number; // If set, this column will have exactly this width\n getValue?: (item: T) => string; // Custom accessor for nested properties\n getWidth?: (item: T) => number; // Custom width calculator\n }[],\n options: {\n borderChars?: number; // Characters used for borders per column\n additionalBorderWidth?: number; // Additional border width (outer borders, etc.)\n } = {}\n): { [key: string]: number } {\n const terminalWidth = getTerminalWidth();\n \n // Calculate total border width\n const borderCharsPerColumn = options.borderChars ?? 3; // Default \"| \" + \" \" per column\n const additionalBorderWidth = options.additionalBorderWidth ?? 1; // Default \"|\" at the end\n const totalBorderWidth = additionalBorderWidth + columns.length * borderCharsPerColumn;\n \n const availableContentWidth = terminalWidth - totalBorderWidth;\n \n // Calculate initial widths based on content and minimum requirements\n const initialWidths: { [key: string]: number } = {};\n let totalFixedWidth = 0;\n let totalWeight = 0;\n \n // First pass: Calculate initial widths and total weight\n for (const column of columns) {\n const key = column.key as string;\n \n if (column.fixedWidth !== undefined) {\n initialWidths[key] = column.fixedWidth;\n totalFixedWidth += column.fixedWidth;\n continue;\n }\n \n const minWidth = column.minWidth ?? column.header.length;\n \n let contentWidth: number;\n if (column.getWidth) {\n // Use custom width calculator if provided\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => column.getWidth!(item))\n );\n } else if (column.getValue) {\n // Use custom accessor if provided\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => String(column.getValue!(item) || '').length)\n );\n } else {\n // Default behavior\n contentWidth = Math.max(\n minWidth,\n column.header.length,\n ...data.map(item => String(item[column.key] || '').length)\n );\n }\n \n initialWidths[key] = contentWidth;\n totalFixedWidth += contentWidth;\n totalWeight += column.weight ?? 1;\n }\n \n // Calculate remaining width to distribute\n const remainingWidth = Math.max(0, availableContentWidth - totalFixedWidth);\n \n // If we have remaining width and weights, distribute according to weights\n if (remainingWidth > 0 && totalWeight > 0) {\n for (const column of columns) {\n const key = column.key as string;\n if (column.fixedWidth === undefined && column.weight) {\n const extraWidth = Math.floor(remainingWidth * (column.weight / totalWeight));\n initialWidths[key] += extraWidth;\n }\n }\n }\n \n // If total width would exceed terminal, scale everything down proportionally\n const calculatedTotalWidth = Object.values(initialWidths).reduce((sum, width) => sum + width, 0) + totalBorderWidth;\n \n if (calculatedTotalWidth > terminalWidth) {\n const scale = availableContentWidth / (calculatedTotalWidth - totalBorderWidth);\n \n const finalWidths: { [key: string]: number } = {};\n for (const column of columns) {\n const key = column.key as string;\n const minWidth = column.minWidth ?? column.header.length;\n finalWidths[key] = Math.max(minWidth, Math.floor(initialWidths[key] * scale));\n }\n \n return finalWidths;\n }\n \n return initialWidths;\n}\n\n// Example usage:\n/**\n * Example of how to use the calculateColumnWidths function\n * @param data Array of objects with name, status, appId, and appUrl properties\n * @returns Object with calculated column widths\n */\nexport function calculateTableWidths(data: { name: string; status: string; appId: string; appUrl: string }[]): { [key: string]: number } {\n return calculateColumnWidths(\n data,\n [\n { key: 'name', header: 'Name', minWidth: 10 },\n { key: 'status', header: 'Status', minWidth: 6 },\n { key: 'appId', header: 'App ID', minWidth: 8, weight: 1 },\n { key: 'appUrl', header: 'App URL', minWidth: 7, weight: 2 }\n ],\n { borderChars: 3, additionalBorderWidth: 1 }\n );\n}\n\n/**\n * Example of how to use calculateColumnWidths with nested objects\n * @param data Array of objects with nested properties\n * @returns Object with calculated column widths\n */\nexport function calculateNestedTableWidths<T>(\n data: T[],\n columns: Array<{\n key: string; // Output key in the result object\n header: string;\n minWidth: number;\n weight?: number;\n accessor: (item: T) => string; // Function to access the nested property\n }>\n): { [key: string]: number } {\n // Convert to the format expected by calculateColumnWidths\n const columnConfig = columns.map((col, index) => ({\n key: `col_${index}` as keyof T, // Use a unique key for each column\n header: col.header,\n minWidth: col.minWidth,\n weight: col.weight,\n getValue: col.accessor\n }));\n\n // Get the raw widths\n const widths = calculateColumnWidths(data, columnConfig, { borderChars: 3, additionalBorderWidth: 1 });\n \n // Remap to expected keys\n const result: { [key: string]: number } = {};\n columns.forEach((col, index) => {\n result[col.key] = widths[`col_${index}` as string];\n });\n \n return result;\n}\n\n/**\n * Format and display data as a table in the terminal with customizable styling\n * @param data Array of objects to display in table\n * @param options Table display options\n */\nexport function formatTable<T>(\n data: T[],\n options: {\n columns?: Array<{\n key: keyof T | string;\n header?: string;\n minWidth?: number;\n weight?: number;\n accessor?: (item: T) => any;\n formatter?: (value: any) => string;\n enableTextWrapping?: boolean; // Changed from wrapText to enableTextWrapping\n }>;\n includeHeaders?: boolean;\n border?: boolean;\n borderStyle?: 'single' | 'double' | 'rounded';\n headerStyle?: (text: string) => string;\n cellStyle?: (text: string, rowIndex: number, colKey: string) => string;\n enableTextWrapping?: boolean; // Global option to control text wrapping\n keyValueMode?: boolean; // Option to display a single object in key-value rows\n } = {}\n): void {\n // If in key-value mode, transform the data\n if (options.keyValueMode && data.length === 1) {\n const obj = data[0];\n const keyValueData: Array<{key: string, value: any}> = [];\n \n // Generate columns if not provided\n if (!options.columns) {\n options.columns = Object.keys(obj).map(key => ({\n key,\n header: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1') // Capitalize and add spaces\n }));\n }\n \n // Transform object to key-value rows\n for (const col of options.columns) {\n const key = String(col.key);\n let value;\n \n if (col.accessor) {\n value = col.accessor(obj);\n } else if (typeof col.key === 'string' && col.key.includes('.')) {\n // Handle dot notation for nested objects\n const parts = col.key.split('.');\n let current: any = obj;\n for (const part of parts) {\n if (current === null || current === undefined) {\n value = '';\n break;\n }\n current = current[part as keyof typeof current];\n }\n value = current;\n } else {\n value = obj[col.key as keyof T];\n }\n \n // Apply formatter if provided\n if (col.formatter) {\n value = col.formatter(value);\n }\n \n keyValueData.push({\n key: col.header || key,\n value: value\n });\n }\n \n // Replace data and columns\n data = keyValueData as unknown as T[];\n options.columns = [\n { key: 'key' as keyof T, header: 'Property', minWidth: 15 },\n { key: 'value' as keyof T, header: 'Value', minWidth: 20 }\n ];\n }\n\n if (data.length === 0) {\n console.log(chalk.yellow('No data to display'));\n return;\n }\n\n // Default options\n const defaultOptions = {\n includeHeaders: true,\n border: true,\n borderStyle: 'single' as const,\n headerStyle: (text: string) => chalk.bold(text),\n cellStyle: (text: string) => text,\n enableTextWrapping: true // Enable text wrapping by default\n };\n\n const mergedOptions = { ...defaultOptions, ...options };\n\n // Auto-generate columns if not provided\n let columns = mergedOptions.columns;\n if (!columns) {\n const sample = data[0];\n columns = Object.keys(sample).map(key => ({\n key,\n header: key.charAt(0).toUpperCase() + key.slice(1), // Capitalize header\n enableTextWrapping: mergedOptions.enableTextWrapping\n }));\n } else {\n // Ensure all columns have enableTextWrapping property set if not explicitly defined\n columns = columns.map(col => ({\n ...col,\n enableTextWrapping: col.enableTextWrapping !== undefined ? col.enableTextWrapping : mergedOptions.enableTextWrapping\n }));\n }\n\n // Configure border characters based on style\n const borderChars = {\n single: {\n topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',\n horizontal: '─', vertical: '│', \n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n },\n double: {\n topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',\n horizontal: '═', vertical: '║',\n leftT: '╠', rightT: '╣', topT: '╦', bottomT: '╩', cross: '╬'\n },\n rounded: {\n topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',\n horizontal: '─', vertical: '│',\n leftT: '├', rightT: '┤', topT: '┬', bottomT: '┴', cross: '┼'\n }\n };\n\n const border = borderChars[mergedOptions.borderStyle];\n\n // Configure column config for width calculation\n const columnConfig = columns.map(col => ({\n key: col.key as keyof T,\n header: col.header || String(col.key),\n minWidth: col.minWidth || 3,\n weight: col.weight,\n enableTextWrapping: col.enableTextWrapping,\n getValue: col.accessor ? \n (item: T) => col.accessor!(item) : \n (item: T) => {\n // Handle dot notation for nested objects\n if (typeof col.key === 'string' && col.key.includes('.')) {\n const parts = col.key.split('.');\n let value: any = item;\n for (const part of parts) {\n if (value === null || value === undefined) return '';\n value = value[part as keyof typeof value];\n }\n return value ?? '';\n }\n return item[col.key as keyof T] ?? '';\n }\n }));\n\n // Calculate column widths\n const widths = calculateColumnWidths(data, columnConfig);\n\n // Prepare column and header arrays with proper keys\n const formattedColumns = columns.map((col, index) => ({\n ...col,\n width: widths[columnConfig[index].key as string]\n }));\n\n // Format headers and rows\n const headers = formattedColumns.map(col => col.header || String(col.key));\n \n // Helper to format a row with text wrapping support\n const formatRow = (row: T, rowIndex: number) => {\n // For each column, get the value and wrap it if needed\n const rowData = formattedColumns.map(col => {\n let value;\n if (col.accessor) {\n value = col.accessor(row);\n } else if (typeof col.key === 'string' && col.key.includes('.')) {\n // Handle dot notation for nested objects\n const parts = col.key.split('.');\n let current: any = row;\n for (const part of parts) {\n if (current === null || current === undefined) {\n value = '';\n break;\n }\n current = current[part as keyof typeof current];\n }\n value = current ?? '';\n } else {\n value = row[col.key as keyof T] ?? '';\n }\n \n // Format the value\n let displayValue = col.formatter ? col.formatter(value) : String(value || '');\n \n // Wrap text if enabled for this column\n if (col.enableTextWrapping) {\n return {\n lines: wrapText(displayValue, col.width),\n key: String(col.key)\n };\n } else {\n // Truncate if not wrapping\n return {\n lines: [displayValue.length > col.width ? \n displayValue.substring(0, col.width - 1) + '…' : \n displayValue],\n key: String(col.key)\n };\n }\n });\n \n // Calculate the maximum number of lines in any column for this row\n const maxLines = Math.max(...rowData.map(col => col.lines.length));\n \n // Format each line of the row\n const formattedLines = [];\n for (let lineIndex = 0; lineIndex < maxLines; lineIndex++) {\n const lineContent = rowData.map((col, colIndex) => {\n const content = col.lines[lineIndex] || '';\n return mergedOptions.cellStyle(\n content.padEnd(formattedColumns[colIndex].width), \n rowIndex, \n col.key\n );\n });\n formattedLines.push(lineContent);\n }\n \n return formattedLines;\n };\n\n // Generate table parts\n if (mergedOptions.border) {\n // Top border\n const topBorder = border.topLeft + \n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.topT) +\n border.topRight;\n console.log(topBorder);\n \n // Headers with possible wrapping\n if (mergedOptions.includeHeaders) {\n // Wrap header text if needed\n const wrappedHeaders = formattedColumns.map((col, i) => ({\n lines: col.enableTextWrapping ? wrapText(headers[i], col.width) : [headers[i]],\n width: col.width\n }));\n \n // Find the maximum number of lines in any header\n const maxHeaderLines = Math.max(...wrappedHeaders.map(h => h.lines.length));\n \n // Display each line of the header\n for (let lineIndex = 0; lineIndex < maxHeaderLines; lineIndex++) {\n const headerLine = border.vertical + \n wrappedHeaders.map((header) => {\n const content = header.lines[lineIndex] || '';\n return ' ' + mergedOptions.headerStyle(content.padEnd(header.width)) + ' ';\n }).join(border.vertical) + \n border.vertical;\n console.log(headerLine);\n }\n \n // Header-data separator\n const headerSeparator = border.leftT +\n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.cross) +\n border.rightT;\n console.log(headerSeparator);\n }\n \n // Data rows with text wrapping\n data.forEach((row, rowIndex) => {\n const formattedRows = formatRow(row, rowIndex);\n \n formattedRows.forEach(rowLine => {\n console.log(\n border.vertical + \n rowLine.map(cell => ` ${cell} `).join(border.vertical) + \n border.vertical\n );\n });\n \n // Optional: Add a separator between rows for better readability\n if (rowIndex < data.length - 1 && formattedRows.length > 1) {\n const rowSeparator = border.leftT +\n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.cross) +\n border.rightT;\n console.log(rowSeparator);\n }\n });\n \n // Bottom border\n const bottomBorder = border.bottomLeft + \n formattedColumns.map(col => border.horizontal.repeat(col.width + 2)).join(border.bottomT) +\n border.bottomRight;\n console.log(bottomBorder);\n } else {\n // No borders, simpler display\n if (mergedOptions.includeHeaders) {\n // Wrap header text if needed\n const wrappedHeaders = formattedColumns.map((col, i) => ({\n lines: col.enableTextWrapping ? wrapText(headers[i], col.width) : [headers[i]],\n width: col.width\n }));\n \n // Find the maximum number of lines in any header\n const maxHeaderLines = Math.max(...wrappedHeaders.map(h => h.lines.length));\n \n // Display each line of the header\n for (let lineIndex = 0; lineIndex < maxHeaderLines; lineIndex++) {\n const headerLine = wrappedHeaders.map((header) => {\n const content = header.lines[lineIndex] || '';\n return mergedOptions.headerStyle(content.padEnd(header.width));\n }).join(' ');\n console.log(headerLine);\n }\n \n // Simple underline for headers\n const headerSeparator = formattedColumns.map(col => \n '─'.repeat(col.width)\n ).join(' ');\n console.log(headerSeparator);\n }\n \n // Data rows with text wrapping\n data.forEach((row, rowIndex) => {\n const formattedRows = formatRow(row, rowIndex);\n \n formattedRows.forEach(rowLine => {\n console.log(rowLine.join(' '));\n });\n \n // Add a blank line between multi-line rows for better readability\n if (rowIndex < data.length - 1 && formattedRows.length > 1) {\n console.log('');\n }\n });\n }\n \n console.log(`Total: ${data.length} rows`);\n}\n\n"],"mappings":"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","names":["chalk","wrapText","text","maxWidth","lines","currentLine","words","word","i","logger","message","args","data","columns","columnConfig","col","formatTable","options","mergedOptions","key","commonAcronyms","customTerms","formatted","part","acronym","regex","term","replacement","value","include","exclude","keyFormatter","valueFormatter","formatKeys","keyHeader","valueHeader","keyWidth","valueWidth","borderStyle","enableTextWrapping","maxDepth","keys","tableData","formattedValue","formatNestedObject","terminalWidth","getTerminalWidth","finalKeyWidth","finalValueWidth","item","border","getBorderChars","topBorder","headerRow","headerSeparator","row","index","keyLines","valueLines","maxLines","keyContent","valueContent","bottomBorder","success","result","icon","resultText","obj","currentDepth","style","calculateColumnWidths","borderCharsPerColumn","totalBorderWidth","availableContentWidth","initialWidths","totalFixedWidth","totalWeight","column","minWidth","contentWidth","remainingWidth","extraWidth","calculatedTotalWidth","sum","width","scale","finalWidths","calculateTableWidths","calculateNestedTableWidths","widths","keyValueData","parts","current","sample","formattedColumns","headers","formatRow","rowIndex","rowData","displayValue","formattedLines","lineIndex","lineContent","colIndex","content","wrappedHeaders","maxHeaderLines","h","headerLine","header","formattedRows","rowLine","cell","rowSeparator"]}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
#!/usr/bin/env bun
|
package/dist/index.js
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
#!/usr/bin/env bun
|
2
|
+
import{a as we,b as r}from"./chunk-A4IAJHG6.js";import{Command as so}from"commander";import Se from"chalk";var ke=Se.hex("#cdfa50"),Ee=ke(`
|
3
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E0\u28E4\u28E4\u28E4\u28C0\u2840\u2800\u2880\u28C0\u28E4\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
4
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u287F\u281B\u2809\u2801\u2800\u2808\u2809\u281B\u283F\u281B\u2809\u2809\u2809\u2809\u2819\u2837\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
5
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u280B\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28E7\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
6
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FF\u2847\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800
|
7
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u281E\u281B\u2809\u2819\u2803\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u281B\u28B6\u28C4\u2800\u2800\u2800
|
8
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u2803\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u28FF\u28E6\u2800\u2800
|
9
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28FF\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u28FF\u2800\u2800
|
10
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2838\u28FF\u28F7\u28C4\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28F4\u28FF\u28FF\u287F\u2800\u2800
|
11
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u28BF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2800\u2800\u28C0\u28F4\u28F6\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2801\u2800\u2800
|
12
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283B\u283F\u283F\u283F\u283F\u2803\u2800\u2880\u28FE\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u281B\u280B\u2801\u2800\u2800\u2800\u2800
|
13
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28FE\u28FF\u287F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
14
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28C0\u2864\u2824\u2824\u2834\u2812\u2812\u2812\u2812\u2812\u28BF\u287F\u2813\u2812\u2812\u2822\u2824\u2824\u2824\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
15
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28FE\u28EF\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E8\u28FF\u28E6\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800
|
16
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28BB\u28FF\u28FF\u28FF\u28FF\u28FF\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28FE\u28FF\u28FF\u28FF\u28FF\u28FF\u284F\u2809\u281B\u28FF\u28C6\u2800\u2800\u2800\u2800\u2800
|
17
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u2800\u28C0\u28C0\u28C0\u28C0\u2878\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u2800\u2800\u28F8\u287F\u2800\u2800\u2800\u2800\u2800
|
18
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2839\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u28B8\u28FF\u28FF\u28FF\u28FF\u2847\u2800\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2803\u2880\u28E0\u28F4\u287F\u2803\u2800\u2800\u2800\u2800\u2800
|
19
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u2887\u28C0\u28C0\u28C0\u28C0\u28F8\u28FF\u28FF\u28FF\u28FF\u28FF\u287F\u283F\u283F\u281B\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
20
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2860\u2800\u2800\u2800\u2800\u2808\u283B\u28BF\u28FF\u28FF\u28FF\u2800\u28B8\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u287F\u280B\u2800\u2800\u2800\u2800\u2820\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
21
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283F\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u281F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FE\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
22
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u283B\u28B6\u28E6\u28E4\u28C4\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28C0\u28C0\u28E4\u28F4\u28F6\u283F\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
23
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u2819\u281B\u283B\u283F\u283F\u283F\u283F\u28BF\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u281F\u281B\u281B\u2809\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
24
|
+
`),mo=ke(`
|
25
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E0\u28E4\u28E4\u28E4\u28C0\u2840\u2800\u2880\u28C0\u28E4\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
26
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u287F\u281B\u2809\u2801\u2800\u2808\u2809\u281B\u283F\u281B\u2809\u2809\u2809\u2809\u2819\u2837\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
27
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u280B\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28E7\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
28
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FF\u2847\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800
|
29
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28F4\u281E\u281B\u2809\u2819\u2803\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u281B\u28B6\u28C4\u2800\u2800\u2800
|
30
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u2803\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u28FF\u28E6\u2800\u2800
|
31
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28FF\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28A0\u28FF\u28FF\u2800\u2800
|
32
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2838\u28FF\u28F7\u28C4\u2840\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28F4\u28FF\u28FF\u287F\u2800\u2800
|
33
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u28BF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2800\u2800\u28C0\u28F4\u28F6\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2801\u2800\u2800
|
34
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283B\u283F\u283F\u283F\u283F\u2803\u2800\u2880\u28FE\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u283F\u281B\u280B\u2801\u2800\u2800\u2800\u2800
|
35
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28FE\u28FF\u287F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
36
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2880\u28C0\u2864\u2824\u2824\u2834\u2812\u2812\u2812\u2812\u2812\u28BF\u287F\u2813\u2812\u2812\u2822\u2824\u2824\u2824\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
37
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28FE\u28EF\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28E8\u28FF\u28E6\u28E4\u28C0\u2840\u2800\u2800\u2800\u2800\u2800\u2800
|
38
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28BB\u28FF\u28FF\u28FF\u28FF\u28FF\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28F6\u28FE\u28FF\u28FF\u28FF\u28FF\u28FF\u284F\u2809\u281B\u28FF\u28C6\u2800\u2800\u2800\u2800\u2800
|
39
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2818\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u2800\u28C0\u28C0\u28C0\u28C0\u2878\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u2800\u2800\u28F8\u287F\u2800\u2800\u2800\u2800\u2800
|
40
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2839\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2800\u28B8\u28FF\u28FF\u28FF\u28FF\u2847\u2800\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2803\u2880\u28E0\u28F4\u287F\u2803\u2800\u2800\u2800\u2800\u2800
|
41
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u2887\u28C0\u28C0\u28C0\u28C0\u28F8\u28FF\u28FF\u28FF\u28FF\u28FF\u287F\u283F\u283F\u281B\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
42
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2860\u2800\u2800\u2800\u2800\u2808\u283B\u28BF\u28FF\u28FF\u28FF\u2800\u28B8\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u287F\u280B\u2800\u2800\u2800\u2800\u2820\u28C4\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
43
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28B8\u28C6\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2809\u281B\u283F\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u283F\u281F\u280B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28FE\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
44
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2819\u283B\u28B6\u28E6\u28E4\u28C4\u28C0\u28C0\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u28C0\u28C0\u28C0\u28E4\u28F4\u28F6\u283F\u281B\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
45
|
+
\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2808\u2809\u2819\u281B\u283B\u283F\u283F\u283F\u283F\u28BF\u28FF\u28FF\u28FF\u283F\u283F\u283F\u283F\u281F\u281B\u281B\u2809\u2801\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800\u2800
|
46
|
+
`),co=Se.cyan("PHALA TEE CLOUD CLI");import{Command as dr}from"commander";import{Command as cr}from"commander";import $ from"fs";import me from"path";import I from"os";import W from"crypto";var N=me.join(I.homedir(),".phala-cloud"),O=me.join(N,"api-key"),ae=me.join(N,"docker-credentials.json");function be(){if(!$.existsSync(N))try{$.mkdirSync(N,{recursive:!0})}catch(t){throw r.error(`Failed to create directory ${N}:`,t),t}}function _e(){let t=[I.hostname(),I.platform(),I.arch(),I.cpus()[0]?.model||"",I.userInfo().username],e=W.createHash("sha256");return e.update(t.join("|")),e.digest()}function xe(t){try{let e=_e(),o=W.randomBytes(16),n=W.createCipheriv("aes-256-cbc",e.slice(0,32),o),i=n.update(t,"utf8","hex");return i+=n.final("hex"),o.toString("hex")+":"+i}catch(e){throw r.error("Encryption failed:",e),new Error("Failed to encrypt data")}}function $e(t){try{let e=_e(),o=t.split(":");if(o.length!==2)throw new Error("Invalid encrypted format");let n=Buffer.from(o[0],"hex"),i=o[1],a=W.createDecipheriv("aes-256-cbc",e.slice(0,32),n),m=a.update(i,"hex","utf8");return m+=a.final("utf8"),m}catch(e){throw r.error("Decryption failed:",e),new Error("Failed to decrypt data")}}async function Pe(t){be();try{let e=xe(t);$.writeFileSync(O,e,{mode:384})}catch(e){throw r.error("Failed to save API key:",e),e}}async function X(){try{if($.existsSync(O)){let t=$.readFileSync(O,"utf8").trim();return $e(t)}return null}catch(t){return r.error("Failed to read API key:",t),null}}async function U(){try{$.existsSync(O)?($.unlinkSync(O),r.success("API key removed successfully.")):r.warn("No API key found to remove.")}catch(t){throw r.error("Failed to remove API key:",t),t}}async function De(t){be();try{t.password=xe(t.password),$.writeFileSync(ae,JSON.stringify(t,null,2),{mode:384}),r.success("Docker credentials saved successfully.")}catch(e){throw r.error("Failed to save Docker credentials:",e),e}}async function x(){try{if($.existsSync(ae)){let t=$.readFileSync(ae,"utf8"),e=JSON.parse(t);return e.password&&(e.password=$e(e.password)),e}return null}catch(t){return r.error("Failed to read Docker credentials:",t),null}}import pr from"prompts";import Wt from"axios";var ce=process.env.CLOUD_API_URL||"https://cloud-api.phala.network",T=process.env.CLOUD_URL||"https://cloud.phala.network",Ie="0.0.1",pe="https://hub.docker.com/v2",Te="phalanetwork/tappd-simulator:latest",L=1,z=2048,j=20,C={USER_INFO:"/api/v1/auth/me",TEEPODS:"/api/v1/teepods?enabled=true",TEEPOD_IMAGES:t=>`/api/v1/teepods/${t}/images`,CVMS:t=>`/api/v1/cvms?user_id=${t}`,CVM_BY_APP_ID:t=>`/api/v1/cvms/app_${t}`,CVM_START:t=>`/api/v1/cvms/app_${t}/start`,CVM_STOP:t=>`/api/v1/cvms/app_${t}/stop`,CVM_RESTART:t=>`/api/v1/cvms/app_${t}/restart`,CVM_LOGS:t=>`/api/v1/cvms/app_${t}/logs`,CVM_FROM_CONFIGURATION:"/api/v1/cvms/from_cvm_configuration",CVM_PUBKEY:"/api/v1/cvms/pubkey/from_cvm_configuration",CVM_UPGRADE:t=>`/api/v1/cvms/app_${t}/compose`,CVM_ATTESTATION:t=>`/api/v1/cvms/app_${t}/attestation`,CVM_RESIZE:t=>`/api/v1/cvms/app_${t}/resources`},Fe=`version: '3.8'
|
47
|
+
services:
|
48
|
+
postgres:
|
49
|
+
image: postgres:15
|
50
|
+
environment:
|
51
|
+
- POSTGRES_PASSWORD=postgres
|
52
|
+
- POSTGRES_USER=postgres
|
53
|
+
- POSTGRES_DB=eliza
|
54
|
+
volumes:
|
55
|
+
- postgres-data:/var/lib/postgresql/data
|
56
|
+
ports:
|
57
|
+
- "127.0.0.1:5432:5432"
|
58
|
+
healthcheck:
|
59
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
60
|
+
interval: 5s
|
61
|
+
timeout: 5s
|
62
|
+
retries: 5
|
63
|
+
restart: always
|
64
|
+
eliza:
|
65
|
+
image: {{imageName}}:{{tag}}
|
66
|
+
container_name: elizav2
|
67
|
+
command: bun run start
|
68
|
+
stdin_open: true
|
69
|
+
tty: true
|
70
|
+
volumes:
|
71
|
+
- /var/run/tappd.sock:/var/run/tappd.sock
|
72
|
+
environment:
|
73
|
+
{{#each envVars}} - {{{this}}}
|
74
|
+
{{/each}}
|
75
|
+
ports:
|
76
|
+
- "3000:3000"
|
77
|
+
- "5173:5173"
|
78
|
+
depends_on:
|
79
|
+
postgres:
|
80
|
+
condition: service_healthy
|
81
|
+
restart: always
|
82
|
+
networks:
|
83
|
+
- eliza-network
|
84
|
+
|
85
|
+
|
86
|
+
networks:
|
87
|
+
eliza-network:
|
88
|
+
driver: bridge
|
89
|
+
|
90
|
+
volumes:
|
91
|
+
postgres-data:`,Ae=`version: '3.8'
|
92
|
+
services:
|
93
|
+
app:
|
94
|
+
image: {{imageName}}:{{tag}}
|
95
|
+
container_name: app
|
96
|
+
volumes:
|
97
|
+
- /var/run/tappd.sock:/var/run/tappd.sock
|
98
|
+
environment:
|
99
|
+
{{#each envVars}} - {{{this}}}
|
100
|
+
{{/each}}
|
101
|
+
restart: always
|
102
|
+
`;function le(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}var ue=class{client;apiKey=null;constructor(e){r.debug(`Creating API client with base URL: ${e}`),this.client=Wt.create({baseURL:e,headers:{"Content-Type":"application/json","User-Agent":`tee-cloud-cli/${Ie}`}}),this.client.interceptors.request.use(async o=>{if(!this.apiKey){if(this.apiKey=await X(),!this.apiKey)throw new Error('API key not found. Please set an API key first with "phala auth login"');r.debug(`API key loaded: ${this.apiKey.substring(0,5)}...`)}return o.headers["X-API-Key"]=this.apiKey,r.debug(`Making request to: ${o.baseURL}${o.url}`),o}),this.client.interceptors.response.use(o=>(r.debug(`Received successful response from: ${o.config.url}`),o),o=>{if(o.response){let{status:n,data:i}=o.response;r.debug(`Received error response: ${n} - ${le(i)}`),n===401?r.error("Authentication failed. Please check your API key."):n===403?r.error("You do not have permission to perform this action."):n===404?r.error("Resource not found."):r.error(`API Error (${n}): ${i.message||le(i)}`)}else o.request?(r.error("No response received from the server. Please check your internet connection."),r.debug(`Request details: ${le(o.request).substring(0,200)}...`)):r.error(`Error: ${o.message}`);return Promise.reject(o)})}async get(e,o){try{return r.debug(`GET request to: ${e}`),(await this.client.get(e,o)).data}catch(n){throw r.debug(`GET request failed: ${n instanceof Error?n.message:String(n)}`),n}}async post(e,o,n){try{return r.debug(`POST request to: ${e}`),(await this.client.post(e,o,n)).data}catch(i){throw r.debug(`POST request failed: ${i instanceof Error?i.message:String(i)}`),i}}async put(e,o,n){try{return r.debug(`PUT request to: ${e}`),(await this.client.put(e,o,n)).data}catch(i){throw r.debug(`PUT request failed: ${i instanceof Error?i.message:String(i)}`),i}}async delete(e,o){try{return r.debug(`DELETE request to: ${e}`),(await this.client.delete(e,o)).data}catch(n){throw r.debug(`DELETE request failed: ${n instanceof Error?n.message:String(n)}`),n}}async patch(e,o,n){try{return r.debug(`PATCH request to: ${e}`),(await this.client.patch(e,o,n)).data}catch(i){throw r.debug(`PATCH request failed: ${i instanceof Error?i.message:String(i)}`),i}}};r.debug(`Initializing API client with URL: ${ce}`);var w=new ue(ce);import{z as s}from"zod";import{INVALID as Xt,ParseStatus as Qt,ZodIssueCode as F,ZodParsedType as Me,ZodType as er,addIssueToContext as A,z as Ve}from"zod";var tr="ZodDecimal",rr=/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,G=class extends er{_parse(e){if(e.data!==null&&typeof e.data=="object"&&"toNumber"in e.data&&(e.data=e.data.toNumber()),this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==Me.number){let a=this._getOrReturnCtx(e);return A(a,{code:F.invalid_type,expected:Me.number,received:a.parsedType}),Xt}let n,i=new Qt;for(let a of this._def.checks)if(a.kind==="precision"){let m=e.data.toString().match(rr);Math.max((m[1]?m[1].length:0)-(m[2]?parseInt(m[2],10):0),0)>a.value&&(n=this._getOrReturnCtx(e,n),A(n,{code:F.custom,message:a.message,params:{precision:a.value}}),i.dirty())}else a.kind==="wholeNumber"?e.data.toString().split(".")[0].length>a.value&&(n=this._getOrReturnCtx(e,n),A(n,{code:F.custom,message:a.message,params:{wholeNumber:a.value}}),i.dirty()):a.kind==="min"?(a.inclusive?e.data<a.value:e.data<=a.value)&&(n=this._getOrReturnCtx(e,n),A(n,{code:F.too_small,minimum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),i.dirty()):a.kind==="max"?(a.inclusive?e.data>a.value:e.data>=a.value)&&(n=this._getOrReturnCtx(e,n),A(n,{code:F.too_big,maximum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),i.dirty()):a.kind==="finite"&&(Number.isFinite(e.data)||(n=this._getOrReturnCtx(e,n),A(n,{code:F.not_finite,message:a.message}),i.dirty()));return{status:i.value,value:e.data}}setLimit(e,o,n,i){return new G({...this._def,checks:[...this._def.checks,{kind:e,value:o,inclusive:n,message:i}]})}_addCheck(e){return new G({...this._def,checks:[...this._def.checks,e]})}lte(e,o){return this.setLimit("max",e,!0,o)}lt(e,o){return this.setLimit("max",e,!1,o)}max=this.lte;gt(e,o){return this.setLimit("min",e,!1,o)}gte(e,o){return this.setLimit("min",e,!0,o)}min=this.gte;precision(e,o){return this._addCheck({kind:"precision",value:e,message:o})}wholeNumber(e,o){return this._addCheck({kind:"wholeNumber",value:e,message:o})}get minValue(){let e=null;for(let o of this._def.checks)o.kind==="min"&&(e===null||o.value>e)&&(e=o.value);return e}get maxValue(){let e=null;for(let o of this._def.checks)o.kind==="max"&&(e===null||o.value<e)&&(e=o.value);return e}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:e})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:e})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:e})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:e})}finite(e){return this._addCheck({kind:"finite",message:e})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:e})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:e})}get isFinite(){let e=null,o=null;for(let n of this._def.checks){if(n.kind==="finite")return!0;n.kind==="min"?(o===null||n.value>o)&&(o=n.value):n.kind==="max"&&(e===null||n.value<e)&&(e=n.value)}return Number.isFinite(o)&&Number.isFinite(e)}},B=G;we(B,"create",e=>new G({checks:[],typeName:tr,coerce:e?.coerce??!1}));var Re=Ve.object({template:Ve.string().min(1,"Template cannot be empty")});var or=s.object({password:s.string(),registry:s.string().nullable(),username:s.string()}),nr=s.object({docker_compose_file:s.string(),docker_config:or.optional(),features:s.array(s.string()),kms_enabled:s.boolean(),manifest_version:s.number(),name:s.string(),public_logs:s.boolean(),public_sysinfo:s.boolean(),runner:s.string().optional(),salt:s.string().nullable().optional(),tproxy_enabled:s.boolean(),version:s.string().optional()}),sr=s.object({name:s.string(),image:s.string(),compose_file:nr,vcpu:s.number(),memory:s.number(),disk_size:s.number(),ports:s.array(s.any())}),ir=s.object({id:s.string(),name:s.string(),status:s.string(),uptime:s.string(),app_url:s.string(),app_id:s.string(),instance_id:s.string(),configuration:sr,exited_at:s.string(),boot_progress:s.string(),boot_error:s.string(),shutdown_progress:s.string(),image_version:s.string()}),ar=s.object({id:s.number(),username:s.string()}),mr=s.object({id:s.number(),name:s.string()}),de=s.object({hosted:ir,name:s.string(),managed_user:ar,node:mr,listed:s.boolean(),status:s.string(),in_progress:s.boolean(),dapp_dashboard_url:s.string().nullable(),syslog_endpoint:s.string(),allow_upgrade:s.boolean()}),Ne=s.object({id:s.number(),name:s.string(),status:s.string(),teepod_id:s.number(),teepod:s.object({id:s.number(),name:s.string()}),user_id:s.number(),app_id:s.string(),vm_uuid:s.string().nullable(),instance_id:s.string().nullable(),app_url:s.string().nullable(),base_image:s.string(),vcpu:s.number(),memory:s.number(),disk_size:s.number(),manifest_version:s.number(),version:s.string(),runner:s.string(),docker_compose_file:s.string(),features:s.array(s.string()).nullable(),created_at:s.string(),encrypted_env_pubkey:s.string()}),Oe=s.object({app_env_encrypt_pubkey:s.string(),app_id_salt:s.string()}),Ue=s.object({id:s.number(),teepod_id:s.number(),teepod:s.object({id:s.number(),name:s.string()}),name:s.string(),status:s.string(),in_progress:s.boolean(),app_id:s.string(),vm_uuid:s.string(),instance_id:s.string(),vcpu:s.number(),memory:s.number(),disk_size:s.number(),base_image:s.string(),encrypted_env_pubkey:s.string(),listed:s.boolean(),project_id:s.string(),project_type:s.string().nullable()}),Le=s.object({username:s.string(),email:s.string(),credits:B.create({coerce:!0}),role:s.string(),avatar:s.string(),flag_reset_password:s.boolean(),team_name:s.string(),team_tier:s.string(),trial_ended_at:s.string().nullable()}),Ro=s.array(de),ze=s.object({detail:s.string()}),No=s.object({key:s.string(),value:s.string()}),je=s.object({id:s.number(),name:s.string(),status:s.string()}),Be=s.object({name:s.string(),description:s.string().optional()});function Ge(t){try{return JSON.stringify(t)}catch(e){return e instanceof Error&&e.message.includes("cyclic")?"[Cyclic Object]":String(t)}}async function q(){try{r.debug(`Fetching user info from ${C.USER_INFO}`);let t=await w.get(C.USER_INFO);r.debug(`Received response: ${Ge(t)}`);try{return Le.parse(t)}catch(e){throw r.error(`Failed to parse user info response: ${e}`),r.debug(`Response structure: ${Ge(t)}`),e}}catch(t){throw r.error(`Failed to get user info: ${t instanceof Error?t.message:String(t)}`),new Error(`Failed to get user info: ${t instanceof Error?t.message:String(t)}`)}}var qe=new cr().name("login").description("Set the API key for authentication").argument("[api-key]","Phala Cloud API key to set").action(async t=>{try{if(!t)t=(await pr({type:"password",name:"apiKey",message:"Enter your API key:",validate:async o=>{if(o.length===0)return"API key cannot be empty";try{if(await Pe(o),!(await q()).username)return await U(),"Invalid API key"}catch{return"Invalid API key"}return!0}})).apiKey;else if(!(await q()).username)return await U(),"Invalid API key";r.success("API key validated and saved successfully"),r.info(`
|
103
|
+
You can check your authentication status with "phala auth status"`)}catch(e){r.error(`Failed to set API key: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as lr}from"commander";var Ke=new lr().name("logout").description("Remove the stored API key").action(async()=>{try{await U(),r.success("API key removed successfully")}catch(t){r.error(`Failed to remove API key: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as ur}from"commander";var He=new ur().name("status").description("Check authentication status").option("-j, --json","Output in JSON format").option("-d, --debug","Enable debug output").action(async t=>{try{t.debug&&(process.env.DEBUG="true");let e=await X();if(!e){r.warn('Not authenticated. Please set an API key with "phala auth login"');return}r.debug(`Using API key: ${e.substring(0,5)}...`);let o=r.startSpinner("Checking authentication status");try{let n=await q();if(o.stop(!0),t.json){console.log(JSON.stringify(n,null,2));return}r.success(`Authenticated as ${n.username}`),r.break();let i={Username:n.username,Email:n.email,Role:n.role,Team:`${n.team_name} (${n.team_tier})`,Credits:`$${n.credits}`};n.trial_ended_at&&(i["Trial Ended At"]=n.trial_ended_at),console.table(i)}catch(n){o.stop(!1),r.error("Authentication failed. Your API key may be invalid or expired."),r.info('Please set a new API key with "phala auth login"'),t.debug&&r.debug(`Error details: ${n instanceof Error?n.message:String(n)}`)}}catch(e){r.error(`Failed to check authentication status: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Ze=new dr().name("auth").description("Authenticate with Phala Cloud").addCommand(qe).addCommand(Ke).addCommand(He);import{Command as hr}from"commander";import{Command as fr}from"commander";import{z as Je}from"zod";async function M(){try{let t=await w.get(C.TEEPODS);return Je.array(je).parse(t)}catch(t){throw new Error(`Failed to get TEEPods: ${t instanceof Error?t.message:String(t)}`)}}async function Q(t){try{let e=await w.get(C.TEEPOD_IMAGES(t));return Je.array(Be).parse(e)}catch(e){throw new Error(`Failed to get TEEPod images: ${e instanceof Error?e.message:String(e)}`)}}var Ye=new fr().name("list").description("List available TEEPods").action(async()=>{try{let t=r.startSpinner("Fetching TEEPods"),e=await M();if(t.stop(!0),e.length===0){r.info("No TEEPods found");return}r.info("Available TEEPods:"),r.table(e,["id","name","status"])}catch(t){r.error(`Failed to list TEEPods: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});import{Command as gr}from"commander";import yr from"inquirer";var We=new gr().name("images").description("List available images for a TEEPod").option("-t, --teepod-id <teepodId>","TEEPod ID").action(async t=>{try{let e=r.startSpinner(`Fetching images for TEEPod ${t.teepodId}`);if(!t.teepodId){let n=r.startSpinner("Fetching available TEEPods"),i=await M();n.stop(!0),i.length===0&&(r.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:a}=await yr.prompt([{type:"list",name:"selectedTeepodId",message:"Select a TEEPod:",choices:i.map(m=>({name:`${m.name} (${m.status})`,value:m.id}))}]);t.teepodId=a}let o=await Q(t.teepodId);if(e.stop(!0),o.length===0){r.info(`No images found for TEEPod ${t.teepodId}`);return}r.info(`Available images for TEEPod ${t.teepodId}:`),r.table(o,["name","description"])}catch(e){r.error(`Failed to list images: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Xe=new hr().name("teepods").description("TEEPod management commands").addCommand(Ye).addCommand(We);import{Command as Fr}from"commander";import{Command as _r}from"commander";import{execa as tt}from"execa";import D from"fs";import fe from"path";import rt from"axios";import vr from"handlebars";import{exec as wr,spawn as Sr}from"child_process";import{promisify as kr}from"util";import Er from"os";import Cr from"inquirer";import Qe from"fs";import et from"path";function E(t,e=process.cwd()){let o=et.resolve(e,t);if(!Qe.existsSync(o))throw new Error(`File not found at ${o}`);return!0}async function V(t,e,o="file",n=process.cwd()){return(await Cr.prompt([{type:"input",name:o,message:t,default:e,validate:a=>{let m=et.resolve(n,a);return Qe.existsSync(m)?!0:`File not found at ${m}`}}]))[o]}var ee=kr(wr),ot=".phala-cloud/logs",br=".phala-cloud/compose",nt=10,h=class{username;image;registry;constructor(e,o,n){this.image=e,this.username=o||"",this.registry=n||""}ensureLogsDir(){let e=fe.resolve(ot);D.existsSync(e)||D.mkdirSync(e,{recursive:!0})}getLogFilePath(e){let o=new Date().toISOString().replace(/[:.]/g,"-");return fe.resolve(ot,`${this.image}-${e}-${o}.log`)}getSystemArchitecture(){let e=Er.arch();switch(e){case"arm":case"arm64":return"arm64";case"x64":return"amd64";default:return e}}spawnProcess(e,o,n){return new Promise((i,a)=>{let m=Sr(e,o),c=this.getLogFilePath(n);this.ensureLogsDir();let p=D.createWriteStream(c,{flags:"a"}),f=[],d=(u,y=!1)=>{let l=u.toString().split(`
|
104
|
+
`);p.write(u),l.forEach(g=>{g.trim()&&(f.push(g),f.length>nt&&f.shift(),console.clear(),console.log(`Latest ${nt} lines (full log at ${c}):`),console.log("-".repeat(50)),f.forEach(k=>{y?console.error(k):console.log(k)}))})};m.stdout.on("data",u=>d(u)),m.stderr.on("data",u=>d(u,!0)),m.on("close",u=>{p.end(),u===0?(console.log(`
|
105
|
+
Operation completed. Full log available at: ${c}`),i()):a(new Error(`Process exited with code ${u}. Check log file: ${c}`))}),m.on("error",u=>{p.end(),a(u)})})}setCredentials(e,o){this.username=e,o&&(this.registry=o)}async buildImage(e,o){try{let n=this.getSystemArchitecture(),i=`${this.username}/${this.image}:${o}`,a=r.startSpinner(`Building Docker image ${this.username}/${this.image}:${o}`);E(e);let m=["build","-t",i,"-f",e];return n==="arm64"&&(console.log("Detected arm64 architecture, using --platform linux/amd64"),m.push("--platform","linux/amd64")),m.push("."),await this.spawnProcess("docker",m,"build"),a.stop(!0,`Docker image ${i} built successfully`),!0}catch(n){return r.error(`Failed to build Docker image: ${n instanceof Error?n.message:String(n)}`),!1}}async pushImage(e){try{let o=r.startSpinner(`Pushing Docker image ${this.username}/${this.image}:${e} to Docker Hub`);if(!await x())throw o.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let i=`${this.username}/${this.image}:${e}`;return console.log(`Pushing image ${i} to Docker Hub...`),await this.spawnProcess("docker",["push",i],"push"),o.stop(!0,`Docker image ${i} pushed successfully`),!0}catch(o){return r.error(`Failed to push Docker image: ${o instanceof Error?o.message:String(o)}`),!1}}async listTags(){try{let e=r.startSpinner(`Listing tags for ${this.username}/${this.image}`),o=await rt.get(`${pe}/repositories/${this.username}/${this.image}/tags`);if(!o.data||!o.data.results)throw e.stop(!1),new Error("Failed to get tags from Docker Hub");let n=o.data.results.map(i=>i.name);return e.stop(!0,`Found ${n.length} tags`),n}catch(e){return r.error(`Failed to list tags: ${e instanceof Error?e.message:String(e)}`),[]}}async deleteTag(e){try{let o=r.startSpinner(`Deleting tag ${this.username}/${this.image}:${e}`),n=await x();if(!n)throw o.stop(!1),new Error('Docker credentials not found. Please log in first with "phala docker login"');let i=await rt.delete(`${pe}/repositories/${this.username}/${this.image}/tags/${e}`,{auth:{username:n.username,password:n.password}});return o.stop(!0,"Tag deleted successfully"),!0}catch(o){return r.error(`Failed to delete tag: ${o instanceof Error?o.message:String(o)}`),!1}}async login(e,o,n){try{let i=r.startSpinner(`Logging in to Docker Hub as ${e}`);return await tt("docker",["login",...n?[n]:[],"-u",e,"--password-stdin"],{input:o}),i.stop(!0,"Logged in to Docker Hub successfully"),!0}catch(i){return r.error(`Failed to login to Docker Hub: ${i instanceof Error?i.message:String(i)}`),!1}}async buildComposeFile(e,o,n){if(!this.username)throw new Error("Docker Hub username is required for building compose file");let i=n=="eliza"?Fe:Ae,a=Re.parse({template:i}),m=br;D.existsSync(m)||(r.info(`Creating directory: ${m}`),D.mkdirSync(m,{recursive:!0}));let c=[];o&&(c=D.readFileSync(o,"utf-8").split(`
|
106
|
+
`).filter(l=>l&&!l.startsWith("#")).map(l=>{let g=l.indexOf("#");return g>0&&(l=l.substring(0,g).trim()),l.trim()}).filter(l=>l.includes("=")).map(l=>{let[g,k]=l.split("=",2),v=g.trim();return(k?k.trim():"")===""?null:`${v}=${v}`}).filter(Boolean));let p=`${this.username}/${this.image}`,d=vr.compile(a.template,{noEscape:!0})({imageName:p,tag:e,envVars:c.map(y=>y.replace(/=.*/,"=${"+y.split("=")[0]+"}"))}),u=fe.join(m,`${this.image}-${e}-tee-compose.yaml`);return D.writeFileSync(u,d),r.success(`Backup of docker compose file created at: ${u}`),u}async runComposeLocally(e,o){try{let n=r.startSpinner(`Running Docker Compose file at ${e}
|
107
|
+
- If you run with the simulator, set DSTACK_SIMULATOR_ENDPOINT to http://host.docker.internal:8090`);E(e);let i=["-f",e,"up","-d"];return o&&(E(o),i.splice(2,0,"--env-file",o)),await tt("docker-compose",i),n.stop(!0,"Docker Compose file running successfully"),!0}catch(n){return r.error(`Failed to run Docker Compose file: ${n instanceof Error?n.message:String(n)}`),!1}}async runSimulator(e){try{r.info(`Running TEE simulator with image ${e}`),r.info("Pulling latest simulator image..."),await ee(`docker pull ${e}`),r.info("Starting simulator in background...");let{stdout:o}=await ee(`docker run -d --name tee-simulator --rm -p 8090:8090 ${e}`),n=o.trim();return r.success(`TEE simulator running successfully. Container ID: ${n}`),r.info(`
|
108
|
+
|
109
|
+
Useful commands:`),r.info(`- View logs: docker logs -f ${n}`),r.info(`- Stop simulator: docker stop ${n}`),!0}catch(o){return r.error(`Failed to run TEE simulator: ${o instanceof Error?o.message:String(o)}`),!1}}async stopSimulator(){try{let e=r.startSpinner("Stopping TEE simulator...");return await ee("docker stop tee-simulator"),e.stop(!0,"TEE simulator stopped successfully"),!0}catch(e){return r.error(`Failed to stop TEE simulator: ${e instanceof Error?e.message:String(e)}`),!1}}static async listLocalImages(){try{let{stdout:e}=await ee('docker images --format "{{.Repository}}:{{.Tag}}"');return e.split(`
|
110
|
+
`).filter(n=>n&&!n.includes("<none>")).map(n=>{let[i,a]=n.split(":"),m=i.split("/");return{name:m.length>1?m[1]:i,tag:a}})}catch(e){return r.error(`Failed to list local Docker images: ${e instanceof Error?e.message:String(e)}`),[]}}};import st from"prompts";var it=new _r().name("login").description("Login to Docker Hub").option("-u, --username <username>","Docker Hub username").option("-p, --password <password>","Docker Hub password").option("-r, --registry <registry>","Docker registry URL").action(async t=>{try{let e=t.username,o=t.password,n=t.registry;if(!e){let m=await st({type:"text",name:"username",message:"Enter your Docker Hub username:",validate:c=>c.length>0?!0:"Username cannot be empty"});m.username||(r.error("Username is required"),process.exit(1)),e=m.username}if(!o){let m=await st({type:"password",name:"password",message:"Enter your Docker Hub password:",validate:c=>c.length>0?!0:"Password cannot be empty"});m.password||(r.error("Password is required"),process.exit(1)),o=m.password}await new h("",e,n).login(e,o,n)||(r.error("Failed to login to Docker Hub"),process.exit(1)),await De({username:e,password:o,registry:n||null}),r.success("Logged in to Docker Hub successfully")}catch(e){r.error(`Failed to login to Docker Hub: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as xr}from"commander";import at from"path";import mt from"inquirer";import $r from"fs";var ct=new xr().name("build").description("Build a Docker image").option("-i, --image <image>","Image name").option("-t, --tag <tag>","Image tag").option("-f, --file <file>","Path to Dockerfile","Dockerfile").action(async t=>{try{let e=await x();if(e||(r.error('Docker credentials not found. Please login first with "phala docker login"'),process.exit(1)),!t.image){let m=await mt.prompt([{type:"input",name:"image",message:"Enter the Docker image name:",validate:c=>c.trim()?!0:"Image name is required"}]);t.image=m.image}if(!t.tag){let m=await mt.prompt([{type:"input",name:"tag",message:"Enter the Docker image tag:",default:"latest",validate:c=>c.trim()?!0:"Tag is required"}]);t.tag=m.tag}let o=at.resolve(process.cwd(),t.file);$r.existsSync(o)||(r.info(`Default Dockerfile not found at ${o}`),t.file=await V("Enter the path to your Dockerfile:","Dockerfile","file"));let n=at.resolve(process.cwd(),t.file);await new h(t.image,e.username,e.registry).buildImage(n,t.tag)||(r.error("Failed to build Docker image"),process.exit(1)),r.success(`Docker image ${e.username}/${t.image}:${t.tag} built successfully`)}catch(e){r.error(`Failed to build Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Pr}from"commander";import pt from"inquirer";var lt=new Pr().name("push").description("Push a Docker image to Docker Hub").option("-i, --image <image>","Image name").option("-t, --tag <tag>","Image tag").action(async t=>{try{let e=await x();e||(r.error('Docker credentials not found. Please login first with "phala docker login"'),process.exit(1));let o=t.image,n=t.tag;if(!o||!n){let m=await h.listLocalImages();if(m.length===0&&(r.error('No local Docker images found. Please build an image first with "phala docker build"'),process.exit(1)),!o){let c=Array.from(new Set(m.map(f=>f.name))),{selectedImage:p}=await pt.prompt([{type:"list",name:"selectedImage",message:"Select an image to push:",choices:c}]);o=p}if(!n){let c=m.filter(f=>f.name===o).map(f=>f.tag);c.length===0&&(r.error(`No tags found for image ${o}`),process.exit(1));let{selectedTag:p}=await pt.prompt([{type:"list",name:"selectedTag",message:`Select a tag for ${o}:`,choices:c}]);n=p}}await new h(o,e.username,e.registry).pushImage(n)||(r.error("Failed to push Docker image"),process.exit(1)),r.success(`Docker image ${e.username}/${o}:${n} pushed successfully`)}catch(e){r.error(`Failed to push Docker image: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Dr}from"commander";var ut=new Dr().name("tags").description("List tags for a Docker image").requiredOption("-i, --image <image>","Image name").option("-j, --json","Output in JSON format").action(async t=>{try{let e=await x();e||(r.error('Docker credentials not found. Please login first with "teecloud docker login"'),process.exit(1));let n=await new h(t.image,e.username,e.registry).listTags();if(n.length===0){r.info(`No tags found for image ${e.username}/${t.image}`);return}if(t.json){console.log(JSON.stringify(n,null,2));return}r.info(`Tags for image ${e.username}/${t.image}:`),n.forEach(i=>{r.info(`- ${i}`)})}catch(e){r.error(`Failed to list tags: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Ir}from"commander";import te from"inquirer";import dt from"fs";import ft from"path";var gt=new Ir().name("run").description("Run a Docker Compose setup").option("-c, --compose <compose>","Path to docker-compose.yml file").option("-e, --env-file <env-file>","Path to environment variables file").option("--skip-env","Skip environment variables file prompt",!0).action(async t=>{try{let e=t.compose,o=t.env;if(e)try{E(e)}catch{r.error(`File not found: ${e}`),process.exit(1)}else{let a=ft.join(process.cwd(),"docker-compose.yml");if(dt.existsSync(a)){let{useDefault:c}=await te.prompt([{type:"confirm",name:"useDefault",message:"Use docker-compose.yml in current directory?",default:!0}]);c&&(e=a)}if(!e){let{composePath:c}=await te.prompt([{type:"input",name:"composePath",message:"Enter path to docker-compose.yml file:",validate:p=>E(p)?!0:"File not found"}]);e=c}}if(!o&&!t.skipEnv){let a=ft.join(process.cwd(),".env");if(dt.existsSync(a)){let{useDefault:c}=await te.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);c&&(o=a)}if(!o){let{envPath:c}=await te.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:p=>{try{return E(p),!0}catch{return`File not found: ${p}`}}}]);o=c}}let n=new h("");if(o){try{E(o)}catch{r.error(`File not found: ${o}`),process.exit(1)}r.info(`Running Docker Compose with compose file: ${e} and env file: ${o}`)}else r.info(`Running Docker Compose with compose file: ${e} without env file`);await n.runComposeLocally(e,o)||(r.error("Failed to run Docker Compose"),process.exit(1)),r.success("Docker Compose is running")}catch(e){r.error(`Failed to run Docker Compose: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Tr}from"commander";import b from"inquirer";import K from"fs";import re from"path";var yt=new Tr().name("generate").description("Generate a Docker Compose file").option("-i, --image <image>","Docker image name to use in the compose file").option("-t, --tag <tag>","Docker image tag to use in the compose file").option("-e, --env-file <envFile>","Path to environment variables file").option("-o, --output <output>","Output path for generated docker-compose.yml").option("--template <template>","Template to use for the generated docker-compose.yml").option("--manual","Skip automatic image detection and enter image/tag manually").action(async t=>{try{let e=await x();(!e||!e.username)&&(r.error("Docker Hub username not found. Please login first with `tcc docker login`"),process.exit(1));let o=t.image||"",n=t.tag||"";if((!o||!n)&&!t.manual)try{r.info("Detecting local Docker images...");let p=await h.listLocalImages();if(p.length===0)r.warn("No local Docker images found. You will need to enter image details manually.");else{let f=new Map;if(p.forEach(d=>{f.has(d.name)||f.set(d.name,[]),f.get(d.name)?.push(d.tag)}),o&&!n){let d=f.get(o)||[];if(d.length>0){let{imageTag:u}=await b.prompt([{type:"list",name:"imageTag",message:`Select a tag for ${o}:`,choices:[...d,new b.Separator,"[ Enter manually ]"]}]);u!=="[ Enter manually ]"&&(n=u)}else r.warn(`No tags found for image ${o}. You will need to enter the tag manually.`)}else if(!o){let d=Array.from(f.keys()),{imageName:u}=await b.prompt([{type:"list",name:"imageName",message:"Select a Docker image:",choices:[...d,new b.Separator,"[ Enter manually ]"]}]);if(u!=="[ Enter manually ]"){o=u;let y=f.get(u)||[],{imageTag:l}=await b.prompt([{type:"list",name:"imageTag",message:"Select a tag:",choices:[...y,new b.Separator,"[ Enter manually ]"]}]);l!=="[ Enter manually ]"&&(n=l)}}}}catch(p){r.warn(`Failed to detect local images: ${p instanceof Error?p.message:String(p)}`),r.info("Continuing with manual input...")}if(!o){let{inputImage:p}=await b.prompt([{type:"input",name:"inputImage",message:"Enter Docker image name:",validate:f=>f.trim()?!0:"Image name cannot be empty"}]);o=p}if(!n){let{inputTag:p}=await b.prompt([{type:"input",name:"inputTag",message:`Enter tag for image ${o}:`,validate:f=>f.trim()?!0:"Tag cannot be empty"}]);n=p}let i=t.envFile;if(i)try{E(i)}catch{r.error(`File not found: ${i}`),process.exit(1)}else{let p=re.join(process.cwd(),".env");if(K.existsSync(p)){let{useDefault:d}=await b.prompt([{type:"confirm",name:"useDefault",message:"Use .env file in current directory?",default:!0}]);d&&(i=p)}if(!i){let{envPath:d}=await b.prompt([{type:"input",name:"envPath",message:"Enter path to environment variables file:",validate:u=>{try{return E(u),!0}catch{return`File not found: ${u}`}}}]);i=d}}let a=t.output;if(!a&&(a=re.join(process.cwd(),"docker-compose.yml"),K.existsSync(a))){let{confirmOverwrite:p}=await b.prompt([{type:"confirm",name:"confirmOverwrite",message:`File ${a} already exists. Overwrite?`,default:!1}]);if(!p){let{customPath:f}=await b.prompt([{type:"input",name:"customPath",message:"Enter alternative output path:",default:re.join(process.cwd(),`${o}-${n}-compose.yml`)}]);a=f}}let m=new h(o,e.username,e.registry);i?r.info(`Generating Docker Compose file for ${o}:${n} using env file: ${i}`):r.info(`Generating Docker Compose file for ${o}:${n} without env file`);let c=await m.buildComposeFile(n,i,t.template);if(c!==a){let p=re.dirname(a);K.existsSync(p)||(r.info(`Creating directory: ${p}`),K.mkdirSync(p,{recursive:!0})),K.copyFileSync(c,a)}r.success(`Docker Compose file generated successfully: ${a}`)}catch(e){r.error(`Failed to generate Docker Compose file: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var ht=new Fr().name("docker").description("Login to Docker Hub and manage Docker images").addCommand(it).addCommand(ct).addCommand(lt).addCommand(ut).addCommand(gt).addCommand(yt);import{Command as Vr}from"commander";import{Command as Ar}from"commander";var Ct=new Ar().name("start").description("Start the TEE simulator").option("-i, --image <image>","Simulator image",Te).action(async t=>{try{await new h("").runSimulator(t.image)||(r.error("Failed to start TEE simulator"),process.exit(1))}catch(e){r.error(`Failed to start TEE simulator: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Mr}from"commander";var vt=new Mr().name("stop").description("Stop the TEE simulator").action(async()=>{try{await new h("").stopSimulator()||(r.error("Failed to stop TEE simulator"),process.exit(1))}catch(t){r.error(`Failed to stop TEE simulator: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}});var wt=new Vr().name("simulator").description("TEE simulator commands").addCommand(Ct).addCommand(vt);import{Command as jr}from"commander";import{Command as Ur}from"commander";import H from"fs";import St from"path";import Rr from"os";var oe=St.join(Rr.homedir(),".phala-cloud"),ye=St.join(oe,"config.json"),ge={apiUrl:"https://cloud-api.phala.network",cloudUrl:"https://cloud.phala.network",defaultTeepodId:3,defaultImage:"dstack-dev-0.3.5",defaultVcpu:1,defaultMemory:2048,defaultDiskSize:20};function Nr(){if(!H.existsSync(oe))try{H.mkdirSync(oe,{recursive:!0})}catch(t){throw r.error(`Failed to create directory ${oe}:`,t),t}}function ne(){try{if(H.existsSync(ye)){let t=H.readFileSync(ye,"utf8");return{...ge,...JSON.parse(t)}}return ge}catch(t){return r.error("Failed to load configuration:",t),ge}}function Or(t){Nr();try{H.writeFileSync(ye,JSON.stringify({...ne(),...t},null,2),{mode:384}),r.success("Configuration saved successfully.")}catch(e){throw r.error("Failed to save configuration:",e),e}}function kt(t){return ne()[t]}function Et(t,e){let o=ne();o[t]=e,Or(o)}function bt(){return ne()}var _t=new Ur().name("get").description("Get a configuration value").argument("<key>","Configuration key").action(t=>{try{let e=kt(t);e===void 0&&(r.error(`Configuration key '${t}' not found`),process.exit(1)),r.info(`${t}: ${JSON.stringify(e)}`)}catch(e){r.error(`Failed to get configuration value: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Lr}from"commander";var xt=new Lr().name("set").description("Set a configuration value").argument("<key>","Configuration key").argument("<value>","Configuration value").action((t,e)=>{try{let o=e;if(e.startsWith("{")||e.startsWith("[")||e==="true"||e==="false"||!isNaN(Number(e)))try{o=JSON.parse(e)}catch{}Et(t,o),r.success(`Configuration value for '${t}' set successfully`)}catch(o){r.error(`Failed to set configuration value: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as zr}from"commander";var $t=new zr().name("list").description("List all configuration values").option("-j, --json","Output in JSON format").action(t=>{try{let e=bt();if(t.json){console.log(JSON.stringify(e,null,2));return}r.info("Configuration values:");for(let[o,n]of Object.entries(e))r.info(`${o}: ${JSON.stringify(n)}`)}catch(e){r.error(`Failed to list configuration values: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});var Pt=new jr().name("config").description("Manage your local configuration").addCommand(_t).addCommand(xt).addCommand($t);import{Command as no}from"commander";import{Command as Br}from"commander";import{z as Dt}from"zod";async function he(){try{let t=await w.get(C.CVMS(0));return Dt.array(de).parse(t)}catch(t){throw new Error(`Failed to get CVMs: ${t instanceof Error?t.message:String(t)}`)}}async function R(t){try{let e=await w.get(C.CVM_BY_APP_ID(t));return Ue.parse(e)}catch(e){throw new Error(`Failed to get CVM by App ID: ${e instanceof Error?e.message:String(e)}`)}}async function It(t){try{let e=await w.post(C.CVM_PUBKEY,t);return Oe.parse(e)}catch(e){throw new Error(`Failed to get pubkey from CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Tt(t){try{let e=await w.post(C.CVM_FROM_CONFIGURATION,t);return Ne.parse(e)}catch(e){throw e instanceof Dt.ZodError?(console.error("Schema validation error:",JSON.stringify(e.errors,null,2)),console.error("API response:",JSON.stringify(e.format(),null,2)),new Error(`Response validation failed: ${JSON.stringify(e.errors)}`)):new Error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Ft(t){try{return await w.post(C.CVM_START(t)),!0}catch(e){throw new Error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`)}}async function At(t){try{return await w.post(C.CVM_STOP(t)),!0}catch(e){throw new Error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Mt(t){try{return await w.post(C.CVM_RESTART(t)),!0}catch(e){throw new Error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`)}}async function Vt(t,e){try{let o=await w.put(C.CVM_UPGRADE(t),e);return ze.parse(o)}catch(o){throw new Error(`Failed to upgrade CVM: ${o instanceof Error?o.message:String(o)}`)}}async function Rt(t){try{return await w.delete(C.CVM_BY_APP_ID(t)),!0}catch(e){throw new Error(`Failed to delete CVM: ${e instanceof Error?e.message:String(e)}`)}}async function S(){let{logger:t}=await import("./logger-LBGFMBSV.js"),e=(await import("inquirer")).default,o=t.startSpinner("Fetching available CVMs"),n=await he();if(o.stop(!0),!n||n.length===0){t.info("No CVMs found for your account");return}let i=n.map(m=>{let c=m.hosted?.app_id||m.hosted?.id,p=m.name||m.hosted&&m.hosted.name,f=m.status||m.hosted&&m.hosted.status;return{name:`${p||"Unnamed"} (${c}) - Status: ${f||"Unknown"}`,value:c}}),{selectedCvm:a}=await e.prompt([{type:"list",name:"selectedCvm",message:"Select a CVM:",choices:i}]);return a}async function Nt(t){try{return await w.get(C.CVM_ATTESTATION(t))}catch(e){throw new Error(`Failed to get attestation information: ${e instanceof Error?e.message:String(e)}`)}}async function Ot(t,e,o,n,i){try{let a={};if(e!==void 0&&(a.vcpu=e),o!==void 0&&(a.memory=o),n!==void 0&&(a.disk_size=n),i!==void 0&&(a.allow_restart=i),Object.keys(a).length===0)throw new Error("At least one resource parameter must be provided");return await w.patch(C.CVM_RESIZE(t),a),!0}catch(a){throw new Error(`Failed to resize CVM: ${a instanceof Error?a.message:String(a)}`)}}var Ut=new Br().name("list").description("List all CVMs").option("-j, --json","Output in JSON format").action(async t=>{try{let e=r.startSpinner("Fetching CVMs"),o=await he();if(e.stop(!0),!o||o.length===0){r.info("No CVMs found");return}if(t.json){console.log(JSON.stringify(o,null,2));return}o.forEach(n=>{r.keyValueTable({"App ID":n.hosted.app_id,Name:n.name,Status:n.status,"Node Info URL":n.hosted.app_url,"App URL":`${T}/dashboard/cvms/app_${n.hosted.app_id}`})}),r.success(`Found ${o.length} CVMs:`)}catch(e){r.error(`Failed to list CVMs: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Gr}from"commander";var Lt=new Gr().name("get").description("Get details of a CVM").option("-i, --id <app-id>","App ID of the CVM (optional)").option("-j, --json","Output in JSON format").action(async t=>{try{let e=t.id;if(!e&&(e=await S(),!e))return;let o=r.startSpinner(`Fetching CVM with App ID ${e}`),n=await R(e);if(o.stop(!0),n||(r.error(`CVM with App ID ${e} not found`),process.exit(1)),t.json){console.log(JSON.stringify(n,null,2));return}r.keyValueTable({Name:n.name,Status:n.status,vCPU:n.vcpu,Memory:`${n.memory} MB`,"Disk Size":`${n.disk_size} GB`,"Dstack Image":n.base_image,"TEEPod ID":n.teepod_id,"App URL":`${T}/dashboard/cvms/app_${n.app_id}`})}catch(e){r.error(`Failed to get CVM details: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as qr}from"commander";var zt=new qr().name("start").description("Start a stopped CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async t=>{try{if(!t&&(t=await S(),!t))return;let e=r.startSpinner(`Starting CVM with App ID ${t}`);await Ft(t),e.stop(!0),r.success(`CVM with App ID ${t} started successfully`)}catch(e){r.error(`Failed to start CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Kr}from"commander";var jt=new Kr().name("stop").description("Stop a running CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async t=>{try{if(!t&&(t=await S(),!t))return;let e=r.startSpinner(`Stopping CVM with App ID ${t}`);await At(t),e.stop(!0),r.success(`CVM with App ID ${t} stopped successfully`)}catch(e){r.error(`Failed to stop CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Hr}from"commander";var Bt=new Hr().name("restart").description("Restart a CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").action(async t=>{try{if(!t&&(t=await S(),!t))return;let e=r.startSpinner(`Restarting CVM with App ID ${t}`);await Mt(t),e.stop(!0),r.success(`CVM with App ID ${t} restarted successfully`)}catch(e){r.error(`Failed to restart CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Zr}from"commander";import se from"chalk";var Gt=new Zr().name("attestation").description("Get attestation information for a CVM").argument("[app-id]","CVM app ID (will prompt for selection if not provided)").option("-j, --json","Output in JSON format").action(async(t,e)=>{try{if(!t){r.info("No CVM specified, fetching available CVMs...");let n=await S();if(!n)return;t=n}r.info(`Fetching attestation information for CVM ${t}...`);let o=r.startSpinner("Fetching attestation information");try{let n=await Nt(t);if(o.stop(!0),!n||Object.keys(n).length===0){r.info("No attestation information found");return}if(e?.json){console.log(JSON.stringify(n,null,2));return}r.success("Attestation Summary:");let i={Status:n.is_online?se.green("Online"):se.red("Offline"),"Public Access":n.is_public?se.green("Enabled"):se.yellow("Disabled"),Error:n.error||"None",Certificates:`${n.app_certificates?.length||0} found`};r.keyValueTable(i,{borderStyle:"rounded"}),n.app_certificates&&n.app_certificates.length>0&&n.app_certificates.forEach((a,m)=>{r.success(`Certificate #${m+1} (${a.position_in_chain===0?"End Entity":"CA"}):`);let c={Subject:`${a.subject.common_name||"Unknown"}${a.subject.organization?` (${a.subject.organization})`:""}`,Issuer:`${a.issuer.common_name||"Unknown"}${a.issuer.organization?` (${a.issuer.organization})`:""}`,"Serial Number":a.serial_number,Validity:`${new Date(a.not_before).toLocaleString()} to ${new Date(a.not_after).toLocaleString()}`,Fingerprint:a.fingerprint,"Signature Algorithm":a.signature_algorithm,"Is CA":a.is_ca?"Yes":"No","Position in Chain":a.position_in_chain};r.keyValueTable(c,{borderStyle:"single"})}),n.tcb_info&&(r.success("Trusted Computing Base (TCB) Information:"),r.keyValueTable(n.tcb_info,{borderStyle:"single"}))}catch(n){throw o.stop(!0),n}}catch(o){r.error(`Failed to get attestation information: ${o instanceof Error?o.message:String(o)}`)}});import{Command as Yr}from"commander";import{encryptEnvVars as Wr}from"@phala/dstack-sdk/encrypt-env-vars";import J from"fs";import ie from"path";import P from"inquirer";import Jr from"fs";var Z=(t,e)=>{let o={};if(t){for(let n of t)if(n.includes("=")){let[i,a]=n.split("=");i&&a&&(o[i]=a)}}if(e){let n=Jr.readFileSync(e,"utf8");for(let i of n.split(`
|
111
|
+
`))if(!(!i.trim()||i.trim().startsWith("#"))&&i.includes("=")){let[a,...m]=i.split("="),c=m.join("="),p=c.search(/\s+#/);p!==-1&&(c=c.substring(0,p).trim()),a&&c&&(o[a.trim()]=c.trim())}}return Object.entries(o).map(([n,i])=>({key:n,value:i}))};var qt=new Yr().name("create").description("Create a new CVM").option("-n, --name <name>","Name of the CVM").option("-c, --compose <compose>","Path to Docker Compose file").option("--vcpu <vcpu>","Number of vCPUs",String(L)).option("--memory <memory>","Memory in MB",String(z)).option("--disk-size <diskSize>","Disk size in GB",String(j)).option("--teepod-id <teepodId>","TEEPod ID to use").option("--image <image>","Version of dstack image to use").option("-e, --env-file <envFile>","Path to environment file").option("--skip-env","Skip environment variable prompt",!1).option("--debug","Enable debug mode",!1).action(async t=>{try{if(!t.name){let{name:l}=await P.prompt([{type:"input",name:"name",message:"Enter a name for the CVM:",validate:g=>g.trim()?!0:"CVM name is required"}]);t.name=l}let e=ie.join(process.cwd(),"examples"),o=[];if(J.existsSync(e)){let l=J.readdirSync(e,{withFileTypes:!0}).filter(g=>g.isDirectory()&&!g.name.startsWith(".")).map(g=>g.name);o.push(...l)}let n="";try{if(!t.compose)if(o.length>0){let g=[...o.map((v,_)=>({name:v,value:{type:"example",name:v}})),new P.Separator,{name:"Enter a file path",value:{type:"custom"}}],{selection:k}=await P.prompt([{type:"list",name:"selection",message:"Choose a Docker Compose example or enter a custom path:",choices:g}]);if(k.type==="example"){let v=ie.join(e,k.name),_=["docker-compose.yml","docker-compose.yaml"],Ce=!1;for(let Yt of _){let ve=ie.join(v,Yt);if(J.existsSync(ve)){t.compose=ve,Ce=!0,r.info(`Using example: ${k.name} (${t.compose})`);break}}Ce||(r.error(`Could not find docker-compose.yml or docker-compose.yaml in ${v}`),process.exit(1))}else{let{customPath:v}=await P.prompt([{type:"input",name:"customPath",message:"Enter the path to your Docker Compose file:",validate:_=>_.trim()?!0:"Docker Compose file path is required"}]);t.compose=v}}else{let{customPath:g}=await P.prompt([{type:"input",name:"customPath",message:"Enter the path to your Docker Compose file:",validate:k=>k.trim()?!0:"Docker Compose file path is required"}]);t.compose=g}let l=ie.resolve(t.compose);J.existsSync(l)||(r.error(`Docker Compose file not found: ${l}`),process.exit(1)),n=J.readFileSync(l,"utf8")}catch(l){r.error(`Failed to read Docker Compose file: ${l instanceof Error?l.message:String(l)}`),process.exit(1)}let i=[];if(t.envFile)try{i=Z([],t.envFile)}catch(l){r.error(`Failed to read environment file: ${l instanceof Error?l.message:String(l)}`),process.exit(1)}else if(!t.skipEnv){let l=await V("Enter the path to your environment file:",".env","file");i=Z([],l)}let a=[];if(t.vcpu===String(L)&&a.push({type:"input",name:"vcpu",message:`Enter number of vCPUs (default: ${L}):`,default:String(L),validate:l=>{let g=parseInt(l);return isNaN(g)||g<=0?"Please enter a valid positive number":!0}}),t.memory===String(z)&&a.push({type:"input",name:"memory",message:`Enter memory in MB (default: ${z}):`,default:String(z),validate:l=>{let g=parseInt(l);return isNaN(g)||g<=0?"Please enter a valid positive number":!0}}),t.diskSize===String(j)&&a.push({type:"input",name:"diskSize",message:`Enter disk size in GB (default: ${j}):`,default:String(j),validate:l=>{let g=parseInt(l);return isNaN(g)||g<=0?"Please enter a valid positive number":!0}}),a.length>0){let l=await P.prompt(a);l.vcpu&&(t.vcpu=l.vcpu),l.memory&&(t.memory=l.memory),l.diskSize&&(t.diskSize=l.diskSize)}if(!t.teepodId){let l=r.startSpinner("Fetching available TEEPods"),g=await M();l.stop(!0),g.length===0&&(r.error("No TEEPods available. Please try again later."),process.exit(1));let{selectedTeepodId:k}=await P.prompt([{type:"list",name:"selectedTeepodId",message:"Select a TEEPod:",choices:g.map(_=>({name:`${_.name} (${_.status})`,value:_.id}))}]),v=g.find(_=>_.id===k);v||(r.error("Failed to find selected TEEPod"),process.exit(1)),r.info(`Selected TEEPod: ${v.name}`),t.teepodId=v.id}if(!t.image){let g=(await Q(t.teepodId)).map(v=>({name:`${v.name}`,value:v.name})),{selectedImage:k}=await P.prompt([{type:"list",name:"selectedImage",message:"Select an image:",choices:g}]);t.image=k.value}let m={teepod_id:t.teepodId||3,name:t.name,image:t.image||"dstack-dev-0.3.5",vcpu:parseInt(t.vcpu),memory:parseInt(t.memory),disk_size:parseInt(t.diskSize),compose_manifest:{docker_compose_file:n,docker_config:{url:"",username:"",password:""},features:["kms","tproxy-net"],kms_enabled:!0,manifest_version:2,name:t.name,public_logs:!0,public_sysinfo:!0,tproxy_enabled:!0},listed:!1},c=r.startSpinner("Getting public key from CVM"),p=await It(m);c.stop(!0),p||(r.error("Failed to get public key from CVM"),process.exit(1));let f=r.startSpinner("Encrypting environment variables"),d=await Wr(i,p.app_env_encrypt_pubkey);f.stop(!0),t.debug&&(r.debug("Public key:",p.app_env_encrypt_pubkey),r.debug("Encrypted environment variables:",d),r.debug("Environment variables:",JSON.stringify(i)));let u=r.startSpinner("Creating CVM"),y=await Tt({...m,encrypted_env:d,app_env_encrypt_pubkey:p.app_env_encrypt_pubkey,app_id_salt:p.app_id_salt});u.stop(!0),y||(r.error("Failed to create CVM"),process.exit(1)),r.success("CVM created successfully"),r.info(`CVM ID: ${y.id}`),r.info(`Name: ${y.name}`),r.info(`Status: ${y.status}`),r.info(`App ID: ${y.app_id}`),y.app_url?r.info(`App URL: ${y.app_url}`):r.info(`App URL: ${T}/dashboard/cvms/app_${y.app_id}`),r.info(""),r.info("Your CVM is being created. You can check its status with:"),r.info(`phala cvms status ${y.app_id}`)}catch(e){r.error(`Failed to create CVM: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});import{Command as Xr}from"commander";import Qr from"inquirer";var Kt=new Xr().name("delete").description("Delete a CVM").argument("[app-id]","App ID of the CVM to delete (if not provided, a selection prompt will appear)").option("-f, --force","Skip confirmation prompt",!1).action(async(t,e)=>{try{if(!t&&(t=await S(),!t))return;if(!e.force){let{confirm:i}=await Qr.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete CVM with App ID ${t}? This action cannot be undone.`,default:!1}]);if(!i){r.info("Deletion cancelled");return}}let o=r.startSpinner(`Deleting CVM ${t}`),n=await Rt(t);o.stop(!0),n||(r.error(`Failed to delete CVM ${t}`),process.exit(1)),r.success(`CVM ${t} deleted successfully`)}catch(o){r.error(`Failed to delete CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as eo}from"commander";import to from"fs";import{encryptEnvVars as ro}from"@phala/dstack-sdk/encrypt-env-vars";var Ht=new eo().name("upgrade").description("Upgrade a CVM to a new version").argument("[app-id]","CVM app ID to upgrade (will prompt for selection if not provided)").option("-c, --compose <compose>","Path to new Docker Compose file").option("-e, --env-file <envFile>","Path to environment file").option("--debug","Enable debug mode",!1).action(async(t,e)=>{try{if(!t){r.info("No CVM specified, fetching available CVMs...");let d=await S();if(!d)return;t=d}let o=r.startSpinner(`Fetching current configuration for CVM ${t}`),n=await R(t);o.stop(!0),n||(r.error(`CVM with App ID ${t} not found`),process.exit(1));let i={};e.compose||(e.compose=await V("Enter the path to your Docker Compose file:","docker-compose.yml","file"));let a="";if(e.compose)try{a=to.readFileSync(e.compose,"utf8")}catch(d){r.error(`Failed to read Docker Compose file: ${d instanceof Error?d.message:String(d)}`),process.exit(1)}let m="";if(e.envFile){let d=[];if(e.envFile)try{d=Z([],e.envFile),m=await ro(d,n.encrypted_env_pubkey)}catch(u){r.error(`Failed to read environment file: ${u instanceof Error?u.message:String(u)}`),process.exit(1)}}let c={compose_manifest:{docker_compose_file:a,manifest_version:1,runner:"docker-compose",version:"1.0.0",features:["kms","tproxy-net"],name:`app_${e.appId}`},encrypted_env:m,allow_restart:!0},p=r.startSpinner(`Upgrading CVM ${t}`),f=await Vt(t,c);p.stop(!0),f||(r.error("Failed to upgrade CVM"),process.exit(1)),r.success(`CVM ${t} upgraded successfully`),f.detail&&r.info(`Details: ${f.detail}`)}catch(o){r.error(`Failed to upgrade CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});import{Command as oo}from"commander";import Y from"inquirer";var Zt=new oo().name("resize").description("Resize resources for a CVM").argument("[app-id]","App ID of the CVM (if not provided, a selection prompt will appear)").option("-v, --vcpu <vcpu>","Number of virtual CPUs").option("-m, --memory <memory>","Memory size in MB").option("-d, --disk-size <diskSize>","Disk size in GB").option("-r, --allow-restart <allowRestart>","Allow restart of the CVM if needed for resizing").option("-y, --yes","Automatically confirm the resize operation").action(async(t,e)=>{try{if(!t&&(t=await S(),!t)){r.info("No CVMs found or selection cancelled");return}let o=await R(t),n=e.vcpu,i=e.memory,a=e.diskSize,m=e.allowRestart;n||(n=(await Y.prompt([{type:"input",name:"vcpu",message:"Enter number of vCPUs:",validate:u=>{let y=parseInt(u);return isNaN(y)||y<0?"Please enter a valid non-negative number":!0},default:o.vcpu,filter:u=>parseInt(u)}])).vcpu),i||(i=(await Y.prompt([{type:"input",name:"memory",message:"Enter memory in MB:",validate:u=>{let y=parseInt(u);return isNaN(y)||y<0?"Please enter a valid non-negative number":!0},default:o.memory,filter:u=>parseInt(u)}])).memory),a||(a=(await Y.prompt([{type:"input",name:"diskSize",message:"Enter disk size in GB:",validate:u=>{let y=parseInt(u);return isNaN(y)||y<0?"Please enter a valid non-negative number":!0},default:o.disk_size,filter:u=>parseInt(u)}])).diskSize),m||(m=(await Y.prompt([{type:"confirm",name:"allowRestart",message:"Allow restart of the CVM if needed for resizing?",default:!1}])).allowRestart);let c=`Are you sure you want to resize CVM ${t} with the following changes:
|
112
|
+
`;if(r.keyValueTable({vCPUs:o.vcpu!==n?`${o.vcpu} -> ${n}`:o.vcpu,Memory:o.memory!==i?`${o.memory} MB -> ${i} MB`:o.memory,"Disk Size":o.disk_size!==a?`${o.disk_size} GB -> ${a} GB`:o.disk_size,"Allow Restart":m?"Yes":"No"}),!e.yes){let{confirm:d}=await Y.prompt([{type:"confirm",name:"confirm",message:c,default:!1}]);if(!d){r.info("Resize operation cancelled");return}}let p=r.startSpinner(`Resizing CVM with App ID ${t}`);await Ot(t,n,i,a,m?1:0),p.stop(!0),r.success(`CVM with App ID ${t} resized successfully`)}catch(o){r.error(`Failed to resize CVM: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});var Jt=new no().name("cvms").description("Manage Phala Confidential Virtual Machines (CVMs)").addCommand(Ut).addCommand(Lt).addCommand(qt).addCommand(Ht).addCommand(zt).addCommand(jt).addCommand(Bt).addCommand(Gt).addCommand(Kt).addCommand(Zt);process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function io(){new so().name("phala").description(`${Ee}
|
113
|
+
Phala Cloud CLI - Manage your Phala Cloud Deployments`).version("0.0.1").addCommand(Ze).addCommand(Xe).addCommand(ht).addCommand(wt).addCommand(Pt).addCommand(Jt).parse(process.argv)}io().catch(t=>{r.error("An error occurred:",t),process.exit(1)});
|
114
|
+
//# sourceMappingURL=index.js.map
|