Public/New-TauriProject.ps1
function New-TauriProject { <# .SYNOPSIS Creates a new Tauri Next.js desktop application project using PowerShell. .DESCRIPTION New-TauriProject scaffolds a new Tauri v2 desktop application with Next.js frontend and configures GitHub Actions for cross-platform releases. This is a simplified version focused on Next.js only. .PARAMETER ProjectName The name of the project directory to create. If not specified, you'll be prompted to enter one. .PARAMETER PackageName The package name for package.json. If not specified, it will be derived from the project name. .PARAMETER TargetOS Array of target operating systems for GitHub Actions. Valid options are: 'windows-latest', 'macos-latest', 'ubuntu-latest'. Default is all three platforms. .PARAMETER Force Overwrite the target directory if it already exists and is not empty. .PARAMETER Interactive Run in interactive mode with prompts for all options (default behavior). .PARAMETER PackageManager The package manager to use. Valid options are: 'npm', 'yarn', 'pnpm'. Default is 'npm'. .EXAMPLE New-TauriProject Creates a new Tauri Next.js project with interactive prompts for all options. .EXAMPLE New-TauriProject -Name "my-tauri-app" Creates a new Tauri Next.js project named "my-tauri-app". .EXAMPLE New-TauriProject -Name "my-app" -TargetOS @("windows-latest", "ubuntu-latest") -Force Creates a new Tauri Next.js project targeting only Windows and Linux, overwriting any existing directory. .NOTES This function uses the Next.js template from the module's Private/nextjs-template directory. The function will copy template files, process configuration files, and set up the project structure. #> [CmdletBinding(DefaultParameterSetName = 'Interactive', SupportsShouldProcess = $true)] param( [Parameter(Position = 0)] [Alias('Name', 'n')] [string]$ProjectName, [Parameter()] [Alias('pn')] [string]$PackageName, [Parameter()] [ValidateSet('windows-latest', 'macos-latest', 'ubuntu-latest')] [alias('os', 'target')] [string[]]$TargetOS = @('windows-latest', 'macos-latest', 'ubuntu-latest'), [Parameter()] [switch]$Force, [Parameter(ParameterSetName = 'Interactive')] [switch]$Interactive, [Parameter()] [ValidateSet('npm', 'yarn', 'pnpm')] [Alias('pm')] [string]$PackageManager ) try { # Detect package manager if not specified if ([string]::IsNullOrWhiteSpace($PackageManager)) { $pkgInfo = [TauriCraft]::DetectPackageManager() $PackageManager = $pkgInfo.name } # Interactive mode or missing required parameters if ($Interactive -or [string]::IsNullOrWhiteSpace($ProjectName)) { $config = Get-InteractiveProjectConfig -ProjectName $ProjectName -PackageName $PackageName -TargetOS $TargetOS -Force:$Force -PackageManager $PackageManager } else { # Non-interactive mode with all parameters provided $config = [ProjectConfig]::new() $config.ProjectName = $ProjectName $config.TargetDirectory = [TauriCraft]::FormatTargetDirectory($ProjectName) if ([string]::IsNullOrWhiteSpace($config.TargetDirectory)) { $config.TargetDirectory = [TauriCraft]::DefaultTargetDir } # No framework selection needed - using Next.js only # Set package name if ([string]::IsNullOrWhiteSpace($PackageName)) { $config.PackageName = [TauriCraft]::ToValidPackageName($config.ProjectName) } else { $config.PackageName = $PackageName } # Validate package name if (![TauriCraft]::IsValidPackageName($config.PackageName)) { throw [System.InvalidOperationException]::new("Invalid package name: $($config.PackageName). Package names must follow npm naming conventions.") } $config.ReleaseOS = $TargetOS $config.Overwrite = $Force $config.PackageManager = $PackageManager } # Create the project $moduleRoot = [IO.Path]::GetDirectoryName($PSScriptRoot) if ($PSCmdlet.ShouldProcess("$moduleRoot", "Create Tauri project")) { [TauriCraft]::CreateProject($config, $moduleRoot) } } catch { Write-Error "Failed to create Tauri Next.js project: $($_.Exception.Message)" return } } function Get-InteractiveProjectConfig { param( [string]$ProjectName, [string]$PackageName, [string[]]$TargetOS, [bool]$Force, [string]$PackageManager ) $config = [ProjectConfig]::new() $config.PackageManager = $PackageManager # Project name prompt if ([string]::IsNullOrWhiteSpace($ProjectName)) { do { $ProjectName = Read-Host "Project name [$([TauriCraft]::DefaultTargetDir)]" if ([string]::IsNullOrWhiteSpace($ProjectName)) { $ProjectName = [TauriCraft]::DefaultTargetDir } $ProjectName = [TauriCraft]::FormatTargetDirectory($ProjectName) } while ([string]::IsNullOrWhiteSpace($ProjectName)) } $config.ProjectName = $ProjectName $config.TargetDirectory = $ProjectName # Check if directory exists and prompt for overwrite $projectPath = [IO.Path]::Combine((Get-Location) , $config.TargetDirectory) if ((Test-Path $projectPath) -and -not [TauriCraft]::IsDirectoryEmpty($projectPath)) { if (-not $Force) { $overwrite = Read-Host "Target directory '$($config.TargetDirectory)' is not empty. Remove existing files and continue? (y/N)" $config.Overwrite = $overwrite -match '^[Yy]' if (-not $config.Overwrite) { throw "Operation cancelled" } } else { $config.Overwrite = $true } } # Package name $defaultPackageName = [TauriCraft]::ToValidPackageName($config.ProjectName) if ([string]::IsNullOrWhiteSpace($PackageName)) { if (-not [TauriCraft]::IsValidPackageName($defaultPackageName)) { do { $PackageName = Read-Host "Package name [$defaultPackageName]" if ([string]::IsNullOrWhiteSpace($PackageName)) { $PackageName = $defaultPackageName } } while (-not [TauriCraft]::IsValidPackageName($PackageName)) } else { $PackageName = $defaultPackageName } } $config.PackageName = $PackageName # Target OS selection Write-Host "`nTarget operating systems for GitHub Actions:" -ForegroundColor Yellow Write-Host "(Use space to toggle, Enter to confirm)" -ForegroundColor Gray $osConfigs = [TauriCraft]::TargetOperatingSystems $selectedOS = @() foreach ($osConfig in $osConfigs) { $default = if ($TargetOS -contains $osConfig.Value) { "Y" } else { "n" } $choice = Read-Host "$($osConfig.Title) [$default]" if ([string]::IsNullOrWhiteSpace($choice)) { $choice = $default } if ($choice -match '^[Yy]') { $selectedOS += $osConfig.Value } } if ($selectedOS.Count -eq 0) { Write-Warning "No target OS selected. Using all platforms." $selectedOS = [TauriCraft]::GetAllOSTargets() } $config.ReleaseOS = $selectedOS return $config } |