@adhd/apigen-plugin-openapi 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +131 -4
  3. package/package.json +3 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,28 @@
1
+ ## 0.1.3 (2026-07-23)
2
+
3
+
4
+ ### 🚀 Features
5
+
6
+ - session batch — dispatch tool-exec + provider routing, publish hygiene, agent/env/apigen fixes
7
+
8
+ - **release:** nx release independent versioning + verify-dist-load publish gate (Agent 2)
9
+
10
+
11
+ ### 🩹 Fixes
12
+
13
+ - resolve build errors from workspace-cleanup merge — unterminated strings, path mappings, lint
14
+
15
+ - **apigen:** update remaining stale @adhd/apigen-errors, core, logical refs
16
+
17
+ - **environment:** correct agent-mcp plugins at: classification (build->runtime)
18
+
19
+ - **apigen:** complete FEAT-APIGEN-022 test coverage — primitive→GET + complex→POST
20
+
21
+ - **apigen:** externalize real npm deps in vite builds — 10 packages shipped broken dist bundles (__filename/timeOrigin crash)
22
+
23
+ - **apigen-plugin-openapi:** sync @adhd/apigen-codegen-openapi range to installed 0.1.2
24
+
25
+
26
+ ### ❤️ Thank You
27
+
28
+ - pseudosky
package/README.md CHANGED
@@ -1,14 +1,141 @@
1
1
  # @adhd/apigen-plugin-openapi
2
2
 
3
- apigen plugin — emits an **OpenAPI** document for a source file's exports, built on
4
- [`@adhd/apigen-codegen-openapi`](../../codegen/openapi).
3
+ **Mount plugin** — serves a **live OpenAPI 3.1 document** at `GET /_meta/openapi`. The document is derived from the extracted operations at request time, so it always reflects the current service definition.
5
4
 
6
- Part of [apigen](../../README.md). Driven via [`@adhd/apigen-cli`](../../cli).
5
+ Part of [apigen](../README.md). Driven via [`@adhd/apigen-cli`](../../../entrypoint/apigen-cli/README.md).
6
+
7
+ ---
8
+
9
+ ## What it does
10
+
11
+ When loaded via `--use` on any HTTP target plugin (`api-fastify`, `api-express`), the openapi plugin contributes a synthetic `_meta/openapi` operation. Hitting `GET /_meta/openapi` returns a full OpenAPI 3.1 spec derived from your operations at request time — every endpoint, parameter type, and response shape, all inferred from your TypeScript types.
12
+
13
+ **No code generation, no build step.** The spec is always current with your running service.
7
14
 
8
15
  ```bash
9
- npx @adhd/apigen-cli generate --source ./api.ts --type openapi --out-dir ./out
16
+ curl http://localhost:3000/_meta/openapi
17
+ # → {
18
+ # "openapi": "3.1.0",
19
+ # "info": { "title": "My API", "version": "1.0.0" },
20
+ # "paths": {
21
+ # "/api/getUser": {
22
+ # "get": {
23
+ # "parameters": [{ "name": "id", "in": "query", "schema": { "type": "string" } }],
24
+ # "responses": { "200": { "description": "success" } }
25
+ # }
26
+ # }
27
+ # }
28
+ # }
29
+ ```
30
+
31
+ ---
32
+
33
+ ## CLI usage
34
+
35
+ ```bash
36
+ # Fastify with OpenAPI doc
37
+ npx @adhd/apigen-cli run --source api.ts --type api-fastify --opt port=3000 --use openapi
38
+
39
+ # With custom title and version
40
+ npx @adhd/apigen-cli run --source api.ts --type api-fastify --use openapi \
41
+ --opt 'useOptions={"openapi":{"title":"User API","version":"2.0.0"}}'
42
+
43
+ # Combined with other plugins
44
+ npx @adhd/apigen-cli run --source api.ts --type api-fastify --use openapi --use health --use logger
10
45
  ```
11
46
 
47
+ ---
48
+
49
+ ## Programmatic usage
50
+
51
+ ```ts
52
+ import { extract, composeSchemas } from '@adhd/apigen-core-client';
53
+ import { apiFastifyPlugin } from '@adhd/apigen-plugin-api-fastify';
54
+ import { openapiPlugin } from '@adhd/apigen-plugin-openapi';
55
+
56
+ const ops = await extract({ sourceFile: './api.ts', namespace: 'api' });
57
+ const schemas = composeSchemas(
58
+ {
59
+ metadata: { namespace: 'api', phase: '' },
60
+ schemas: Object.fromEntries(
61
+ ops.filter(o => o.kind === 'action').map(op => [
62
+ op.path[op.path.length - 1].raw,
63
+ { input: op.input, output: op.output, hasCtx: op.hasCtx, 'x-apigen-safe': op.safe },
64
+ ])
65
+ ),
66
+ },
67
+ []
68
+ );
69
+ const mod = await import('./api.ts');
70
+
71
+ const abort = new AbortController();
72
+ process.on('SIGINT', () => abort.abort());
73
+
74
+ await apiFastifyPlugin.run({
75
+ packages: [{ id: 'api', schemas, importPath: './api.ts', fns: mod, createClient: async () => ({}) }],
76
+ outputDir: '',
77
+ options: {
78
+ port: 3000,
79
+ usePlugins: [
80
+ openapiPlugin, // ← mounts GET /_meta/openapi
81
+ ],
82
+ // Custom title and version:
83
+ // useOptions: { openapi: { title: 'User API', version: '2.0.0' } },
84
+ },
85
+ signal: abort.signal,
86
+ operations: ops,
87
+ });
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Options
93
+
94
+ ```ts
95
+ import { type OpenapiOptions } from '@adhd/apigen-plugin-openapi';
96
+ ```
97
+
98
+ | Option | Type | Default | Description |
99
+ |--------|------|---------|-------------|
100
+ | `title` | `string` | `'API'` | `info.title` in the generated OpenAPI document |
101
+ | `version` | `string` | `'0.0.0'` | `info.version` in the generated OpenAPI document |
102
+
103
+ ---
104
+
105
+ ## What gets documented
106
+
107
+ Every operation extracted from your source file appears in the `paths` section:
108
+
109
+ - **Safe operations** (`x-apigen-safe: true`) → listed as `GET` with query parameters
110
+ - **Unsafe operations** → listed as `POST` with `requestBody`
111
+
112
+ Rich types (Date, Decimal, bigint, UUID) use their canonical JSON Schema representations with `x-apigen-*` hints so codegen tools can reconstruct the correct types.
113
+
114
+ ---
115
+
116
+ ## How it works
117
+
118
+ The openapi plugin implements the **mount capability** (SPEC §7.2b). At compose time, it registers a synthetic `_meta/openapi` operation. At request time, the handler calls `toOpenApi()` from `@adhd/apigen-codegen-openapi` with the full `Operation[]` descriptor — the same one used to serve requests — and returns the live document. No caching, no staleness.
119
+
120
+ This is the same function you can use independently:
121
+
122
+ ```ts
123
+ import { toOpenApi } from '@adhd/apigen-codegen-openapi';
124
+ import type { Operation } from '@adhd/apigen-core-client';
125
+
126
+ const doc = toOpenApi(operations, { title: 'My API', version: '1.0.0' });
127
+ // doc satisfies the OpenAPI 3.1 schema
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Exports
133
+
134
+ | Export | Kind |
135
+ |--------|------|
136
+ | `openapiPlugin` | v2 `Plugin<OpenapiOptions>` — mount capability only |
137
+ | `OpenapiOptions` | TypeScript interface |
138
+
12
139
  ```ts
13
140
  import { openapiPlugin, type OpenapiOptions } from '@adhd/apigen-plugin-openapi';
14
141
  ```
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@adhd/apigen-plugin-openapi",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "main": "./index.js",
5
5
  "dependencies": {
6
- "@adhd/apigen-core-client": "^0.1.0",
7
- "@adhd/apigen-codegen-openapi": "^0.1.2"
6
+ "@adhd/apigen-core-client": "^0.1.1",
7
+ "@adhd/apigen-codegen-openapi": "^0.1.3"
8
8
  },
9
9
  "publishConfig": {
10
10
  "access": "public"