Skip to content

Instantly share code, notes, and snippets.

@ongkiii
Last active December 27, 2025 21:28
Show Gist options
  • Select an option

  • Save ongkiii/b40620d8d4a98ab17642858dce4cb2ec to your computer and use it in GitHub Desktop.

Select an option

Save ongkiii/b40620d8d4a98ab17642858dce4cb2ec to your computer and use it in GitHub Desktop.
REPOS/TELEGRAM CHANNELS LIST BY u/angkitbharadwaj

🗂️ REPOS/TELEGRAM CHANNELS LIST

By u/angkitbharadwaj


⚙️ Signers


⚙️ Repositories

These are links to be used with Feather, eSign, Scarlet, etc.

zxcvbn's Repo Access

  • Main: https://aio.yippee.rip/repo.json
  • AltStore: https://aio.zxcvbn.fyi/r/repo.altstore.json
  • eSign: https://aio.zxcvbn.fyi/r/repo.esign.json
  • Feather: https://aio.zxcvbn.fyi/r/repo.feather.json

Misc. Repos (heads up, some might be down)

https://flyinghead.github.io/flycast-builds/altstore.json  
https://raw.githubusercontent.com/Neoncat-OG/TrollStore-IPAs/main/apps_esign.json  
https://qnblackcat.github.io/AltStore/apps.json  
https://pokemmo.eu/altstore/  
https://altstore.oatmealdome.me  
https://wuxu1.github.io/wuxu-complete-plus.json  
https://ipa.cypwn.xyz/cypwn.json  
https://community-apps.sidestore.io/sidecommunity.json  
https://tiny.one/SpotC  
https://raw.githubusercontent.com/arichornloveralt/arichornloveralt.github.io/main/apps.json  
https://raw.githubusercontent.com/whoeevee/EeveeSpotify/swift/repo.json  
https://aio.yippee.rip/repo.json  
https://css.eyz.ink/appstore  
https://xitrix.github.io/iTorrent/AltStore.json  
https://ish.app/altstore.json  
https://repository.apptesters.org  
https://repo.whoeevee.com/esign  
https://repo.madari.media/nightly/repo.json  
https://github.com/dvntm0/AltStore/raw/refs/heads/main/feather.json  
https://raw.githubusercontent.com/notrifty1/riftysrepo/refs/heads/main/reposource.json  
https://altstore.oatmealdome.me/  
https://raw.githubusercontent.com/driftywinds/driftywinds.github.io/master/AltStore/apps.json  
https://web.archive.org/web/20240828224000/https://raw.githubusercontent.com/swaggyP36000/TrollStore-IPAs/main/apps_esign.json
https://repo.realmzer.xyz  
https://raw.githubusercontent.com/Gliddd4/gliddd4-repo/refs/heads/main/app.json
https://repo.chungchi365.com/repo.json
https://raw.githubusercontent.com/zigwangles/zigwangles-repo/refs/heads/main/app-repo.json
https://raw.githubusercontent.com/AntonP29/AntonP29-Repo/refs/heads/main/repo.json
https://repo.owo.network/
https://balackburn.github.io/Apollo/apps.json
https://apps.altstore.io/
https://bit.ly/Altstore-complete
https://appmarket.tech/altstore.json
https://raw.githubusercontent.com/Auties00/Artemis/refs/heads/main/source.json
https://bunduuk.github.io/altstore-source/apps.json
https://get.furaffinity.app/altstore-world/
https://ipa.cypwn.xyz/cypwn_ts.json
https://enmity-mod.github.io/repo/altstore.json
https://github.com/khcrysalis/Feather/raw/main/app-repo.json
https://therealfoxster.github.io/altsource/apps.json
https://hottubapp.io/altstore
https://altstore.ignitedemulator.com
https://raw.githubusercontent.com/Nyasami/Ksign/refs/heads/main/repo.json
https://alts.lao.sb
https://buildbot.libretro.com/stable/altstore.json
https://raw.githubusercontent.com/LiveContainer/LiveContainer/refs/heads/main/apps.json
https://theodyssey.dev/altstore/odysseysource.json
https://raw.githubusercontent.com/vizunchik/AltStoreRus/master/apps.json
https://alt.crystall1ne.dev
https://pokemmo.com/altstore/
https://provenance-emu.com/apps.json
https://quarksources.github.io/dist/quantumsource.min.json
https://bit.ly/Quantumsource-plus
https://quarksources.github.io/quarksource-cracked.json
https://randomblock1.com/altstore/apps.json
https://spotc-repo.yodaluca.dev/AltStore%20Repo.json
https://taurine.app/altstore/taurinestore.json
https://alt.getutm.app
https://wuxu1.github.io/wuxu-complete.json
https://raw.githubusercontent.com/Balackburn/YTLitePlusAltstore/main/apps.json
https://azu0609.github.io/repo/altstore_repo.json
https://raw.githubusercontent.com/cbruegg/altstore-source/refs/heads/main/source.json
https://raw.githubusercontent.com/driftywinds/driftywinds.github.io/master/AltStore/nyx.json
https://raw.githubusercontent.com/driftywinds/driftywinds.github.io/master/AltStore/theta.json
https://repo.ethsign.fyi
https://raw.githubusercontent.com/lo-cafe/winston-altstore/main/apps.json
https://esign.yyyue.xyz/app.json
https://alt.thatstel.la/
https://apps.nabzclan.vip/repos/altstore.php
https://apps.sidestore.io/
https://binnichtaktiv.signapp.me/repo/esign.json
https://burritosoftware.github.io/altstore/channels/burritosource.json
https://connect.sidestore.io/apps.json
https://cranci.tech/repo.json
https://driftywinds.github.io/repos/esign.json
https://dvntm0.github.io/AltStore/raw/refs/heads/main/esign.json
https://floridaman7588.me/altjb/altsource.json
https://gbox.run/Public/Source.json
https://hann8n.github.io/JackCracks/MovieboxPro.json
https://ia601404.us.archive.org/11/items/ms_20220903/MS.json
https://ia601407.us.archive.org/11/items/ms_20220903/MS.json
https://ia601505.us.archive.org/10/items/motoca-store/Motoca%20Store.json
https://ikghd.site/repo.json
https://ipa.thuthuatjb.com/repo
https://ittza7aa.com/repo.json
https://lo-cafe/winston-altstore/main/apps.json
https://madari.media/nightly/repo.json
https://nabzclan.vip/repos/esign.php
https://qingsongqian.github.io/all.html
https://quarksources.github.io/quantumsource++.json
https://quarksources.github.io/quantumsource.json
https://raw.githubusercontent.com/Omni-Development/The-Omni-Repository/refs/heads/main/app-repo.json
https://raw.githubusercontent.com/RealBlackAstronaut/CelestialRepo/main/CelestialRepo.json
https://raw.githubusercontent.com/TheNightmanCodeth/chromium-ios/master/altstore-source.json
https://raw.githubusercontent.com/WhySooooFurious/Ultimate-Sideloading-Guide/refs/heads/main/app-repo.json
https://raw.githubusercontent.com/YourName028/System-Apps/main/repo.json
https://raw.githubusercontent.com/actuallyaridan/NeoFreeBird/refs/heads/main/AltSource.json
https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps2.json
https://raw.githubusercontent.com/jay-goobuh/samhub/main/apps
https://raw.githubusercontent.com/qnblackcat/AltStore/gh-pages/apps.json
https://raw.githubusercontent.com/sinceohsix/lcdl-repo/refs/heads/main/repo.json
https://raw.githubusercontent.com/ssalggnikool/.github/refs/heads/main/b.json
https://repo.starfiles.co
https://repo.ucerts.io
https://repo.zsign.app/repo.json
https://repos.yattee.stream/alt/apps.json
https://rickowens.su/repo.json
https://tweakrain.pages.dev/ios/altstore.json
https://web.archive.org/web/20210225095501if_/https://appybois.com/
https://web.archive.org/web/20250310010244if_/https://repo.realmzer.xyz/
https://website.burrito.software/altstore/channels/burritosource.json
https://www.sachcharak.com/esign/repo/RAK.json

📲 Telegram

☪️ Arabic iPA Channels


🌐 Websites

@kylefmohr
Copy link

You should add ipafile.zone after decrypt.day, as it is another site that provides decrypted App Store apps

@ongkiii
Copy link
Author

ongkiii commented Oct 2, 2025

You should add ipafile.zone after decrypt.day, as it is another site that provides decrypted App Store apps

thanks, will do.

@gliddd4
Copy link

gliddd4 commented Oct 18, 2025

https://aio.yippee.rip/repo.json
https://alt.crystall1ne.dev
https://alt.thatstel.la/
https://altstore.ignitedemulator.com/
https://altstore.oatmealdome.me
https://apps.altstore.io
https://apps.nabzclan.vip/repos/altstore.php
https://apps.sidestore.io/
https://appmarket.tech/altstore.json
https://azu0609.github.io/repo/altstore_repo.json
https://balackburn.github.io/Apollo/apps.json
https://binnichtaktiv.signapp.me/repo/esign.json
https://bit.ly/Altstore-complete
https://burritosoftware.github.io/altstore/channels/burritosource.json
https://community-apps.sidestore.io/sidecommunity.json
https://connect.sidestore.io/apps.json
https://cranci.tech/repo.json
https://css.eyz.ink/appstore
https://driftywinds.github.io/repos/esign.json
https://dvntm0.github.io/AltStore/raw/refs/heads/main/esign.json
https://dvntm0.github.io/AltStore/raw/refs/heads/main/feather.json
https://esign.yyyue.xyz/app.json
https://floridaman7588.me/altjb/altsource.json
https://flyinghead.github.io/flycast-builds/altstore.json
https://gbox.run/Public/Source.json
https://github.com/dvntm0/AltStore/raw/refs/heads/main/feather.json
https://github.com/khcrysalis/Feather/raw/main/app-repo.json
https://hann8n.github.io/JackCracks/MovieboxPro.json
https://hottubapp.io/altstore
https://ia601404.us.archive.org/11/items/ms_20220903/MS.json
https://ia601407.us.archive.org/11/items/ms_20220903/MS.json
https://ia601505.us.archive.org/10/items/motoca-store/Motoca%20Store.json
https://ikghd.site/repo.json
https://ipa.cypwn.xyz/cypwn.json
https://ipa.cypwn.xyz/cypwn_ts.json
https://ipa.thuthuatjb.com/repo
https://ish.app/altstore.json
https://ittza7aa.com/repo.json
https://lo-cafe/winston-altstore/main/apps.json
https://madari.media/nightly/repo.json
https://nabzclan.vip/repos/esign.php
https://pokemmo.com/altstore
https://pokemmo.eu/altstore/
https://provenance-emu.com/apps.json
https://qnblackcat.github.io/AltStore/apps.json
https://qingsongqian.github.io/all.html
https://quarksources.github.io/quantumsource++.json
https://quarksources.github.io/quantumsource.json
https://randomblock1.com/altstore/apps.json
https://raw.githubusercontent.com/AntonP29/AntonP29-Repo/refs/heads/main/repo.json
https://raw.githubusercontent.com/Balackburn/YTLitePlusAltstore/main/apps.json
https://raw.githubusercontent.com/Omni-Development/The-Omni-Repository/refs/heads/main/app-repo.json
https://raw.githubusercontent.com/RealBlackAstronaut/CelestialRepo/main/CelestialRepo.json
https://raw.githubusercontent.com/TheNightmanCodeth/chromium-ios/master/altstore-source.json
https://raw.githubusercontent.com/WhySooooFurious/Ultimate-Sideloading-Guide/refs/heads/main/app-repo.json
https://raw.githubusercontent.com/YourName028/System-Apps/main/repo.json
https://raw.githubusercontent.com/actuallyaridan/NeoFreeBird/refs/heads/main/AltSource.json
https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps.json
https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps2.json
https://raw.githubusercontent.com/driftywinds/driftywinds.github.io/master/AltStore/apps.json
https://raw.githubusercontent.com/jay-goobuh/samhub/main/apps
https://raw.githubusercontent.com/khcrysalis/Feather/refs/heads/main/app-repo.json
https://raw.githubusercontent.com/lo-cafe/winston-altstore/main/apps.json
https://raw.githubusercontent.com/Neoncat-OG/TrollStore-IPAs/main/apps_esign.json
https://raw.githubusercontent.com/Omni-Development/The-Omni-Repository/refs/heads/main/app-repo.json
https://raw.githubusercontent.com/RealBlackAstronaut/CelestialRepo/main/CelestialRepo.json
https://raw.githubusercontent.com/WhySooooFurious/Ultimate-Sideloading-Guide/refs/heads/main/app-repo.json
https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps.json
https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps2.json
https://raw.githubusercontent.com/driftywinds/driftywinds.github.io/master/AltStore/apps.json
https://raw.githubusercontent.com/khcrysalis/Feather/raw/main/app-repo.json
https://raw.githubusercontent.com/lo-cafe/winston-altstore/main/apps.json
https://raw.githubusercontent.com/notrifty1/riftysrepo/refs/heads/main/reposource.json
https://raw.githubusercontent.com/qnblackcat/AltStore/gh-pages/apps.json
https://raw.githubusercontent.com/sinceohsix/lcdl-repo/refs/heads/main/repo.json
https://raw.githubusercontent.com/ssalggnikool/.github/refs/heads/main/b.json
https://raw.githubusercontent.com/swaggyP36000/TrollStore-IPAs/main/apps_esign.json
https://raw.githubusercontent.com/vizunchik/AltStoreRus/master/apps.json
https://raw.githubusercontent.com/zigwangles/zigwangles-repo/refs/heads/main/app-repo.json
https://repo.madari.media/nightly/repo.json
https://repo.starfiles.co
https://repo.ucerts.io
https://repo.whoeevee.com/esign
https://repo.zsign.app/repo.json
https://repository.apptesters.org
https://repos.yattee.stream/alt/apps.json
https://rickowens.su/repo.json
https://spotc-repo.yodaluca.dev/AltStore%20Repo.json
https://taurine.app/altstore/taurinestore.json
https://theodyssey.dev/altstore/odysseysource.json
https://therealfoxster.github.io/altsource/apps.json
https://tiny.one/SpotC
https://tweakrain.pages.dev/ios/altstore.json
https://web.archive.org/web/20210225095501if_/https://appybois.com/
https://web.archive.org/web/20250310010244if_/https://repo.realmzer.xyz/
https://website.burrito.software/altstore/channels/burritosource.json
https://www.sachcharak.com/esign/repo/RAK.json
https://wuxu1.github.io/wuxu-complete-plus.json
https://wuxu1.github.io/wuxu-complete.json
https://xitrix.github.io/iTorrent/AltStore.json

old list:

https://t.me/+6Ehf6gRLcyQ3OWQx
https://t.me/blatantbruh
https://t.me/binnichtaktivsipas
https://t.me/zxcvbn_tweaked
https://t.me/iOS_Randy420/748
https://t.me/IPADecrypt
https://t.me/AppleTesters
https://t.me/appdb_telegram
https://t.me/glesign
https://t.me/SpotilifeIPAs
https://t.me/kamohacks
https://t.me/dpixel
https://t.me/LKTEAM2023
https://t.me/ipafire
https://t.me/+pYbkxE6kb_tmZDc0
https://t.me/iCrackiPADone
https://t.me/testflightlinks
https://t.me/CAbdullahiPA
https://t.me/iapps_games
https://t.me/fayezupdatespublic
https://t.me/SideloadsMadeEasy
https://t.me/IPA_FREE_RAK

@ongkiii
Copy link
Author

ongkiii commented Oct 18, 2025

https://aio.yippee.rip/repo.json https://alt.crystall1ne.dev https://alt.thatstel.la/ https://altstore.ignitedemulator.com/ https://altstore.oatmealdome.me https://apps.altstore.io https://apps.nabzclan.vip/repos/altstore.php https://apps.sidestore.io/ https://appmarket.tech/altstore.json https://azu0609.github.io/repo/altstore_repo.json https://balackburn.github.io/Apollo/apps.json https://binnichtaktiv.signapp.me/repo/esign.json https://bit.ly/Altstore-complete https://burritosoftware.github.io/altstore/channels/burritosource.json https://community-apps.sidestore.io/sidecommunity.json https://connect.sidestore.io/apps.json https://cranci.tech/repo.json https://css.eyz.ink/appstore https://driftywinds.github.io/repos/esign.json https://dvntm0.github.io/AltStore/raw/refs/heads/main/esign.json https://dvntm0.github.io/AltStore/raw/refs/heads/main/feather.json https://esign.yyyue.xyz/app.json https://floridaman7588.me/altjb/altsource.json https://flyinghead.github.io/flycast-builds/altstore.json https://gbox.run/Public/Source.json https://github.com/dvntm0/AltStore/raw/refs/heads/main/feather.json https://github.com/khcrysalis/Feather/raw/main/app-repo.json https://hann8n.github.io/JackCracks/MovieboxPro.json https://hottubapp.io/altstore https://ia601404.us.archive.org/11/items/ms_20220903/MS.json https://ia601407.us.archive.org/11/items/ms_20220903/MS.json https://ia601505.us.archive.org/10/items/motoca-store/Motoca%20Store.json https://ikghd.site/repo.json https://ipa.cypwn.xyz/cypwn.json https://ipa.cypwn.xyz/cypwn_ts.json https://ipa.thuthuatjb.com/repo https://ish.app/altstore.json https://ittza7aa.com/repo.json https://lo-cafe/winston-altstore/main/apps.json https://madari.media/nightly/repo.json https://nabzclan.vip/repos/esign.php https://pokemmo.com/altstore https://pokemmo.eu/altstore/ https://provenance-emu.com/apps.json https://qnblackcat.github.io/AltStore/apps.json https://qingsongqian.github.io/all.html https://quarksources.github.io/quantumsource++.json https://quarksources.github.io/quantumsource.json https://randomblock1.com/altstore/apps.json https://raw.githubusercontent.com/AntonP29/AntonP29-Repo/refs/heads/main/repo.json https://raw.githubusercontent.com/Balackburn/YTLitePlusAltstore/main/apps.json https://raw.githubusercontent.com/Omni-Development/The-Omni-Repository/refs/heads/main/app-repo.json https://raw.githubusercontent.com/RealBlackAstronaut/CelestialRepo/main/CelestialRepo.json https://raw.githubusercontent.com/TheNightmanCodeth/chromium-ios/master/altstore-source.json https://raw.githubusercontent.com/WhySooooFurious/Ultimate-Sideloading-Guide/refs/heads/main/app-repo.json https://raw.githubusercontent.com/YourName028/System-Apps/main/repo.json https://raw.githubusercontent.com/actuallyaridan/NeoFreeBird/refs/heads/main/AltSource.json https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps.json https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps2.json https://raw.githubusercontent.com/driftywinds/driftywinds.github.io/master/AltStore/apps.json https://raw.githubusercontent.com/jay-goobuh/samhub/main/apps https://raw.githubusercontent.com/khcrysalis/Feather/refs/heads/main/app-repo.json https://raw.githubusercontent.com/lo-cafe/winston-altstore/main/apps.json https://raw.githubusercontent.com/Neoncat-OG/TrollStore-IPAs/main/apps_esign.json https://raw.githubusercontent.com/Omni-Development/The-Omni-Repository/refs/heads/main/app-repo.json https://raw.githubusercontent.com/RealBlackAstronaut/CelestialRepo/main/CelestialRepo.json https://raw.githubusercontent.com/WhySooooFurious/Ultimate-Sideloading-Guide/refs/heads/main/app-repo.json https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps.json https://raw.githubusercontent.com/arichornloverALT/arichornloveralt.github.io/main/apps2.json https://raw.githubusercontent.com/driftywinds/driftywinds.github.io/master/AltStore/apps.json https://raw.githubusercontent.com/khcrysalis/Feather/raw/main/app-repo.json https://raw.githubusercontent.com/lo-cafe/winston-altstore/main/apps.json https://raw.githubusercontent.com/notrifty1/riftysrepo/refs/heads/main/reposource.json https://raw.githubusercontent.com/qnblackcat/AltStore/gh-pages/apps.json https://raw.githubusercontent.com/sinceohsix/lcdl-repo/refs/heads/main/repo.json https://raw.githubusercontent.com/ssalggnikool/.github/refs/heads/main/b.json https://raw.githubusercontent.com/swaggyP36000/TrollStore-IPAs/main/apps_esign.json https://raw.githubusercontent.com/vizunchik/AltStoreRus/master/apps.json https://raw.githubusercontent.com/zigwangles/zigwangles-repo/refs/heads/main/app-repo.json https://repo.madari.media/nightly/repo.json https://repo.starfiles.co https://repo.ucerts.io https://repo.whoeevee.com/esign https://repo.zsign.app/repo.json https://repository.apptesters.org https://repos.yattee.stream/alt/apps.json https://rickowens.su/repo.json https://spotc-repo.yodaluca.dev/AltStore%20Repo.json https://taurine.app/altstore/taurinestore.json https://theodyssey.dev/altstore/odysseysource.json https://therealfoxster.github.io/altsource/apps.json https://tiny.one/SpotC https://tweakrain.pages.dev/ios/altstore.json https://web.archive.org/web/20210225095501if_/https://appybois.com/ https://web.archive.org/web/20250310010244if_/https://repo.realmzer.xyz/ https://website.burrito.software/altstore/channels/burritosource.json https://www.sachcharak.com/esign/repo/RAK.json https://wuxu1.github.io/wuxu-complete-plus.json https://wuxu1.github.io/wuxu-complete.json https://xitrix.github.io/iTorrent/AltStore.json

old list:

https://t.me/+6Ehf6gRLcyQ3OWQx https://t.me/blatantbruh https://t.me/binnichtaktivsipas https://t.me/zxcvbn_tweaked https://t.me/iOS_Randy420/748 https://t.me/IPADecrypt https://t.me/AppleTesters https://t.me/appdb_telegram https://t.me/glesign https://t.me/SpotilifeIPAs https://t.me/kamohacks https://t.me/dpixel https://t.me/LKTEAM2023 https://t.me/ipafire https://t.me/+pYbkxE6kb_tmZDc0 https://t.me/iCrackiPADone https://t.me/testflightlinks https://t.me/CAbdullahiPA https://t.me/iapps_games https://t.me/fayezupdatespublic https://t.me/SideloadsMadeEasy https://t.me/IPA_FREE_RAK

hey thanks!

@gliddd4
Copy link

gliddd4 commented Nov 11, 2025

@profound-killah
Copy link

profound-killah commented Dec 16, 2025

Here's a quick script to remove the dupe entries in the json, but you'll have to host locally to avoid altstore throwing an error when adding the source.

# Removes duplicate entries from repo.json based on app versions

param(
    [string]$InputFile = "",
    [string]$OutputFile = "",
    [switch]$NoBackup,
    [switch]$DryRun,
    [switch]$Verbose
)

$ErrorActionPreference = "Stop"

function Write-Status {
    param([string]$Message, [string]$Color = "Green")
    Write-Host "[$((Get-Date).ToString('HH:mm:ss'))] $Message" -ForegroundColor $Color
}

function Write-Error-Status {
    param([string]$Message)
    Write-Status $Message "Red"
}

function Write-Warning-Status {
    param([string]$Message)
    Write-Status $Message "Yellow"
}

# Auto-detect input file if not specified
if ([string]::IsNullOrEmpty($InputFile)) {
    if (Test-Path "repo.altstore.json") {
        $InputFile = "repo.altstore.json"
    } elseif (Test-Path "repo.json") {
        $InputFile = "repo.json"
    } else {
        Write-Error-Status "No repo JSON file found in current directory"
        Write-Status "Please specify -InputFile parameter or ensure repo.json or repo.altstore.json exists"
        exit 1
    }
}

# Validate input file
if (-not (Test-Path $InputFile)) {
    Write-Error-Status "Input file not found: $InputFile"
    exit 1
}

# Set output file if not specified
if ([string]::IsNullOrEmpty($OutputFile)) {
    $OutputFile = $InputFile
}

Write-Status "=== JSON Deduplication Tool ===" "Cyan"
Write-Status "Input file: $InputFile"
Write-Status "Output file: $OutputFile"

if ($DryRun) {
    Write-Warning-Status "DRY RUN MODE - No changes will be saved"
}

# Create backup if not disabled
if (-not $NoBackup -and -not $DryRun -and (Test-Path $InputFile)) {
    $backupFile = "$InputFile.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
    Copy-Item $InputFile $backupFile
    Write-Status "Backup created: $backupFile" "Yellow"
}

# Load JSON
Write-Status "Loading JSON file..."
try {
    $json = Get-Content $InputFile -Raw | ConvertFrom-Json
} catch {
    Write-Error-Status "Failed to parse JSON: $($_.Exception.Message)"
    exit 1
}

if (-not $json.apps) {
    Write-Error-Status "JSON structure invalid - 'apps' array not found"
    exit 1
}

Write-Status "Found $($json.apps.Count) apps in the file"

# Statistics
$stats = @{
    TotalApps = $json.apps.Count
    AppsWithVersions = 0
    TotalVersionsBefore = 0
    TotalVersionsAfter = 0
    DuplicatesRemoved = 0
    AppsProcessed = 0
}

# Process each app
Write-Status ""
Write-Status "Scanning for duplicates..." "Cyan"

foreach ($app in $json.apps) {
    if (-not $app.versions -or $app.versions.Count -eq 0) {
        if ($Verbose) {
            Write-Status "  Skipping '$($app.name)' - no versions" "Gray"
        }
        continue
    }
    
    $stats.AppsWithVersions++
    $originalCount = $app.versions.Count
    $stats.TotalVersionsBefore += $originalCount
    
    # Deduplicate versions
    # Group by version number and keep only the first (most recent) entry for each version
    $uniqueVersions = @{}
    $dedupedVersions = @()
    $duplicatesFound = 0
    
    foreach ($version in $app.versions) {
        $versionKey = $version.version
        
        if (-not $versionKey) {
            # If no version field, use full object as key (shouldn't happen but handle it)
            Write-Warning-Status "    Warning: Version entry has no version number, keeping it"
            $dedupedVersions += $version
            continue
        }
        
        if (-not $uniqueVersions.ContainsKey($versionKey)) {
            # First occurrence of this version number - keep it
            $uniqueVersions[$versionKey] = $version
            $dedupedVersions += $version
        } else {
            # Duplicate version number found
            $duplicatesFound++
            if ($Verbose) {
                Write-Status "    Found duplicate: Version $($version.version) (different download URL)" "Yellow"
            }
        }
    }
    
    if ($duplicatesFound -gt 0) {
        Write-Status "  📦 $($app.name)" "White"
        Write-Status "    Before: $originalCount versions" "Gray"
        Write-Status "    After: $($dedupedVersions.Count) versions" "Green"
        Write-Status "    Removed: $duplicatesFound duplicate version(s)" "Yellow"
        
        # Show which versions were duplicated
        if ($Verbose) {
            $versionCounts = @{}
            foreach ($v in $app.versions) {
                if ($versionCounts.ContainsKey($v.version)) {
                    $versionCounts[$v.version]++
                } else {
                    $versionCounts[$v.version] = 1
                }
            }
            foreach ($ver in ($versionCounts.Keys | Where-Object { $versionCounts[$_] -gt 1 })) {
                Write-Status "      - Version '$ver' appeared $($versionCounts[$ver]) times" "Yellow"
            }
        }
        
        $stats.DuplicatesRemoved += $duplicatesFound
        $stats.AppsProcessed++
        
        # Update the app with deduplicated versions
        $app.versions = $dedupedVersions
    } else {
        if ($Verbose) {
            Write-Status "  ✓ $($app.name) - no duplicates ($originalCount versions)" "Green"
        }
    }
    
    $stats.TotalVersionsAfter += $dedupedVersions.Count
}

# Display summary
Write-Status ""
Write-Status "=== Summary ===" "Cyan"
Write-Status "Total apps: $($stats.TotalApps)"
Write-Status "Apps with versions: $($stats.AppsWithVersions)"
Write-Status "Apps with duplicates: $($stats.AppsProcessed)" $(if ($stats.AppsProcessed -gt 0) { "Yellow" } else { "Green" })
Write-Status ""
Write-Status "Total versions before: $($stats.TotalVersionsBefore)"
Write-Status "Total versions after: $($stats.TotalVersionsAfter)"
Write-Status "Duplicates removed: $($stats.DuplicatesRemoved)" $(if ($stats.DuplicatesRemoved -gt 0) { "Yellow" } else { "Green" })

if ($stats.DuplicatesRemoved -gt 0) {
    $percentReduced = [math]::Round((($stats.DuplicatesRemoved / $stats.TotalVersionsBefore) * 100), 2)
    Write-Status "Space saved: $percentReduced%" "Green"
}

# Save output
if (-not $DryRun) {
    if ($stats.DuplicatesRemoved -gt 0) {
        Write-Status ""
        Write-Status "Saving deduplicated JSON..." "Cyan"
        
        try {
            # Convert back to JSON with proper formatting
            $jsonOutput = $json | ConvertTo-Json -Depth 100 -Compress:$false
            $jsonOutput | Set-Content -Path $OutputFile -Encoding UTF8
            
            Write-Status "✓ File saved: $OutputFile" "Green"
            
            # Show file size comparison
            $originalSize = (Get-Item $InputFile).Length
            $newSize = (Get-Item $OutputFile).Length
            $sizeDiff = $originalSize - $newSize
            
            Write-Status ""
            Write-Status "Original size: $([math]::Round($originalSize / 1MB, 2)) MB"
            Write-Status "New size: $([math]::Round($newSize / 1MB, 2)) MB"
            
            if ($sizeDiff -gt 0) {
                Write-Status "Reduced by: $([math]::Round($sizeDiff / 1KB, 2)) KB" "Green"
            }
        } catch {
            Write-Error-Status "Failed to save file: $($_.Exception.Message)"
            exit 1
        }
    } else {
        Write-Status ""
        Write-Status "No duplicates found - no changes needed" "Green"
    }
} else {
    Write-Status ""
    Write-Status "DRY RUN - No files were modified" "Yellow"
    if ($stats.DuplicatesRemoved -gt 0) {
        Write-Status "Run without -DryRun to apply changes" "Yellow"
    }
}

Write-Status ""
Write-Status "Done!" "Green"

@miuirussia
Copy link

I have developer account, how to generate certificate for signing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment