mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
Merge pull request #6089 from mostafa/fix-oas-validation-errors
fix: generate valid OpenAPI spec
This commit is contained in:
commit
a43434c42f
4 changed files with 38 additions and 9 deletions
8
.changeset/heavy-badgers-jog.md
Normal file
8
.changeset/heavy-badgers-jog.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
"@logto/core": patch
|
||||
---
|
||||
|
||||
fix OpenAPI schema returned by the `GET /api/swagger.json` endpoint
|
||||
|
||||
1. The `:` character is invalid in parameter names, such as `organizationId:root`. These characters have been replaced with `-`.
|
||||
2. The `tenantId` parameter of the `/api/.well-known/endpoints/{tenantId}` route was missing from the generated OpenAPI spec document, resulting in validation errors. This has been fixed.
|
|
@ -120,7 +120,7 @@ describe('GET /swagger.json', () => {
|
|||
get: {
|
||||
parameters: [
|
||||
{
|
||||
$ref: '#/components/parameters/mockId:root',
|
||||
$ref: '#/components/parameters/mockId-root',
|
||||
},
|
||||
{
|
||||
name: 'field',
|
||||
|
@ -135,7 +135,7 @@ describe('GET /swagger.json', () => {
|
|||
get: {
|
||||
parameters: [
|
||||
{
|
||||
$ref: '#/components/parameters/mockId:root',
|
||||
$ref: '#/components/parameters/mockId-root',
|
||||
},
|
||||
{
|
||||
name: 'field',
|
||||
|
|
|
@ -35,6 +35,7 @@ import {
|
|||
paginationParameters,
|
||||
buildPathIdParameters,
|
||||
mergeParameters,
|
||||
customParameters,
|
||||
} from './utils/parameters.js';
|
||||
|
||||
type RouteObject = {
|
||||
|
@ -242,8 +243,11 @@ export default function swaggerRoutes<T extends AnonymousRouter, R extends Route
|
|||
components: {
|
||||
schemas: translationSchemas,
|
||||
parameters: identifiableEntityNames.reduce(
|
||||
(previous, entityName) => ({ ...previous, ...buildPathIdParameters(entityName) }),
|
||||
{}
|
||||
(previous, entityName) => ({
|
||||
...previous,
|
||||
...buildPathIdParameters(entityName),
|
||||
}),
|
||||
customParameters()
|
||||
),
|
||||
},
|
||||
tags: [...tags, ...additionalTags].map((tag) => ({ name: tag })),
|
||||
|
|
|
@ -48,7 +48,7 @@ type BuildParameters = {
|
|||
* For path parameters, this function will try to match reusable ID parameters:
|
||||
*
|
||||
* - If the parameter name is `id`, and the path is `/organizations/{id}/users`, the parameter
|
||||
* `id` will be a reference to `#/components/parameters/organizationId:root`.
|
||||
* `id` will be a reference to `#/components/parameters/organizationId-root`.
|
||||
* - If the parameter name ends with `Id`, and the path is `/organizations/{id}/users/{userId}`,
|
||||
* the parameter `userId` will be a reference to `#/components/parameters/userId`.
|
||||
*
|
||||
|
@ -91,7 +91,7 @@ export const buildParameters: BuildParameters = (
|
|||
if (key === 'id') {
|
||||
if (rootComponent) {
|
||||
return {
|
||||
$ref: `#/components/parameters/${pluralize(rootComponent, 1)}Id:root`,
|
||||
$ref: `#/components/parameters/${pluralize(rootComponent, 1)}Id-root`,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -206,7 +206,7 @@ export const mergeParameters = (destination: unknown[], source: unknown[]) => {
|
|||
* type: 'string',
|
||||
* },
|
||||
* },
|
||||
* 'organizationId:root': {
|
||||
* 'organizationId-root': {
|
||||
* name: 'id',
|
||||
* // ... same as above
|
||||
* },
|
||||
|
@ -216,7 +216,7 @@ export const mergeParameters = (destination: unknown[], source: unknown[]) => {
|
|||
* @remarks
|
||||
* The root path component is the first path component in the path. For example, the root path
|
||||
* component of `/organizations/{id}/users` is `organizations`. Since the name of the parameter is
|
||||
* same for all root path components, we need to add an additional key with the `:root` suffix to
|
||||
* same for all root path components, we need to add an additional key with the `-root` suffix to
|
||||
* distinguish them.
|
||||
*
|
||||
* @param rootComponent The root path component in kebab case (`foo-bar`).
|
||||
|
@ -241,7 +241,7 @@ export const buildPathIdParameters = (
|
|||
// Need to duplicate the object because OpenAPI does not support partial reference.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/issues/2026
|
||||
return {
|
||||
[`${entityId}:root`]: {
|
||||
[`${entityId}-root`]: {
|
||||
...shared,
|
||||
name: 'id',
|
||||
},
|
||||
|
@ -251,3 +251,20 @@ export const buildPathIdParameters = (
|
|||
},
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Build a parameter object with additional parameters that are not inferred from the path.
|
||||
*/
|
||||
export const customParameters = (): Record<string, OpenAPIV3.ParameterObject> => {
|
||||
return Object.freeze({
|
||||
tenantId: {
|
||||
name: 'tenantId',
|
||||
in: 'path',
|
||||
description: 'The unique identifier of the tenant.',
|
||||
required: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue