@syncular/server-hono 0.0.6-225 → 0.0.6-228
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 +26 -0
- package/dist/openapi.d.ts +30 -3
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +40 -0
- package/dist/openapi.js.map +1 -1
- package/package.json +7 -6
- package/src/__tests__/openapi.test.ts +78 -0
- package/src/openapi.ts +67 -2
package/README.md
CHANGED
|
@@ -56,6 +56,32 @@ Use a function origin only when you need dynamic policy logic.
|
|
|
56
56
|
When `routes.websocket.allowedOrigins` is unset, realtime websocket upgrades
|
|
57
57
|
inherit static `routes.cors` origins automatically.
|
|
58
58
|
|
|
59
|
+
## OpenAPI and Scalar
|
|
60
|
+
|
|
61
|
+
Serve a generated OpenAPI document:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { Hono } from 'hono';
|
|
65
|
+
import { createOpenAPIHandler } from '@syncular/server-hono';
|
|
66
|
+
|
|
67
|
+
const app = new Hono();
|
|
68
|
+
app.get('/openapi.json', createOpenAPIHandler(app, { title: 'Syncular API' }));
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Or mount both the OpenAPI document and a Scalar reference page:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { Hono } from 'hono';
|
|
75
|
+
import { createOpenAPIDocsRoutes } from '@syncular/server-hono';
|
|
76
|
+
|
|
77
|
+
const app = new Hono();
|
|
78
|
+
app.route('/', createOpenAPIDocsRoutes(app, { title: 'Syncular API' }));
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
That serves:
|
|
82
|
+
- `/openapi.json`
|
|
83
|
+
- `/spec`
|
|
84
|
+
|
|
59
85
|
## Links
|
|
60
86
|
|
|
61
87
|
- GitHub: https://github.com/syncular/syncular
|
package/dist/openapi.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides utilities for generating and serving OpenAPI specifications.
|
|
5
5
|
*/
|
|
6
|
-
import type
|
|
7
|
-
interface OpenAPIConfig {
|
|
6
|
+
import { type Handler, Hono } from 'hono';
|
|
7
|
+
export interface OpenAPIConfig {
|
|
8
8
|
title?: string;
|
|
9
9
|
version?: string;
|
|
10
10
|
description?: string;
|
|
@@ -13,6 +13,15 @@ interface OpenAPIConfig {
|
|
|
13
13
|
description?: string;
|
|
14
14
|
}>;
|
|
15
15
|
}
|
|
16
|
+
export interface ScalarReferenceConfig {
|
|
17
|
+
url?: string;
|
|
18
|
+
cdn?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface OpenAPIDocsRoutesConfig extends OpenAPIConfig {
|
|
21
|
+
openAPIPath?: string;
|
|
22
|
+
scalarPath?: string;
|
|
23
|
+
scalar?: ScalarReferenceConfig;
|
|
24
|
+
}
|
|
16
25
|
/**
|
|
17
26
|
* Create an OpenAPI spec handler that can be used with Hono routes.
|
|
18
27
|
*
|
|
@@ -36,10 +45,28 @@ interface OpenAPIConfig {
|
|
|
36
45
|
* ```
|
|
37
46
|
*/
|
|
38
47
|
export declare function createOpenAPIHandler(app: Hono, config?: OpenAPIConfig): import("hono").MiddlewareHandler<import("hono/types").BlankEnv, "/", import("hono/types").BlankInput>;
|
|
48
|
+
/**
|
|
49
|
+
* Create a Scalar API reference handler that points at an OpenAPI document.
|
|
50
|
+
*/
|
|
51
|
+
export declare function createScalarReferenceHandler(config?: ScalarReferenceConfig): Handler;
|
|
52
|
+
/**
|
|
53
|
+
* Create a small Hono app that serves both `/openapi.json` and `/spec`.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* import { Hono } from 'hono';
|
|
58
|
+
* import { createOpenAPIDocsRoutes } from '@syncular/server-hono';
|
|
59
|
+
*
|
|
60
|
+
* const app = new Hono();
|
|
61
|
+
* app.route('/', createOpenAPIDocsRoutes(app, {
|
|
62
|
+
* title: 'Syncular API',
|
|
63
|
+
* }));
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function createOpenAPIDocsRoutes(app: Hono, config?: OpenAPIDocsRoutesConfig): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
39
67
|
/**
|
|
40
68
|
* Generate OpenAPI document from a Hono app instance.
|
|
41
69
|
* This is useful for build-time spec generation.
|
|
42
70
|
*/
|
|
43
71
|
export declare function generateOpenAPIDocument(app: Hono, config?: OpenAPIConfig): Promise<unknown>;
|
|
44
|
-
export {};
|
|
45
72
|
//# sourceMappingURL=openapi.d.ts.map
|
package/dist/openapi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM1C,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,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;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAwB,SAAQ,aAAa;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AAMD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,GAAE,aAAkB,yGAazE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,GAAE,qBAA0B,GACjC,OAAO,CAKT;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,IAAI,EACT,MAAM,GAAE,uBAA4B,8EAgBrC;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,IAAI,EACT,MAAM,GAAE,aAAkB,GACzB,OAAO,CAAC,OAAO,CAAC,CAalB"}
|
package/dist/openapi.js
CHANGED
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides utilities for generating and serving OpenAPI specifications.
|
|
5
5
|
*/
|
|
6
|
+
import { Scalar } from '@scalar/hono-api-reference';
|
|
7
|
+
import { Hono } from 'hono';
|
|
6
8
|
import { generateSpecs, openAPIRouteHandler } from 'hono-openapi';
|
|
9
|
+
const DEFAULT_SCALAR_CDN = 'https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest';
|
|
10
|
+
function normalizeRoutePath(path) {
|
|
11
|
+
return path.startsWith('/') ? path : `/${path}`;
|
|
12
|
+
}
|
|
7
13
|
/**
|
|
8
14
|
* Create an OpenAPI spec handler that can be used with Hono routes.
|
|
9
15
|
*
|
|
@@ -39,6 +45,40 @@ export function createOpenAPIHandler(app, config = {}) {
|
|
|
39
45
|
},
|
|
40
46
|
});
|
|
41
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Create a Scalar API reference handler that points at an OpenAPI document.
|
|
50
|
+
*/
|
|
51
|
+
export function createScalarReferenceHandler(config = {}) {
|
|
52
|
+
return Scalar({
|
|
53
|
+
url: config.url ?? '/openapi.json',
|
|
54
|
+
cdn: config.cdn ?? DEFAULT_SCALAR_CDN,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a small Hono app that serves both `/openapi.json` and `/spec`.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* import { Hono } from 'hono';
|
|
63
|
+
* import { createOpenAPIDocsRoutes } from '@syncular/server-hono';
|
|
64
|
+
*
|
|
65
|
+
* const app = new Hono();
|
|
66
|
+
* app.route('/', createOpenAPIDocsRoutes(app, {
|
|
67
|
+
* title: 'Syncular API',
|
|
68
|
+
* }));
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export function createOpenAPIDocsRoutes(app, config = {}) {
|
|
72
|
+
const docsApp = new Hono();
|
|
73
|
+
const openAPIPath = normalizeRoutePath(config.openAPIPath ?? '/openapi.json');
|
|
74
|
+
const scalarPath = normalizeRoutePath(config.scalarPath ?? '/spec');
|
|
75
|
+
docsApp.get(openAPIPath, createOpenAPIHandler(app, config));
|
|
76
|
+
docsApp.get(scalarPath, createScalarReferenceHandler({
|
|
77
|
+
url: config.scalar?.url ?? openAPIPath,
|
|
78
|
+
cdn: config.scalar?.cdn,
|
|
79
|
+
}));
|
|
80
|
+
return docsApp;
|
|
81
|
+
}
|
|
42
82
|
/**
|
|
43
83
|
* Generate OpenAPI document from a Hono app instance.
|
|
44
84
|
* This is useful for build-time spec generation.
|
package/dist/openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAgB,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAElE,MAAM,kBAAkB,GACtB,2DAA2D,CAAC;AAoB9D,SAAS,kBAAkB,CAAC,IAAY,EAAU;IAChD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;AAAA,CACjD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAS,EAAE,MAAM,GAAkB,EAAE,EAAE;IAC1E,OAAO,mBAAmB,CAAC,GAAG,EAAE;QAC9B,aAAa,EAAE;YACb,IAAI,EAAE;gBACJ,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,cAAc;gBACrC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO;gBAClC,WAAW,EACT,MAAM,CAAC,WAAW;oBAClB,4DAA4D;aAC/D;YACD,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB;KACF,CAAC,CAAC;AAAA,CACJ;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAC1C,MAAM,GAA0B,EAAE,EACzB;IACT,OAAO,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,eAAe;QAClC,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,kBAAkB;KACtC,CAAC,CAAC;AAAA,CACJ;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CACrC,GAAS,EACT,MAAM,GAA4B,EAAE,EACpC;IACA,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,WAAW,IAAI,eAAe,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,CAAC;IAEpE,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CACT,UAAU,EACV,4BAA4B,CAAC;QAC3B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,WAAW;QACtC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG;KACxB,CAAC,CACH,CAAC;IAEF,OAAO,OAAO,CAAC;AAAA,CAChB;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,GAAS,EACT,MAAM,GAAkB,EAAE,EACR;IAClB,OAAO,aAAa,CAAC,GAAG,EAAE;QACxB,aAAa,EAAE;YACb,IAAI,EAAE;gBACJ,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,cAAc;gBACrC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO;gBAClC,WAAW,EACT,MAAM,CAAC,WAAW;oBAClB,4DAA4D;aAC/D;YACD,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB;KACF,CAAC,CAAC;AAAA,CACJ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncular/server-hono",
|
|
3
|
-
"version": "0.0.6-
|
|
3
|
+
"version": "0.0.6-228",
|
|
4
4
|
"description": "Hono adapter for the Syncular server with OpenAPI support",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Benjamin Kniffler",
|
|
@@ -59,20 +59,21 @@
|
|
|
59
59
|
"release": "bunx syncular-publish"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
+
"@scalar/hono-api-reference": "^0.10.2",
|
|
62
63
|
"@hono/standard-validator": "^0.2.2",
|
|
63
64
|
"@standard-community/standard-json": "^0.3.5",
|
|
64
65
|
"@standard-community/standard-openapi": "^0.2.9",
|
|
65
|
-
"@syncular/console": "0.0.6-
|
|
66
|
-
"@syncular/core": "0.0.6-
|
|
67
|
-
"@syncular/server": "0.0.6-
|
|
66
|
+
"@syncular/console": "0.0.6-228",
|
|
67
|
+
"@syncular/core": "0.0.6-228",
|
|
68
|
+
"@syncular/server": "0.0.6-228",
|
|
68
69
|
"@types/json-schema": "^7.0.15",
|
|
69
70
|
"hono-openapi": "^1.2.0",
|
|
70
71
|
"openapi-types": "^12.1.3"
|
|
71
72
|
},
|
|
72
73
|
"devDependencies": {
|
|
73
74
|
"@syncular/config": "0.0.0",
|
|
74
|
-
"@syncular/dialect-pglite": "0.0.6-
|
|
75
|
-
"@syncular/server-dialect-postgres": "0.0.6-
|
|
75
|
+
"@syncular/dialect-pglite": "0.0.6-228",
|
|
76
|
+
"@syncular/server-dialect-postgres": "0.0.6-228",
|
|
76
77
|
"kysely": "*",
|
|
77
78
|
"zod": "*"
|
|
78
79
|
},
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import {
|
|
4
|
+
createOpenAPIDocsRoutes,
|
|
5
|
+
createOpenAPIHandler,
|
|
6
|
+
createScalarReferenceHandler,
|
|
7
|
+
} from '../openapi';
|
|
8
|
+
|
|
9
|
+
describe('OpenAPI helpers', () => {
|
|
10
|
+
it('serves an OpenAPI document with configured metadata', async () => {
|
|
11
|
+
const sourceApp = new Hono();
|
|
12
|
+
const app = new Hono();
|
|
13
|
+
|
|
14
|
+
app.get(
|
|
15
|
+
'/openapi.json',
|
|
16
|
+
createOpenAPIHandler(sourceApp, {
|
|
17
|
+
title: 'Test API',
|
|
18
|
+
version: '1.2.3',
|
|
19
|
+
description: 'Test description',
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const response = await app.request('/openapi.json');
|
|
24
|
+
expect(response.status).toBe(200);
|
|
25
|
+
|
|
26
|
+
const document = await response.json();
|
|
27
|
+
expect(document.info).toEqual({
|
|
28
|
+
title: 'Test API',
|
|
29
|
+
version: '1.2.3',
|
|
30
|
+
description: 'Test description',
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('serves a Scalar API reference that points at the configured document', async () => {
|
|
35
|
+
const app = new Hono();
|
|
36
|
+
app.get(
|
|
37
|
+
'/spec',
|
|
38
|
+
createScalarReferenceHandler({
|
|
39
|
+
url: '/docs/openapi.json',
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const response = await app.request('/spec');
|
|
44
|
+
expect(response.status).toBe(200);
|
|
45
|
+
|
|
46
|
+
const html = await response.text();
|
|
47
|
+
expect(html).toContain('/docs/openapi.json');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('creates paired OpenAPI and Scalar routes', async () => {
|
|
51
|
+
const sourceApp = new Hono();
|
|
52
|
+
const app = new Hono();
|
|
53
|
+
|
|
54
|
+
app.route(
|
|
55
|
+
'/',
|
|
56
|
+
createOpenAPIDocsRoutes(sourceApp, {
|
|
57
|
+
title: 'Docs API',
|
|
58
|
+
version: '9.9.9',
|
|
59
|
+
openAPIPath: '/api-docs.json',
|
|
60
|
+
scalarPath: '/docs',
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const openApiResponse = await app.request('/api-docs.json');
|
|
65
|
+
expect(openApiResponse.status).toBe(200);
|
|
66
|
+
const document = await openApiResponse.json();
|
|
67
|
+
expect(document.info).toEqual({
|
|
68
|
+
title: 'Docs API',
|
|
69
|
+
version: '9.9.9',
|
|
70
|
+
description: 'Sync infrastructure API for real-time data synchronization',
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const docsResponse = await app.request('/docs');
|
|
74
|
+
expect(docsResponse.status).toBe(200);
|
|
75
|
+
const html = await docsResponse.text();
|
|
76
|
+
expect(html).toContain('/api-docs.json');
|
|
77
|
+
});
|
|
78
|
+
});
|
package/src/openapi.ts
CHANGED
|
@@ -4,16 +4,35 @@
|
|
|
4
4
|
* Provides utilities for generating and serving OpenAPI specifications.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import { Scalar } from '@scalar/hono-api-reference';
|
|
8
|
+
import { type Handler, Hono } from 'hono';
|
|
8
9
|
import { generateSpecs, openAPIRouteHandler } from 'hono-openapi';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
const DEFAULT_SCALAR_CDN =
|
|
12
|
+
'https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest';
|
|
13
|
+
|
|
14
|
+
export interface OpenAPIConfig {
|
|
11
15
|
title?: string;
|
|
12
16
|
version?: string;
|
|
13
17
|
description?: string;
|
|
14
18
|
servers?: Array<{ url: string; description?: string }>;
|
|
15
19
|
}
|
|
16
20
|
|
|
21
|
+
export interface ScalarReferenceConfig {
|
|
22
|
+
url?: string;
|
|
23
|
+
cdn?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface OpenAPIDocsRoutesConfig extends OpenAPIConfig {
|
|
27
|
+
openAPIPath?: string;
|
|
28
|
+
scalarPath?: string;
|
|
29
|
+
scalar?: ScalarReferenceConfig;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function normalizeRoutePath(path: string): string {
|
|
33
|
+
return path.startsWith('/') ? path : `/${path}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
17
36
|
/**
|
|
18
37
|
* Create an OpenAPI spec handler that can be used with Hono routes.
|
|
19
38
|
*
|
|
@@ -51,6 +70,52 @@ export function createOpenAPIHandler(app: Hono, config: OpenAPIConfig = {}) {
|
|
|
51
70
|
});
|
|
52
71
|
}
|
|
53
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Create a Scalar API reference handler that points at an OpenAPI document.
|
|
75
|
+
*/
|
|
76
|
+
export function createScalarReferenceHandler(
|
|
77
|
+
config: ScalarReferenceConfig = {}
|
|
78
|
+
): Handler {
|
|
79
|
+
return Scalar({
|
|
80
|
+
url: config.url ?? '/openapi.json',
|
|
81
|
+
cdn: config.cdn ?? DEFAULT_SCALAR_CDN,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Create a small Hono app that serves both `/openapi.json` and `/spec`.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* import { Hono } from 'hono';
|
|
91
|
+
* import { createOpenAPIDocsRoutes } from '@syncular/server-hono';
|
|
92
|
+
*
|
|
93
|
+
* const app = new Hono();
|
|
94
|
+
* app.route('/', createOpenAPIDocsRoutes(app, {
|
|
95
|
+
* title: 'Syncular API',
|
|
96
|
+
* }));
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export function createOpenAPIDocsRoutes(
|
|
100
|
+
app: Hono,
|
|
101
|
+
config: OpenAPIDocsRoutesConfig = {}
|
|
102
|
+
) {
|
|
103
|
+
const docsApp = new Hono();
|
|
104
|
+
const openAPIPath = normalizeRoutePath(config.openAPIPath ?? '/openapi.json');
|
|
105
|
+
const scalarPath = normalizeRoutePath(config.scalarPath ?? '/spec');
|
|
106
|
+
|
|
107
|
+
docsApp.get(openAPIPath, createOpenAPIHandler(app, config));
|
|
108
|
+
docsApp.get(
|
|
109
|
+
scalarPath,
|
|
110
|
+
createScalarReferenceHandler({
|
|
111
|
+
url: config.scalar?.url ?? openAPIPath,
|
|
112
|
+
cdn: config.scalar?.cdn,
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
return docsApp;
|
|
117
|
+
}
|
|
118
|
+
|
|
54
119
|
/**
|
|
55
120
|
* Generate OpenAPI document from a Hono app instance.
|
|
56
121
|
* This is useful for build-time spec generation.
|