feat: scaffold workspace with search, fetch, and extract packages
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# TTS Workshop
|
||||
|
||||
Search the Tabletop Simulator Steam Workshop, fetch full TTS save files, and
|
||||
analyze their contents. A lightweight, client-only pnpm monorepo.
|
||||
|
||||
## Packages
|
||||
|
||||
| Package | Role | Runtime |
|
||||
| ------------------- | ------------------------------------------------------ | ---------- |
|
||||
| `apps/proxy` | Hono HTTP server: Workshop search + save fetch | Node |
|
||||
| `packages/tts` | Fetch save from Steam, BSON-parse to `TTSMod` | Node |
|
||||
| `packages/extract` | Analyze a `TTSMod`: objects, asset refs, downloads | Isomorphic |
|
||||
| `packages/shared` | Shared types + zod schemas | Isomorphic |
|
||||
|
||||
See [`docs/architecture.md`](docs/architecture.md) for the architecture and
|
||||
[`docs/implementation-plan.md`](docs/implementation-plan.md) for the plan.
|
||||
|
||||
## Setup
|
||||
|
||||
```sh
|
||||
pnpm install
|
||||
cp .env.example .env # then set STEAM_API_KEY
|
||||
pnpm dev # runs the proxy at http://localhost:3000
|
||||
```
|
||||
|
||||
Get a Steam Web API key at https://steamcommunity.com/dev/apikey (free).
|
||||
|
||||
## API
|
||||
|
||||
| Method | Path | Description |
|
||||
| ------ | ----------------- | -------------------------------------------- |
|
||||
| GET | `/health` | Liveness |
|
||||
| GET | `/search?q=&page=`| Search the Workshop (scrapes browse page) |
|
||||
| GET | `/items/:id` | Full parsed `TTSMod` (BSON save) |
|
||||
| GET | `/items/:id/file` | Raw save bytes, filename from header |
|
||||
|
||||
## Commands
|
||||
|
||||
```sh
|
||||
pnpm dev # run the proxy (tsx watch)
|
||||
pnpm build # compile all packages
|
||||
pnpm typecheck # typecheck all packages
|
||||
pnpm lint # lint all packages
|
||||
```
|
||||
|
||||
## How search works
|
||||
|
||||
Steam has no official search API. The proxy fetches the Workshop browse page
|
||||
(`steamcommunity.com/workshop/browse/?appid=286160`) and parses the embedded
|
||||
`window.SSR.renderContext` JSON (a React Query cache containing a
|
||||
`workshop_browse` entry with the results). This is more robust than scraping
|
||||
the DOM, but Steam can still change the page structure — if search breaks, that
|
||||
parser is the first place to look.
|
||||
|
||||
## Notes
|
||||
|
||||
- `STEAM_API_KEY` is only needed for `/items/*` (resolving `file_url`). Search
|
||||
works without it.
|
||||
- Each request fetches fresh; there is no caching by design (client-only tool).
|
||||
- `packages/extract` has zero runtime dependencies and runs in browser or Node,
|
||||
ready for a future frontend.
|
||||
Reference in New Issue
Block a user