Merge branch 'main' into main

This commit is contained in:
Daniil Zotov
2024-09-26 13:24:30 +03:00
committed by GitHub
6 changed files with 86 additions and 15 deletions

View File

@@ -1,3 +1,10 @@
# 1.1.2 - 5 Sep 2024
Feature:
- add provenance publish
# 1.1.1 - 12 Aug 2024
Feature:
- add hide flag
# 1.1.0 - 16 Jul 2024
Change:
@@ -59,9 +66,9 @@ Change:
Change:
- Add support for Elysia 0.8
# 0.7.5
# 0.7.5
Improvement:
- #[59](https://github.com/elysiajs/elysia-swagger/pull/59) use relative path to swagger json #59
- #[59](https://github.com/elysiajs/elysia-swagger/pull/59) use relative path to swagger json #59
# 0.7.4 - 27 Oct 2023
Improvement:
@@ -78,7 +85,7 @@ Bug fix:
# 0.7.3 - 26 Sep 2023
Feature:
- [#19](https://github.com/elysiajs/elysia-swagger/pull/19) feat: handle nullish response types
- [#18](https://github.com/elysiajs/elysia-swagger/pull/18) swagger ui options
- [#18](https://github.com/elysiajs/elysia-swagger/pull/18) swagger ui options
Improvement:

BIN
bun.lockb

Binary file not shown.

View File

@@ -1,6 +1,6 @@
{
"name": "@elysiajs/swagger",
"version": "1.1.0",
"version": "1.1.2",
"description": "Plugin for Elysia to auto-generate Swagger page",
"author": {
"name": "saltyAom",
@@ -74,6 +74,7 @@
"typescript": "^5.5.3"
},
"dependencies": {
"openapi-types": "^12.1.3"
"openapi-types": "^12.1.3",
"pathe": "^1.1.2"
}
}
}

View File

@@ -66,7 +66,7 @@ export const swagger = async <Path extends string = '/swagger'>(
app.get(path, function documentation() {
const combinedSwaggerOptions = {
url: `${relativePath}/json`,
url: `/${relativePath}/json`,
dom_id: '#swagger-ui',
...swaggerOptions
}
@@ -83,7 +83,7 @@ export const swagger = async <Path extends string = '/swagger'>(
const scalarConfiguration: ReferenceConfiguration = {
spec: {
...scalarConfig.spec,
url: `${relativePath}/json`
url: `/${relativePath}/json`
},
...scalarConfig
}
@@ -111,7 +111,7 @@ export const swagger = async <Path extends string = '/swagger'>(
if (routes.length !== totalRoutes) {
const ALLOWED_METHODS = ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS', 'HEAD', 'PATCH', 'TRACE']
totalRoutes = routes.length
routes.forEach((route: InternalRoute) => {
if (route.hooks?.detail?.hide === true) return
// TODO: route.hooks?.detail?.hide !== false add ability to hide: false to prevent excluding

View File

@@ -1,4 +1,52 @@
import type { OpenAPIV3 } from 'openapi-types'
import { OpenAPIV3 } from 'openapi-types';
type DateTimeSchema = {
type: 'string';
format: 'date-time';
default?: string;
};
type SchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject;
function isSchemaObject(schema: SchemaObject): schema is OpenAPIV3.SchemaObject {
return 'type' in schema || 'properties' in schema || 'items' in schema;
}
function isDateTimeProperty(key: string, schema: OpenAPIV3.SchemaObject): boolean {
return (key === 'createdAt' || key === 'updatedAt') &&
'anyOf' in schema &&
Array.isArray(schema.anyOf);
}
function transformDateProperties(schema: SchemaObject): SchemaObject {
if (!isSchemaObject(schema) || typeof schema !== 'object' || schema === null) {
return schema;
}
const newSchema: OpenAPIV3.SchemaObject = { ...schema };
Object.entries(newSchema).forEach(([key, value]) => {
if (isSchemaObject(value)) {
if (isDateTimeProperty(key, value)) {
const dateTimeFormat = value.anyOf?.find((item): item is OpenAPIV3.SchemaObject =>
isSchemaObject(item) && item.format === 'date-time'
);
if (dateTimeFormat) {
const dateTimeSchema: DateTimeSchema = {
type: 'string',
format: 'date-time',
default: dateTimeFormat.default
};
(newSchema as Record<string, SchemaObject>)[key] = dateTimeSchema;
}
} else {
(newSchema as Record<string, SchemaObject>)[key] = transformDateProperties(value);
}
}
});
return newSchema;
}
export const SwaggerUIRender = (
info: OpenAPIV3.InfoObject,
@@ -11,7 +59,21 @@ export const SwaggerUIRender = (
},
stringifiedSwaggerOptions: string,
autoDarkMode?: boolean
) => `<!DOCTYPE html>
): string => {
const swaggerOptions: OpenAPIV3.Document = JSON.parse(stringifiedSwaggerOptions);
if (swaggerOptions.components && swaggerOptions.components.schemas) {
swaggerOptions.components.schemas = Object.fromEntries(
Object.entries(swaggerOptions.components.schemas).map(([key, schema]) => [
key,
transformDateProperties(schema)
])
);
}
const transformedStringifiedSwaggerOptions = JSON.stringify(swaggerOptions);
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
@@ -57,8 +119,9 @@ export const SwaggerUIRender = (
<script src="https://unpkg.com/swagger-ui-dist@${version}/swagger-ui-bundle.js" crossorigin></script>
<script>
window.onload = () => {
window.ui = SwaggerUIBundle(${stringifiedSwaggerOptions});
window.ui = SwaggerUIBundle(${transformedStringifiedSwaggerOptions});
};
</script>
</body>
</html>`
</html>`;
};

View File

@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-unused-vars */
import path from 'path'
import { normalize } from 'pathe'
import type { HTTPMethod, LocalHook } from 'elysia'
import { Kind, type TSchema } from '@sinclair/typebox'
@@ -306,7 +306,7 @@ export const filterPaths = (
// exclude docs path and OpenAPI json path
const excludePaths = [`/${docsPath}`, `/${docsPath}/json`].map((p) =>
path.normalize(p)
normalize(p)
)
for (const [key, value] of Object.entries(paths))