added addl wrappers

This commit is contained in:
reynold
2025-08-28 16:34:16 +08:00
parent a385484a69
commit 747aa90d26
17 changed files with 4265 additions and 21 deletions

290
sf-data-export.ps1 Normal file
View File

@@ -0,0 +1,290 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Data export wrapper for Salesforce CLI with SOQL query support
.DESCRIPTION
A user-friendly wrapper around 'sf data export' that simplifies data export
from Salesforce orgs with SOQL query support, multiple formats, and intelligent defaults.
.PARAMETER Query
SOQL query to export data
.PARAMETER File
File containing SOQL query
.PARAMETER SObject
Standard object query (exports common fields)
.PARAMETER Output
Output file path (default: export.csv)
.PARAMETER TargetOrg
Target org username or alias
.PARAMETER Format
Output format: csv, json (default: csv)
.PARAMETER Bulk
Use bulk API for large datasets
.PARAMETER Wait
Wait time in minutes (default: 10)
.PARAMETER Verbose
Enable verbose output
.PARAMETER Help
Show this help message
.EXAMPLE
.\sf-data-export.ps1 -Query "SELECT Id, Name FROM Account LIMIT 100"
.\sf-data-export.ps1 -SObject Account -Format json -Output accounts.json
.\sf-data-export.ps1 -File queries/contacts.soql -Bulk -Wait 15
.\sf-data-export.ps1 -Query "SELECT Id FROM User" -TargetOrg production
.NOTES
This script automatically checks for Salesforce CLI installation and runs
diagnostics if the CLI is not found.
#>
param(
[Parameter(ParameterSetName="Query")]
[string]$Query,
[Parameter(ParameterSetName="File")]
[string]$File,
[Parameter(ParameterSetName="SObject")]
[string]$SObject,
[string]$Output = "export.csv",
[string]$TargetOrg,
[ValidateSet("csv", "json")]
[string]$Format = "csv",
[switch]$Bulk,
[int]$Wait = 10,
[switch]$Verbose,
[switch]$Help
)
# Show help if requested
if ($Help) {
Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0
}
# Function to check if Salesforce CLI is installed
function Test-SalesforceCLI {
try {
$null = Get-Command sf -ErrorAction Stop
return $true
} catch {
return $false
}
}
# Function to run sf-check diagnostics
function Invoke-SalesforceCheck {
$checkScript = if (Test-Path "sf-check.ps1") {
".\sf-check.ps1"
} elseif (Test-Path "sf-check.sh") {
"bash sf-check.sh"
} else {
$null
}
if ($checkScript) {
Write-Host "Running Salesforce CLI diagnostics..." -ForegroundColor Yellow
Invoke-Expression $checkScript
} else {
Write-Host "Salesforce CLI not found and no diagnostic script available." -ForegroundColor Red
Write-Host "Please install the Salesforce CLI: https://developer.salesforce.com/tools/salesforcecli" -ForegroundColor Red
}
}
# Function to build standard object query
function New-SObjectQuery {
param([string]$SObjectType)
switch ($SObjectType) {
"Account" {
return "SELECT Id, Name, Type, Industry, Phone, Website, BillingCity, BillingState, BillingCountry FROM Account"
}
"Contact" {
return "SELECT Id, FirstName, LastName, Email, Phone, AccountId, Account.Name FROM Contact"
}
"Lead" {
return "SELECT Id, FirstName, LastName, Email, Phone, Company, Status, Source FROM Lead"
}
"Opportunity" {
return "SELECT Id, Name, AccountId, Account.Name, Amount, CloseDate, StageName, Probability FROM Opportunity"
}
"Case" {
return "SELECT Id, CaseNumber, Subject, Status, Priority, Origin, AccountId, Account.Name, ContactId, Contact.Name FROM Case"
}
"User" {
return "SELECT Id, Name, Email, Username, Profile.Name, IsActive, LastLoginDate FROM User"
}
default {
return "SELECT Id, Name FROM $SObjectType"
}
}
}
# Function to validate SOQL query
function Test-SOQLQuery {
param([string]$QueryText)
if ($QueryText -notmatch '^\s*SELECT\s+') {
Write-Host "Error: Query must start with SELECT" -ForegroundColor Red
return $false
}
return $true
}
# Silently check for Salesforce CLI
if (-not (Test-SalesforceCLI)) {
Invoke-SalesforceCheck
exit 1
}
# Validate that exactly one query method is specified
$queryMethods = @($Query, $File, $SObject | Where-Object { $_ }).Count
if ($queryMethods -eq 0) {
Write-Host "Error: Must specify one of: -Query, -File, or -SObject" -ForegroundColor Red
Write-Host ""
Write-Host "Usage examples:" -ForegroundColor Yellow
Write-Host " .\sf-data-export.ps1 -Query `"SELECT Id, Name FROM Account`"" -ForegroundColor Gray
Write-Host " .\sf-data-export.ps1 -File queries/accounts.soql" -ForegroundColor Gray
Write-Host " .\sf-data-export.ps1 -SObject Account" -ForegroundColor Gray
Write-Host ""
Write-Host "Use -Help for detailed usage information." -ForegroundColor Yellow
exit 1
}
if ($queryMethods -gt 1) {
Write-Host "Error: Can only specify one of: -Query, -File, or -SObject" -ForegroundColor Red
exit 1
}
# Determine the final query
$finalQuery = ""
if ($Query) {
$finalQuery = $Query
Write-Host "Using inline query" -ForegroundColor Green
} elseif ($File) {
if (-not (Test-Path $File)) {
Write-Host "Error: Query file not found: $File" -ForegroundColor Red
exit 1
}
$finalQuery = Get-Content $File -Raw
Write-Host "Using query from file: $File" -ForegroundColor Green
} elseif ($SObject) {
$finalQuery = New-SObjectQuery $SObject
Write-Host "Using standard query for $SObject" -ForegroundColor Green
}
# Validate the query
if (-not (Test-SOQLQuery $finalQuery)) {
exit 1
}
# Build the sf command
$sfArgs = @("data", "export", "--query", $finalQuery)
# Add optional parameters
if ($TargetOrg) {
$sfArgs += "--target-org"
$sfArgs += $TargetOrg
Write-Host "Target org: $TargetOrg" -ForegroundColor Cyan
}
if ($Bulk) {
$sfArgs += "--bulk"
Write-Host "Using Bulk API" -ForegroundColor Yellow
}
if ($Wait -ne 10) {
$sfArgs += "--wait"
$sfArgs += $Wait.ToString()
}
# Set output file and format
$sfArgs += "--output-file"
$sfArgs += $Output
if ($Format -eq "json") {
$sfArgs += "--json"
}
Write-Host "Output format: $Format" -ForegroundColor Cyan
Write-Host "Output file: $Output" -ForegroundColor Cyan
# Add verbose flag if requested
if ($Verbose) {
$sfArgs += "--verbose"
}
# Display export information
Write-Host ""
Write-Host "📊 Starting Data Export" -ForegroundColor Blue
Write-Host "=======================" -ForegroundColor Blue
# Show query preview if verbose
if ($Verbose) {
Write-Host ""
Write-Host "📝 SOQL Query:" -ForegroundColor Yellow
Write-Host "----------------------------------------" -ForegroundColor Gray
Write-Host $finalQuery -ForegroundColor Gray
Write-Host "----------------------------------------" -ForegroundColor Gray
}
# Display the command being run
Write-Host ""
Write-Host "Executing: sf $($sfArgs -join ' ')" -ForegroundColor Gray
Write-Host ""
# Execute the command
try {
& sf @sfArgs
$exitCode = $LASTEXITCODE
Write-Host ""
if ($exitCode -eq 0) {
Write-Host "✅ Data export completed successfully!" -ForegroundColor Green
# Show file information if it exists
if (Test-Path $Output) {
$fileInfo = Get-Item $Output
$fileSize = if ($fileInfo.Length -gt 1MB) {
"{0:N1} MB" -f ($fileInfo.Length / 1MB)
} elseif ($fileInfo.Length -gt 1KB) {
"{0:N1} KB" -f ($fileInfo.Length / 1KB)
} else {
"$($fileInfo.Length) bytes"
}
if ($Format -eq "csv") {
# Count records (excluding header)
$recordCount = (Get-Content $Output).Count - 1
Write-Host "📁 Exported $recordCount records to $Output ($fileSize)" -ForegroundColor Cyan
} else {
Write-Host "📁 Data exported to $Output ($fileSize)" -ForegroundColor Cyan
}
}
if ($Verbose) {
Write-Host "💡 Use a spreadsheet application or text editor to view the exported data" -ForegroundColor Yellow
}
} else {
Write-Host "❌ Data export failed with exit code: $exitCode" -ForegroundColor Red
Write-Host "💡 Check query syntax and permissions" -ForegroundColor Yellow
exit $exitCode
}
} catch {
Write-Host "Error executing sf command: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}