mirror of
https://github.com/logto-io/logto.git
synced 2025-01-27 21:39:16 -05:00
refactor(core): add cloud-only API prune for API docs
This commit is contained in:
parent
9c7956da5c
commit
77b67fbd04
3 changed files with 100 additions and 1 deletions
|
@ -188,6 +188,50 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/api/configs/jwt-customizer/test": {
|
||||||
|
"post": {
|
||||||
|
"tags": ["cloud-only"],
|
||||||
|
"summary": "Test JWT customizer",
|
||||||
|
"description": "Test the JWT customizer script with the given sample context and sample token payload.",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"tokenType": {
|
||||||
|
"description": "The token type to test the JWT customizer for."
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"properties": {
|
||||||
|
"script": {
|
||||||
|
"description": "The code snippet of the JWT customizer."
|
||||||
|
},
|
||||||
|
"envVars": {
|
||||||
|
"description": "The environment variables for the JWT customizer."
|
||||||
|
},
|
||||||
|
"contextSample": {
|
||||||
|
"description": "The sample context for the JWT customizer script testing purpose."
|
||||||
|
},
|
||||||
|
"tokenSample": {
|
||||||
|
"description": "The sample token payload for the JWT customizer script testing purpose."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The result of the JWT customizer script testing."
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "The request body is invalid."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import {
|
||||||
buildTag,
|
buildTag,
|
||||||
findSupplementFiles,
|
findSupplementFiles,
|
||||||
normalizePath,
|
normalizePath,
|
||||||
|
pruneSupplementPaths,
|
||||||
validateSupplement,
|
validateSupplement,
|
||||||
validateSwaggerDocument,
|
validateSwaggerDocument,
|
||||||
} from './utils/general.js';
|
} from './utils/general.js';
|
||||||
|
@ -192,12 +193,15 @@ export default function swaggerRoutes<T extends AnonymousRouter, R extends Route
|
||||||
assertThat(routesDirectory, new Error('Cannot find routes directory.'));
|
assertThat(routesDirectory, new Error('Cannot find routes directory.'));
|
||||||
|
|
||||||
const supplementPaths = await findSupplementFiles(routesDirectory);
|
const supplementPaths = await findSupplementFiles(routesDirectory);
|
||||||
const supplementDocuments = await Promise.all(
|
const rawSupplementDocuments = await Promise.all(
|
||||||
supplementPaths.map(
|
supplementPaths.map(
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
async (path) => JSON.parse(await fs.readFile(path, 'utf8')) as Record<string, unknown>
|
async (path) => JSON.parse(await fs.readFile(path, 'utf8')) as Record<string, unknown>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
const supplementDocuments = rawSupplementDocuments.map((document) =>
|
||||||
|
pruneSupplementPaths(document)
|
||||||
|
);
|
||||||
|
|
||||||
const baseDocument: OpenAPIV3.Document = {
|
const baseDocument: OpenAPIV3.Document = {
|
||||||
openapi: '3.0.1',
|
openapi: '3.0.1',
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { isKeyInObject, type Optional } from '@silverhand/essentials';
|
||||||
import { OpenAPIV3 } from 'openapi-types';
|
import { OpenAPIV3 } from 'openapi-types';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { EnvSet } from '#src/env-set/index.js';
|
||||||
import { consoleLog } from '#src/utils/console.js';
|
import { consoleLog } from '#src/utils/console.js';
|
||||||
|
|
||||||
const capitalize = (value: string) => value.charAt(0).toUpperCase() + value.slice(1);
|
const capitalize = (value: string) => value.charAt(0).toUpperCase() + value.slice(1);
|
||||||
|
@ -201,3 +202,53 @@ export const validateSwaggerDocument = (document: OpenAPIV3.Document) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some path are only available in the cloud version, so we need to prune them out in the OSS.
|
||||||
|
*/
|
||||||
|
export const pruneSupplementPaths = (supplement: Record<string, unknown>) => {
|
||||||
|
if (EnvSet.values.isCloud) {
|
||||||
|
return supplement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
const supplementName = ((supplement.tags ?? []) as OpenAPIV3.TagObject[])[0]?.name;
|
||||||
|
|
||||||
|
if (!supplementName) {
|
||||||
|
return supplement;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!supplement.paths) {
|
||||||
|
return supplement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
const supplementPaths = supplement.paths as OpenAPIV3.PathsObject;
|
||||||
|
|
||||||
|
if (Object.entries(supplement.paths).length === 0) {
|
||||||
|
return supplement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
const newPaths = Object.fromEntries(
|
||||||
|
Object.entries(supplementPaths)
|
||||||
|
.map(([path, pathBody]) => [
|
||||||
|
path,
|
||||||
|
Object.fromEntries(
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
Object.entries(pathBody as OpenAPIV3.PathItemObject).filter(
|
||||||
|
([_, operationBody]) =>
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
!((operationBody as OpenAPIV3.OperationObject).tags ?? []).includes('cloud-only')
|
||||||
|
)
|
||||||
|
),
|
||||||
|
])
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
.filter(([_, pathBody]) => Object.entries(pathBody as OpenAPIV3.PathItemObject).length > 0)
|
||||||
|
) as OpenAPIV3.PathsObject;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...supplement,
|
||||||
|
paths: newPaths,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue