@blixis-io/openapi 0.1.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Michael Voeten
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # `@blixis-io/openapi`
2
+
3
+ Generates an OpenAPI 3.1 document from a running app's real controllers. Built on `@blixis-io/http`'s decorator metadata; no serving mechanism or bundled UI of its own.
4
+
5
+ ```bash
6
+ npm install @blixis-io/openapi @blixis-io/http @blixis-io/di zod
7
+ ```
8
+
9
+ ```ts
10
+ import { generateOpenApiDocument } from "@blixis-io/openapi";
11
+
12
+ const app = await createHttpApplication(AppModule);
13
+
14
+ const doc = generateOpenApiDocument(app, {
15
+ title: "my-api",
16
+ version: "1.0.0",
17
+ });
18
+ ```
19
+
20
+ Reads the same `@Controller`/`@Get`/`@Body`/`@Query`/`@Param`/`@Returns` metadata the router itself already uses — no separate annotation system to keep in sync. `generateOpenApiDocument` only needs `{ controllers: readonly Class[] }`, so it's cheap to unit test without booting a real app.
21
+
22
+ Part of [Blixis Framework](https://github.com/blixis-io/framework) — full docs: [API Documentation](https://blixis-io.github.io/framework/concepts/api-documentation/) · [API reference](https://blixis-io.github.io/framework/reference/blixis-openapi/).
@@ -0,0 +1,69 @@
1
+ import { Class } from "@blixis-io/di";
2
+ //#region src/generate.d.ts
3
+ /** The one thing `generateOpenApiDocument` needs — a real `HttpApplication` satisfies this structurally, no import of the class itself required. */
4
+ interface ControllerSource {
5
+ readonly controllers: readonly Class[];
6
+ }
7
+ type JsonSchema = Record<string, unknown>;
8
+ interface OpenApiParameter {
9
+ name: string;
10
+ in: "path" | "query" | "header";
11
+ required: boolean;
12
+ schema: JsonSchema;
13
+ }
14
+ interface OpenApiResponse {
15
+ description: string;
16
+ content?: {
17
+ "application/json": {
18
+ schema: JsonSchema;
19
+ };
20
+ };
21
+ }
22
+ interface OpenApiOperation {
23
+ operationId: string;
24
+ summary?: string;
25
+ description?: string;
26
+ tags?: string[];
27
+ parameters?: OpenApiParameter[];
28
+ requestBody?: {
29
+ required: boolean;
30
+ content: {
31
+ "application/json": {
32
+ schema: JsonSchema;
33
+ };
34
+ };
35
+ };
36
+ responses: Record<string, OpenApiResponse>;
37
+ }
38
+ interface OpenApiDocument {
39
+ openapi: "3.1.0";
40
+ info: {
41
+ title: string;
42
+ version: string;
43
+ description?: string;
44
+ };
45
+ paths: Record<string, Record<string, OpenApiOperation>>;
46
+ components: {
47
+ schemas: {
48
+ Problem: JsonSchema;
49
+ };
50
+ };
51
+ }
52
+ interface OpenApiDocumentOptions {
53
+ title: string;
54
+ version: string;
55
+ description?: string;
56
+ }
57
+ /**
58
+ * Builds an OpenAPI 3.1 document from `app`'s real controller list —
59
+ * walking the same public decorator-metadata readers `@blixis-io/http`'s own
60
+ * `buildRouter` uses internally, so the document always reflects the
61
+ * routes actually registered, not a separately-maintained description of
62
+ * them. Returns a plain object; mount it yourself (`@Get("openapi.json")
63
+ * spec() { return generateOpenApiDocument(...); }`) — no serving
64
+ * mechanism or bundled UI here.
65
+ */
66
+ export declare function generateOpenApiDocument(app: ControllerSource, options: OpenApiDocumentOptions): OpenApiDocument;
67
+ //#endregion
68
+ export type { ControllerSource, JsonSchema, OpenApiDocument, OpenApiDocumentOptions, OpenApiOperation, OpenApiParameter, OpenApiResponse };
69
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/generate.ts"],"mappings":";;;UAeiB;WACN,sBAAsB;;KAGrB,aAAa;UAER;EACf;EACA;EACA;EACA,QAAQ;;UAGO;EACf;EACA;IAAY;MAAsB,QAAQ;;;;UAG3B;EACf;EACA;EACA;EACA;EACA,aAAa;EACb;IAAgB;IAAmB;MAAW;QAAsB,QAAQ;;;;EAC5E,WAAW,eAAe;;UAGX;EACf;EACA;IAAQ;IAAe;IAAiB;;EACxC,OAAO,eAAe,eAAe;EACrC;IAAc;MAAW,SAAS;;;;UAGnB;EACf;EACA;EACA;;;;;;;;;;;wBA0Hc,wBAAwB,KAAK,kBAAkB,SAAS,yBAAyB"}
package/dist/index.js ADDED
@@ -0,0 +1,136 @@
1
+ import { getApiOperation, getClassApiTags, getControllerPrefix, getHttpCode, getMethodApiTags, getParamSources, getReturnsSchema, getRoutes } from "@blixis-io/http";
2
+ import { z } from "zod";
3
+ //#region src/generate.ts
4
+ const PROBLEM_SCHEMA = {
5
+ type: "object",
6
+ properties: {
7
+ type: { type: "string" },
8
+ title: { type: "string" },
9
+ status: { type: "integer" },
10
+ detail: { type: "string" }
11
+ },
12
+ required: [
13
+ "type",
14
+ "title",
15
+ "status",
16
+ "detail"
17
+ ]
18
+ };
19
+ /** `z.toJSONSchema()`'s output, minus the top-level `$schema` key — OpenAPI Schema Objects don't carry that. */
20
+ function toSchema(schema) {
21
+ const { $schema: _unused, ...rest } = z.toJSONSchema(schema);
22
+ return rest;
23
+ }
24
+ /**
25
+ * Converts one route's path segments to an OpenAPI path template
26
+ * (`:id` → `{id}`), or `undefined` if the route contains a `*` wildcard
27
+ * segment — OpenAPI has no equivalent construct, so wildcard routes are
28
+ * excluded from the generated document entirely.
29
+ */
30
+ function buildOpenApiPath(prefix, routePath) {
31
+ const segments = `${prefix}/${routePath}`.split("/").filter((segment) => segment.length > 0);
32
+ if (segments.includes("*")) return;
33
+ return `/${segments.map((segment) => segment.startsWith(":") ? `{${segment.slice(1)}}` : segment).join("/")}`;
34
+ }
35
+ function buildParameters(prototype, propertyKey) {
36
+ const parameters = [];
37
+ let requestBody;
38
+ for (const source of getParamSources(prototype, propertyKey).values()) switch (source.kind) {
39
+ case "param":
40
+ parameters.push({
41
+ name: source.name,
42
+ in: "path",
43
+ required: true,
44
+ schema: source.schema ? toSchema(source.schema) : { type: "string" }
45
+ });
46
+ break;
47
+ case "query":
48
+ if (source.schema instanceof z.ZodObject) for (const [name, fieldSchema] of Object.entries(source.schema.shape)) parameters.push({
49
+ name,
50
+ in: "query",
51
+ required: !fieldSchema.isOptional(),
52
+ schema: toSchema(fieldSchema)
53
+ });
54
+ break;
55
+ case "headers":
56
+ if (source.name) parameters.push({
57
+ name: source.name,
58
+ in: "header",
59
+ required: false,
60
+ schema: { type: "string" }
61
+ });
62
+ break;
63
+ case "body": if (source.schema) requestBody = {
64
+ required: true,
65
+ content: { "application/json": { schema: toSchema(source.schema) } }
66
+ };
67
+ }
68
+ return {
69
+ parameters,
70
+ requestBody
71
+ };
72
+ }
73
+ function buildResponses(prototype, propertyKey) {
74
+ const status = String(getHttpCode(prototype, propertyKey) ?? 200);
75
+ const returnsSchema = getReturnsSchema(prototype, propertyKey);
76
+ return {
77
+ [status]: returnsSchema ? {
78
+ description: "Success",
79
+ content: { "application/json": { schema: toSchema(returnsSchema) } }
80
+ } : { description: "Success" },
81
+ default: {
82
+ description: "Error",
83
+ content: { "application/json": { schema: { $ref: "#/components/schemas/Problem" } } }
84
+ }
85
+ };
86
+ }
87
+ function buildOperation(controller, route) {
88
+ const prototype = controller.prototype;
89
+ const operation = getApiOperation(prototype, route.propertyKey);
90
+ const tags = [...getClassApiTags(controller), ...getMethodApiTags(prototype, route.propertyKey)];
91
+ const { parameters, requestBody } = buildParameters(prototype, route.propertyKey);
92
+ return {
93
+ operationId: operation?.operationId ?? `${controller.name}_${String(route.propertyKey)}`,
94
+ ...operation?.summary ? { summary: operation.summary } : {},
95
+ ...operation?.description ? { description: operation.description } : {},
96
+ ...tags.length > 0 ? { tags } : {},
97
+ ...parameters.length > 0 ? { parameters } : {},
98
+ ...requestBody ? { requestBody } : {},
99
+ responses: buildResponses(prototype, route.propertyKey)
100
+ };
101
+ }
102
+ /**
103
+ * Builds an OpenAPI 3.1 document from `app`'s real controller list —
104
+ * walking the same public decorator-metadata readers `@blixis-io/http`'s own
105
+ * `buildRouter` uses internally, so the document always reflects the
106
+ * routes actually registered, not a separately-maintained description of
107
+ * them. Returns a plain object; mount it yourself (`@Get("openapi.json")
108
+ * spec() { return generateOpenApiDocument(...); }`) — no serving
109
+ * mechanism or bundled UI here.
110
+ */
111
+ function generateOpenApiDocument(app, options) {
112
+ const paths = {};
113
+ for (const controller of app.controllers) {
114
+ const prefix = getControllerPrefix(controller) ?? "";
115
+ for (const route of getRoutes(controller)) {
116
+ const path = buildOpenApiPath(prefix, route.path);
117
+ if (!path) continue;
118
+ paths[path] ??= {};
119
+ paths[path][route.method.toLowerCase()] = buildOperation(controller, route);
120
+ }
121
+ }
122
+ return {
123
+ openapi: "3.1.0",
124
+ info: {
125
+ title: options.title,
126
+ version: options.version,
127
+ ...options.description ? { description: options.description } : {}
128
+ },
129
+ paths,
130
+ components: { schemas: { Problem: PROBLEM_SCHEMA } }
131
+ };
132
+ }
133
+ //#endregion
134
+ export { generateOpenApiDocument };
135
+
136
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/generate.ts"],"sourcesContent":["import type { Class } from \"@blixis-io/di\";\nimport {\n getApiOperation,\n getClassApiTags,\n getControllerPrefix,\n getHttpCode,\n getMethodApiTags,\n getParamSources,\n getReturnsSchema,\n getRoutes,\n type RouteDefinition,\n} from \"@blixis-io/http\";\nimport { z, type ZodType } from \"zod\";\n\n/** The one thing `generateOpenApiDocument` needs — a real `HttpApplication` satisfies this structurally, no import of the class itself required. */\nexport interface ControllerSource {\n readonly controllers: readonly Class[];\n}\n\nexport type JsonSchema = Record<string, unknown>;\n\nexport interface OpenApiParameter {\n name: string;\n in: \"path\" | \"query\" | \"header\";\n required: boolean;\n schema: JsonSchema;\n}\n\nexport interface OpenApiResponse {\n description: string;\n content?: { \"application/json\": { schema: JsonSchema } };\n}\n\nexport interface OpenApiOperation {\n operationId: string;\n summary?: string;\n description?: string;\n tags?: string[];\n parameters?: OpenApiParameter[];\n requestBody?: { required: boolean; content: { \"application/json\": { schema: JsonSchema } } };\n responses: Record<string, OpenApiResponse>;\n}\n\nexport interface OpenApiDocument {\n openapi: \"3.1.0\";\n info: { title: string; version: string; description?: string };\n paths: Record<string, Record<string, OpenApiOperation>>;\n components: { schemas: { Problem: JsonSchema } };\n}\n\nexport interface OpenApiDocumentOptions {\n title: string;\n version: string;\n description?: string;\n}\n\nconst PROBLEM_SCHEMA: JsonSchema = {\n type: \"object\",\n properties: {\n type: { type: \"string\" },\n title: { type: \"string\" },\n status: { type: \"integer\" },\n detail: { type: \"string\" },\n },\n required: [\"type\", \"title\", \"status\", \"detail\"],\n};\n\n/** `z.toJSONSchema()`'s output, minus the top-level `$schema` key — OpenAPI Schema Objects don't carry that. */\nfunction toSchema(schema: ZodType): JsonSchema {\n const { $schema: _unused, ...rest } = z.toJSONSchema(schema);\n return rest;\n}\n\n/**\n * Converts one route's path segments to an OpenAPI path template\n * (`:id` → `{id}`), or `undefined` if the route contains a `*` wildcard\n * segment — OpenAPI has no equivalent construct, so wildcard routes are\n * excluded from the generated document entirely.\n */\nfunction buildOpenApiPath(prefix: string, routePath: string): string | undefined {\n const segments = `${prefix}/${routePath}`.split(\"/\").filter((segment) => segment.length > 0);\n if (segments.includes(\"*\")) {\n return undefined;\n }\n const converted = segments.map((segment) => (segment.startsWith(\":\") ? `{${segment.slice(1)}}` : segment));\n return `/${converted.join(\"/\")}`;\n}\n\nfunction buildParameters(prototype: object, propertyKey: string | symbol): {\n parameters: OpenApiParameter[];\n requestBody: OpenApiOperation[\"requestBody\"];\n} {\n const parameters: OpenApiParameter[] = [];\n let requestBody: OpenApiOperation[\"requestBody\"];\n\n for (const source of getParamSources(prototype, propertyKey).values()) {\n switch (source.kind) {\n case \"param\":\n parameters.push({\n name: source.name,\n in: \"path\",\n required: true,\n schema: source.schema ? toSchema(source.schema) : { type: \"string\" },\n });\n break;\n case \"query\":\n if (source.schema instanceof z.ZodObject) {\n for (const [name, fieldSchema] of Object.entries(source.schema.shape)) {\n parameters.push({\n name,\n in: \"query\",\n required: !fieldSchema.isOptional(),\n schema: toSchema(fieldSchema),\n });\n }\n }\n break;\n case \"headers\":\n if (source.name) {\n parameters.push({ name: source.name, in: \"header\", required: false, schema: { type: \"string\" } });\n }\n break;\n case \"body\":\n if (source.schema) {\n requestBody = { required: true, content: { \"application/json\": { schema: toSchema(source.schema) } } };\n }\n break;\n // `req` (the raw Request) has nothing documentable — no case needed.\n }\n }\n\n return { parameters, requestBody };\n}\n\nfunction buildResponses(prototype: object, propertyKey: string | symbol): Record<string, OpenApiResponse> {\n const status = String(getHttpCode(prototype, propertyKey) ?? 200);\n const returnsSchema = getReturnsSchema(prototype, propertyKey);\n\n return {\n [status]: returnsSchema\n ? { description: \"Success\", content: { \"application/json\": { schema: toSchema(returnsSchema) } } }\n : { description: \"Success\" },\n default: {\n description: \"Error\",\n content: { \"application/json\": { schema: { $ref: \"#/components/schemas/Problem\" } } },\n },\n };\n}\n\nfunction buildOperation(controller: Class, route: RouteDefinition): OpenApiOperation {\n const prototype = controller.prototype as object;\n const operation = getApiOperation(prototype, route.propertyKey);\n const tags = [...getClassApiTags(controller), ...getMethodApiTags(prototype, route.propertyKey)];\n const { parameters, requestBody } = buildParameters(prototype, route.propertyKey);\n\n return {\n operationId: operation?.operationId ?? `${controller.name}_${String(route.propertyKey)}`,\n ...(operation?.summary ? { summary: operation.summary } : {}),\n ...(operation?.description ? { description: operation.description } : {}),\n ...(tags.length > 0 ? { tags } : {}),\n ...(parameters.length > 0 ? { parameters } : {}),\n ...(requestBody ? { requestBody } : {}),\n responses: buildResponses(prototype, route.propertyKey),\n };\n}\n\n/**\n * Builds an OpenAPI 3.1 document from `app`'s real controller list —\n * walking the same public decorator-metadata readers `@blixis-io/http`'s own\n * `buildRouter` uses internally, so the document always reflects the\n * routes actually registered, not a separately-maintained description of\n * them. Returns a plain object; mount it yourself (`@Get(\"openapi.json\")\n * spec() { return generateOpenApiDocument(...); }`) — no serving\n * mechanism or bundled UI here.\n */\nexport function generateOpenApiDocument(app: ControllerSource, options: OpenApiDocumentOptions): OpenApiDocument {\n const paths: OpenApiDocument[\"paths\"] = {};\n\n for (const controller of app.controllers) {\n const prefix = getControllerPrefix(controller) ?? \"\";\n\n for (const route of getRoutes(controller)) {\n const path = buildOpenApiPath(prefix, route.path);\n if (!path) {\n continue;\n }\n\n paths[path] ??= {};\n paths[path][route.method.toLowerCase()] = buildOperation(controller, route);\n }\n }\n\n return {\n openapi: \"3.1.0\",\n info: { title: options.title, version: options.version, ...(options.description ? { description: options.description } : {}) },\n paths,\n components: { schemas: { Problem: PROBLEM_SCHEMA } },\n };\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@blixis-io/openapi",
3
+ "version": "0.1.0",
4
+ "description": "Generates an OpenAPI 3.1 document from a running app's real controllers. Built on @blixis-io/http's decorator metadata; no serving mechanism or bundled UI of its own.",
5
+ "license": "MIT",
6
+ "author": "Michael Voeten <michael@voeten.online>",
7
+ "homepage": "https://blixis-io.github.io/framework/",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/blixis-io/framework.git",
11
+ "directory": "packages/openapi"
12
+ },
13
+ "type": "module",
14
+ "engines": {
15
+ "node": ">=24"
16
+ },
17
+ "keywords": [
18
+ "openapi",
19
+ "swagger",
20
+ "api-documentation",
21
+ "typescript"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "exports": {
30
+ ".": {
31
+ "@blixis-io/source": "./src/index.ts",
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ }
35
+ },
36
+ "dependencies": {
37
+ "@blixis-io/di": "0.1.0",
38
+ "@blixis-io/http": "0.1.0",
39
+ "zod": "^4.6.5"
40
+ },
41
+ "scripts": {
42
+ "typecheck": "tsc -p tsconfig.json",
43
+ "build": "rolldown -c"
44
+ }
45
+ }