lljz66/ios-app-store-explorer
iOS App Store Explorer
Search the App Store, select an app, download & extract its IPA — all in the browser.
Structure
├── frontend/ # React UI
├── backend/
│ ├── api/
│ │ ├── search/ # App Store search endpoint
│ │ ├── download/ # IPA download endpoint
│ │ └── extract/ # IPA extraction endpoint
│ ├── services/ # ipatool / HTTP download logic
│ └── utils/ # shared helpers
├── Dockerfile
└── docker-compose.ymlStructure Reall ONE
ios-app-store-explorer/ │ ├── Dockerfile ← multi-stage: React build + Python runtime ├── docker-compose.yml ← local dev │ ├── frontend/ ← React + Vite SPA │ ├── index.html │ ├── vite.config.js │ ├── package.json │ └── src/ │ ├── main.jsx ← app entry │ ├── App.jsx ← step orchestrator (search→select→download→extract) │ ├── App.module.css │ ├── api/ │ │ ├── searchApi.js ← GET /api/search │ │ └── downloadApi.js ← POST /api/download, /api/extract │ └── components/ │ ├── Header ← step indicator │ ├── SearchBar ← query + country picker │ ├── AppGrid ← results grid (click to select) │ ├── AppDetail ← selected app info card │ ├── DownloadPanel ← HTTP or ipatool mode │ ├── ExtractPanel ← live progress + file tree │ └── FileTree ← collapsible tree with icons + sizes │ └── backend/ ├── main.py ← FastAPI app + static serving ├── requirements.txt ├── api/ │ ├── search/ │ │ ├── router.py ← GET /api/search │ │ └── schema.py ← AppResult, SearchResponse │ ├── download/ │ │ ├── router.py ← POST /api/download, GET status │ │ └── schema.py ← DownloadRequest/Response/Status │ └── extract/ │ ├── router.py ← POST /api/extract/{jobid} │ └── schema.py ← FileNode, ExtractResponse ├── services/ │ ├── appstoresearch.py ← iTunes Search API → AppResult[] │ ├── ipadownloader.py ← ipatool first, HTTP fallback, job store │ └── ipaextractor.py ← zipfile unpack → FileNode tree └── utils/ ├── paths.py ← DOWNLOADDIR / EXTRACTDIR constants └── logger.py ← centralised logger factory
