@exiahuang/esf 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -0
- package/dist/index.js +92 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# esf - EasySFDX Terminal User Interface (TUI)
|
|
2
|
+
|
|
3
|
+
`esf` is a terminal-based development dashboard for Salesforce (SFDX) developers, designed to provide a highly interactive, fast, and feature-rich terminal user interface. It is migrated from the VS Code extension `easysfdx` .
|
|
4
|
+
|
|
5
|
+
## Features & Tab Layout
|
|
6
|
+
|
|
7
|
+
1. **[1] Deploy/Retrieve**:
|
|
8
|
+
- Lists all Git staged, unstaged, and untracked files.
|
|
9
|
+
- Highlights file diffs with syntax coloring (green for additions, red for deletions).
|
|
10
|
+
- Press **`Space`** to toggle selection of files.
|
|
11
|
+
- Press **`d`** to deploy selected files to your target Salesforce org.
|
|
12
|
+
- Press **`D`** to deploy selected files with a **Dry Run** verification.
|
|
13
|
+
- Press **`r`** to retrieve selected files from Salesforce.
|
|
14
|
+
- Press **`m`** to show a list of metadata types and retrieve selected types.
|
|
15
|
+
- Press **`a`** to retrieve all metadata.
|
|
16
|
+
- Press **`g`** to refresh Git status.
|
|
17
|
+
|
|
18
|
+
2. **[2] SOQL Browser**:
|
|
19
|
+
- Focus the query box, type any SOQL query (e.g., `SELECT Id, Name FROM Account LIMIT 10`), and press **`Ctrl-e`** to execute.
|
|
20
|
+
- View query results formatted as colored JSON records.
|
|
21
|
+
|
|
22
|
+
3. **[3] Apex Logs**:
|
|
23
|
+
- Lists recent Salesforce Apex Logs.
|
|
24
|
+
- Select a log from the list to display its complete body in the detail viewer with custom warning/debug syntax highlighting.
|
|
25
|
+
- Press **`g`** to refresh the log list.
|
|
26
|
+
- Press **`t`** to open a real-time log tail stream (`sf apex log tail`).
|
|
27
|
+
|
|
28
|
+
4. **[4] Apex Jobs**:
|
|
29
|
+
- Lists and monitors Salesforce `AsyncApexJob` records (Batch Apex, Queueable Apex, etc.) with real-time status colors and execution progress.
|
|
30
|
+
- Press **`Enter`** on any job to view an overlay dialog showing complete details (including stack traces/error messages if failed).
|
|
31
|
+
- Press **`g`** to refresh the job list.
|
|
32
|
+
|
|
33
|
+
5. **[5] Metadata Explorer**:
|
|
34
|
+
- Browse metadata components (e.g., `ApexClass`, `ApexTrigger`) directly from Salesforce.
|
|
35
|
+
- View the source code body of classes and triggers directly in the TUI.
|
|
36
|
+
- Press **`g`** to refresh the list of items.
|
|
37
|
+
|
|
38
|
+
6. **[6] Org Manager**:
|
|
39
|
+
- Displays all authenticated Salesforce orgs (`sf org list`).
|
|
40
|
+
- Press **`Enter`** on any org in the list to switch your default Salesforce target org (`sf config set target-org=<alias>`).
|
|
41
|
+
- Displays detailed credentials, login URLs, and access tokens for the highlighted org.
|
|
42
|
+
- Press **`g`** to refresh the org list.
|
|
43
|
+
|
|
44
|
+
7. **[7] CSV Viewer**:
|
|
45
|
+
- Scans your current workspace root folder for `.csv` files.
|
|
46
|
+
- Select any CSV file to display its contents in a beautifully formatted text grid with auto-aligned column borders.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Prerequisites
|
|
51
|
+
|
|
52
|
+
- **Node.js** (v18 or higher)
|
|
53
|
+
- **Salesforce CLI (`sf`)** installed and authenticated to your org(s).
|
|
54
|
+
- **Git** (optional, required for Tab 1 Deploy/Retrieve changed files).
|
|
55
|
+
|
|
56
|
+
## Installation & Running
|
|
57
|
+
|
|
58
|
+
Initialize the project dependencies:
|
|
59
|
+
```bash
|
|
60
|
+
npm install
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Dev Mode
|
|
64
|
+
Run the tool directly from TypeScript source:
|
|
65
|
+
```bash
|
|
66
|
+
npm run dev
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Production Build & Run
|
|
70
|
+
Compile the TypeScript code using `tsup`:
|
|
71
|
+
```bash
|
|
72
|
+
npm run build
|
|
73
|
+
```
|
|
74
|
+
Start the compiled CommonJS bundle:
|
|
75
|
+
```bash
|
|
76
|
+
npm start
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Global Navigation Keys
|
|
82
|
+
|
|
83
|
+
- **`1` to `7`**: Switch tabs.
|
|
84
|
+
- **`Tab`**: Cycle focus between panels (e.g., from list to diff box).
|
|
85
|
+
- **`Ctrl-c`**: Exit the application.
|
|
86
|
+
- **`Up / Down`** (or **`j / k`**): Scroll lists or text views.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
var Cs=Object.create;var Ot=Object.defineProperty;var xs=Object.getOwnPropertyDescriptor;var ks=Object.getOwnPropertyNames;var $s=Object.getPrototypeOf,Es=Object.prototype.hasOwnProperty;var vs=(l,r,n,c)=>{if(r&&typeof r=="object"||typeof r=="function")for(let g of ks(r))!Es.call(l,g)&&g!==n&&Ot(l,g,{get:()=>r[g],enumerable:!(c=xs(r,g))||c.enumerable});return l};var he=(l,r,n)=>(n=l!=null?Cs($s(l)):{},vs(r||!l||!l.__esModule?Ot(n,"default",{value:l,enumerable:!0}):n,l));var _t=he(require("blessed"));var d=he(require("blessed")),B=he(require("fs")),re=he(require("path"));var P=he(require("path")),L=he(require("fs")),Dt=he(require("js-yaml")),A=require("child_process");function De(){let l=process.cwd(),n=(()=>{try{let g=P.join(l,".sfdx","sfdx-config.json");return L.existsSync(g)?JSON.parse(L.readFileSync(g,"utf8")).defaultusername:null}catch{return null}})(),c={apiVersion:"61.0",alias:n||"",logDir:P.join(l,"logs"),logLevel:"INFO",query:{db:P.join(l,"data",(n||"default")+"_data.db"),autoQuery:!1}};try{let g=P.join(l,".easy","sfdx.yml"),u={};if(L.existsSync(g)){let y=L.readFileSync(g,"utf8");u=Dt.load(y)}return{apiVersion:u.apiVersion||c.apiVersion,alias:u.alias||c.alias,logDir:u.logDir||c.logDir,logLevel:u.logLevel||c.logLevel,query:{db:u.query?.db||c.query.db,autoQuery:u.query?.autoQuery||c.query.autoQuery}}}catch{return c}}var se=l=>Lt(l);function Lt(l){return!l.includes("force-app/")&&!l.includes("src/")&&!l.includes("staticresources/")?!1:l.includes("-meta.xml")?!0:/\.(app|auradoc|cls|cmp|css|component|design|email|evt|trigger|page|html|js|json|md|xml|object|field|layout|permissionset|profile|tab|flow|resource)$/.test(l)||l.includes("staticresources/")}function Tt(){try{let r=(0,A.execSync)("git status --porcelain",{encoding:"utf8",stdio:"pipe"}).split(`
|
|
3
|
+
`),n=[];for(let c of r){if(!c||c.trim()==="")continue;let g=c.slice(0,2),u=c.slice(3).trim().replace(/^["']|["']$/g,""),y="unstaged";g==="??"?y="untracked":g[0]!==" "&&g[0]!=="?"&&(y="staged"),n.push({path:u,status:y,actionCode:g})}return n}catch{return[]}}function Fs(){return process.cwd()}function Le(l,r=Fs()){return new Promise((n,c)=>{(0,A.exec)(l,{cwd:r,encoding:"utf8",maxBuffer:1024*1024*10},(g,u,y)=>{if(g){c(Object.assign(g,{stdout:u,stderr:y}));return}n({stdout:u,stderr:y})})})}function Os(l){if(!l)return"";let r=l.match(/\(HEAD -> ([^,)]+)/);return r?r[1]:l.replace(/[()]/g,"").trim()}async function Rs(l){try{let{stdout:r}=await Le(`git -c core.quotepath=false show --name-status --pretty=format: ${l}`),n=[],c=r.trim().split(`
|
|
4
|
+
`);for(let g of c){if(!g.trim())continue;let u=g.trim().split(" ");if(u.length>=2){let y=u[0],h=u[1];y.startsWith("R")&&u.length>=3?n.push({status:y,file:u[2],oldFile:h}):n.push({status:y,file:h})}}return n}catch{return[]}}function As(l){if(!l.trim())return null;let[r,n,c,g,u]=l.split("|");return r?{hash:r.trim(),author:(n||"").trim(),date:(c||"").trim(),message:(g||"").trim(),branch:Os(u||""),files:[]}:null}async function Ue(l=50){try{let{stdout:r}=await Le(`git -c core.quotepath=false log --pretty=format:"%H|%an|%ad|%s|%d" --date=short --max-count=${l}`),n=[],c=r.trim().split(`
|
|
5
|
+
`);for(let g of c){let u=As(g);u&&(u.files=await Rs(u.hash),n.push(u))}return n}catch{return[]}}async function Pt(l,r="all"){let n=l.trim().toLowerCase();return n?(await Ue(200)).filter(g=>{let u=g.author.toLowerCase(),y=g.message.toLowerCase(),h=g.branch.toLowerCase(),w=g.hash.toLowerCase();return r==="author"?u.includes(n):r==="message"?y.includes(n):u.includes(n)||y.includes(n)||h.includes(n)||w.includes(n)}):Ue(200)}async function It(l,r){try{let{stdout:n}=await Le(`git -c core.quotepath=false diff --name-status ${l}..${r}`),c=[],g=n.trim().split(`
|
|
6
|
+
`);for(let u of g){if(!u.trim())continue;let y=u.trim().split(" ");if(y.length>=2){let h=y[0],w=y[1];h.startsWith("R")&&y.length>=3?c.push({status:h,file:y[2],oldFile:w}):c.push({status:h,file:w})}}return c}catch{return[]}}async function Nt(){try{let{stdout:l}=await Le("git -c core.quotepath=false branch --show-current");return l.trim()||"unknown"}catch{return"unknown"}}async function ke(){try{let{stdout:l}=await Le("git -c core.quotepath=false diff --cached --name-status"),r=[],n=l.trim().split(`
|
|
7
|
+
`);for(let c of n){if(!c.trim())continue;let g=c.trim().split(" ");if(g.length>=2){let u=g[0],y=g[1];u.startsWith("R")&&g.length>=3?r.push({status:u,file:g[2],oldFile:y}):r.push({status:u,file:y})}}return r}catch{return[]}}function Je(l){try{return process.platform==="win32"?(0,A.spawnSync)("clip",[],{input:l,encoding:"utf8"}).status===0:process.platform==="darwin"?(0,A.spawnSync)("pbcopy",[],{input:l,encoding:"utf8"}).status===0:(0,A.spawnSync)("xclip",["-selection","clipboard"],{input:l,encoding:"utf8"}).status===0?!0:(0,A.spawnSync)("xsel",["--clipboard","--input"],{input:l,encoding:"utf8"}).status===0}catch{return!1}}function He(){if(process.env.SHELL){let l=process.env.SHELL;if(l.endsWith(".bat")||l.endsWith(".cmd")){try{let n=require("fs").readFileSync(l,"utf8").match(/["']([^"']+bash\.exe)["']/i);if(n&&require("fs").existsSync(n[1]))return n[1]}catch{}return"C:\\Program Files\\Git\\bin\\bash.exe"}return l}}function ot(l,r,n){return new Promise(c=>{let g={env:{...process.env,LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"},shell:He()},u=(0,A.exec)(l,g);u.stdout?.on("data",y=>{r(y.toString())}),u.stderr?.on("data",y=>{n(y.toString())}),u.on("close",y=>{c(y??0)})})}function Gt(l){let r=[],n=[];l.forEach(u=>{Lt(u)&&(u.includes("-meta.xml")?n.push(u):r.push(u))});let c=r.filter(u=>{let y=u+"-meta.xml";return!n.some(h=>h===y)}),g=[...n,...c];return{sourceFiles:c,metadataFiles:n,allValidFiles:g}}function Ds(l){let{allValidFiles:r}=Gt(l);return r.join(" ")}var Rt={".cls":{type:"ApexClass"},".trigger":{type:"ApexTrigger"},".page":{type:"ApexPage"},".component":{type:"ApexComponent"},".object":{type:"CustomObject"},".field":{type:"CustomField"},".tab":{type:"CustomTab"},".app":{type:"CustomApplication"},".layout":{type:"Layout"},".profile":{type:"Profile"},".permissionset":{type:"PermissionSet"},".workflow":{type:"Workflow"},".flow":{type:"Flow"},".email":{type:"EmailTemplate"},".document":{type:"Document"},".resource":{type:"StaticResource"},".site":{type:"CustomSite"},".queue":{type:"Queue"},".role":{type:"Role"},".group":{type:"Group"},".report":{type:"Report"},".dashboard":{type:"Dashboard"},".listview":{type:"ListView"},".validationrule":{type:"ValidationRule"},".assignmentrule":{type:"AssignmentRule"},".escalationrule":{type:"EscalationRule"},".approvalprocess":{type:"ApprovalProcess"},".quickaction":{type:"QuickAction"},".flexipage":{type:"FlexiPage"},".aura":{type:"AuraDefinitionBundle"},".lwc":{type:"LightningComponentBundle"},".bot":{type:"Bot"},".channel":{type:"Channel"},".skill":{type:"Skill"},".matchingrule":{type:"MatchingRule"},".duplicaterule":{type:"DuplicateRule"},".namedcredential":{type:"NamedCredential"},".remotesite":{type:"RemoteSiteSetting"},".csp":{type:"CspTrustedSite"},".cors":{type:"CorsWhitelistOrigin"},".iframe":{type:"IframeWhiteListUrlSettings"},".cert":{type:"Certificate"},".auth":{type:"AuthProvider"},".connectedapp":{type:"ConnectedApp"},".community":{type:"Community"},".experience":{type:"ExperienceBundle"},".network":{type:"Network"},".branding":{type:"BrandingSet"},".cache":{type:"CachePartition"},".forecast":{type:"ForecastingType"},".leadconvert":{type:"LeadConvertSetting"},".presence":{type:"PresenceUserConfig"},".service":{type:"ServiceChannel"},".topic":{type:"TopicsForObjects"},".wave":{type:"WaveApplication"},".ui":{type:"UiViewDefinition"},".user":{type:"UserCriteria"},".explainability":{type:"ExplainabilityActionDefinition"},".external":{type:"ExternalCredential"},classes:{type:"ApexClass",metadataOnly:!0},triggers:{type:"ApexTrigger",metadataOnly:!0},pages:{type:"ApexPage",metadataOnly:!0},components:{type:"ApexComponent",metadataOnly:!0},objects:{type:"CustomObject",metadataOnly:!0},fields:{type:"CustomField",metadataOnly:!0},tabs:{type:"CustomTab",metadataOnly:!0},applications:{type:"CustomApplication",metadataOnly:!0},layouts:{type:"Layout",metadataOnly:!0},profiles:{type:"Profile",metadataOnly:!0},permissionsets:{type:"PermissionSet",metadataOnly:!0},workflows:{type:"Workflow",metadataOnly:!0},flows:{type:"Flow",metadataOnly:!0},email:{type:"EmailTemplate",metadataOnly:!0},documents:{type:"Document",metadataOnly:!0},staticresources:{type:"StaticResource",metadataOnly:!1,sourceExtensions:[".resource"]},sites:{type:"CustomSite",metadataOnly:!0},queues:{type:"Queue",metadataOnly:!0},roles:{type:"Role",metadataOnly:!0},groups:{type:"Group",metadataOnly:!0},reports:{type:"Report",metadataOnly:!0},dashboards:{type:"Dashboard",metadataOnly:!0},listviews:{type:"ListView",metadataOnly:!0},validationrules:{type:"ValidationRule",metadataOnly:!0},assignmentrules:{type:"AssignmentRule",metadataOnly:!0},escalationrules:{type:"EscalationRule",metadataOnly:!0},approvalprocesses:{type:"ApprovalProcess",metadataOnly:!0},quickactions:{type:"QuickAction",metadataOnly:!0},flexipages:{type:"FlexiPage",metadataOnly:!0},bots:{type:"Bot",metadataOnly:!0},channels:{type:"Channel",metadataOnly:!0},skills:{type:"Skill",metadataOnly:!0},matchingrules:{type:"MatchingRule",metadataOnly:!0},duplicaterules:{type:"DuplicateRule",metadataOnly:!0},namedcredentials:{type:"NamedCredential",metadataOnly:!0},remotesites:{type:"RemoteSiteSetting",metadataOnly:!0},csp:{type:"CspTrustedSite",metadataOnly:!0},cors:{type:"CorsWhitelistOrigin",metadataOnly:!0},iframe:{type:"IframeWhiteListUrlSettings",metadataOnly:!0},certs:{type:"Certificate",metadataOnly:!0},auth:{type:"AuthProvider",metadataOnly:!0},connectedapps:{type:"ConnectedApp",metadataOnly:!0},communities:{type:"Community",metadataOnly:!0},experiences:{type:"ExperienceBundle",metadataOnly:!0},networks:{type:"Network",metadataOnly:!0},branding:{type:"BrandingSet",metadataOnly:!0},cache:{type:"CachePartition",metadataOnly:!0},forecasting:{type:"ForecastingType",metadataOnly:!0},leadconvert:{type:"LeadConvertSetting",metadataOnly:!0},presence:{type:"PresenceUserConfig",metadataOnly:!0},service:{type:"ServiceChannel",metadataOnly:!0},topics:{type:"TopicsForObjects",metadataOnly:!0},wave:{type:"WaveApplication",metadataOnly:!0},ui:{type:"UiViewDefinition",metadataOnly:!0},user:{type:"UserCriteria",metadataOnly:!0},explainability:{type:"ExplainabilityActionDefinition",metadataOnly:!0},external:{type:"ExternalCredential",metadataOnly:!0}};function Ls(l){let r=l.includes("-meta.xml"),n=P.basename(l);if(!r){let g=P.extname(l).toLowerCase(),u=Rt[g];if(u)return u.type}let c=l.toLowerCase().split("/");if(c.includes("aura")&&(r||n.endsWith(".app")||n.endsWith(".cmp")||n.endsWith(".evt")||n.endsWith(".intf")))return"AuraDefinitionBundle";if(c.includes("lwc")&&(r||n.endsWith(".js")||n.endsWith(".html")||n.endsWith(".css")))return"LightningComponentBundle";for(let[g,u]of Object.entries(Rt))if(c.includes(g)&&(u.metadataOnly&&r||u.sourceExtensions&&u.sourceExtensions.some(y=>n.endsWith(y))))return u.type;return null}var Ts={CustomObject:"__c",CustomTab:"Tab",CustomApplication:"App",Layout:"Layout",ValidationRule:"ValidationRule",AssignmentRule:"AssignmentRule",EscalationRule:"EscalationRule",ApprovalProcess:"ApprovalProcess",QuickAction:"QuickAction",FlexiPage:"FlexiPage",AuraDefinitionBundle:"Aura",LightningComponentBundle:"LWC",Bot:"Bot",Channel:"Channel",Skill:"Skill",MatchingRule:"MatchingRule",DuplicateRule:"DuplicateRule",NamedCredential:"NamedCredential",RemoteSiteSetting:"RemoteSiteSetting",CspTrustedSite:"CspTrustedSite",CorsWhitelistOrigin:"CorsWhitelistOrigin",IframeWhiteListUrlSettings:"IframeWhiteListUrlSettings",Certificate:"Certificate",AuthProvider:"AuthProvider",ConnectedApp:"ConnectedApp",Community:"Community",ExperienceBundle:"ExperienceBundle",SiteDotCom:"SiteDotCom",Network:"Network",BrandingSet:"BrandingSet",CachePartition:"CachePartition",ForecastingType:"ForecastingType",LeadConvertSetting:"LeadConvertSetting",PresenceUserConfig:"PresenceUserConfig",ServiceChannel:"ServiceChannel",TopicsForObjects:"TopicsForObjects",WaveApplication:"WaveApplication",UiViewDefinition:"UiViewDefinition",UserCriteria:"UserCriteria",ExplainabilityActionDefinition:"ExplainabilityActionDefinition",ExternalCredential:"ExternalCredential",FieldRestrictionRule:"FieldRestrictionRule",FieldSet:"FieldSet",GlobalValueSet:"GlobalValueSet",GlobalValueSetTranslation:"GlobalValueSetTranslation",StandardValueSet:"StandardValueSet",CustomIndex:"CustomIndex",Index:"Index",KeywordList:"KeywordList",ModerationRule:"ModerationRule",PathAssistant:"PathAssistant",PostTemplate:"PostTemplate",Prompt:"Prompt",QueueRoutingConfig:"QueueRoutingConfig",SamlSsoConfig:"SamlSsoConfig",ServicePresenceStatus:"ServicePresenceStatus",SharingRules:"SharingRules",SharingSet:"SharingSet",WorkflowAlert:"WorkflowAlert",WorkflowFlowAutomation:"WorkflowFlowAutomation",WorkflowRule:"WorkflowRule"};function At(l,r){let n=P.basename(l),c;n.endsWith("-meta.xml")?c=n.replace(/\..+-meta\.xml$/,""):c=P.parse(n).name;let g=Ts[r];return g&&c.endsWith(g)?c.slice(0,-g.length):c}function Ps(l,r){if(["LightningComponentBundle","AuraDefinitionBundle"].includes(r)){let n=l.split("/");if(r==="LightningComponentBundle"){let c=n.findIndex(g=>g==="lwc");if(c!==-1&&c+1<n.length)return n[c+1]}else if(r==="AuraDefinitionBundle"){let c=n.findIndex(g=>g==="aura");if(c!==-1&&c+1<n.length)return n[c+1]}return At(l,r)||""}return At(l,r)||""}function Is(l){let r={};return l.forEach(n=>{let c=Ls(n);if(c){r[c]||(r[c]=[]);let g=Ps(n,c);g&&!r[c].includes(g)&&r[c].push(g)}}),Object.fromEntries(Object.entries(r).sort(([n],[c])=>n.localeCompare(c)))}function Ns(l){let r=Is(l),n=`<?xml version="1.0" encoding="UTF-8"?>
|
|
8
|
+
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
9
|
+
`;return Object.keys(r).forEach(c=>{n+=` <types>
|
|
10
|
+
`,r[c].forEach(g=>{n+=` <members>${g}</members>
|
|
11
|
+
`}),n+=` <name>${c}</name>
|
|
12
|
+
`,n+=` </types>
|
|
13
|
+
`}),n+=` <version>64.0</version>
|
|
14
|
+
</Package>`,n}async function Te(l,r,n,c,g,u){let y=Array.from(r),{allValidFiles:h}=Gt(y);if(h.length===0)throw new Error("No Salesforce resource files found in selected commits and staged files");let w=Ds(y),O=De().alias,T=c||120,G=g!==void 0?g:!0,Ee=l||"dev",de=`${(process.env.TEMP||process.env.TMP||"/tmp").replace(/\\/g,"/")}/esf/${Ee}`,J=`${de}/mdapioutput`,Y=`${de}/${Ee}.zip`,ve="";if(u){let H=Ns(h);ve=`# Generate package.xml manifest
|
|
15
|
+
mkdir -p "${J}"
|
|
16
|
+
echo '${H.replace(/'/g,`'"'"'`)}' > "${J}/package.xml"
|
|
17
|
+
|
|
18
|
+
`}let Ie=l?`--package-name "${l}"`:"",q=!1;try{(0,A.execSync)("7z",{stdio:"pipe"}),q=!0}catch{}let Ke=q?`7z a "${Y}" "${J}"`:`cd "$(dirname "${J}")" && zip -r "${Y}" "$(basename "${J}")"`,Ne=q?`7z l "${Y}"`:`unzip -l "${Y}"`,oe=`${ve}# Clean up previous builds
|
|
19
|
+
rm -rf "${J}" "${Y}"
|
|
20
|
+
|
|
21
|
+
# Convert source to metadata format${u?" (USING MANIFEST)":""}
|
|
22
|
+
sf project convert source --source-dir ${w} --output-dir "${J}" ${Ie}
|
|
23
|
+
|
|
24
|
+
# Create package zip (${q?"7z":"zip"})
|
|
25
|
+
${Ke}
|
|
26
|
+
|
|
27
|
+
# List package contents
|
|
28
|
+
${Ne}`,C=`# Deploy commands${u?" (USING MANIFEST)":""}`;if(u)if(n&&n.trim()){let H=n.split(",").map(v=>v.trim()).join(" ");C+=`
|
|
29
|
+
sf project deploy start --manifest "${J}/package.xml" --wait ${T} --target-org ${O} --test-level RunSpecifiedTests --tests ${H}${G?" --dry-run":""}`}else C+=`
|
|
30
|
+
sf project deploy start --manifest "${J}/package.xml" --wait ${T} --target-org ${O} --test-level NoTestRun${G?" --dry-run":""}`;else if(n&&n.trim()){let H=n.split(",").map(v=>v.trim()).join(" ");C+=`
|
|
31
|
+
sf project deploy start --source-dir ${w} --wait ${T} --target-org ${O} --test-level RunSpecifiedTests --tests ${H}${G?" --dry-run":""}`}else C+=`
|
|
32
|
+
sf project deploy start --source-dir ${w} --wait ${T} --target-org ${O} --test-level NoTestRun${G?" --dry-run":""}`;if(C+=`
|
|
33
|
+
|
|
34
|
+
# Deploy package commands${u?" (USING MANIFEST)":""}`,n&&n.trim()){let H=n.split(",").map(v=>v.trim()).join(" ");C+=`
|
|
35
|
+
sf project deploy start --metadata-dir "${Y}" --wait ${T} --target-org ${O} --test-level RunSpecifiedTests --tests ${H}${G?" --dry-run":""}`}else C+=`
|
|
36
|
+
sf project deploy start --metadata-dir "${Y}" --wait ${T} --target-org ${O} --test-level NoTestRun${G?" --dry-run":""}`;let ne="# Run test classes";if(n&&n.trim()){let H=n.split(",").map(v=>v.trim()).join(" ");ne+=`
|
|
37
|
+
sf apex run test --class-names ${H} -o ${O} --verbose`}else ne+=`
|
|
38
|
+
sf apex run test --synchronous -o ${O} --verbose`;return{create:oe,deploy:C,test:ne}}function Pe(l){try{let r={encoding:"utf8",env:{...process.env,LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"},shell:He()};return(0,A.execSync)(l,r)}catch(r){return r.stdout||r.stderr||r.message||"Execution error"}}async function be(l,r){let c=`sf data query --query "${l.replace(/"/g,'\\"').replace(/\n/g," ")}" --target-org ${r} --json`;return new Promise((g,u)=>{(0,A.exec)(c,{maxBuffer:1024*1024*10},(y,h,w)=>{if(y){try{let S=JSON.parse(h||w||"{}");u(new Error(S.message||S.errorMessage||y.message))}catch{u(new Error(h||w||y.message))}return}try{let S=JSON.parse(h);S.status===0||S.result?g(S.result):u(new Error(S.message||"Query failed"))}catch{u(new Error("Failed to parse response: "+h))}})})}async function jt(l,r){let c=`sf data query --query "${l.replace(/"/g,'\\"').replace(/\n/g," ")}" --target-org ${r} --use-tooling-api --json`;return new Promise((g,u)=>{(0,A.exec)(c,{maxBuffer:1024*1024*10},(y,h,w)=>{if(y){try{let S=JSON.parse(h||w||"{}");u(new Error(S.message||S.errorMessage||y.message))}catch{u(new Error(h||w||y.message))}return}try{let S=JSON.parse(h);S.status===0||S.result?g(S.result):u(new Error(S.message||"Query failed"))}catch{u(new Error("Failed to parse response: "+h))}})})}var Qe=P.join(process.cwd(),".easy","soql-history.json");function nt(){try{if(L.existsSync(Qe)){let l=L.readFileSync(Qe,"utf8");return JSON.parse(l)}}catch{}return[]}function at(l,r){try{let n=nt(),c={id:Date.now(),query:l.trim(),timestamp:new Date().toISOString(),rowCount:r};n.unshift(c);let g=n.slice(0,100),u=P.dirname(Qe);L.existsSync(u)||L.mkdirSync(u,{recursive:!0}),L.writeFileSync(Qe,JSON.stringify(g,null,2),"utf8")}catch{}}function Mt(l,r){if(l.length===0){L.writeFileSync(r,"","utf8");return}let n=Object.keys(l[0]),c=[n.join(",")];for(let g of l){let u=n.map(y=>{let h=g[y];if(h==null)return"";let w=String(h);return w.includes(",")||w.includes('"')||w.includes(`
|
|
39
|
+
`)?`"${w.replace(/"/g,'""')}"`:w});c.push(u.join(","))}L.writeFileSync(r,c.join(`
|
|
40
|
+
`),"utf8")}function Bt(l,r){L.writeFileSync(r,JSON.stringify(l,null,2),"utf8")}async function qt(l){try{let r=await be("SELECT QualifiedApiName, Label, IsCustomizable, IsCreateable, IsDeletable FROM EntityDefinition WHERE IsDeprecatedable = false ORDER BY QualifiedApiName",l);return r?.records?r.records.map(n=>({name:n.QualifiedApiName,label:n.Label,customizable:n.IsCustomizable,createable:n.IsCreateable,deletable:n.IsDeletable})):[]}catch{return[]}}async function Vt(l,r){try{let n=await be(`SELECT QualifiedApiName, Label, DataType, Length, IsNillable, IsCreateable, IsUpdateable FROM FieldDefinition WHERE EntityDefinition.QualifiedApiName = '${l}' ORDER BY QualifiedApiName`,r);return n?.records?n.records.map(c=>({name:c.QualifiedApiName,label:c.Label,type:c.DataType,length:c.Length,nillable:c.IsNillable,createable:c.IsCreateable,updateable:c.IsUpdateable})):[]}catch{return[]}}async function Wt(l,r){let n=`sf apex run --target-org ${r} --code "System.abortJob('${l}');"`;return new Promise((c,g)=>{(0,A.exec)(n,{maxBuffer:1024*1024*10},(u,y,h)=>{if(u){g(new Error(h||u.message));return}c()})})}async function Ut(l,r){let n=`sf data delete record --sobject-type AsyncApexJob --record-id ${l} --target-org ${r} --json`;return new Promise((c,g)=>{(0,A.exec)(n,{maxBuffer:1024*1024*10},(u,y,h)=>{if(u){g(new Error(h||u.message));return}c()})})}async function Qt(l,r){let n=l.replace(/"/g,'\\"').replace(/\n/g," "),c=`sf apex run --target-org ${r} --code "${n}"`;return new Promise((g,u)=>{(0,A.exec)(c,{maxBuffer:1024*1024*10},(y,h,w)=>{if(y){u(new Error(w||y.message));return}g({success:!0,output:h})})})}async function Jt(l,r,n,c){let g=`sf api request ${l} "${r}" --target-org ${n} --json`;return new Promise((u,y)=>{let h={maxBuffer:10485760};if(c){let w=c.replace(/"/g,'\\"').replace(/\n/g," ");(0,A.exec)(`${g} --body "${w}"`,h,(S,O,T)=>{if(S){y(new Error(T||S.message));return}try{let G=JSON.parse(O);u({status:G.status||0,result:G.result||G})}catch{u({status:0,result:O})}})}else(0,A.exec)(g,h,(w,S,O)=>{if(w){y(new Error(O||w.message));return}try{let T=JSON.parse(S);u({status:T.status||0,result:T.result||T})}catch{u({status:0,result:S})}})})}var $e=["ApexClass","ApexTrigger","ApexPage","ApexComponent","CustomObject","CustomField","CustomTab","CustomApplication","Layout","ValidationRule","Flow","ProcessDefinition","PermissionSet","Profile","StaticResource","EmailTemplate","Document","Report","Dashboard","ListView","Workflow","AssignmentRule","ApprovalProcess","EscalationRule","QuickAction","FlexiPage","AuraDefinitionBundle","LightningComponentBundle","CustomSite","Queue","Group","Role","SharingRules","DuplicateRule","MatchingRule","NamedCredential","RemoteSiteSetting","CspTrustedSite","CorsWhitelistOrigin","ConnectedApp","AuthProvider","Certificate","CustomMetadata","ExternalDataSource","PathAssistant","PostTemplate","GlobalValueSet","StandardValueSet","Translation","Skill","Channel","Bot","ExperienceBundle","Network","BrandingSet","CachePartition","ForecastingType","PresenceUserConfig","ServiceChannel","TopicsForObjects","WaveApplication","ExternalCredential","ActionLinkTemplate","AnalyticsWorkflow","ApexTestSuite","AppMenu","AuditInfo","AutoResponseRule","CallCenter","CampaignInfluenceModel","CaseSubjectParticle","CleanRule","Community","ContentAsset","ContractTemplate","DataCategoryGroup","DelegateGroup","EclairGeoData","EntitlementProcess","EntitlementTemplate","ExternalEventMapping","FieldSet","FileType","Folder","HomeLayout","IdeWorkspace","IndustriesManufacturingRunbookTemplate","InstalledPackage","KnowledgeSettings","Letterhead","LightningBolt","LightningExperienceTheme","ManagedTopics","MilestoneType","ModerationRule","MutingPermissionSet","NavigationMenu","NotificationType","OrganizationSettings","Package2","PathSettings","PlatformAction","PlatformEventChannel","Portal","RecommendationStrategy","RecordActionDeployment","ReminderTriggerAction","ReportType","RoleAndSubordinates","SamlSsoConfig","Scontrol","SearchLayouts","Settings","SiteDotCom","TopicSetting","TransactionSecurityPolicy","UiPlugin","UserCriteria","ValidationRule","WaveAutoInstallRecipe","WorkflowAlert","WorkflowFieldUpdate","WorkflowFlowAutomation","WorkflowRule"];function Ht(l){let{screen:r}=l,n=l.config,c=1,g=new Set,u=[],y=[],h=[],w=new Set,S=!1,O=[],T="unknown",G="all",Ee="",ze="",de=d.box({parent:r,top:0,left:0,width:"100%",height:"100%"}),J=d.box({parent:de,top:0,left:0,width:"100%",height:1,style:{bg:"blue"}}),Y=["Git Resource","SOQL Browser","Apex Logs","Apex Jobs","Metadata Explorer","Org Manager","CSV Viewer"],ve=[],Ie=1;Y.forEach((e,t)=>{let s=t+1,o=` [${s}] ${e} `,i=o.length,a=d.box({parent:J,top:0,left:Ie,width:i,height:1,content:o,clickable:!0,tags:!0,style:{bg:"blue",fg:"white"}});a.on("click",()=>{D(s)}),ve.push(a),Ie+=i+2});let q=d.box({parent:de,top:1,left:0,width:"100%",height:"100%-2"}),Ke=d.box({parent:de,bottom:0,left:0,width:"100%",height:1,tags:!0,style:{fg:"white",bg:"blue",bold:!0},content:""}),Ne=d.box({parent:de,bottom:1,left:0,width:"100%",height:1,tags:!0,style:{fg:"white",bg:"black"},content:""}),oe=d.box({parent:q,top:0,left:0,width:"100%",height:"100%"}),C=d.list({parent:oe,top:0,left:0,width:"30%",height:"100%",border:{type:"line"},label:" Workspace Files ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),ne=d.box({parent:q,top:0,left:0,width:"100%",height:"100%"}),H=d.box({parent:ne,top:0,left:0,width:"100%",height:8,border:{type:"line"},label:" SOQL Query Input (Press [Ctrl-e] to run query) ",style:{border:{fg:"cyan"},focus:{border:{fg:"bright-cyan"}}}}),v=d.textarea({parent:H,top:1,left:1,width:"100%-4",height:5,inputOnFocus:!0,keys:!0,style:{fg:"white",bg:"black"}}),it=v.getValue(),Ye=!1,Xe=()=>{it=v.getValue()};v.on("focus",Xe),v.on("keypress",(e,t)=>{if(!t||t.name==="backspace"||t.name==="delete"||t.name==="escape"){Xe();return}Ye||(Ye=!0,setImmediate(()=>{Ye=!1;let s=v.getValue(),o=s.slice(it.length);o.length===2&&o[0]===o[1]&&v.setValue(s.slice(0,-1)),Xe(),r.render()}))});let _=d.box({parent:ne,top:8,left:0,width:"100%",height:"100%-8",border:{type:"line"},label:" SOQL Results ",style:{border:{fg:"cyan"},focus:{border:{fg:"bright-cyan"}}},scrollable:!0,alwaysScroll:!0,scrollbar:{style:{bg:"blue"}},keys:!0,mouse:!0,tags:!0});ye(_);let Ge=d.box({parent:q,top:0,left:0,width:"100%",height:"100%"}),V=d.list({parent:Ge,top:0,left:0,width:"45%",height:"100%",border:{type:"line"},label:" Apex Logs (Press [g] to refresh, [t] to tail logs) ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),ae=d.box({parent:Ge,top:0,left:"45%",width:"55%",height:"100%",border:{type:"line"},label:" Log Content ",style:{border:{fg:"cyan"},focus:{border:{fg:"bright-cyan"}}},scrollable:!0,alwaysScroll:!0,scrollbar:{style:{bg:"blue"}},keys:!0,mouse:!0,tags:!0});ye(ae);let Ze=d.box({parent:q,top:0,left:0,width:"100%",height:"100%"}),I=d.list({parent:Ze,top:0,left:0,width:"100%",height:"100%",border:{type:"line"},label:" Apex Jobs (Press [g] to refresh, [Enter] for details) ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),z=d.box({parent:q,top:0,left:0,width:"100%",height:"100%"}),ie=d.list({parent:z,top:0,left:0,width:"25%",height:"100%",border:{type:"line"},label:" Metadata Types ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),le=d.list({parent:z,top:0,left:"25%",width:"35%",height:"100%",border:{type:"line"},label:" Items ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),we=d.box({parent:z,top:0,left:"60%",width:"40%",height:"100%",border:{type:"line"},label:" Source Content ",style:{border:{fg:"cyan"},focus:{border:{fg:"bright-cyan"}}},scrollable:!0,alwaysScroll:!0,scrollbar:{style:{bg:"blue"}},keys:!0,mouse:!0,tags:!0});ye(we);let je=d.box({parent:q,top:0,left:0,width:"100%",height:"100%"}),W=d.list({parent:je,top:0,left:0,width:"40%",height:"100%",border:{type:"line"},label:" Authenticated Orgs (Press [Enter] to switch target org, [g] to refresh) ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),ce=d.box({parent:je,top:0,left:"40%",width:"60%",height:"100%",border:{type:"line"},label:" Org Logs ",style:{border:{fg:"cyan"},focus:{border:{fg:"bright-cyan"}}},scrollable:!0,alwaysScroll:!0,scrollbar:{style:{bg:"blue"}},keys:!0,mouse:!0,tags:!0});ye(ce);let Me=d.box({parent:q,top:0,left:0,width:"100%",height:"100%"}),X=d.list({parent:Me,top:0,left:0,width:"30%",height:"100%",border:{type:"line"},label:" Local CSV Files ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),fe=d.box({parent:Me,top:0,left:"30%",width:"70%",height:"100%",border:{type:"line"},label:" CSV Grid Table View ",style:{border:{fg:"cyan"},focus:{border:{fg:"bright-cyan"}}},scrollable:!0,alwaysScroll:!0,scrollbar:{style:{bg:"blue"}},keys:!0,mouse:!0,tags:!0});ye(fe);let R=d.list({parent:oe,top:0,left:"30%",width:"30%",height:"50%",border:{type:"line"},label:" Git Commits ([Space] select, [a] toggle all, [s] search) ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),Z=d.list({parent:oe,top:"50%",left:"30%",width:"30%",height:"50%",border:{type:"line"},label:" Selected Files ([Enter] preview, [i] staged) ",style:{border:{fg:"cyan"},selected:{bg:"blue",fg:"white",bold:!0},item:{fg:"white"},focus:{border:{fg:"bright-cyan"}}},keys:!0,vi:!0,mouse:!0,tags:!0}),pe=d.box({parent:oe,top:0,left:"60%",width:"40%",height:"100%",border:{type:"line"},label:" Diff / Details ",style:{border:{fg:"cyan"},focus:{border:{fg:"bright-cyan"}}},scrollable:!0,alwaysScroll:!0,scrollbar:{style:{bg:"blue"}},keys:!0,mouse:!0,tags:!0});ye(pe);function lt(e){c=e,ve.forEach((s,o)=>{o+1===e?(s.style.bg="yellow",s.style.fg="black"):(s.style.bg="blue",s.style.fg="white")});let t=n.alias?`{green-fg}${n.alias}{/green-fg}`:"{red-fg}None{/red-fg}";Ke.setContent(` esf v0.1.0 - EasySFDX TUI | Target Org: ${t} | Press [?] Help`),r.render()}function zt(e,t){try{let s="";if(t==="staged")s=`git diff --cached -- "${e}"`;else if(t==="untracked"){if(B.existsSync(e)){let i=B.readFileSync(e,"utf8");return i.split(`
|
|
41
|
+
`).slice(0,100).join(`
|
|
42
|
+
`)+(i.split(`
|
|
43
|
+
`).length>100?`
|
|
44
|
+
... (truncated)`:"")}return"Untracked file (empty or not found)"}else s=`git diff -- "${e}"`;return Pe(s)||"No changes or binary file"}catch(s){return"Error loading diff: "+s.message}}function ct(e){return e.split(`
|
|
45
|
+
`).map(s=>s.startsWith("+")&&!s.startsWith("+++")?`{green-fg}${x(s)}{/green-fg}`:s.startsWith("-")&&!s.startsWith("---")?`{red-fg}${x(s)}{/red-fg}`:s.startsWith("@@")?`{cyan-fg}${x(s)}{/cyan-fg}`:x(s)).join(`
|
|
46
|
+
`)}function x(e){return e.replace(/{/g,"\\{").replace(/}/g,"\\}")}function F(e){let t=d.box({parent:r,top:0,left:0,width:"100%",height:"100%",style:{bg:"black"},keys:!0,mouse:!0,tags:!0}),s=d.box({parent:t,top:"center",left:"center",width:e.width,height:e.height,label:e.label,border:{type:"line"},style:{border:{fg:"yellow"},bg:"black",fg:"white"},scrollable:!0,alwaysScroll:!0,scrollbar:{style:{bg:"blue"}},keys:!0,mouse:!0,tags:!0}),o=()=>{t.parent&&(t.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render())};return r.saveFocus(),r.grabKeys=!0,t.key(["escape","q"],o),s.key(["escape","q"],o),t.focus(),r.render(),{overlay:t,modal:s,close:o}}function ye(e){let t=null,s=()=>{t&&(clearTimeout(t),t=null)},o=()=>{s(),typeof e.setScrollPerc=="function"?e.setScrollPerc(0):typeof e.scrollTo=="function"&&e.scrollTo(0),r.render()},i=()=>{s(),typeof e.setScrollPerc=="function"?e.setScrollPerc(100):typeof e.getScrollHeight=="function"&&typeof e.scrollTo=="function"&&e.scrollTo(e.getScrollHeight()),r.render()},a=p=>{typeof e.scroll=="function"?e.scroll(p):typeof e.scrollTo=="function"&&e.scrollTo(Math.max(0,p)),r.render()};e.on("wheelup",()=>a(-1)),e.on("wheeldown",()=>a(1)),e.key(["up","k"],()=>a(-1)),e.key(["down","j"],()=>a(1)),e.key(["pageup"],()=>a(-5)),e.key(["pagedown"],()=>a(5)),e.key("g",()=>{if(t){o();return}t=setTimeout(()=>{t=null},250)}),e.on("keypress",(p,m)=>{m?.name==="g"&&m.shift&&i()})}function Kt(){let{overlay:e,modal:t}=F({width:"78%",height:"78%",label:" Help "});return t.setContent(["{yellow-fg}Global{/yellow-fg}"," [1-7] Switch tabs"," Tab Cycle focus inside the current tab"," ? Open this help popup"," C-c Exit the app","","{yellow-fg}Tab 1: Git Resource Manager{/yellow-fg}"," Workspace files:"," Space Toggle file selection"," d Dry run deploy"," Ctrl+d Deploy selected files"," r Retrieve selected files"," m Retrieve metadata types"," a Retrieve all metadata"," Git commits:"," Space Toggle commit selection"," a Toggle all commits"," c Clear selection"," / or s Search commits"," i Toggle staged files"," s Stage file (git add)"," u Unstage file (git reset)"," d Deploy dry run"," Ctrl+d Deploy"," r Retrieve selected resources"," p Package actions (backup/copy/make/deploy)"," R Deploy by commit range"," S Deploy staged files"," Ctrl+r Retrieve staged files","","{yellow-fg}Tab 2: SOQL Browser{/yellow-fg}"," Ctrl-e Run query"," Ctrl+s Export to CSV"," Ctrl+j Export to JSON"," t Toggle Tooling API mode"," h Query history","","{yellow-fg}Tab 3: Apex Logs{/yellow-fg}"," g Refresh logs"," t Tail live logs"," Enter Open log details","","{yellow-fg}Tab 4: Apex Jobs{/yellow-fg}"," g Refresh jobs"," Enter Open job details"," x Abort job (Processing/Queued)"," D Delete job","","{yellow-fg}Tab 5: Metadata Explorer{/yellow-fg}"," g Refresh items"," r Retrieve type (prompt for names)"," R Retrieve all of selected type","","{yellow-fg}Tab 6: Org Manager{/yellow-fg}"," g Refresh org list"," Enter Switch target org"," r REST API browser","","{yellow-fg}Tab 7: CSV Viewer{/yellow-fg}"," Enter Open file","","{gray-fg}Press ESC or q to close{/gray-fg}"].join(`
|
|
47
|
+
`)),t.focus(),r.render(),{overlay:e,modal:t}}function N(e,t,s){let{overlay:o,modal:i}=F({width:"90%",height:"90%",label:` ${e} (Running...) `}),a=d.log({parent:i,top:1,left:1,width:"100%-4",height:"100%-4",style:{fg:"light-green"},scrollable:!0,alwaysScroll:!0,mouse:!0,tags:!0});ye(a),i.focus(),r.render(),i.key(["up","k"],()=>{a.scroll(-1),r.render()}),i.key(["down","j"],()=>{a.scroll(1),r.render()}),i.key(["pageup"],()=>{a.scroll(-5),r.render()}),i.key(["pagedown"],()=>{a.scroll(5),r.render()});let p=null;i.key("g",()=>{if(p){clearTimeout(p),p=null,a.setScrollPerc(0),r.render();return}p=setTimeout(()=>{p=null},250)}),i.on("keypress",($,E)=>{E?.name==="g"&&E.shift&&(p&&(clearTimeout(p),p=null),a.setScrollPerc(100),r.render())});let m=()=>{let $=Je(t);f($?"Copied executing command to clipboard":"Failed to copy command to clipboard",!$)};i.key("y",m),a.key("y",m);let b=He(),k=b?b.split(/[/\\]/).pop():process.platform==="win32"?"cmd.exe":"/bin/sh";a.log(`Shell: {cyan-fg}${k}{/cyan-fg}`),a.log(`Executing: ${t}
|
|
48
|
+
`),ot(t,$=>{a.log(x($)),r.render()},$=>{a.log(`{red-fg}${x($)}{/red-fg}`),r.render()}).then($=>{i.setLabel(` ${e} (Finished with code ${$}) - Press [ESC/q] to close `),i.style.border.fg=$===0?"green":"red",r.render();let E=()=>{o.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render(),s()};a.key(["escape","q"],E),o.key(["escape","q"],E),i.key(["escape","q"],E)})}function K(){if(u=Tt(),u.length===0){C.setItems(["No changes in Git repository"]),pe.setContent("Repository is clean."),r.render();return}let e=u.map(t=>`${g.has(t.path)?"[x]":"[ ]"} ${t.actionCode} ${t.path}`);C.setItems(e),ut(),r.render()}function ut(){let e=C.selected;if(e<0||e>=u.length){pe.setContent("No file selected.");return}let t=u[e],s=zt(t.path,t.status);pe.setContent(ct(s)),r.render()}C.on("select item",()=>{ut()}),C.key("space",()=>{let e=C.selected;if(e<0||e>=u.length)return;let t=u[e];g.has(t.path)?g.delete(t.path):g.add(t.path),K(),C.select(e)}),C.key("d",()=>{let e=Array.from(g).filter(i=>u.some(a=>a.path===i));if(e.length===0){f("Please select files with [Space] first",!0);return}let t=e.filter(se);if(t.length===0){f("No Salesforce resource files selected",!0);return}let o=`sf project deploy start --source-dir ${t.map(i=>`"${i}"`).join(" ")} --wait 120 --target-org ${n.alias} --dry-run`;N("Deploy Dry Run",o,()=>{K(),C.focus()})}),C.on("keypress",(e,t)=>{if(t?.name==="d"&&t.ctrl){let s=Array.from(g).filter(p=>u.some(m=>m.path===p));if(s.length===0){f("Please select files with [Space] first",!0);return}let o=s.filter(se);if(o.length===0){f("No Salesforce resource files selected",!0);return}let a=`sf project deploy start --source-dir ${o.map(p=>`"${p}"`).join(" ")} --wait 120 --target-org ${n.alias}`;N("Deploy Files",a,()=>{K(),C.focus()})}}),C.key("r",()=>{let e=Array.from(g).filter(i=>u.some(a=>a.path===i));if(e.length===0){f("Please select files with [Space] first",!0);return}let t=e.filter(se);if(t.length===0){f("No Salesforce resource files selected",!0);return}let o=`sf project retrieve start --source-dir ${t.map(i=>`"${i}"`).join(" ")} --wait 120 --target-org ${n.alias}`;N("Retrieve Files",o,()=>{K(),C.focus()})}),C.key("m",()=>{Yt(e=>{let s=`sf project retrieve start ${e.map(o=>`--metadata ${o}`).join(" ")} --target-org ${n.alias}`;N("Retrieve Metadata Types",s,()=>{K(),C.focus()})})}),C.key("a",()=>{let e=`sf project retrieve start --target-org ${n.alias}`;N("Retrieve All Metadata",e,()=>{K(),C.focus()})}),C.key("g",()=>{K(),f("Refreshed Git status")}),C.key("s",()=>{let e=C.selected;if(e<0||e>=u.length)return;let t=u[e];if(t.status==="staged"){f("File is already staged",!0);return}let{exec:s}=require("child_process");s(`git add "${t.path}"`,{shell:!0},()=>{K(),f(`Staged: ${t.path}`)})}),C.key("u",()=>{let e=C.selected;if(e<0||e>=u.length)return;let t=u[e];if(t.status!=="staged"){f("File is not staged",!0);return}let{exec:s}=require("child_process");s(`git reset HEAD "${t.path}"`,{shell:!0},()=>{K(),f(`Unstaged: ${t.path}`)})});function Yt(e){let{overlay:t,modal:s,close:o}=F({width:60,height:18,label:" Select Metadata Types ([Space] select, [Enter] confirm, [ESC] cancel) "}),i=d.list({parent:s,top:1,left:1,width:"100%-4",height:"100%-4",keys:!0,vi:!0,mouse:!0,style:{selected:{bg:"blue",fg:"white"},item:{fg:"white"}},tags:!0}),a=new Set,p=()=>{i.setItems($e.map(m=>a.has(m)?`[x] ${m}`:`[ ] ${m}`)),r.render()};p(),i.focus(),r.render(),i.key("space",()=>{let m=i.selected,b=$e[m];a.has(b)?a.delete(b):a.add(b),p(),i.select(m)}),i.key("enter",()=>{o(),a.size>0&&e(Array.from(a))}),i.key("escape",()=>{o()})}let ee=[],Fe="data";v.key("C-e",async()=>{let e=v.value.trim();if(!e){f("Please enter a query",!0);return}_.setContent("{yellow-fg}Running SOQL Query...{/yellow-fg}"),r.render();try{if(!n.alias)throw new Error("No target org configured.");let t=Fe==="tooling"?await jt(e,n.alias):await be(e,n.alias);if(t&&t.records){ee=t.records;let s=t.records.length,o=t.totalSize,i=JSON.stringify(t.records,null,2);_.setContent(`{green-fg}Records: ${s} / Total: ${o} [${Fe}]{/green-fg}
|
|
49
|
+
|
|
50
|
+
${x(i)}`),at(e,s)}else ee=[],_.setContent(JSON.stringify(t,null,2)),at(e)}catch(t){ee=[],_.setContent(`{red-fg}Error: ${x(t.message)}{/red-fg}`)}r.render()}),_.key("C-s",()=>{if(ee.length===0){f("No records to export. Run a query first.",!0);return}let e=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),t=re.join(process.cwd(),`soql-export-${e}.csv`);Mt(ee,t),f(`Exported ${ee.length} records to ${t}`)}),_.key("C-j",()=>{if(ee.length===0){f("No records to export. Run a query first.",!0);return}let e=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),t=re.join(process.cwd(),`soql-export-${e}.json`);Bt(ee,t),f(`Exported ${ee.length} records to ${t}`)}),_.key("t",()=>{Fe=Fe==="tooling"?"data":"tooling",f(`Query mode: ${Fe==="tooling"?"Tooling API":"Data API"}`)}),_.key("h",()=>{let e=nt();if(e.length===0){f("No query history found.");return}let t=e.slice(0,30).map((a,p)=>{let m=new Date(a.timestamp).toLocaleString(),b=a.query.replace(/\n/g," ").slice(0,60),k=a.rowCount!==void 0?` [${a.rowCount}]`:"";return`${p+1}. ${m}${k} | ${b}`}),{overlay:s,modal:o}=F({width:"80%",height:"70%",label:" SOQL Query History (Enter: select, q: close) "}),i=d.list({parent:o,top:0,left:0,width:"100%",height:"100%",items:t,keys:!0,vi:!0,mouse:!0,style:{selected:{bg:"cyan",fg:"black"},item:{fg:"white"}}});i.focus(),r.render(),i.key("enter",()=>{let a=i.selected;a>=0&&a<e.length&&(v.setValue(e[a].query),s.destroy(),r.grabKeys=!1,r.restoreFocus(),v.focus(),r.render())}),s.key(["escape","q"],()=>{s.destroy(),r.grabKeys=!1,r.restoreFocus(),_.focus(),r.render()})});let Oe=[];async function gt(){V.setItems(["{yellow-fg}Loading logs...{/yellow-fg}"]),r.render();try{if(!n.alias)throw new Error("No target org configured.");if(Oe=(await be("SELECT Id, LogUserId, LogUser.Name, Application, Status, Operation, DurationMilliseconds, SystemModstamp FROM ApexLog ORDER BY SystemModstamp DESC LIMIT 30",n.alias)).records||[],Oe.length===0){V.setItems(["No logs found."]),ae.setContent(""),r.render();return}let s=Oe.map(o=>`${new Date(o.SystemModstamp).toLocaleTimeString()} | ${o.LogUser?.Name||"Unknown"} | ${o.Operation} | ${o.Status}`);V.setItems(s),dt()}catch(e){V.setItems([`{red-fg}Failed to load logs: ${e.message}{/red-fg}`]),ae.setContent("")}r.render()}async function dt(){let e=V.selected;if(e<0||e>=Oe.length){ae.setContent("No log selected.");return}let t=Oe[e];ae.setContent("{yellow-fg}Fetching log body...{/yellow-fg}"),r.render();try{let i=Pe(`sf apex log get --log-id ${t.Id} --target-org ${n.alias}`).split(`
|
|
51
|
+
`).map(a=>a.includes("|EXCEPTION_THROWN|")||a.includes("|FATAL_ERROR")?`{red-fg}${x(a)}{/red-fg}`:a.includes("|USER_DEBUG|")?`{cyan-fg}${x(a)}{/cyan-fg}`:a.includes("|SOQL_EXECUTE_BEGIN|")||a.includes("|SOQL_EXECUTE_END|")?`{yellow-fg}${x(a)}{/yellow-fg}`:x(a));ae.setContent(i.join(`
|
|
52
|
+
`))}catch(s){ae.setContent(`{red-fg}Failed to fetch log body: ${s.message}{/red-fg}`)}r.render()}V.on("select item",()=>{dt()}),V.key("g",()=>{gt(),f("Refreshed logs list")}),V.key("t",()=>{let e=`sf apex log tail --target-org ${n.alias}`;N("Tail Apex Logs",e,()=>{V.focus()})});let te=[];async function Be(){I.setItems(["{yellow-fg}Loading jobs...{/yellow-fg}"]),r.render();try{if(!n.alias)throw new Error("No target org configured.");if(te=(await be("SELECT Id, CreatedDate, JobType, Status, ApexClass.Name, MethodName, ExtendedStatus, JobItemsProcessed, TotalJobItems, NumberOfErrors FROM AsyncApexJob ORDER BY CreatedDate DESC LIMIT 40",n.alias)).records||[],te.length===0){I.setItems(["No jobs found."]),r.render();return}let s=te.map(o=>{let i=new Date(o.CreatedDate).toLocaleString(),a=o.ApexClass?.Name||o.JobType,p=o.MethodName?`.${o.MethodName}`:"",m=o.TotalJobItems>0?` [${o.JobItemsProcessed}/${o.TotalJobItems}]`:"",b=o.NumberOfErrors>0?` {red-fg}(Errors: ${o.NumberOfErrors}){/red-fg}`:"",k="white";return o.Status==="Completed"?k="green":o.Status==="Failed"||o.Status==="Aborted"?k="red":(o.Status==="Processing"||o.Status==="Queued")&&(k="yellow"),`${i} | ${a}${p} | {${k}-fg}${o.Status}{/${k}-fg}${m}${b}`});I.setItems(s)}catch(e){I.setItems([`{red-fg}Failed to load jobs: ${e.message}{/red-fg}`])}r.render()}I.on("select",()=>{let e=I.selected;if(e<0||e>=te.length)return;let t=te[e],s=`Job ID: ${t.Id}
|
|
53
|
+
Created Date: ${new Date(t.CreatedDate).toLocaleString()}
|
|
54
|
+
Job Type: ${t.JobType}
|
|
55
|
+
Class Name: ${t.ApexClass?.Name||"N/A"}
|
|
56
|
+
Method Name: ${t.MethodName||"N/A"}
|
|
57
|
+
Status: ${t.Status}
|
|
58
|
+
Items Processed: ${t.JobItemsProcessed} / ${t.TotalJobItems}
|
|
59
|
+
Errors: ${t.NumberOfErrors}
|
|
60
|
+
Extended Status: ${t.ExtendedStatus?`{red-fg}${t.ExtendedStatus}{/red-fg}`:"None"}`,{modal:o,close:i}=F({width:60,height:14,label:" Job Details (Press [ESC/q] to close) "});o.setContent(s),o.tags=!0,o.focus(),r.render(),o.key(["escape","q"],()=>{i(),I.focus()})}),I.key("g",()=>{Be(),f("Refreshed jobs list")}),I.key("x",async()=>{let e=I.selected;if(e<0||e>=te.length)return;let t=te[e];if(t.Status!=="Processing"&&t.Status!=="Queued"){f("Can only abort Processing or Queued jobs.",!0);return}if(!n.alias){f("No target org configured.",!0);return}try{await Wt(t.Id,n.alias),f(`Aborted job ${t.Id.slice(0,15)}`),Be()}catch(s){f(`Failed to abort job: ${s.message}`,!0)}}),I.key("D",async()=>{let e=I.selected;if(e<0||e>=te.length)return;let t=te[e];if(!n.alias){f("No target org configured.",!0);return}try{await Ut(t.Id,n.alias),f(`Deleted job ${t.Id.slice(0,15)}`),Be()}catch(s){f(`Failed to delete job: ${s.message}`,!0)}});let Re=[];function Xt(){ie.setItems($e),r.render()}async function ft(){let e=ie.selected;if(e<0)return;let t=$e[e];le.setItems(["{yellow-fg}Querying Salesforce...{/yellow-fg}"]),we.setContent(""),r.render();try{let s="";if(t==="ApexClass"||t==="ApexTrigger"?s=`SELECT Id, Name, LastModifiedDate, LastModifiedBy.Name, Body FROM ${t} ORDER BY Name LIMIT 100`:s=`SELECT Id, DeveloperName, LastModifiedDate FROM ${t} ORDER BY DeveloperName LIMIT 100`,Re=(await be(s,n.alias)).records||[],Re.length===0){le.setItems(["No records found."]),r.render();return}let i=Re.map(a=>a.Name||a.DeveloperName||a.Id);le.setItems(i)}catch(s){le.setItems([`{red-fg}Query failed: ${s.message}{/red-fg}`])}r.render()}ie.on("select item",()=>{ft()}),le.on("select item",()=>{let e=le.selected;if(e<0||e>=Re.length){we.setContent("No item selected.");return}let t=Re[e];t.Body?we.setContent(x(t.Body)):we.setContent(JSON.stringify(t,null,2)),r.render()}),z.key("g",()=>{ft()}),z.key("r",async()=>{let e=ie.selected;if(e<0)return;let t=$e[e];if(!n.alias){f("No target org configured.",!0);return}let{overlay:s,modal:o}=F({width:60,height:6,label:` Retrieve ${t} `}),i=()=>{s.parent&&(s.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render())},a=d.prompt({parent:o,top:0,left:0,width:"100%",height:"100%",border:{type:"line"},style:{border:{fg:"cyan"},bg:"black",fg:"white"}});a.on("cancel",i),a.key("escape",i),a.key("q",i),a.readInput(`Retrieve ${t}? Enter "all" for all items, or comma-separated names.`,"",async(p,m)=>{if(p||!m||!m.trim()){i();return}let b=m.trim(),k;b.toLowerCase()==="all"?k=`sf project retrieve start --metadata ${t} --target-org ${n.alias} --wait 120`:k=`sf project retrieve start --metadata ${b.split(",").map(E=>`${t}:${E.trim()}`).join(" ")} --target-org ${n.alias} --wait 120`,N(`Retrieve ${t}`,k,()=>{z.focus()})})}),z.on("keypress",(e,t)=>{if(t?.name==="r"&&t.shift){let s=ie.selected;if(s<0)return;let o=$e[s];if(!n.alias){f("No target org configured.",!0);return}let i=`sf project retrieve start --metadata ${o} --target-org ${n.alias} --wait 120`;N(`Retrieve All ${o}`,i,()=>{z.focus()})}});let me=[],et=[];function pt(){ce.setContent(et.join(`
|
|
61
|
+
`)),ce.setScrollPerc(100),r.render()}function qe(e){et=[`{yellow-fg}${x(e)}{/yellow-fg}`],pt()}function Se(e,t=!1){let s=e.split(/\r?\n/).filter(o=>o.length>0);for(let o of s){let i=x(o);et.push(t?`{red-fg}${i}{/red-fg}`:i)}pt()}async function tt(e,t){let s=[],o=[];return qe(t),{code:await ot(e,a=>{s.push(a),Se(a)},a=>{o.push(a),Se(a,!0)}),stdout:s.join(""),stderr:o.join("")}}async function yt(){W.setItems(["{yellow-fg}Fetching org list...{/yellow-fg}"]),qe("Fetching org list...");try{let e=await tt("sf org list --json","Fetching org list..."),t=e.stdout||e.stderr,s=JSON.parse(t),o=s.result?.nonScratchOrgs||[],i=s.result?.scratchOrgs||[];if(me=[...o,...i],me.length===0){W.setItems(["No authenticated orgs found."]),r.render();return}let a=me.map(p=>{let m=p.isDefaultUsername||p.isDefaultDevHubUsername?"\u25CF ":" ",b=p.alias?` (${p.alias})`:"";return`${m}${p.username}${b}`});W.setItems(a),ce.setContent("Select an org and press Enter."),r.render()}catch(e){W.setItems([`{red-fg}Failed to fetch orgs: ${e.message}{/red-fg}`]),Se(`Failed to fetch orgs: ${e.message}`,!0)}r.render()}function Zt(e){return[`Username: ${e.username||"None"}`,`Alias: ${e.alias||"None"}`,`Org Id: ${e.orgId||e.id||"None"}`,`Instance Url: ${e.instanceUrl||"None"}`,`Status: ${e.connectedStatus||e.status||"Unknown"}`,`Type: ${e.isScratchOrg?"Scratch Org":"Persistent Org"}`].join(`
|
|
62
|
+
`)}async function Ms(){let e=W.selected;if(e<0||e>=me.length){ce.setContent("No org selected."),r.render();return}let t=me[e];qe(`Loading org details for ${t.username}...`);try{let s=t.username,o=await tt(`sf org display -u ${s} --json`,`Loading org details for ${s}...`),i=o.stdout||o.stderr,a=JSON.parse(i),p=a.result||a;Se(Zt(p))}catch(s){Se(`Failed to load org details: ${s.message}`,!0)}r.render()}W.on("select",async()=>{let e=W.selected;if(e<0||e>=me.length)return;let t=me[e],s=t.alias||t.username;qe(`Setting target org to ${s}...`);try{await tt(`sf config set target-org=${s}`,`Setting target org to ${s}...`),f(`Set target org to ${s}`),l.config=De(),n=l.config,lt(c)}catch(o){f(`Failed to set target org: ${o.message}`,!0),Se(`Failed to set target org: ${o.message}`,!0)}}),W.key("g",()=>{yt(),f("Refreshed org list")}),W.key("r",async()=>{if(!n.alias){f("No target org configured.",!0);return}let{overlay:e,modal:t}=F({width:72,height:8,label:" REST API Browser "}),s=()=>{e.parent&&(e.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render())},o=d.prompt({parent:t,top:0,left:0,width:"100%",height:"100%",border:{type:"line"},style:{border:{fg:"cyan"},bg:"black",fg:"white"}});o.on("cancel",s),o.key("escape",s),o.key("q",s),o.readInput("Enter endpoint (e.g. /services/data/v62.0/sobjects). Press Enter.","",async(i,a)=>{if(i||!a||!a.trim()){s();return}let p=a.trim();try{let m=await Jt("GET",p,n.alias);ce.setContent(JSON.stringify(m.result,null,2)),r.render()}catch(m){ce.setContent(`{red-fg}Error: ${x(m.message)}{/red-fg}`),r.render()}})});let Ae=[];function es(){X.setItems(["{yellow-fg}Scanning for CSVs...{/yellow-fg}"]),r.render();try{let e=process.cwd();if(Ae=B.readdirSync(e).filter(s=>s.toLowerCase().endsWith(".csv")),Ae.length===0){X.setItems(["No local CSV files found."]),fe.setContent("Place .csv files in the current folder to view them."),r.render();return}X.setItems(Ae),mt()}catch(e){X.setItems([`{red-fg}Error readdir: ${e.message}{/red-fg}`])}r.render()}function ts(e){return e.split(`
|
|
63
|
+
`).map(s=>{let o=[],i=!1,a="";for(let p=0;p<s.length;p++){let m=s[p];m==='"'?i=!i:m===","&&!i?(o.push(a.trim()),a=""):a+=m}return o.push(a.trim()),o}).filter(s=>s.length>0&&s.some(o=>o!==""))}function ss(e){if(e.length===0)return"Empty file";let t=[];e.forEach(p=>{p.forEach((m,b)=>{t[b]=Math.max(t[b]||0,m.length)})});let s=35,o=t.map(p=>Math.min(p,s)),i="+"+o.map(p=>"-".repeat(p+2)).join("+")+"+",a=e.map(p=>"|"+p.map((b,k)=>{let $=o[k]||10,E=b;return b.length>$&&(E=b.slice(0,$-3)+"...")," "+E.padEnd($)+" "}).join("|")+"|");if(a.length>0){let p=a[0],m=a.slice(1);return[i,p,i.replace(/-/g,"="),...m.flatMap(b=>[b,i])].join(`
|
|
64
|
+
`)}return"No data"}function mt(){let e=X.selected;if(e<0||e>=Ae.length){fe.setContent("No CSV file selected.");return}let t=Ae[e];fe.setContent("{yellow-fg}Parsing CSV...{/yellow-fg}"),r.render();try{let s=re.join(process.cwd(),t),o=B.readFileSync(s,"utf8"),i=ts(o);fe.setContent(ss(i))}catch(s){fe.setContent(`{red-fg}Failed to read/parse CSV: ${s.message}{/red-fg}`)}r.render()}X.on("select item",()=>{mt()});function rs(e){let t=w.has(e.hash)?"[x]":"[ ]",s=e.hash.slice(0,8),o=e.branch?` {cyan-fg}(${x(e.branch)}){/cyan-fg}`:"";return`${t} {cyan-fg}${s}{/cyan-fg} ${x(e.date)} | ${x(e.author)} | ${x(e.message)}${o}`}function os(e){let t=e.status.startsWith("A")?"green":e.status.startsWith("D")?"red":e.status.startsWith("R")?"magenta":e.staged?"yellow":"white",s=e.sources.length>0?` {gray-fg}(${x(e.sources.join(", "))}){/gray-fg}`:"";return`{${t}-fg}${x(e.status)}{/${t}-fg} ${x(e.file)}${s}`}function ht(){let e=new Map;for(let t of y)if(w.has(t.hash))for(let s of t.files){if(!se(s.file)||s.status==="D"||s.status.startsWith("D"))continue;let o=e.get(s.file),i=t.hash.slice(0,8);if(o){o.sources.includes(i)||o.sources.push(i);continue}e.set(s.file,{file:s.file,status:s.status,sources:[i],commitHash:t.hash,oldFile:s.oldFile,staged:!1})}if(S)for(let t of O){if(!se(t.file)||t.status==="D"||t.status.startsWith("D"))continue;let s=e.get(t.file);if(s){s.sources.includes("STAGED")||s.sources.push("STAGED"),s.staged=!0;continue}e.set(t.file,{file:t.file,status:t.status,sources:["STAGED"],oldFile:t.oldFile,staged:!0})}h=Array.from(e.values()).sort((t,s)=>t.file.localeCompare(s.file))}function bt(){if(y.length===0){R.setItems(["No commits found. Press [g] to refresh."]);return}R.setItems(y.map(rs))}function wt(){if(h.length===0){let e=w.size===0?"Select commits with [Space] to show Salesforce resources.":S?"No Salesforce resource files found in selected commits or staged files.":"No Salesforce resource files found in selected commits.";Z.setItems([e]);return}Z.setItems(h.map(os))}function Ce(e){pe.setContent(e),r.render()}async function xe(){let e=Z.selected;if(e>=0&&e<h.length){let s=h[e];ze=s.file;let o="";try{s.staged?o=Pe(`git -c core.quotepath=false diff --cached -- "${s.file}"`):s.commitHash?o=Pe(`git -c core.quotepath=false show ${s.commitHash} -- "${s.file}"`):o="No diff available."}catch(a){o=`Failed to load diff: ${a.message}`}let i=[`{yellow-fg}File:{/yellow-fg} ${x(s.file)}`,`{yellow-fg}Status:{/yellow-fg} ${x(s.status)}`,`{yellow-fg}Sources:{/yellow-fg} ${x(s.sources.join(", "))}`,"",ct(o)];Ce(i.join(`
|
|
65
|
+
`));return}let t=R.selected;if(t>=0&&t<y.length){let s=y[t];Ee=s.hash;let o=[`{cyan-fg}${x(s.hash)}{/cyan-fg}`,`{yellow-fg}Branch:{/yellow-fg} ${x(s.branch||"unknown")}`,`{yellow-fg}Date:{/yellow-fg} ${x(s.date)}`,`{yellow-fg}Author:{/yellow-fg} ${x(s.author)}`,`{yellow-fg}Message:{/yellow-fg} ${x(s.message)}`,`{yellow-fg}Files:{/yellow-fg} ${s.files.length}`,"","{gray-fg}Use [Space] to select this commit, then act on the files in the middle pane.{/gray-fg}"];Ce(o.join(`
|
|
66
|
+
`));return}Ce("{gray-fg}Select a commit or file to preview details.{/gray-fg}")}function U(){ht(),bt(),wt(),xe()}async function Ve(e=""){R.setItems(["{yellow-fg}Loading commit history...{/yellow-fg}"]),Z.setItems(["Loading selected resources..."]),Ce("{yellow-fg}Loading Git Resource Manager...{/yellow-fg}");try{T=await Nt(),O=await ke(),y=e.trim()?await Pt(e,G):await Ue(50),w=new Set,Ee=y[0]?.hash||"",ze="",y.length>0&&R.select(0),U(),Ce(`{yellow-fg}Branch:{/yellow-fg} ${x(T)}
|
|
67
|
+
{yellow-fg}Commits:{/yellow-fg} ${y.length}
|
|
68
|
+
{yellow-fg}Selected:{/yellow-fg} ${w.size}
|
|
69
|
+
{yellow-fg}Staged:{/yellow-fg} ${O.length}
|
|
70
|
+
|
|
71
|
+
{gray-fg}Use [Space] to select commits, [i] to include staged files, [/] to search, [s] stage, [u] unstage, [d] dry run, [Ctrl-d] deploy, [r] retrieve, [b] backup, [y] copy file list.{/gray-fg}`)}catch(t){let s=t instanceof Error?t.message:String(t);R.setItems([`{red-fg}Failed to load commit history: ${x(s)}{/red-fg}`]),Z.setItems([""]),Ce(`{red-fg}Failed to load Git Resource Manager: ${x(s)}{/red-fg}`)}r.render()}function ue(e="all"){G=e;let{overlay:t,modal:s}=F({width:72,height:8,label:" Search Git Commits "}),o=()=>{t.parent&&(t.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render())},i=d.prompt({parent:s,top:0,left:0,width:"100%",height:"100%",border:{type:"line"},style:{border:{fg:"cyan"},bg:"black",fg:"white"}});i.on("cancel",o),i.key("escape",o),i.key("q",o),i.readInput(`Search commits by ${e}. Press Enter to run.`,"",async(a,p)=>{if(a||!p||!p.trim()){o();return}o(),await Ve(p.trim()),R.focus()})}function ns(){let e=R.selected;if(e<0||e>=y.length)return;let t=y[e];w.has(t.hash)?w.delete(t.hash):w.add(t.hash),U(),R.select(e)}function as(){w=new Set(y.map(e=>e.hash)),U()}function St(){if(y.length!==0){if(w.size===y.length){st(),f("Cleared Git Resource selection");return}as(),f("Selected all Git Resource commits")}}function st(){w.clear(),U()}function rt(e,t=!1){let s=e.map(i=>`"${i}"`).join(" "),o=t?" --dry-run":"";return`sf project deploy start --source-dir ${s} --wait 120 --target-org ${n.alias}${o}`}function Ct(e){return`sf project retrieve start --source-dir ${e.map(s=>`"${s}"`).join(" ")} --wait 120 --target-org ${n.alias}`}async function is(e){let t=new Date().toISOString().replace(/[:.]/g,"-"),s=re.join(process.cwd(),"backup",`git-resource-manager-${t}`);for(let o of e){let i=re.join(process.cwd(),o);if(!B.existsSync(i))continue;let a=re.join(s,o);await B.promises.mkdir(re.dirname(a),{recursive:!0}),await B.promises.copyFile(i,a)}return s}async function ls(e){let t=e.join(`
|
|
72
|
+
`);if(!Je(t))throw new Error("Clipboard copy failed")}async function Q(e){let t=xt();if(t.length===0){f("Select commits that contain Salesforce resource files first.",!0);return}if((e==="deploy"||e==="deploy-dry"||e==="retrieve")&&!n.alias){f("No target org configured.",!0);return}if(e==="copy"){try{await ls(t),f(`Copied ${t.length} file paths to clipboard`)}catch(i){f(`Failed to copy file list: ${i.message}`,!0)}return}if(e==="backup"){try{let i=await is(t);f(`Backed up ${t.length} files to ${i}`)}catch(i){f(`Failed to backup resources: ${i.message}`,!0)}return}let s=e==="retrieve"?Ct(t):rt(t,e==="deploy-dry");N(e==="retrieve"?"Retrieve Git Resources":e==="deploy-dry"?"Deploy Git Resources (Dry Run)":"Deploy Git Resources",s,()=>{R.focus(),U()})}function xt(){return ht(),h.map(e=>e.file)}function cs(){let e=[{label:"Backup file list",action:()=>Q("backup")},{label:"Copy file list to clipboard",action:()=>Q("copy")},{label:"Make package...",action:()=>We("make")},{label:"Deploy package...",action:()=>We("deploy")}],t=d.box({parent:r,top:0,left:0,width:"100%",height:"100%",style:{bg:"black"},keys:!0,mouse:!0,tags:!0}),s=d.box({parent:t,top:"center",left:"center",width:60,height:e.length+6,label:" Package Actions ",border:{type:"line"},style:{border:{fg:"yellow"},bg:"black",fg:"white"},keys:!0,mouse:!0,tags:!0,scrollable:!1}),o=()=>{t.parent&&(t.removeAllListeners(),t.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render())},i=d.list({parent:s,top:0,left:0,width:"100%",height:"100%-1",items:e.map(a=>a.label),keys:!0,vi:!0,mouse:!0,style:{selected:{bg:"cyan",fg:"black"},item:{fg:"white"}}});d.box({parent:s,bottom:0,left:0,width:"100%",height:1,content:" Enter=Select Esc=Close ",style:{fg:"gray"}}),i.focus(),r.saveFocus(),r.grabKeys=!0,r.render(),r.on("keypress",(a,p)=>{p?.name==="escape"&&o()}),t.on("click",o),i.key("enter",()=>{let a=i.selected;if(a>=0&&a<e.length){let p=e[a].action;o(),p()}}),i.on("keypress",(a,p)=>{p?.name==="escape"&&o()})}async function We(e){let t=xt();if(t.length===0){f("Select commits that contain Salesforce resource files first.",!0);return}if(!n.alias){f("No target org configured.",!0);return}let{overlay:s,modal:o}=F({width:72,height:e==="make"?10:12,label:e==="make"?" Make Package ":" Deploy Package "}),i=()=>{s.parent&&(s.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render())},a=d.prompt({parent:o,top:0,left:0,width:"100%",height:"100%",border:{type:"line"},style:{border:{fg:"cyan"},bg:"black",fg:"white"}});a.on("cancel",i),a.key("escape",i),a.key("q",i),a.readInput(e==="make"?"Package name (used for zip file). Press Enter to run.":"Package name (used for zip file). Press Enter to deploy.","",async(p,m)=>{if(p||m==null){i();return}i();let b=m.trim()||"dev";try{let k=await Te(b,t,void 0,120,!0,!1);e==="make"?N("Make Package",k.create,()=>{R.focus(),U()}):N("Deploy Package (Source)",k.deploy,()=>{R.focus(),U()})}catch(k){f(`Failed: ${k.message}`,!0)}})}async function kt(){if(!n.alias){f("No target org configured.",!0);return}let{overlay:e,modal:t}=F({width:72,height:8,label:" Deploy by Commit Range "}),s=()=>{e.parent&&(e.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render())},o=d.prompt({parent:t,top:0,left:0,width:"100%",height:"100%",border:{type:"line"},style:{border:{fg:"cyan"},bg:"black",fg:"white"}});o.on("cancel",s),o.key("escape",s),o.key("q",s),o.readInput("Enter commit range (e.g. abc123..def456). Press Enter.","",async(i,a)=>{if(i||a==null||!a.trim()){s();return}s();let m=a.trim().split("..");if(m.length!==2||!m[0]||!m[1]){f("Invalid format. Use: fromHash..toHash",!0);return}try{let k=(await It(m[0],m[1])).filter(E=>E.status!=="D"&&!E.status.startsWith("D")).filter(E=>se(E.file)).map(E=>E.file);if(k.length===0){f("No Salesforce resource files found in commit range.",!0);return}let $=rt(k,!1);N(`Deploy Commit Range (${m[0].slice(0,8)}..${m[1].slice(0,8)})`,$,()=>{R.focus(),U()})}catch(b){f(`Failed: ${b.message}`,!0)}})}async function $t(){if(!n.alias){f("No target org configured.",!0);return}let t=(await ke()).filter(o=>o.status!=="D"&&!o.status.startsWith("D")).filter(o=>se(o.file)).map(o=>o.file);if(t.length===0){f("No staged Salesforce resource files found.",!0);return}let s=rt(t,!1);N("Deploy Staged Files",s,()=>{R.focus(),U()})}async function Et(){let t=(await ke()).filter(o=>se(o.file)).map(o=>o.file);if(t.length===0){f("No staged Salesforce resource files found.",!0);return}let s=Ct(t);N("Retrieve Staged Files",s,()=>{R.focus(),U()})}function us(e){e.key("space",ns),e.key("enter",()=>{xe()}),e.key("g",()=>{Ve()}),e.key("/",()=>{ue("all")}),e.key("s",()=>{ue("all")}),e.on("keypress",(t,s)=>{s?.name==="a"&&s.shift&&ue("author")}),e.on("keypress",(t,s)=>{s?.name==="m"&&s.shift&&ue("message")}),e.key("i",()=>{(async()=>(S=!S,S&&(O=await ke()),U(),f(S?"Included staged files":"Excluded staged files")))()}),e.key("a",()=>{St()}),e.key("c",()=>{st(),f("Cleared Git Resource selection")}),e.key("d",()=>{Q("deploy-dry")}),e.on("keypress",(t,s)=>{s?.name==="d"&&s.ctrl&&Q("deploy")}),e.key("r",()=>{Q("retrieve")}),e.key("p",()=>{cs()}),e.on("keypress",(t,s)=>{s?.name==="r"&&s.shift&&kt()}),e.on("keypress",(t,s)=>{s?.name==="s"&&s.shift&&$t()}),e.on("keypress",(t,s)=>{s?.name==="r"&&s.ctrl&&Et()})}function vt(e){e.key("enter",()=>{xe()}),e.key("g",()=>{Ve()}),e.key("/",()=>{ue("all")}),e.key("s",()=>{ue("all")}),e.on("keypress",(t,s)=>{s?.name==="a"&&s.shift&&ue("author")}),e.on("keypress",(t,s)=>{s?.name==="m"&&s.shift&&ue("message")}),e.key("i",()=>{(async()=>(S=!S,S&&(O=await ke()),U(),f(S?"Included staged files":"Excluded staged files")))()}),e.key("a",()=>{St()}),e.key("c",()=>{st(),f("Cleared Git Resource selection")}),e.key("d",()=>{Q("deploy-dry")}),e.on("keypress",(t,s)=>{s?.name==="d"&&s.ctrl&&Q("deploy")}),e.key("r",()=>{Q("retrieve")}),e.key("b",()=>{Q("backup")}),e.key("y",()=>{Q("copy")})}us(R),vt(Z),vt(pe),R.on("select item",()=>{xe()}),Z.on("select item",()=>{xe()});function D(e){ne.hide(),Ge.hide(),Ze.hide(),z.hide(),je.hide(),Me.hide(),oe.hide(),e===1?(oe.show(),K(),y.length===0?Ve():(bt(),wt(),xe()),C.focus()):e===2?(ne.show(),v.focus()):e===3?(Ge.show(),gt(),V.focus()):e===4?(Ze.show(),Be(),I.focus()):e===5?(z.show(),Xt(),ie.focus()):e===6?(je.show(),yt(),W.focus()):e===7&&(Me.show(),es(),X.focus()),lt(e)}for(let e=1;e<=7;e++)r.key(String(e),()=>{r.focused!==v&&D(e)});let Ft=[{category:"Git",label:"Deploy Staged Files",shortcut:"S-s",action:()=>{$t()}},{category:"Git",label:"Retrieve Staged Files",shortcut:"C-r",action:()=>{Et()}},{category:"Git",label:"Deploy Commit Range...",shortcut:"S-r",action:()=>{kt()}},{category:"Git",label:"Make Package...",shortcut:"p",action:()=>{We("make")}},{category:"Git",label:"Deploy Package...",shortcut:"P",action:()=>{We("deploy")}},{category:"Git",label:"Backup Resources",shortcut:"b",action:()=>{Q("backup")}},{category:"Git",label:"Copy File List",shortcut:"y",action:()=>{Q("copy")}},{category:"SOQL",label:"Execute Query",shortcut:"C-e",action:()=>D(2)},{category:"SOQL",label:"Export to CSV",shortcut:"C-s",action:()=>D(2)},{category:"SOQL",label:"Export to JSON",shortcut:"C-j",action:()=>D(2)},{category:"SOQL",label:"SOQL Formatter",action:()=>{ds()}},{category:"Apex",label:"Execute Anonymous...",action:()=>{fs()}},{category:"Apex",label:"Abort Job",shortcut:"x",action:()=>D(4)},{category:"Apex",label:"Delete Job",shortcut:"D",action:()=>D(4)},{category:"Apex",label:"Start Debug Log",action:()=>f("Debug log management not yet implemented.")},{category:"Apex",label:"Stop Debug Log",action:()=>f("Debug log management not yet implemented.")},{category:"Metadata",label:"Retrieve Selected Type...",shortcut:"r",action:()=>D(5)},{category:"Metadata",label:"PermSet Generator...",action:()=>{ps()}},{category:"Metadata",label:"Profile Generator...",action:()=>{ys()}},{category:"Metadata",label:"Package from Files...",action:()=>{ms()}},{category:"Metadata",label:"Destructive Changes...",action:()=>{hs()}},{category:"Metadata",label:"Export SObject Schema...",action:()=>{bs()}},{category:"Org",label:"Switch Target Org...",action:()=>D(6)},{category:"Org",label:"REST API Browser...",shortcut:"r",action:()=>D(6)},{category:"Tools",label:"Data Loader...",action:()=>{ws()}},{category:"View",label:"Git Resource",shortcut:"1",action:()=>D(1)},{category:"View",label:"SOQL Browser",shortcut:"2",action:()=>D(2)},{category:"View",label:"Apex Logs",shortcut:"3",action:()=>D(3)},{category:"View",label:"Apex Jobs",shortcut:"4",action:()=>D(4)},{category:"View",label:"Metadata Explorer",shortcut:"5",action:()=>D(5)},{category:"View",label:"Org Manager",shortcut:"6",action:()=>D(6)},{category:"View",label:"CSV Viewer",shortcut:"7",action:()=>D(7)}];function gs(e=""){let t=e;function s(j){if(!j)return Ft;let M=j.toLowerCase();return Ft.filter(ge=>ge.label.toLowerCase().includes(M)||ge.category.toLowerCase().includes(M))}let o=s(t),i=d.box({parent:r,top:0,left:0,width:"100%",height:"100%",style:{bg:"black"},keys:!0,mouse:!0,tags:!0}),a=Math.min(o.length+4,30),p=d.box({parent:i,top:"center",left:"center",width:"70%",height:a,label:" Command Palette ",border:{type:"line"},style:{border:{fg:"yellow"},bg:"black",fg:"white"},keys:!0,mouse:!0,tags:!0,scrollable:!1}),m=d.box({parent:p,top:0,left:0,width:"100%",height:1,tags:!0,style:{fg:"cyan",bg:"black"}});d.box({parent:p,top:1,left:0,width:"100%",height:1,content:"\u2500".repeat(200),style:{fg:"cyan"}});let b=d.list({parent:p,top:2,left:0,width:"100%",height:"100%-2",items:[],keys:!0,vi:!0,mouse:!0,style:{selected:{bg:"cyan",fg:"black"},item:{fg:"white"}}});function k(){m.setContent(" > "+t+"_")}function $(){o=s(t),b.setItems(o.map(j=>{let M="["+j.category+"]",ge=j.shortcut?" ".repeat(Math.max(1,40-M.length-j.label.length)):"";return M+" "+j.label+ge+(j.shortcut||"")})),b.select(0),k(),r.render()}function E(){b.removeAllListeners(),i.removeAllListeners(),r.removeAllListeners("keypress"),i.parent&&i.destroy(),r.grabKeys=!1,r.restoreFocus(),r.render()}k(),$(),b.focus(),r.saveFocus(),r.grabKeys=!0,r.render(),r.on("keypress",(j,M)=>{M?.name==="escape"&&E()}),i.on("click",()=>{E()}),b.on("keypress",(j,M)=>{if(M?.name==="escape")E();else if(M?.name==="enter"){let ge=b.selected;if(ge>=0&&ge<o.length){let Ss=o[ge];E(),Ss.action()}}else M?.name==="backspace"?(t=t.slice(0,-1),$()):!M?.ctrl&&!M?.meta&&j&&j.length===1&&(t+=j,$())})}function f(e,t=!1){let{overlay:s,modal:o,close:i}=F({width:60,height:5,label:t?" Error ":" Message "});d.text({parent:o,top:1,left:1,width:"100%-2",height:1,content:e,style:{fg:t?"red":"green"}}),o.key(["enter","escape","q"],i),s.key(["enter","escape","q"],i)}function ds(){let{overlay:e,modal:t,close:s}=F({width:"80%",height:"80%",label:" SOQL Formatter "}),o=d.textarea({parent:t,top:0,left:0,width:"100%",height:"100%-1",border:{type:"line"},label:" Paste SOQL ",style:{border:{fg:"cyan"},bg:"black",fg:"white"},keys:!0,vi:!0,mouse:!0,inputOnFocus:!0}),i=d.box({parent:t,bottom:0,left:0,width:"100%",height:1,content:" Enter=Format Esc=Close ",style:{fg:"gray"}});o.focus(),r.render(),o.key("enter",()=>{let a=o.getValue();if(!a.trim()){s();return}let p=a.replace(/\bSELECT\b/gi,`SELECT
|
|
73
|
+
`).replace(/\bFROM\b/gi,`
|
|
74
|
+
FROM
|
|
75
|
+
`).replace(/\bWHERE\b/gi,`
|
|
76
|
+
WHERE
|
|
77
|
+
`).replace(/\bAND\b/gi,`
|
|
78
|
+
AND`).replace(/\bOR\b/gi,`
|
|
79
|
+
OR`).replace(/\bORDER BY\b/gi,`
|
|
80
|
+
ORDER BY
|
|
81
|
+
`).replace(/\bGROUP BY\b/gi,`
|
|
82
|
+
GROUP BY
|
|
83
|
+
`).replace(/\bHAVING\b/gi,`
|
|
84
|
+
HAVING
|
|
85
|
+
`).replace(/\bLIMIT\b/gi,`
|
|
86
|
+
LIMIT
|
|
87
|
+
`).replace(/,\s*/g,`,
|
|
88
|
+
`);s();let{modal:m,close:b}=F({width:"80%",height:"80%",label:" Formatted SOQL "}),k=d.textarea({parent:m,top:0,left:0,width:"100%",height:"100%-1",border:{type:"line"},label:" Result ",style:{border:{fg:"green"},bg:"black",fg:"white"},keys:!0,vi:!0,mouse:!0,inputOnFocus:!0,value:p});d.box({parent:m,bottom:0,left:0,width:"100%",height:1,content:" Ctrl-c=Copy Esc=Close ",style:{fg:"gray"}}),k.focus(),r.render(),k.key("escape",b),k.key(["C-c"],()=>{Je(p),b()})}),o.key("escape",s)}function fs(){if(!n.alias){f("No target org configured.",!0);return}let{overlay:e,modal:t,close:s}=F({width:72,height:12,label:" Execute Anonymous Apex "}),o=d.textarea({parent:t,top:0,left:0,width:"100%",height:"100%-1",border:{type:"line"},label:" Apex Code ",style:{border:{fg:"cyan"},bg:"black",fg:"white"},keys:!0,vi:!0,mouse:!0,inputOnFocus:!0});d.box({parent:t,bottom:0,left:0,width:"100%",height:1,content:" Enter=Execute Esc=Close ",style:{fg:"gray"}}),o.focus(),r.render(),o.key("enter",async()=>{let i=o.getValue();if(i.trim()){s(),f("Executing...",!1);try{let a=await Qt(n.alias,i);f(a||"Executed successfully.",!1)}catch(a){f("Error: "+(a.message||a),!0)}}}),o.key("escape",s)}function ps(){if(!n.alias){f("No target org configured.",!0);return}let{overlay:e,modal:t,close:s}=F({width:70,height:10,label:" Permission Set Generator "});d.box({parent:t,top:0,left:0,width:"100%",height:3,tags:!0,content:" Enter object names (comma-separated):"});let o=d.textbox({parent:t,top:3,left:0,width:"100%",height:1,border:{type:"line"},label:" Objects ",style:{border:{fg:"cyan"},bg:"black",fg:"white"},inputOnFocus:!0,keys:!0});d.box({parent:t,bottom:0,left:0,width:"100%",height:1,content:" Enter=Generate Esc=Close ",style:{fg:"gray"}}),o.focus(),r.render(),o.key("enter",async()=>{let i=o.getValue().split(",").map(a=>a.trim()).filter(Boolean);if(i.length!==0){s();try{let a=Te(i,"PermissionSet");f("Generated "+a.length+" permission set commands.",!1)}catch(a){f("Error: "+a.message,!0)}}}),o.key("escape",s)}function ys(){if(!n.alias){f("No target org configured.",!0);return}let{overlay:e,modal:t,close:s}=F({width:70,height:10,label:" Profile Generator "});d.box({parent:t,top:0,left:0,width:"100%",height:3,tags:!0,content:" Enter object names (comma-separated):"});let o=d.textbox({parent:t,top:3,left:0,width:"100%",height:1,border:{type:"line"},label:" Objects ",style:{border:{fg:"cyan"},bg:"black",fg:"white"},inputOnFocus:!0,keys:!0});d.box({parent:t,bottom:0,left:0,width:"100%",height:1,content:" Enter=Generate Esc=Close ",style:{fg:"gray"}}),o.focus(),r.render(),o.key("enter",async()=>{let i=o.getValue().split(",").map(a=>a.trim()).filter(Boolean);if(i.length!==0){s();try{let a=Te(i,"Profile");f("Generated "+a.length+" profile commands.",!1)}catch(a){f("Error: "+a.message,!0)}}}),o.key("escape",s)}function ms(){let{overlay:e,modal:t,close:s}=F({width:70,height:10,label:" Package from Files "});d.box({parent:t,top:0,left:0,width:"100%",height:3,tags:!0,content:" Enter file paths (comma-separated):"});let o=d.textbox({parent:t,top:3,left:0,width:"100%",height:1,border:{type:"line"},label:" Files ",style:{border:{fg:"cyan"},bg:"black",fg:"white"},inputOnFocus:!0,keys:!0});d.box({parent:t,bottom:0,left:0,width:"100%",height:1,content:" Enter=Generate Esc=Close ",style:{fg:"gray"}}),o.focus(),r.render(),o.key("enter",()=>{let i=o.getValue().split(",").map(a=>a.trim()).filter(Boolean);if(i.length!==0){s();try{let a=Te(i,"destructiveChanges");f("Generated package XML with "+a.length+" entries.",!1)}catch(a){f("Error: "+a.message,!0)}}}),o.key("escape",s)}function hs(){let{overlay:e,modal:t,close:s}=F({width:70,height:10,label:" Destructive Changes "});d.box({parent:t,top:0,left:0,width:"100%",height:3,tags:!0,content:" Enter metadata to delete (type:name, comma-separated):"});let o=d.textbox({parent:t,top:3,left:0,width:"100%",height:1,border:{type:"line"},label:" Metadata ",style:{border:{fg:"cyan"},bg:"black",fg:"white"},inputOnFocus:!0,keys:!0});d.box({parent:t,bottom:0,left:0,width:"100%",height:1,content:" Enter=Generate Esc=Close ",style:{fg:"gray"}}),o.focus(),r.render(),o.key("enter",()=>{let i=o.getValue().split(",").map(a=>a.trim()).filter(Boolean);i.length!==0&&(s(),f("Generated destructiveChanges.xml with "+i.length+" entries.",!1))}),o.key("escape",s)}function bs(){if(!n.alias){f("No target org configured.",!0);return}f("Fetching SObject list...",!1),qt(n.alias).then(async e=>{let{overlay:t,modal:s,close:o}=F({width:60,height:Math.min(e.length+4,25),label:" Export SObject Schema "}),i=d.list({parent:s,top:0,left:0,width:"100%",height:"100%-1",items:e.map(a=>a.name),keys:!0,vi:!0,mouse:!0,style:{selected:{bg:"cyan",fg:"black"},item:{fg:"white"}}});d.box({parent:s,bottom:0,left:0,width:"100%",height:1,content:" Enter=Export Esc=Close ",style:{fg:"gray"}}),i.focus(),r.render(),i.key("enter",async()=>{let a=i.selected;if(a<0||a>=e.length)return;let p=e[a].name;o();try{let m=await Vt(n.alias,p),b=`Name,Label,Type,Length,Required,ReferenceTo
|
|
89
|
+
`+m.map($=>`${$.name},${$.label||""},${$.type||""},${$.length||""},${$.required||""},${$.referenceTo||""}`).join(`
|
|
90
|
+
`),k=p+"_schema.csv";B.writeFileSync(k,b),f("Exported "+m.length+" fields to "+k,!1)}catch(m){f("Error: "+m.message,!0)}}),i.key("escape",o)}).catch(e=>{f("Error fetching SObjects: "+e.message,!0)})}function ws(){let{overlay:e,modal:t,close:s}=F({width:70,height:12,label:" Data Loader "});d.box({parent:t,top:0,left:0,width:"100%",height:5,tags:!0,content:` CSV-based data operations
|
|
91
|
+
Supported: Insert, Update, Upsert
|
|
92
|
+
Enter SOQL to select records for update/upsert:`});let o=d.textarea({parent:t,top:5,left:0,width:"100%",height:"100%-1",border:{type:"line"},label:" SOQL Query ",style:{border:{fg:"cyan"},bg:"black",fg:"white"},keys:!0,vi:!0,mouse:!0,inputOnFocus:!0});d.box({parent:t,bottom:0,left:0,width:"100%",height:1,content:" Esc=Close ",style:{fg:"gray"}}),o.focus(),r.render(),o.key("escape",s)}r.key(["?","S-/"],()=>{Kt()}),r.key([":","S-;"],()=>{gs()}),r.key("tab",()=>{c===1?r.focused===C?R.focus():r.focused===R?Z.focus():r.focused===Z?pe.focus():C.focus():c===2?r.focused===v?_.focus():v.focus():c===3?r.focused===V?ae.focus():V.focus():c===4?I.focus():c===5?r.focused===ie?le.focus():r.focused===le?we.focus():ie.focus():c===6?r.focused===W?ce.focus():W.focus():c===7&&(r.focused===X?fe.focus():X.focus())}),D(1)}function Gs(){if(process.platform!=="win32")return!1;let l=process.env.TERM||"",r=process.env.WT_SESSION||"",n=process.env.ConEmuPID||"",c=process.env.MSYSTEM||"";return!(l||r||n||c)}var _e=class{constructor(){if(process.platform==="win32")try{require("child_process").execSync("chcp 65001",{stdio:"pipe"})}catch{}let r=Gs();this.screen=_t.screen({smartCSR:!r,title:"esf - EasySFDX TUI",autoPadding:!0,useBCE:!r,mouse:!r,encoding:"utf-8",fullUnicode:!0,cursor:{artificial:!0,shape:"line",blink:!r,color:"white"}}),this.screen.key(["C-c"],()=>process.exit(0)),this.config=De()}start(){Ht(this)}};var js=new _e;js.start();
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@exiahuang/esf",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "EasySFDX TUI - Terminal User Interface for Salesforce Development",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"esf": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsup",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"dev": "tsx src/index.ts"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"blessed": "^0.1.81",
|
|
20
|
+
"js-yaml": "^4.1.0",
|
|
21
|
+
"simple-git": "^3.22.0"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/blessed": "^0.1.19",
|
|
25
|
+
"@types/js-yaml": "^4.0.9",
|
|
26
|
+
"@types/node": "^20.11.0",
|
|
27
|
+
"tsup": "^8.5.1",
|
|
28
|
+
"tsx": "^4.7.0",
|
|
29
|
+
"typescript": "^5.3.3"
|
|
30
|
+
}
|
|
31
|
+
}
|