@hestjs/scalar 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/README.md +115 -0
- package/dist/decorators/openapi.decorators.d.ts +266 -0
- package/dist/decorators/openapi.decorators.d.ts.map +1 -0
- package/dist/decorators/openapi.decorators.js +113 -0
- package/dist/decorators/openapi.decorators.js.map +1 -0
- package/dist/extensions.d.ts +22 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +27 -0
- package/dist/extensions.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/openapi-generator.d.ts +61 -0
- package/dist/openapi-generator.d.ts.map +1 -0
- package/dist/openapi-generator.js +215 -0
- package/dist/openapi-generator.js.map +1 -0
- package/dist/scalar-config.interface.d.ts +73 -0
- package/dist/scalar-config.interface.d.ts.map +1 -0
- package/dist/scalar-config.interface.js +2 -0
- package/dist/scalar-config.interface.js.map +1 -0
- package/dist/scalar.middleware.d.ts +20 -0
- package/dist/scalar.middleware.d.ts.map +1 -0
- package/dist/scalar.middleware.js +149 -0
- package/dist/scalar.middleware.js.map +1 -0
- package/dist/scalar.module.d.ts +15 -0
- package/dist/scalar.module.d.ts.map +1 -0
- package/dist/scalar.module.js +42 -0
- package/dist/scalar.module.js.map +1 -0
- package/dist/utils/index.d.ts +25 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +212 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +68 -0
@@ -0,0 +1,215 @@
|
|
1
|
+
import 'reflect-metadata';
|
2
|
+
/**
|
3
|
+
* OpenAPI 文档生成器
|
4
|
+
*/
|
5
|
+
export class OpenAPIGenerator {
|
6
|
+
config;
|
7
|
+
paths = {};
|
8
|
+
components = {
|
9
|
+
schemas: {},
|
10
|
+
responses: {},
|
11
|
+
parameters: {},
|
12
|
+
examples: {},
|
13
|
+
requestBodies: {},
|
14
|
+
headers: {},
|
15
|
+
securitySchemes: {},
|
16
|
+
links: {},
|
17
|
+
callbacks: {},
|
18
|
+
};
|
19
|
+
constructor(config) {
|
20
|
+
this.config = config;
|
21
|
+
if (config.components) {
|
22
|
+
this.components = { ...this.components, ...config.components };
|
23
|
+
}
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* 从控制器类生成 OpenAPI 路径
|
27
|
+
*/
|
28
|
+
addController(controller, basePath = '') {
|
29
|
+
console.log(`Processing controller: ${controller.name}, basePath: ${basePath}`);
|
30
|
+
const controllerTags = Reflect.getMetadata('openapi:tags', controller) || [];
|
31
|
+
console.log(`Controller tags:`, controllerTags);
|
32
|
+
// 获取HestJS的路由元数据(存储在控制器类上)
|
33
|
+
const HEST_ROUTE_KEY = Symbol.for('hest:route');
|
34
|
+
const routes = Reflect.getMetadata(HEST_ROUTE_KEY, controller) || [];
|
35
|
+
console.log(`Found routes:`, routes);
|
36
|
+
for (const route of routes) {
|
37
|
+
const { method, path, methodName } = route;
|
38
|
+
const fullPath = this.joinPaths(basePath, path);
|
39
|
+
console.log(`Adding route: ${method.toUpperCase()} ${fullPath} (method: ${methodName})`);
|
40
|
+
// 确保路径存在
|
41
|
+
if (!this.paths[fullPath]) {
|
42
|
+
this.paths[fullPath] = {};
|
43
|
+
}
|
44
|
+
// 生成操作对象
|
45
|
+
const operation = this.generateOperation(controller, methodName, controllerTags);
|
46
|
+
this.paths[fullPath][method.toLowerCase()] = operation;
|
47
|
+
}
|
48
|
+
// 处理类级别的schema
|
49
|
+
this.addSchemaFromClass(controller);
|
50
|
+
}
|
51
|
+
/**
|
52
|
+
* 生成操作对象
|
53
|
+
*/
|
54
|
+
generateOperation(controller, methodName, defaultTags) {
|
55
|
+
const prototype = controller.prototype;
|
56
|
+
// 基础操作信息
|
57
|
+
const operationMetadata = Reflect.getMetadata('openapi:operation', prototype, methodName) || {};
|
58
|
+
const operation = {
|
59
|
+
tags: operationMetadata.tags || defaultTags,
|
60
|
+
summary: operationMetadata.summary,
|
61
|
+
description: operationMetadata.description,
|
62
|
+
operationId: operationMetadata.operationId || `${controller.name}_${methodName}`,
|
63
|
+
responses: {},
|
64
|
+
...operationMetadata
|
65
|
+
};
|
66
|
+
// 参数
|
67
|
+
const parameters = Reflect.getMetadata('openapi:parameters', prototype, methodName);
|
68
|
+
if (parameters && parameters.length > 0) {
|
69
|
+
operation.parameters = parameters;
|
70
|
+
}
|
71
|
+
// 请求体
|
72
|
+
const requestBody = Reflect.getMetadata('openapi:requestBody', prototype, methodName);
|
73
|
+
if (requestBody) {
|
74
|
+
operation.requestBody = requestBody;
|
75
|
+
}
|
76
|
+
// 响应
|
77
|
+
const responses = Reflect.getMetadata('openapi:responses', prototype, methodName);
|
78
|
+
if (responses && Object.keys(responses).length > 0) {
|
79
|
+
operation.responses = responses;
|
80
|
+
}
|
81
|
+
else {
|
82
|
+
// 默认响应
|
83
|
+
operation.responses = {
|
84
|
+
'200': {
|
85
|
+
description: 'Success'
|
86
|
+
}
|
87
|
+
};
|
88
|
+
}
|
89
|
+
// 安全
|
90
|
+
const security = Reflect.getMetadata('openapi:security', prototype, methodName);
|
91
|
+
if (security) {
|
92
|
+
operation.security = security;
|
93
|
+
}
|
94
|
+
return operation;
|
95
|
+
}
|
96
|
+
/**
|
97
|
+
* 从类添加 Schema
|
98
|
+
*/
|
99
|
+
addSchemaFromClass(target) {
|
100
|
+
const schema = Reflect.getMetadata('openapi:schema', target);
|
101
|
+
if (schema) {
|
102
|
+
const schemaName = target.name;
|
103
|
+
this.components.schemas[schemaName] = schema;
|
104
|
+
}
|
105
|
+
// 处理属性级别的schema
|
106
|
+
const properties = Reflect.getMetadata('openapi:properties', target);
|
107
|
+
if (properties && Object.keys(properties).length > 0) {
|
108
|
+
const schemaName = target.name;
|
109
|
+
if (!this.components.schemas[schemaName]) {
|
110
|
+
this.components.schemas[schemaName] = {
|
111
|
+
type: 'object',
|
112
|
+
properties: {},
|
113
|
+
};
|
114
|
+
}
|
115
|
+
const existingSchema = this.components.schemas[schemaName];
|
116
|
+
if (!existingSchema.properties) {
|
117
|
+
existingSchema.properties = {};
|
118
|
+
}
|
119
|
+
// 合并属性
|
120
|
+
Object.assign(existingSchema.properties, properties);
|
121
|
+
// 收集required字段
|
122
|
+
const required = [];
|
123
|
+
for (const [propName, propSchema] of Object.entries(properties)) {
|
124
|
+
if (propSchema.required === true) {
|
125
|
+
required.push(propName);
|
126
|
+
}
|
127
|
+
}
|
128
|
+
if (required.length > 0) {
|
129
|
+
existingSchema.required = [...(existingSchema.required || []), ...required];
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
/**
|
134
|
+
* 标准化路径
|
135
|
+
*/
|
136
|
+
normalizePath(path) {
|
137
|
+
// 将 :id 格式转换为 {id} 格式
|
138
|
+
let normalized = path.replace(/:([^/]+)/g, '{$1}');
|
139
|
+
// 移除末尾的斜杠(除非是根路径)
|
140
|
+
if (normalized !== '/' && normalized.endsWith('/')) {
|
141
|
+
normalized = normalized.slice(0, -1);
|
142
|
+
}
|
143
|
+
return normalized;
|
144
|
+
}
|
145
|
+
/**
|
146
|
+
* 拼接路径
|
147
|
+
*/
|
148
|
+
joinPaths(basePath, path) {
|
149
|
+
// 规范化基础路径
|
150
|
+
basePath = basePath.replace(/\/$/, ''); // 移除末尾斜杠
|
151
|
+
// 规范化路径
|
152
|
+
if (path === '/') {
|
153
|
+
// 如果路径是根路径,直接使用基础路径
|
154
|
+
return basePath || '/';
|
155
|
+
}
|
156
|
+
else if (!path.startsWith('/')) {
|
157
|
+
// 如果路径不以斜杠开头,添加斜杠
|
158
|
+
path = '/' + path;
|
159
|
+
}
|
160
|
+
const fullPath = basePath + path;
|
161
|
+
return this.normalizePath(fullPath);
|
162
|
+
}
|
163
|
+
/**
|
164
|
+
* 添加全局组件
|
165
|
+
*/
|
166
|
+
addComponent(type, name, component) {
|
167
|
+
if (!this.components[type]) {
|
168
|
+
this.components[type] = {};
|
169
|
+
}
|
170
|
+
this.components[type][name] = component;
|
171
|
+
}
|
172
|
+
/**
|
173
|
+
* 生成完整的 OpenAPI 文档
|
174
|
+
*/
|
175
|
+
generateDocument() {
|
176
|
+
// 清理空的组件
|
177
|
+
const cleanComponents = {};
|
178
|
+
for (const [key, value] of Object.entries(this.components)) {
|
179
|
+
if (value && Object.keys(value).length > 0) {
|
180
|
+
cleanComponents[key] = value;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
return {
|
184
|
+
openapi: '3.0.0',
|
185
|
+
info: this.config.info,
|
186
|
+
servers: this.config.servers,
|
187
|
+
paths: this.paths,
|
188
|
+
components: Object.keys(cleanComponents).length > 0 ? cleanComponents : undefined,
|
189
|
+
security: this.config.security,
|
190
|
+
tags: this.config.tags,
|
191
|
+
externalDocs: this.config.externalDocs,
|
192
|
+
};
|
193
|
+
}
|
194
|
+
/**
|
195
|
+
* 重置生成器
|
196
|
+
*/
|
197
|
+
reset() {
|
198
|
+
this.paths = {};
|
199
|
+
this.components = {
|
200
|
+
schemas: {},
|
201
|
+
responses: {},
|
202
|
+
parameters: {},
|
203
|
+
examples: {},
|
204
|
+
requestBodies: {},
|
205
|
+
headers: {},
|
206
|
+
securitySchemes: {},
|
207
|
+
links: {},
|
208
|
+
callbacks: {},
|
209
|
+
};
|
210
|
+
if (this.config.components) {
|
211
|
+
this.components = { ...this.components, ...this.config.components };
|
212
|
+
}
|
213
|
+
}
|
214
|
+
}
|
215
|
+
//# sourceMappingURL=openapi-generator.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"openapi-generator.js","sourceRoot":"","sources":["../src/openapi-generator.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import type { Context } from 'hono';
|
2
|
+
/**
|
3
|
+
* Scalar 配置选项
|
4
|
+
*/
|
5
|
+
export interface ScalarConfig {
|
6
|
+
/**
|
7
|
+
* 是否启用 Scalar
|
8
|
+
* @default true
|
9
|
+
*/
|
10
|
+
enabled?: boolean;
|
11
|
+
/**
|
12
|
+
* 文档服务路径
|
13
|
+
* @default '/docs'
|
14
|
+
*/
|
15
|
+
path?: string;
|
16
|
+
/**
|
17
|
+
* OpenAPI 规范(URL 或对象)
|
18
|
+
*/
|
19
|
+
spec?: string | object | ((c: Context) => string | object | Promise<string | object>);
|
20
|
+
/**
|
21
|
+
* 页面标题
|
22
|
+
* @default 'API Documentation'
|
23
|
+
*/
|
24
|
+
title?: string;
|
25
|
+
/**
|
26
|
+
* UI 主题
|
27
|
+
* @default 'elysia'
|
28
|
+
*/
|
29
|
+
theme?: 'elysia' | 'default' | 'alternate' | 'moon' | 'purple' | 'solarized' | 'none';
|
30
|
+
/**
|
31
|
+
* 自定义 CDN 地址
|
32
|
+
*/
|
33
|
+
cdn?: string;
|
34
|
+
/**
|
35
|
+
* 代理 URL(用于开发环境解决 CORS 问题)
|
36
|
+
*/
|
37
|
+
proxyUrl?: string;
|
38
|
+
/**
|
39
|
+
* 服务器配置
|
40
|
+
*/
|
41
|
+
servers?: Array<{
|
42
|
+
url: string;
|
43
|
+
description?: string;
|
44
|
+
}>;
|
45
|
+
/**
|
46
|
+
* 自定义 CSS
|
47
|
+
*/
|
48
|
+
customCss?: string;
|
49
|
+
/**
|
50
|
+
* 是否启用 Markdown 导出(供 LLM 使用)
|
51
|
+
* @default false
|
52
|
+
*/
|
53
|
+
enableMarkdown?: boolean;
|
54
|
+
/**
|
55
|
+
* Markdown 导出路径
|
56
|
+
* @default '/llms.txt'
|
57
|
+
*/
|
58
|
+
markdownPath?: string;
|
59
|
+
}
|
60
|
+
/**
|
61
|
+
* Scalar 中间件配置
|
62
|
+
*/
|
63
|
+
export interface ScalarMiddlewareConfig extends Omit<ScalarConfig, 'path'> {
|
64
|
+
/**
|
65
|
+
* OpenAPI 规范 URL
|
66
|
+
*/
|
67
|
+
url?: string;
|
68
|
+
/**
|
69
|
+
* OpenAPI 规范内容
|
70
|
+
*/
|
71
|
+
content?: object;
|
72
|
+
}
|
73
|
+
//# sourceMappingURL=scalar-config.interface.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"scalar-config.interface.d.ts","sourceRoot":"","sources":["../src/scalar-config.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IAEtF;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;IAEtF;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IAEH;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;IACxE;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"scalar-config.interface.js","sourceRoot":"","sources":["../src/scalar-config.interface.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import type { Hono, MiddlewareHandler } from "hono";
|
2
|
+
import type { ScalarConfig, ScalarMiddlewareConfig } from "./scalar-config.interface";
|
3
|
+
import { type OpenAPIGeneratorConfig } from './openapi-generator';
|
4
|
+
/**
|
5
|
+
* 创建 Scalar 中间件
|
6
|
+
*/
|
7
|
+
export declare function createScalarMiddleware(config: ScalarMiddlewareConfig): MiddlewareHandler;
|
8
|
+
/**
|
9
|
+
* 创建 Markdown 中间件(供 LLM 使用)
|
10
|
+
*/
|
11
|
+
export declare function createMarkdownMiddleware(spec: string | object): MiddlewareHandler;
|
12
|
+
/**
|
13
|
+
* 在 Hono 应用上设置 Scalar
|
14
|
+
*/
|
15
|
+
export declare function setupScalar(app: Hono, config: ScalarConfig): void;
|
16
|
+
/**
|
17
|
+
* 从控制器生成 OpenAPI 并设置 Scalar
|
18
|
+
*/
|
19
|
+
export declare function setupScalarWithControllers(app: Hono, controllers: any[], generatorConfig: OpenAPIGeneratorConfig, scalarConfig?: Omit<ScalarConfig, 'spec'>): void;
|
20
|
+
//# sourceMappingURL=scalar.middleware.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"scalar.middleware.d.ts","sourceRoot":"","sources":["../src/scalar.middleware.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAW,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC7D,OAAO,KAAK,EACV,YAAY,EACZ,sBAAsB,EACvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAoB,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGpF;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,iBAAiB,CA6DnB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GAAG,MAAM,GACpB,iBAAiB,CA6BnB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAsBjE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,IAAI,EACT,WAAW,EAAE,GAAG,EAAE,EAClB,eAAe,EAAE,sBAAsB,EACvC,YAAY,GAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAM,GAC5C,IAAI,CA8CN"}
|
@@ -0,0 +1,149 @@
|
|
1
|
+
import { Scalar } from "@scalar/hono-api-reference";
|
2
|
+
import { createMarkdownFromOpenApi } from "@scalar/openapi-to-markdown";
|
3
|
+
import { OpenAPIGenerator } from './openapi-generator';
|
4
|
+
import { elysiajsTheme } from '@scalar/themes';
|
5
|
+
/**
|
6
|
+
* 创建 Scalar 中间件
|
7
|
+
*/
|
8
|
+
export function createScalarMiddleware(config) {
|
9
|
+
const { spec, url, content, theme = "hestjs", title = "API Documentation", cdn, proxyUrl, servers, customCss, } = config;
|
10
|
+
// 构建 Scalar 配置
|
11
|
+
const scalarConfig = {};
|
12
|
+
// 选择主题CSS
|
13
|
+
let themeCSS = '';
|
14
|
+
if (theme === 'elysia') {
|
15
|
+
themeCSS = elysiajsTheme;
|
16
|
+
}
|
17
|
+
// 设置自定义CSS(主题CSS + 用户自定义CSS)
|
18
|
+
if (themeCSS || customCss) {
|
19
|
+
scalarConfig.customCss = `${themeCSS}
|
20
|
+
${customCss || ''}`;
|
21
|
+
}
|
22
|
+
// 设置规范来源
|
23
|
+
if (url) {
|
24
|
+
scalarConfig.url = url;
|
25
|
+
}
|
26
|
+
else if (content) {
|
27
|
+
scalarConfig.content = content;
|
28
|
+
}
|
29
|
+
else if (spec) {
|
30
|
+
if (typeof spec === "string") {
|
31
|
+
scalarConfig.url = spec;
|
32
|
+
}
|
33
|
+
else if (typeof spec === "function") {
|
34
|
+
// 动态配置,需要在中间件中处理
|
35
|
+
return async (c, next) => {
|
36
|
+
const resolvedSpec = await spec(c);
|
37
|
+
const dynamicConfig = {
|
38
|
+
...scalarConfig,
|
39
|
+
...(typeof resolvedSpec === "string"
|
40
|
+
? { url: resolvedSpec }
|
41
|
+
: { content: resolvedSpec }),
|
42
|
+
};
|
43
|
+
return Scalar(dynamicConfig)(c, next);
|
44
|
+
};
|
45
|
+
}
|
46
|
+
else {
|
47
|
+
scalarConfig.content = spec;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
// 设置其他选项
|
51
|
+
if (title)
|
52
|
+
scalarConfig.pageTitle = title;
|
53
|
+
if (cdn)
|
54
|
+
scalarConfig.cdn = cdn;
|
55
|
+
if (proxyUrl)
|
56
|
+
scalarConfig.proxyUrl = proxyUrl;
|
57
|
+
if (servers)
|
58
|
+
scalarConfig.servers = servers;
|
59
|
+
return Scalar(scalarConfig);
|
60
|
+
}
|
61
|
+
/**
|
62
|
+
* 创建 Markdown 中间件(供 LLM 使用)
|
63
|
+
*/
|
64
|
+
export function createMarkdownMiddleware(spec) {
|
65
|
+
return async (c) => {
|
66
|
+
try {
|
67
|
+
let specContent;
|
68
|
+
if (typeof spec === "string") {
|
69
|
+
// 如果是 URL,需要获取内容
|
70
|
+
if (spec.startsWith("http")) {
|
71
|
+
const response = await fetch(spec);
|
72
|
+
specContent = await response.text();
|
73
|
+
}
|
74
|
+
else {
|
75
|
+
// 假设是相对路径,从当前应用获取
|
76
|
+
const baseUrl = new URL(c.req.url).origin;
|
77
|
+
const response = await fetch(`${baseUrl}${spec}`);
|
78
|
+
specContent = await response.text();
|
79
|
+
}
|
80
|
+
}
|
81
|
+
else {
|
82
|
+
specContent = JSON.stringify(spec);
|
83
|
+
}
|
84
|
+
const markdown = await createMarkdownFromOpenApi(specContent);
|
85
|
+
return c.text(markdown, 200, {
|
86
|
+
"Content-Type": "text/plain; charset=utf-8",
|
87
|
+
});
|
88
|
+
}
|
89
|
+
catch (error) {
|
90
|
+
console.error("Failed to generate markdown:", error);
|
91
|
+
return c.text("Failed to generate API documentation markdown", 500);
|
92
|
+
}
|
93
|
+
};
|
94
|
+
}
|
95
|
+
/**
|
96
|
+
* 在 Hono 应用上设置 Scalar
|
97
|
+
*/
|
98
|
+
export function setupScalar(app, config) {
|
99
|
+
const { path = "/docs", enableMarkdown = false, markdownPath = "/llms.txt", spec, ...middlewareConfig } = config;
|
100
|
+
// 设置主文档路径
|
101
|
+
const scalarMiddleware = createScalarMiddleware({
|
102
|
+
...middlewareConfig,
|
103
|
+
spec,
|
104
|
+
});
|
105
|
+
app.get(path, scalarMiddleware);
|
106
|
+
// 如果启用了 Markdown 导出
|
107
|
+
if (enableMarkdown && spec) {
|
108
|
+
const markdownMiddleware = createMarkdownMiddleware(spec);
|
109
|
+
app.get(markdownPath, markdownMiddleware);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
/**
|
113
|
+
* 从控制器生成 OpenAPI 并设置 Scalar
|
114
|
+
*/
|
115
|
+
export function setupScalarWithControllers(app, controllers, generatorConfig, scalarConfig = {}) {
|
116
|
+
const generator = new OpenAPIGenerator(generatorConfig);
|
117
|
+
// 从控制器生成路径
|
118
|
+
for (const controller of controllers) {
|
119
|
+
// 获取控制器的基础路径(从 @Controller 装饰器)
|
120
|
+
const HEST_CONTROLLER_KEY = Symbol.for('hest:controller');
|
121
|
+
const controllerMetadata = Reflect.getMetadata(HEST_CONTROLLER_KEY, controller);
|
122
|
+
const controllerPath = controllerMetadata?.path || '';
|
123
|
+
console.log(`Controller ${controller.name} path:`, controllerPath);
|
124
|
+
generator.addController(controller, controllerPath);
|
125
|
+
}
|
126
|
+
// 生成 OpenAPI 文档
|
127
|
+
const openApiDoc = generator.generateDocument();
|
128
|
+
// 调试:打印生成的文档
|
129
|
+
console.log('Generated OpenAPI Document:', JSON.stringify(openApiDoc, null, 2));
|
130
|
+
// 首先设置 OpenAPI JSON 端点
|
131
|
+
const openApiPath = '/openapi.json';
|
132
|
+
app.get(openApiPath, (c) => {
|
133
|
+
return c.json(openApiDoc);
|
134
|
+
});
|
135
|
+
// 然后设置 Scalar,指向 OpenAPI JSON 端点
|
136
|
+
const { path = '/docs', enableMarkdown = false, markdownPath = '/llms.txt', ...middlewareConfig } = scalarConfig;
|
137
|
+
// 设置 Scalar 中间件,使用 URL 而不是直接传递对象
|
138
|
+
const scalarMiddleware = createScalarMiddleware({
|
139
|
+
...middlewareConfig,
|
140
|
+
url: openApiPath, // 使用 URL 而不是 content
|
141
|
+
});
|
142
|
+
app.get(path, scalarMiddleware);
|
143
|
+
// 如果启用了 Markdown 导出
|
144
|
+
if (enableMarkdown) {
|
145
|
+
const markdownMiddleware = createMarkdownMiddleware(openApiDoc);
|
146
|
+
app.get(markdownPath, markdownMiddleware);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
//# sourceMappingURL=scalar.middleware.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"scalar.middleware.js","sourceRoot":"","sources":["../src/scalar.middleware.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/**
|
2
|
+
* Scalar 模块
|
3
|
+
*
|
4
|
+
* 这个模块可以在 HestJS 应用中导入,提供 Scalar API 文档功能
|
5
|
+
*/
|
6
|
+
export declare class ScalarModule {
|
7
|
+
/**
|
8
|
+
* 静态方法:配置 Scalar 模块
|
9
|
+
*
|
10
|
+
* @param config Scalar 配置选项
|
11
|
+
* @returns 配置后的模块
|
12
|
+
*/
|
13
|
+
static forRoot(config: any): any;
|
14
|
+
}
|
15
|
+
//# sourceMappingURL=scalar.module.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"scalar.module.d.ts","sourceRoot":"","sources":["../src/scalar.module.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,qBAIa,YAAY;IACvB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG;CAajC"}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
var ScalarModule_1;
|
8
|
+
import { Module } from '@hestjs/core';
|
9
|
+
/**
|
10
|
+
* Scalar 模块
|
11
|
+
*
|
12
|
+
* 这个模块可以在 HestJS 应用中导入,提供 Scalar API 文档功能
|
13
|
+
*/
|
14
|
+
let ScalarModule = ScalarModule_1 = class ScalarModule {
|
15
|
+
/**
|
16
|
+
* 静态方法:配置 Scalar 模块
|
17
|
+
*
|
18
|
+
* @param config Scalar 配置选项
|
19
|
+
* @returns 配置后的模块
|
20
|
+
*/
|
21
|
+
static forRoot(config) {
|
22
|
+
// 这里可以根据需要扩展,目前主要通过中间件使用
|
23
|
+
return {
|
24
|
+
module: ScalarModule_1,
|
25
|
+
providers: [
|
26
|
+
{
|
27
|
+
provide: 'SCALAR_CONFIG',
|
28
|
+
useValue: config,
|
29
|
+
},
|
30
|
+
],
|
31
|
+
exports: ['SCALAR_CONFIG'],
|
32
|
+
};
|
33
|
+
}
|
34
|
+
};
|
35
|
+
ScalarModule = ScalarModule_1 = __decorate([
|
36
|
+
Module({
|
37
|
+
providers: [],
|
38
|
+
exports: [],
|
39
|
+
})
|
40
|
+
], ScalarModule);
|
41
|
+
export { ScalarModule };
|
42
|
+
//# sourceMappingURL=scalar.module.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"scalar.module.js","sourceRoot":"","sources":["../src/scalar.module.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;GAIG;AAKI,IAAM,YAAY,oBAAlB,MAAM,YAAY;IACvB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,MAAW;QACxB,yBAAyB;QACzB,OAAO;YACL,MAAM,EAAE,cAAY;YACpB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,eAAe;oBACxB,QAAQ,EAAE,MAAM;iBACjB;aACF;YACD,OAAO,EAAE,CAAC,eAAe,CAAC;SAC3B,CAAC;IACJ,CAAC;CACF,CAAA;AApBY,YAAY;IAJxB,MAAM,CAAC;QACN,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,EAAE;KACZ,CAAC;GACW,YAAY,CAoBxB"}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
/**
|
2
|
+
* 生成基础 OpenAPI 文档结构
|
3
|
+
*/
|
4
|
+
export declare function generateBaseOpenApiSpec(config: {
|
5
|
+
title: string;
|
6
|
+
version: string;
|
7
|
+
description?: string;
|
8
|
+
servers?: Array<{
|
9
|
+
url: string;
|
10
|
+
description?: string;
|
11
|
+
}>;
|
12
|
+
}): object;
|
13
|
+
/**
|
14
|
+
* 从类元数据生成 OpenAPI schema
|
15
|
+
*/
|
16
|
+
export declare function generateSchemaFromClass(target: any): object;
|
17
|
+
/**
|
18
|
+
* 从控制器生成 OpenAPI 路径
|
19
|
+
*/
|
20
|
+
export declare function generatePathsFromController(controller: any, basePath?: string): object;
|
21
|
+
/**
|
22
|
+
* 合并多个 OpenAPI 文档
|
23
|
+
*/
|
24
|
+
export declare function mergeOpenApiSpecs(...specs: object[]): object;
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD,GAAG,MAAM,CAsBT;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CA+B3D;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,GAAG,EAAE,QAAQ,GAAE,MAAW,GAAG,MAAM,CA0B1F;AAyFD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAkD5D"}
|