Skip to content
Open
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
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Each input has its own limitations, corner cases, and features; thus, each has s
- [AsyncAPI](./inputs/asyncapi.md)
- [OpenAPI](./inputs/openapi.md)
- [JSON Schema](./inputs/jsonschema.md)
- [EventCatalog](./inputs/eventcatalog.md)

### Protocols
Each protocol has its own limitations, corner cases, and features; thus, each has separate documentation.
Expand Down
9 changes: 9 additions & 0 deletions docs/configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ If no explicit configuration file is sat, it will be looked for in the following
- codegen.mjs
- codegen.cjs

## Input Types

The `inputType` field selects which input pipeline drives generation. Supported values:

- `'asyncapi'` — AsyncAPI 2.x / 3.x documents. See [AsyncAPI input](./inputs/asyncapi.md).
- `'openapi'` — Swagger 2.0 / OpenAPI 3.0 / 3.1 documents. See [OpenAPI input](./inputs/openapi.md).
- `'jsonschema'` — Standalone JSON Schema documents. See [JSON Schema input](./inputs/jsonschema.md).
- `'eventcatalog'` — An [EventCatalog](https://eventcatalog.dev) directory; the loader picks one service via the required `service` field and forwards generation through the AsyncAPI or OpenAPI pipeline. See [EventCatalog input](./inputs/eventcatalog.md).

## TypeScript Configuration

When generating TypeScript code, you can configure global options that apply to all generators. These options can be overridden per-generator if needed.
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,6 @@ Discover how The Codegen Project supports various messaging protocols like NATS,
### Explore Further
- **[Generator Documentation](../generators/README.md)** - Detailed documentation for each generator type
- **[Protocol Documentation](../protocols/)** - Complete protocol reference and implementation details
- **[Input Types](../inputs/)** - Learn about AsyncAPI, OpenAPI, and JSON Schema support
- **[Input Types](../inputs/)** - Learn about AsyncAPI, OpenAPI, JSON Schema, and EventCatalog support
- **[Examples](../../examples/)** - Real-world examples and integration patterns

126 changes: 126 additions & 0 deletions docs/inputs/eventcatalog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
sidebar_position: 99
---

# EventCatalog

[EventCatalog](https://eventcatalog.dev) is a documentation tool that organizes events, services, and domains in a single browsable catalog. The Codegen Project can read an EventCatalog directory directly and generate code for a chosen service — no need to maintain a separate AsyncAPI/OpenAPI file alongside the catalog.

The loader is a producer composer: it picks the requested service, reads the underlying spec(s) (AsyncAPI and/or OpenAPI) plus any native events declared under `sends`/`receives`, and feeds whichever combination is present to the typed `{Generator}Input` shapes consumed by built-in generators. Native events are turned into channel/payload entries directly — no AsyncAPI synthesis round-trip.

## Supported Generators

| **Presets** | EventCatalog |
|---|---|
| [`payloads`](../generators/payloads.md) | ✅ |
| [`parameters`](../generators/parameters.md) | ✅ |
| [`headers`](../generators/headers.md) | ✅ |
| [`types`](../generators/types.md) | ✅ |
| [`channels`](../generators/channels.md) | ✅ |
| [`client`](../generators/client.md) | ✅ * |
| [`custom`](../generators/custom.md) | ✅ |
| [`models`](../generators/models.md) | ✅ |

\* The `client` preset currently only generates a client wrapper for AsyncAPI-backed services.

## Configuration

| Field | Required | Description |
|---|---|---|
| `inputType` | yes | Must be `'eventcatalog'`. |
| `inputPath` | yes | Path (or remote URL) to the EventCatalog root — the directory that contains `services/`. |
| `service` | yes | The `id` of the service inside `services/<id>/index.md` to generate from. |
| `auth` | no | Bearer / apiKey / custom auth used when the service's spec path is a remote URL. See [configurations guide](../configurations.md#remote-url-inputs). |

```js
export default {
inputType: 'eventcatalog',
inputPath: './eventcatalog',
service: 'user-service',
language: 'typescript',
generators: [
{ preset: 'payloads', outputPath: './src/payloads' },
{ preset: 'channels', outputPath: './src/channels', protocols: ['nats'] },
{ preset: 'client', outputPath: './src/client', protocols: ['nats'] }
]
};
```

## How service modes are composed

The loader builds a `ParsedEventCatalog` from the selected service's `index.md` frontmatter. Each EventCatalog producer composes whatever fields are present:

- `specifications.asyncapiPath` → load the AsyncAPI document; AsyncAPI producers run.
- `specifications.openapiPath` → load the OpenAPI document; OpenAPI producers run.
- Native `sends` / `receives` events with `events/<id>/schema.json` → emitted as channel/payload entries directly.

Composition is additive: a service with both an AsyncAPI spec and an OpenAPI spec runs both producers and merges the results. There is no `specType` disambiguator because the producer-composition design lets every spec contribute. (When a service declares specs, the listed `sends`/`receives` event references are treated as catalog-navigation metadata only — the spec is the authoritative source of channels and payloads.)

### AsyncAPI service

```yaml
---
id: user-service
name: User Service
specifications:
asyncapiPath: asyncapi.yaml
---
```

### OpenAPI service

```yaml
---
id: petstore-api
name: Petstore API
specifications:
openapiPath: openapi.json
---
```

### Native service (no `specifications`)

The service has no spec file but lists `sends` / `receives` events. The EventCatalog producers walk each referenced event under `events/<event-id>/`, read its `schema.json` (or whatever `schemaPath` is set in the event's frontmatter), and emit channel/payload entries directly:

- one channel per event id (channel address = event id)
- one operation per event with `action: 'send'` for `sends[i]` and `action: 'receive'` for `receives[i]`
- one payload entry keyed by the event id with the schema as the model

```yaml
---
id: order-service
name: Order Service
sends:
- id: OrderCreated
version: 1.0.0
receives:
- id: OrderShipped
version: 1.0.0
---
```

If you need richer mappings — multi-message channels, parameters, status-code variants, etc. — author a real AsyncAPI document and reference it via `specifications.asyncapiPath` instead.

### Both-specs services

If a service declares **both** `asyncapiPath` and `openapiPath`, both pipelines run and their results are merged into the typed `{Generator}Input` shapes. Channels/payloads/etc. that appear in only one spec are emitted; entries that overlap defer to whichever producer ran last (OpenAPI in the current implementation). This removes the need for a manual `specType` disambiguator that earlier versions required.

## Remote URLs in `asyncapiPath` / `openapiPath`

If your service frontmatter points to a remote URL instead of a local file, the loader fetches it the same way the underlying input pipeline does. The `auth` field on your codegen configuration is passed through unchanged. See the [remote URL inputs section](../configurations.md#remote-url-inputs) of the configurations guide for the full set of auth options and security considerations.

## Examples

The repository ships three end-to-end examples under `examples/`:

- `examples/eventcatalog-asyncapi/` — a service backed by a real AsyncAPI 3.0 document
- `examples/eventcatalog-openapi/` — a service backed by an OpenAPI 3.0 document
- `examples/eventcatalog-native/` — a service with no spec file, demonstrating the native-event flow

Each example contains an `eventcatalog/` directory plus a `codegen.config.mjs` that mirrors the snippets above. Running `npx codegen generate` inside any of the three produces the generated TypeScript directly.

## Limitations

- **`domains/` and `flows/` are ignored.** Only the selected service plus the events it directly references are read.
- **Cross-service event references aren't resolved.** Events referenced via `receives` are loaded from the catalog's `events/<id>/` directory, not from the producing service.
- **Browser mode is not supported.** EventCatalog is filesystem-bound; the browser bundle returns a clear error when invoked with `specFormat: 'eventcatalog'`. Use AsyncAPI / OpenAPI / JSON Schema directly in the browser.
2 changes: 1 addition & 1 deletion docs/telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ Example configuration:
{
event: 'generator_used',
generator_type: 'payloads',
input_type: 'asyncapi', // Can be: asyncapi, openapi, jsonschema
input_type: 'asyncapi', // Can be: asyncapi, openapi, jsonschema, eventcatalog
input_source: 'remote_url', // Not the actual URL!
language: 'typescript',
options: '{"includeValidation":true,"serializationType":"json"}',
Expand Down
11 changes: 7 additions & 4 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,10 @@ Initialize The Codegen Project in your project
```
USAGE
$ codegen init [--json] [--no-color] [--debug | | [--silent | -v | -q]] [--help] [--input-file <value>]
[--config-name <value>] [--input-type asyncapi|openapi] [--output-directory <value>] [--config-type
esm|json|yaml|ts] [--languages typescript] [--no-tty] [--include-payloads] [--include-headers] [--include-client]
[--include-parameters] [--include-channels] [--gitignore-generated]
[--config-name <value>] [--input-type asyncapi|openapi|jsonschema|eventcatalog] [--service <value>]
[--output-directory <value>] [--config-type esm|json|yaml|ts] [--languages typescript] [--no-tty]
[--include-payloads] [--include-headers] [--include-client] [--include-parameters] [--include-channels]
[--gitignore-generated]

FLAGS
-q, --quiet Only show errors and warnings
Expand All @@ -163,7 +164,7 @@ FLAGS
--include-payloads Include payloads generation, available for TypeScript
--input-file=<value> File path for the code generation input such as AsyncAPI document
--input-type=<option> Input file type
<options: asyncapi|openapi>
<options: asyncapi|openapi|jsonschema|eventcatalog>
--json Output results as JSON for scripting
--languages=<option> Which languages do you wish to generate code for?
<options: typescript>
Expand All @@ -172,6 +173,8 @@ FLAGS
--output-directory=<value> [default: ./] Output configuration location, path to where the configuration file
should be located. If relative path, the current working directory of the terminal
will be used
--service=<value> Service ID inside the EventCatalog directory (only used with
--input-type=eventcatalog)
--silent Suppress all output except fatal errors

DESCRIPTION
Expand Down
9 changes: 9 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ An example demonstrating how to generate complete, type-safe client SDKs for NAT
### [E-commerce AsyncAPI Types](./ecommerce-asyncapi-types/)
A comprehensive example showing how to generate TypeScript types from AsyncAPI specifications for an e-commerce messaging system.

### [EventCatalog + AsyncAPI](./eventcatalog-asyncapi/)
An example demonstrating how to generate TypeScript code from AsyncAPI specifications stored in an [EventCatalog](https://eventcatalog.dev/). Shows how to use The Codegen Project with EventCatalog's service documentation structure.

### [EventCatalog + OpenAPI](./eventcatalog-openapi/)
An example demonstrating how to generate a TypeScript HTTP client from OpenAPI specifications stored in an [EventCatalog](https://eventcatalog.dev/). Shows how to use The Codegen Project with EventCatalog's API documentation structure.

### [EventCatalog Native](./eventcatalog-native/)
An example showing the native EventCatalog structure with markdown documentation and JSON Schema files, without AsyncAPI or OpenAPI specifications. Demonstrates generating models directly from EventCatalog event schemas.

## Getting Started

1. Choose an example that matches your use case
Expand Down
9 changes: 9 additions & 0 deletions examples/eventcatalog-asyncapi/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Generated code
src/

# Dependencies
node_modules/
eventcatalog/node_modules/

# Build artifacts
.eventcatalog/
72 changes: 72 additions & 0 deletions examples/eventcatalog-asyncapi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# EventCatalog + AsyncAPI Example

This example demonstrates the **proposed** EventCatalog integration where a service has an AsyncAPI specification attached.

> **Note**: This is a showcase of the proposed `inputType: 'eventcatalog'` configuration. This feature does not exist yet.

## Configuration

```javascript
// codegen.config.mjs
export default {
inputType: 'eventcatalog',
inputPath: './eventcatalog',
service: 'user-service', // Service with asyncapiPath
language: 'typescript',
generators: [
{ preset: 'payloads', outputPath: './src/payloads' },
{ preset: 'channels', outputPath: './src/channels', protocols: ['nats'] },
{ preset: 'client', outputPath: './src/client', protocols: ['nats'] },
],
};
```

## How It Works

1. Read EventCatalog at `./eventcatalog`
2. Find `user-service` in `services/`
3. Detect `asyncapiPath: asyncapi.yaml` in service metadata
4. Load and parse the AsyncAPI spec
5. Generate code using AsyncAPI processing

## Service Metadata

The service's `index.md` declares its AsyncAPI spec:

```yaml
---
id: user-service
name: User Service
version: 1.0.0
specifications:
asyncapiPath: asyncapi.yaml # <-- Auto-detected
---
```

## Project Structure

```
eventcatalog-asyncapi/
├── codegen.config.mjs
├── eventcatalog/
│ ├── eventcatalog.config.js
│ ├── domains/user-domain/index.md
│ ├── services/user-service/
│ │ ├── index.md # Has asyncapiPath in metadata
│ │ └── asyncapi.yaml # AsyncAPI 3.0 spec
│ └── events/UserSignedUp/index.md
└── src/ # Generated code
```

## Auto-Detection Logic

| Service Metadata | Processing |
|------------------|------------|
| `asyncapiPath: ...` | AsyncAPI processing |
| `openapiPath: ...` | OpenAPI processing |
| Neither (just `sends`/`receives`) | Native JSON Schema |

## Related Examples

- [eventcatalog-openapi](../eventcatalog-openapi/) - Service with OpenAPI spec
- [eventcatalog-native](../eventcatalog-native/) - Service with native JSON Schema events
47 changes: 47 additions & 0 deletions examples/eventcatalog-asyncapi/codegen.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Codegen configuration for EventCatalog with an AsyncAPI service.
*
* The loader reads the selected service's frontmatter, sees that
* user-service declares `specifications.asyncapiPath: asyncapi.yaml`,
* and routes generation through the AsyncAPI pipeline.
*
* @type {import("@the-codegen-project/cli").TheCodegenConfiguration}
*/
export default {
inputType: 'eventcatalog',
inputPath: './eventcatalog',
language: 'typescript',

// Select which service to generate code for
service: 'user-service',

generators: [
{
preset: 'payloads',
outputPath: './src/payloads',
serializationType: 'json',
},
{
preset: 'parameters',
outputPath: './src/parameters',
},
{
preset: 'headers',
outputPath: './src/headers',
},
{
preset: 'types',
outputPath: './src',
},
{
preset: 'channels',
outputPath: './src/channels',
protocols: ['nats'],
},
{
preset: 'client',
outputPath: './src/client',
protocols: ['nats'],
},
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
id: user-domain
name: User Domain
version: 1.0.0
summary: Domain responsible for all user-related functionality
owners:
- platform-team
services:
- id: user-service
version: 1.0.0
badges:
- content: Core Domain
backgroundColor: blue
textColor: white
---

## Overview

The User Domain encompasses all functionality related to user management, including:

- User registration and authentication
- Profile management
- User preferences
- Account lifecycle

## Bounded Context

This domain owns the concept of a "User" and is the source of truth for user identity and profile information.

## Services

| Service | Description |
|---------|-------------|
| User Service | Core service for user operations |

## Events

| Event | Published By | Description |
|-------|--------------|-------------|
| UserSignedUp | User Service | New user registration |
| UserProfileUpdated | User Service | Profile changes |
Loading
Loading