param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $false)] [string]$SamplePath, [switch]$Strict ) $ErrorActionPreference = 'Stop' function Fail([string]$Message) { Write-Error $Message exit 1 } function Parse-Json([string]$JsonText, [string]$Label) { try { return ($JsonText | ConvertFrom-Json -ErrorAction Stop) } catch { Fail "Invalid JSON ($Label): $($_.Exception.Message)" } } if (-not (Test-Path -LiteralPath $Path)) { Fail "File not found: $Path" } $raw = Get-Content -LiteralPath $Path -Raw $json = Parse-Json -JsonText $raw -Label $Path if ($null -eq $json -or $json.GetType().Name -ne 'PSCustomObject') { Fail "Expected a JSON object at top-level: $Path" } if ($Strict -and -not $SamplePath) { Fail "Strict mode requires -SamplePath (exported from your Dify)." } if ($SamplePath) { if (-not (Test-Path -LiteralPath $SamplePath)) { Fail "Sample file not found: $SamplePath" } $sampleRaw = Get-Content -LiteralPath $SamplePath -Raw $sample = Parse-Json -JsonText $sampleRaw -Label $SamplePath if ($null -eq $sample -or $sample.GetType().Name -ne 'PSCustomObject') { Fail "Expected a JSON object at top-level (sample): $SamplePath" } $sampleKeys = @($sample.PSObject.Properties.Name | Sort-Object) $keys = @($json.PSObject.Properties.Name | Sort-Object) $missing = @() foreach ($k in $sampleKeys) { if ($keys -notcontains $k) { $missing += $k } } if ($missing.Count -gt 0) { $msg = "Missing top-level keys vs sample: " + ($missing -join ', ') if ($Strict) { Fail $msg } else { Write-Warning $msg } } } Write-Host "OK: $Path is valid JSON. Top-level keys: $(@($json.PSObject.Properties.Name) -join ', ')" exit 0