Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ npm run build # rimraf dist && tsdown

- **release-please** automates versioning and CHANGELOG generation
- **workspaces-publish** publishes all changed packages to npm
- Linked version groups: `rate-limit` + `rate-limit-redis`, `swagger-generator` + `swagger-ui`
- Linked version groups: `rate-limit` + `rate-limit-redis`

## Adding a New Plugin

Expand Down
20 changes: 10 additions & 10 deletions .agents/references/trapi.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TRAPI Reference

[TRAPI](https://github.com/tada5hi/trapi) is the metadata + OpenAPI generation library that `@routup/swagger-generator` depends on. The `@trapi/metadata` preset that decodes routup's `@D*` decorators lives in `@routup/decorators` (under `packages/decorators/src/preset/`, exposed as the `./preset` subpath export); `@routup/swagger-generator` is a thin wrapper around `generateSwagger()` that pulls that preset in by default.
[TRAPI](https://github.com/tada5hi/trapi) is the metadata + OpenAPI generation library this repo's decorators feed into. The `@trapi/metadata` preset that decodes routup's `@D*` decorators lives in `@routup/decorators` (under `packages/decorators/src/preset/`, exposed as the `./preset` subpath export). There is no first-party generator wrapper — consumers call `@trapi/swagger`'s `generateSwagger()` directly, or use the `trapi` CLI with `--preset @routup/decorators/preset`.

The local clone lives at `/opt/projects/tada5hi/trapi` — refer to it whenever a routup-side change needs to know how the metadata pipeline interprets a decorator.

Expand All @@ -21,9 +21,9 @@ The local clone lives at `/opt/projects/tada5hi/trapi` — refer to it whenever
| `@trapi/metadata` `MarkerName` (`Hidden`, `Deprecated`, `Extension`) | Concept tags so the resolver can find renamed decorators | Set on `@DHidden`/`@DDeprecated` handlers |
| `@trapi/metadata` `ParamKind` (`Body`, `BodyProp`, `Query`, `QueryProp`, `Path`, `Cookie`, `Header`, `FormData`, `Context`) | Parameter source enumeration | Mapped from `@D*` parameter decorators |
| `@trapi/metadata` `generateMetadata()` | Public entry: scans source, returns `Metadata` | Called by `@trapi/swagger`'s `generateSwagger()` (transitively) |
| `@trapi/swagger` `generateSwagger({ version, metadata, data })` | Produces OpenAPI spec | Wrapped by `@routup/swagger-generator` `generate()` |
| `@trapi/swagger` `saveSwagger(spec, options)` | Writes spec JSON/YAML to disk | Available for users who need a file (no longer baked into `generate()`) |
| `@trapi/swagger` `Version` enum | `V2 / V3 / V3_1 / V3_2` | Forwarded as `context.version` |
| `@trapi/swagger` `generateSwagger({ version, metadata, data })` | Produces OpenAPI spec | Called by consumers directly (with `buildPreset()` from `@routup/decorators/preset`) |
| `@trapi/swagger` `saveSwagger(spec, options)` | Writes spec JSON/YAML to disk | Called by consumers after `generateSwagger()` |
| `@trapi/swagger` `Version` enum | `V2 / V3 / V3_1 / V3_2` | Passed as `version` field |

## Source layout (TRAPI repo)

Expand Down Expand Up @@ -87,18 +87,18 @@ The build SHA is the head SHA of the PR or branch — find it in the pkg-pr-new
- **PR tada5hi/trapi#798** (2026-04): TRAPI v2 — preset-based decorator system, marker-driven resolver, dropped `DecoratorID`/`DecoratorConfig` types. routup/plugins migrated in lockstep (preset handlers originally lived in `packages/swagger-preset/src/*`).
- **2026-05-04 (morning)**: `@routup/swagger-preset` package removed. Its preset was inlined into `@routup/swagger`; bumped `@trapi/metadata` and `@trapi/swagger` to `^2.0.0-beta.2`. `preset:` is now passed as a `Preset` object (returned by `buildPreset()`) instead of a string lookup.
- **2026-05-04 (afternoon)**: `@routup/swagger` split into `@routup/swagger-generator` (generator) and `@routup/swagger-ui` (UI-only). UI-only consumers no longer pull `@trapi/metadata` / `@trapi/swagger` (TypeScript); generator-only consumers no longer pull `swagger-ui-dist` (~10MB of static assets).
- **2026-05-04 (evening)**: Preset moved from `@routup/swagger-generator` into `@routup/decorators` as the `./preset` subpath export (`packages/decorators/src/preset/`). `@trapi/metadata` is an optional peer dep on decorators (runtime-only users skip it). `generate()` switched to taking `SwaggerGenerateOptions` directly (`{ version, metadata, data }`) instead of the old `GeneratorContext` wrapper, and `@routup/swagger-generator` re-exports everything from `@trapi/swagger` plus `buildPreset` from the decorators subpath. Trapi CLI consumers can now pass `--preset @routup/decorators/preset`.
- **2026-05-04 (evening)**: Preset moved from `@routup/swagger-generator` into `@routup/decorators` as the `./preset` subpath export (`packages/decorators/src/preset/`). `@trapi/metadata` is an optional peer dep on decorators (runtime-only users skip it). Trapi CLI consumers can now pass `--preset @routup/decorators/preset`.
- **2026-05-05**: Removed `@routup/swagger-generator` entirely — the wrapper added too little value to justify its own package. Consumers now call `@trapi/swagger`'s `generateSwagger()` directly with `buildPreset()` from `@routup/decorators/preset`. Integration tests moved to `packages/decorators/test/unit/preset/{v2,v3}.spec.ts` so they validate the preset against the controllers it decodes. See `packages/decorators/README.md` (#openapi-generation) for the snippet.

## Quick-check after a TRAPI bump

```bash
# from /opt/projects/routup/plugins
npx nx run @routup/swagger-generator:build
npx nx run @routup/swagger-generator:test # 16 tests
npx nx run @routup/decorators:build
npx nx run @routup/decorators:test # decorator + preset (V2 + V3) integration tests
npx nx run @routup/swagger-ui:build
npx nx run @routup/swagger-ui:test # 6 tests
npx nx run @routup/decorators:test # 7 tests
npx nx run @routup/swagger-ui:test
npm run lint
```

If TRAPI removed or renamed an exported type, the `@routup/decorators` typecheck (`build:types`) will fail loudly — adjust the imports in `packages/decorators/src/preset/*.ts` (handler builders, marker enums). For changes to the swagger entry-point shape, see `packages/swagger-generator/src/generate.ts`. The UI half (`packages/swagger-ui/`) does not depend on TRAPI.
If TRAPI removed or renamed an exported type, the `@routup/decorators` typecheck (`build:types`) will fail loudly — adjust the imports in `packages/decorators/src/preset/*.ts` (handler builders, marker enums). The UI half (`packages/swagger-ui/`) does not depend on TRAPI.
6 changes: 3 additions & 3 deletions .agents/structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ plugins/
│ ├── query/ # Query string parsing (qs)
│ ├── rate-limit/ # In-memory rate limiting
│ ├── rate-limit-redis/ # Redis adapter for rate-limit
│ ├── swagger-generator/ # OpenAPI document generator (uses @routup/decorators/preset)
│ └── swagger-ui/ # Mount Swagger UI from a generated/given OpenAPI document
├── .github/ # CI workflows + reusable actions
├── nx.json # NX task config and caching
Expand Down Expand Up @@ -60,13 +59,14 @@ packages/[name]/
| `query` | `@routup/query` | Query string parsing | `qs` |
| `rate-limit` | `@routup/rate-limit` | In-memory rate limiter | — |
| `rate-limit-redis` | `@routup/rate-limit-redis` | Redis rate-limit adapter | `@routup/rate-limit`, `ioredis` |
| `swagger-generator` | `@routup/swagger-generator` | OpenAPI v2 / v3 generator from decorated controllers (thin wrapper over `generateSwagger()`) | `@routup/decorators`, `@trapi/metadata`, `@trapi/swagger`, `smob` |
| `swagger-ui` | `@routup/swagger-ui` | Mount Swagger UI from a JSON document or URL | `@routup/assets`, `swagger-ui-dist` |

OpenAPI generation is not a routup-owned package — call `@trapi/swagger`'s `generateSwagger()` directly with `buildPreset()` from `@routup/decorators/preset`, or use the `trapi` CLI with `--preset @routup/decorators/preset`. See `packages/decorators/README.md` for the snippet.

## Dependency Layers

```
Layer 3 (composites): basic, swagger-generator
Layer 3 (composites): basic
Layer 2 (adapters): rate-limit-redis, swagger-ui
Layer 1 (standalone): assets, body, cookie, decorators, i18n, prometheus, query, rate-limit
```
Expand Down
1 change: 0 additions & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@
"packages/query": "2.4.3",
"packages/rate-limit": "2.4.2",
"packages/rate-limit-redis": "3.1.2",
"packages/swagger-generator": "2.4.3",
"packages/swagger-ui": "2.4.3"
}
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ typically http framework functions, which are not integrated in the main package
| [query](packages/query) | Read and parse the query string of the request url. |
| [rate-limit](packages/rate-limit) | Rate limit incoming requests. |
| [rate-limit-redis](packages/rate-limit-redis) | Redis adapter for the rate-limit plugin. |
| [swagger-generator](packages/swagger-generator) | Generate OpenAPI v2 / v3 documents from decorated controllers via @trapi/metadata. |
| [swagger-ui](packages/swagger-ui) | Mount Swagger UI on a routup router from a JSON document or URL. |

## Contributing
Expand Down
Loading
Loading