@scalar/hono-api-reference 0.12.12 → 0.12.14
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/dist/scalar.d.ts +9 -7
- package/dist/scalar.d.ts.map +1 -1
- package/dist/scalar.js +6 -4
- package/dist/scalar.test.js +59 -0
- package/package.json +7 -7
package/dist/scalar.d.ts
CHANGED
|
@@ -3,23 +3,23 @@ import { Hono } from 'hono';
|
|
|
3
3
|
import type { ApiReferenceConfiguration } from './types.js';
|
|
4
4
|
type Configuration<E extends Env> = Partial<ApiReferenceConfiguration> | ((c: Context<E>) => Partial<ApiReferenceConfiguration> | Promise<Partial<ApiReferenceConfiguration>>);
|
|
5
5
|
/**
|
|
6
|
-
* An OpenAPI document.
|
|
6
|
+
* An OpenAPI or AsyncAPI document.
|
|
7
7
|
*
|
|
8
8
|
* Typed loosely as an object on purpose, so it accepts both plain document objects and the typed
|
|
9
9
|
* return values of generators like Zod OpenAPI Hono's `getOpenAPI31Document()`, whose interfaces do
|
|
10
10
|
* not carry an index signature.
|
|
11
11
|
*/
|
|
12
|
-
type
|
|
12
|
+
type ApiDocument = object;
|
|
13
13
|
/**
|
|
14
14
|
* The configuration for `Scalar.serve`.
|
|
15
15
|
*
|
|
16
|
-
* On top of the universal API Reference configuration, this takes the
|
|
16
|
+
* On top of the universal API Reference configuration, this takes the API `document` to render
|
|
17
17
|
* and expose. Because `Scalar.serve` sources the document itself, `content` and `url` are managed for
|
|
18
18
|
* you and are not accepted here.
|
|
19
19
|
*/
|
|
20
20
|
export type ServeConfiguration<E extends Env> = Omit<Partial<ApiReferenceConfiguration>, 'content' | 'url'> & {
|
|
21
21
|
/**
|
|
22
|
-
* The OpenAPI document to render and serve.
|
|
22
|
+
* The OpenAPI or AsyncAPI document to render and serve.
|
|
23
23
|
*
|
|
24
24
|
* Pass the document directly, or a function that returns it. The function receives the Hono
|
|
25
25
|
* `Context`, so it can read `c.env` or `c.req` and build the document per request. This is also how
|
|
@@ -32,9 +32,11 @@ export type ServeConfiguration<E extends Env> = Omit<Partial<ApiReferenceConfigu
|
|
|
32
32
|
* }))
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
|
-
document:
|
|
35
|
+
document: ApiDocument | ((c: Context<E>) => ApiDocument | Promise<ApiDocument>);
|
|
36
36
|
/**
|
|
37
|
-
* Path, relative to the mount point, where the
|
|
37
|
+
* Path, relative to the mount point, where the API document is served as JSON.
|
|
38
|
+
*
|
|
39
|
+
* Use `/asyncapi.json` for an AsyncAPI document. The default stays `/openapi.json` for either format.
|
|
38
40
|
*
|
|
39
41
|
* @default '/openapi.json'
|
|
40
42
|
*/
|
|
@@ -44,7 +46,7 @@ export type ServeConfiguration<E extends Env> = Omit<Partial<ApiReferenceConfigu
|
|
|
44
46
|
* Render the Scalar API Reference in a Hono app.
|
|
45
47
|
*
|
|
46
48
|
* Use `Scalar(...)` as a middleware to render the reference on a route, or `Scalar.serve(...)` to
|
|
47
|
-
* serve the reference and its OpenAPI document together from a single mount.
|
|
49
|
+
* serve the reference and its OpenAPI or AsyncAPI document together from a single mount.
|
|
48
50
|
*/
|
|
49
51
|
export declare const Scalar: (<E extends Env>(configOrResolver: Configuration<E>) => MiddlewareHandler<E>) & {
|
|
50
52
|
serve: <E extends Env>(options: ServeConfiguration<E>) => Hono<E>;
|
package/dist/scalar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scalar.d.ts","sourceRoot":"","sources":["../src/scalar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AA+DxD,KAAK,aAAa,CAAC,CAAC,SAAS,GAAG,IAC5B,OAAO,CAAC,yBAAyB,CAAC,GAClC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,yBAAyB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAA;AA2BzG;;;;;;GAMG;AACH,KAAK,
|
|
1
|
+
{"version":3,"file":"scalar.d.ts","sourceRoot":"","sources":["../src/scalar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AA+DxD,KAAK,aAAa,CAAC,CAAC,SAAS,GAAG,IAC5B,OAAO,CAAC,yBAAyB,CAAC,GAClC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,yBAAyB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAA;AA2BzG;;;;;;GAMG;AACH,KAAK,WAAW,GAAG,MAAM,CAAA;AAEzB;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG;IAC5G;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAA;IAC/E;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAkDD;;;;;GAKG;AACH,eAAO,MAAM,MAAM,IAtHO,CAAC,SAAS,GAAG,oBAAoB,aAAa,CAAC,CAAC,CAAC,KAAG,iBAAiB,CAAC,CAAC,CAAC;YAmF7E,CAAC,SAAS,GAAG,WAAW,kBAAkB,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAAC;CAmCC,CAAA"}
|
package/dist/scalar.js
CHANGED
|
@@ -82,12 +82,14 @@ const scalarMiddleware = (configOrResolver) => {
|
|
|
82
82
|
};
|
|
83
83
|
};
|
|
84
84
|
/**
|
|
85
|
-
* Serve the API Reference and its OpenAPI document together as a mountable Hono app.
|
|
85
|
+
* Serve the API Reference and its OpenAPI or AsyncAPI document together as a mountable Hono app.
|
|
86
86
|
*
|
|
87
87
|
* Unlike the `Scalar` middleware — which only renders the reference and expects the document to live
|
|
88
88
|
* somewhere else — this exposes both from a single call, so you do not have to wire up a separate
|
|
89
89
|
* document route and keep its `url` in sync.
|
|
90
90
|
*
|
|
91
|
+
* This serves an existing document or calls your factory; it does not generate a document from routes.
|
|
92
|
+
*
|
|
91
93
|
* Mount it with `app.route(...)`:
|
|
92
94
|
*
|
|
93
95
|
* @example
|
|
@@ -95,14 +97,14 @@ const scalarMiddleware = (configOrResolver) => {
|
|
|
95
97
|
* import { Scalar } from '@scalar/hono-api-reference'
|
|
96
98
|
*
|
|
97
99
|
* // Serves the reference at `/scalar` and the document at `/scalar/openapi.json`
|
|
98
|
-
* app.route('/scalar', Scalar.serve({ document:
|
|
100
|
+
* app.route('/scalar', Scalar.serve({ document: myApiDocument }))
|
|
99
101
|
* ```
|
|
100
102
|
*/
|
|
101
103
|
const scalarServe = (options) => {
|
|
102
104
|
const { document, documentPath = '/openapi.json', ...rest } = options;
|
|
103
105
|
const app = new Hono();
|
|
104
106
|
const resolveDocument = (c) => typeof document === 'function' ? document(c) : document;
|
|
105
|
-
// Expose the
|
|
107
|
+
// Expose the API document as JSON, so a single call powers both the reference and its source.
|
|
106
108
|
app.get(documentPath, async (c) => c.json(await resolveDocument(c)));
|
|
107
109
|
// Render the reference, pointing it at the document we expose above.
|
|
108
110
|
app.get('/', (c) => {
|
|
@@ -122,6 +124,6 @@ const scalarServe = (options) => {
|
|
|
122
124
|
* Render the Scalar API Reference in a Hono app.
|
|
123
125
|
*
|
|
124
126
|
* Use `Scalar(...)` as a middleware to render the reference on a route, or `Scalar.serve(...)` to
|
|
125
|
-
* serve the reference and its OpenAPI document together from a single mount.
|
|
127
|
+
* serve the reference and its OpenAPI or AsyncAPI document together from a single mount.
|
|
126
128
|
*/
|
|
127
129
|
export const Scalar = Object.assign(scalarMiddleware, { serve: scalarServe });
|
package/dist/scalar.test.js
CHANGED
|
@@ -206,6 +206,65 @@ describe('Scalar', () => {
|
|
|
206
206
|
expect(text).toContain('Test API');
|
|
207
207
|
expect(text).toContain('deepSpace');
|
|
208
208
|
});
|
|
209
|
+
it.each([
|
|
210
|
+
{ mount: '/', source: 'object' },
|
|
211
|
+
{ mount: '/api/reference', source: 'object' },
|
|
212
|
+
{ mount: '/', source: 'factory' },
|
|
213
|
+
{ mount: '/api/reference', source: 'factory' },
|
|
214
|
+
{ mount: '/', source: 'async factory' },
|
|
215
|
+
{ mount: '/api/reference', source: 'async factory' },
|
|
216
|
+
])('serves an AsyncAPI $source mounted at $mount', async ({ mount, source }) => {
|
|
217
|
+
const document = {
|
|
218
|
+
asyncapi: '3.0.0',
|
|
219
|
+
info: { title: 'WebSocket Chat', version: '1.0.0' },
|
|
220
|
+
servers: {
|
|
221
|
+
local: { host: 'localhost:3000', protocol: 'ws' },
|
|
222
|
+
},
|
|
223
|
+
channels: {
|
|
224
|
+
chat: {
|
|
225
|
+
address: '/chat',
|
|
226
|
+
servers: [{ $ref: '#/servers/local' }],
|
|
227
|
+
messages: {
|
|
228
|
+
text: { payload: { type: 'string' } },
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
operations: {
|
|
233
|
+
receiveMessage: {
|
|
234
|
+
action: 'receive',
|
|
235
|
+
channel: { $ref: '#/channels/chat' },
|
|
236
|
+
messages: [{ $ref: '#/channels/chat/messages/text' }],
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
const documentUrl = mount === '/' ? '/asyncapi.json' : '/api/reference/asyncapi.json';
|
|
241
|
+
const app = new Hono();
|
|
242
|
+
const reference = Scalar.serve({
|
|
243
|
+
document: source === 'object'
|
|
244
|
+
? document
|
|
245
|
+
: (c) => {
|
|
246
|
+
expect(c.req.path).toBe(documentUrl);
|
|
247
|
+
return source === 'async factory' ? Promise.resolve(document) : document;
|
|
248
|
+
},
|
|
249
|
+
documentPath: '/asyncapi.json',
|
|
250
|
+
});
|
|
251
|
+
if (mount === '/') {
|
|
252
|
+
app.route('/', reference);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
const api = new Hono();
|
|
256
|
+
api.route('/reference', reference);
|
|
257
|
+
app.route('/api', api);
|
|
258
|
+
}
|
|
259
|
+
const html = await app.request(mount);
|
|
260
|
+
expect(html.status).toBe(200);
|
|
261
|
+
expect(html.headers.get('content-type')).toContain('text/html');
|
|
262
|
+
expect(await html.text()).toContain(`"url": "${documentUrl}"`);
|
|
263
|
+
const json = await app.request(documentUrl);
|
|
264
|
+
expect(json.status).toBe(200);
|
|
265
|
+
expect(json.headers.get('content-type')).toContain('application/json');
|
|
266
|
+
expect(await json.json()).toStrictEqual(document);
|
|
267
|
+
});
|
|
209
268
|
describe('serve', () => {
|
|
210
269
|
const document = {
|
|
211
270
|
openapi: '3.1.0',
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"url": "git+https://github.com/scalar/scalar.git",
|
|
11
11
|
"directory": "integrations/hono"
|
|
12
12
|
},
|
|
13
|
-
"version": "0.12.
|
|
13
|
+
"version": "0.12.14",
|
|
14
14
|
"engines": {
|
|
15
15
|
"node": ">=22"
|
|
16
16
|
},
|
|
@@ -44,15 +44,15 @@
|
|
|
44
44
|
"documentation": "https://scalar.com/products/api-references/integrations/hono"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@scalar/client-side-rendering": "0.4.
|
|
47
|
+
"@scalar/client-side-rendering": "0.4.13"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@hono/node-server": "^2.1.
|
|
50
|
+
"@hono/node-server": "^2.1.5",
|
|
51
51
|
"@hono/zod-openapi": "^1.6.3",
|
|
52
|
-
"@scalar/openapi-to-markdown": "1.
|
|
53
|
-
"hono": "^4.13.
|
|
54
|
-
"vite": "8.
|
|
55
|
-
"vitest": "4.1.
|
|
52
|
+
"@scalar/openapi-to-markdown": "1.7.0",
|
|
53
|
+
"hono": "^4.13.13",
|
|
54
|
+
"vite": "8.3.4",
|
|
55
|
+
"vitest": "4.1.12"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"hono": "^4.12.5"
|