Skip to content

Commit 8e928ac

Browse files
committed
🧹 chore: merge main
2 parents ebf0e54 + 65bae78 commit 8e928ac

File tree

2 files changed

+103
-96
lines changed

2 files changed

+103
-96
lines changed

src/index.ts

Lines changed: 75 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,118 @@
11
/* eslint-disable @typescript-eslint/ban-ts-comment */
2-
import { Elysia, type InternalRoute } from "elysia";
2+
import { Elysia, type InternalRoute } from 'elysia'
33

4-
import { SwaggerUIRender } from "./swagger";
5-
import { ScalarRender } from "./scalar";
4+
import { SwaggerUIRender } from './swagger'
5+
import { ScalarRender } from './scalar'
66

7-
import { filterPaths, registerSchemaPath } from "./utils";
7+
import { filterPaths, registerSchemaPath } from './utils'
88

9-
import type { OpenAPIV3 } from "openapi-types";
10-
import type { ReferenceConfiguration } from "./scalar/types";
11-
import type { ElysiaSwaggerConfig } from "./types";
9+
import type { OpenAPIV3 } from 'openapi-types'
10+
import type { ReferenceConfiguration } from './scalar/types'
11+
import type { ElysiaSwaggerConfig } from './types'
1212

1313
/**
1414
* Plugin for [elysia](https://github.com/elysiajs/elysia) that auto-generate Swagger page.
1515
*
1616
* @see https://github.com/elysiajs/elysia-swagger
1717
*/
18-
export const swagger = async <Path extends string = "/swagger">(
18+
export const swagger = async <Path extends string = '/swagger'>(
1919
{
20-
provider = "scalar",
21-
scalarVersion = "latest",
22-
scalarCDN = "",
20+
provider = 'scalar',
21+
scalarVersion = 'latest',
22+
scalarCDN = '',
2323
scalarConfig = {},
2424
documentation = {},
25-
version = "5.9.0",
25+
version = '5.9.0',
2626
excludeStaticFile = true,
27-
path = "/swagger" as Path,
27+
path = '/swagger' as Path,
2828
exclude = [],
2929
swaggerOptions = {},
3030
theme = `https://unpkg.com/swagger-ui-dist@${version}/swagger-ui.css`,
3131
autoDarkMode = true,
32-
excludeMethods = ["OPTIONS"],
33-
excludeTags = [],
32+
excludeMethods = ['OPTIONS'],
33+
excludeTags = []
3434
}: ElysiaSwaggerConfig<Path> = {
35-
provider: "scalar",
36-
scalarVersion: "latest",
37-
scalarCDN: "",
35+
provider: 'scalar',
36+
scalarVersion: 'latest',
37+
scalarCDN: '',
3838
scalarConfig: {},
3939
documentation: {},
40-
version: "5.9.0",
40+
version: '5.9.0',
4141
excludeStaticFile: true,
42-
path: "/swagger" as Path,
42+
path: '/swagger' as Path,
4343
exclude: [],
4444
swaggerOptions: {},
4545
autoDarkMode: true,
46-
excludeMethods: ["OPTIONS"],
47-
excludeTags: [],
48-
},
46+
excludeMethods: ['OPTIONS'],
47+
excludeTags: []
48+
}
4949
) => {
50-
const schema = {};
51-
let totalRoutes = 0;
50+
const schema = {}
51+
let totalRoutes = 0
5252

5353
if (!version)
54-
version = `https://unpkg.com/swagger-ui-dist@${version}/swagger-ui.css`;
54+
version = `https://unpkg.com/swagger-ui-dist@${version}/swagger-ui.css`
5555

5656
const info = {
57-
title: "Elysia Documentation",
58-
description: "Development documentation",
59-
version: "0.0.0",
60-
...documentation.info,
61-
};
57+
title: 'Elysia Documentation',
58+
description: 'Development documentation',
59+
version: '0.0.0',
60+
...documentation.info
61+
}
6262

63-
const relativePath = path.startsWith("/") ? path.slice(1) : path;
63+
const relativePath = path.startsWith('/') ? path.slice(1) : path
6464

65-
const app = new Elysia({ name: "@elysiajs/swagger" });
65+
const app = new Elysia({ name: '@elysiajs/swagger' })
6666

6767
app.get(path, function documentation() {
6868
const combinedSwaggerOptions = {
6969
url: `${relativePath}/json`,
70-
dom_id: "#swagger-ui",
71-
...swaggerOptions,
72-
};
70+
dom_id: '#swagger-ui',
71+
...swaggerOptions
72+
}
7373

7474
const stringifiedSwaggerOptions = JSON.stringify(
7575
combinedSwaggerOptions,
7676
(key, value) => {
77-
if (typeof value == "function") return undefined;
77+
if (typeof value == 'function') return undefined
7878

79-
return value;
80-
},
81-
);
79+
return value
80+
}
81+
)
8282

8383
const scalarConfiguration: ReferenceConfiguration = {
8484
spec: {
8585
...scalarConfig.spec,
86-
url: `${relativePath}/json`,
86+
url: `${relativePath}/json`
8787
},
88-
...scalarConfig,
89-
};
88+
...scalarConfig
89+
}
9090

9191
return new Response(
92-
provider === "swagger-ui"
92+
provider === 'swagger-ui'
9393
? SwaggerUIRender(
9494
info,
9595
version,
9696
theme,
9797
stringifiedSwaggerOptions,
98-
autoDarkMode,
98+
autoDarkMode
9999
)
100100
: ScalarRender(scalarVersion, scalarConfiguration, scalarCDN),
101101
{
102102
headers: {
103-
"content-type": "text/html; charset=utf8",
104-
},
105-
},
106-
);
107-
}).get(path === "/" ? "/json" : `${path}/json`, function openAPISchema() {
103+
'content-type': 'text/html; charset=utf8'
104+
}
105+
}
106+
)
107+
}).get(path === '/' ? '/json' : `${path}/json`, function openAPISchema() {
108108
// @ts-expect-error Private property
109-
const routes = app.getGlobalRoutes() as InternalRoute[];
109+
const routes = app.getGlobalRoutes() as InternalRoute[]
110110

111111
if (routes.length !== totalRoutes) {
112-
totalRoutes = routes.length;
112+
totalRoutes = routes.length
113113

114114
routes.forEach((route: InternalRoute) => {
115-
if (excludeMethods.includes(route.method)) return;
115+
if (excludeMethods.includes(route.method)) return
116116

117117
registerSchemaPath({
118118
schema,
@@ -121,45 +121,45 @@ export const swagger = async <Path extends string = "/swagger">(
121121
path: route.path,
122122
// @ts-ignore
123123
models: app.definitions?.type,
124-
contentType: route.hooks.type,
125-
});
126-
});
124+
contentType: route.hooks.type
125+
})
126+
})
127127
}
128128

129129
return {
130-
openapi: "3.0.3",
130+
openapi: '3.0.3',
131131
...{
132132
...documentation,
133133
tags: documentation.tags?.filter(
134-
(tag) => !excludeTags?.includes(tag?.name),
134+
(tag) => !excludeTags?.includes(tag?.name)
135135
),
136136
info: {
137-
title: "Elysia Documentation",
138-
description: "Development documentation",
139-
version: "0.0.0",
140-
...documentation.info,
141-
},
137+
title: 'Elysia Documentation',
138+
description: 'Development documentation',
139+
version: '0.0.0',
140+
...documentation.info
141+
}
142142
},
143143
paths: {
144-
...filterPaths(schema, {
144+
...filterPaths(schema, relativePath, {
145145
excludeStaticFile,
146-
exclude: Array.isArray(exclude) ? exclude : [exclude],
146+
exclude: Array.isArray(exclude) ? exclude : [exclude]
147147
}),
148-
...documentation.paths,
148+
...documentation.paths
149149
},
150150
components: {
151151
...documentation.components,
152152
schemas: {
153153
// @ts-ignore
154154
...app.definitions?.type,
155-
...documentation.components?.schemas,
156-
},
157-
},
158-
} satisfies OpenAPIV3.Document;
159-
});
155+
...documentation.components?.schemas
156+
}
157+
}
158+
} satisfies OpenAPIV3.Document
159+
})
160160

161-
// This is intentional to prevent deeply nested type
162-
return app;
163-
};
161+
return app
162+
}
164163

165-
export default swagger;
164+
export type { ElysiaSwaggerConfig }
165+
export default swagger

src/utils.ts

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable @typescript-eslint/ban-ts-comment */
22
/* eslint-disable @typescript-eslint/no-unused-vars */
3+
import path from 'path'
34
import type { HTTPMethod, LocalHook } from 'elysia'
45

56
import { Kind, type TSchema } from '@sinclair/typebox'
@@ -295,30 +296,36 @@ export const registerSchemaPath = ({
295296
}
296297

297298
export const filterPaths = (
298-
paths: Record<string, any>,
299-
{
300-
excludeStaticFile = true,
301-
exclude = []
302-
}: {
303-
excludeStaticFile: boolean
304-
exclude: (string | RegExp)[]
305-
}
299+
paths: Record<string, any>,
300+
docsPath: string,
301+
{
302+
excludeStaticFile = true,
303+
exclude = []
304+
}: {
305+
excludeStaticFile: boolean
306+
exclude: (string | RegExp)[]
307+
}
306308
) => {
307309
const newPaths: Record<string, any> = {}
308310

309-
for (const [key, value] of Object.entries(paths))
310-
if (
311-
!exclude.some((x) => {
312-
if (typeof x === 'string') return key === x
313-
314-
return x.test(key)
315-
}) &&
316-
!key.includes('/swagger') &&
317-
!key.includes('*') &&
318-
(excludeStaticFile ? !key.includes('.') : true)
319-
) {
320-
Object.keys(value).forEach((method) => {
321-
const schema = value[method]
311+
// exclude docs path and OpenAPI json path
312+
const excludePaths = [`/${docsPath}`, `/${docsPath}/json`].map((p) =>
313+
path.normalize(p)
314+
)
315+
316+
for (const [key, value] of Object.entries(paths))
317+
if (
318+
!exclude.some((x) => {
319+
if (typeof x === 'string') return key === x
320+
321+
return x.test(key)
322+
}) &&
323+
!excludePaths.includes(key) &&
324+
!key.includes('*') &&
325+
(excludeStaticFile ? !key.includes('.') : true)
326+
) {
327+
Object.keys(value).forEach((method) => {
328+
const schema = value[method]
322329

323330
if (key.includes('{')) {
324331
if (!schema.parameters) schema.parameters = []

0 commit comments

Comments
 (0)