mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor: undo changes on swagger API utils and hide SAML app APIs
This commit is contained in:
parent
0795ba9364
commit
ccb47b7443
5 changed files with 20 additions and 44 deletions
|
@ -12,7 +12,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"precommit": "lint-staged",
|
"precommit": "lint-staged",
|
||||||
"copy:apidocs": "rsync -a -m --include '*/' --include '*.openapi.json' --exclude '*' src/routes/ build/routes/ && rsync -a -m --include '*/' --include '*.openapi.json' --exclude '*' src/saml-applications/ build/saml-applications/",
|
"copy:apidocs": "rsync -a -m --include '*/' --include '*.openapi.json' --exclude '*' src/routes/ build/routes/",
|
||||||
"check": "tsc --noEmit",
|
"check": "tsc --noEmit",
|
||||||
"build": "tsup",
|
"build": "tsup",
|
||||||
"build:test": "rm -rf build/ && tsc -p tsconfig.test.json --sourcemap && pnpm run copy:apidocs",
|
"build:test": "rm -rf build/ && tsc -p tsconfig.test.json --sourcemap && pnpm run copy:apidocs",
|
||||||
|
|
|
@ -47,17 +47,11 @@ const managementApiIdentifiableEntityNames = Object.freeze([
|
||||||
'organization-role',
|
'organization-role',
|
||||||
'organization-scope',
|
'organization-scope',
|
||||||
'organization-invitation',
|
'organization-invitation',
|
||||||
'saml-application',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/** Additional tags that cannot be inferred from the path. */
|
/** Additional tags that cannot be inferred from the path. */
|
||||||
const additionalTags = Object.freeze(
|
const additionalTags = Object.freeze(
|
||||||
condArray<string>(
|
condArray<string>('Organization applications', 'Custom UI assets', 'Organization users')
|
||||||
'Organization applications',
|
|
||||||
'Custom UI assets',
|
|
||||||
'Organization users',
|
|
||||||
EnvSet.values.isDevFeaturesEnabled && 'SAML applications'
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const buildManagementApiBaseDocument = (
|
export const buildManagementApiBaseDocument = (
|
||||||
|
@ -213,7 +207,7 @@ export const buildUserApiBaseDocument = (
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getSupplementDocuments = async (
|
export const getSupplementDocuments = async (
|
||||||
directory = 'build',
|
directory = 'routes',
|
||||||
option?: FindSupplementFilesOptions
|
option?: FindSupplementFilesOptions
|
||||||
) => {
|
) => {
|
||||||
// Find supplemental documents
|
// Find supplemental documents
|
||||||
|
|
|
@ -35,7 +35,6 @@ const tagMap = new Map([
|
||||||
['sso-connectors', 'SSO connectors'],
|
['sso-connectors', 'SSO connectors'],
|
||||||
['sso-connector-providers', 'SSO connector providers'],
|
['sso-connector-providers', 'SSO connector providers'],
|
||||||
['.well-known', 'Well-known'],
|
['.well-known', 'Well-known'],
|
||||||
['saml-applications', 'SAML applications'],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,43 +67,25 @@ export const findSupplementFiles = async (
|
||||||
option?: FindSupplementFilesOptions
|
option?: FindSupplementFilesOptions
|
||||||
) => {
|
) => {
|
||||||
const result: string[] = [];
|
const result: string[] = [];
|
||||||
const files = await fs.readdir(directory);
|
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of await fs.readdir(directory)) {
|
||||||
const fullPath = path.join(directory, file);
|
const stats = await fs.stat(path.join(directory, file));
|
||||||
const stats = await fs.stat(fullPath);
|
|
||||||
|
if (
|
||||||
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||||
|
option?.excludeDirectories?.includes(file) ||
|
||||||
|
(option?.includeDirectories && !option.includeDirectories.includes(file))
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
// Skip if the current directory is excluded
|
result.push(...(await findSupplementFiles(path.join(directory, file))));
|
||||||
if (option?.excludeDirectories?.includes(file)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursively search subdirectories
|
|
||||||
const subFiles = await findSupplementFiles(fullPath, option);
|
|
||||||
result.push(...subFiles);
|
|
||||||
} else if (file.endsWith('.openapi.json')) {
|
} else if (file.endsWith('.openapi.json')) {
|
||||||
result.push(fullPath);
|
result.push(path.join(directory, file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If `includeDirectories` is specified, only keep files that contain the specified subdirectories
|
|
||||||
if (option?.includeDirectories?.length && option.includeDirectories.length > 0) {
|
|
||||||
return result.filter((filePath) =>
|
|
||||||
// The fallback to empty array will never happen here, as we've already checked the length of option.`includeDirectories` before entering this branch
|
|
||||||
(option.includeDirectories ?? []).some((directory) => filePath.includes(`/${directory}/`))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If `excludeDirectories` is specified, exclude files that contain the specified subdirectories
|
|
||||||
if (option?.excludeDirectories?.length && option.excludeDirectories.length > 0) {
|
|
||||||
return result.filter(
|
|
||||||
(filePath) =>
|
|
||||||
// The fallback to empty array will never happen here, as we've already checked the length of option.`excludeDirectories` before entering this branch
|
|
||||||
!(option.excludeDirectories ?? []).some((directory) => filePath.includes(`/${directory}/`))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
/* eslint-enable @silverhand/fp/no-mutating-methods, no-await-in-loop */
|
/* eslint-enable @silverhand/fp/no-mutating-methods, no-await-in-loop */
|
||||||
|
@ -157,9 +138,7 @@ const validateSupplementPaths = (
|
||||||
if (
|
if (
|
||||||
isKeyInObject(operation, 'tags') &&
|
isKeyInObject(operation, 'tags') &&
|
||||||
Array.isArray(operation.tags) &&
|
Array.isArray(operation.tags) &&
|
||||||
!operation.tags.every(
|
!operation.tags.every((tag) => typeof tag === 'string' && reservedTags.has(tag))
|
||||||
(tag) => typeof tag === 'string' && [cloudOnlyTag, devFeatureTag].includes(tag)
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
throw new TypeError(
|
throw new TypeError(
|
||||||
`Cannot use \`tags\` in supplement document on path \`${path}\` and operation \`${method}\` except for tag \`${cloudOnlyTag}\` and \`${devFeatureTag}\`. Define tags in the document root instead.`
|
`Cannot use \`tags\` in supplement document on path \`${path}\` and operation \`${method}\` except for tag \`${cloudOnlyTag}\` and \`${devFeatureTag}\`. Define tags in the document root instead.`
|
||||||
|
|
|
@ -138,6 +138,9 @@ export const buildRouterObjects = <T extends UnknownRouter>(routers: T[], option
|
||||||
.map((method) => method.toLowerCase())
|
.map((method) => method.toLowerCase())
|
||||||
// There is no need to show the HEAD method.
|
// There is no need to show the HEAD method.
|
||||||
.filter((method): method is OpenAPIV3.HttpMethods => method !== 'head')
|
.filter((method): method is OpenAPIV3.HttpMethods => method !== 'head')
|
||||||
|
// TODO: Remove this and bring back `/saml-applications` routes before release.
|
||||||
|
// Exclude `/saml-applications` routes for now.
|
||||||
|
.filter(() => !routerPath.startsWith('/saml-applications'))
|
||||||
.map((httpMethod) => {
|
.map((httpMethod) => {
|
||||||
const path = normalizePath(routerPath);
|
const path = normalizePath(routerPath);
|
||||||
const operation = buildOperation(httpMethod, stack, routerPath, isAuthGuarded);
|
const operation = buildOperation(httpMethod, stack, routerPath, isAuthGuarded);
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default function openapiRoutes<T extends AnonymousRouter, R extends Unkno
|
||||||
const { pathMap, tags } = groupRoutesByPath(managementApiRoutes);
|
const { pathMap, tags } = groupRoutesByPath(managementApiRoutes);
|
||||||
|
|
||||||
// Find supplemental documents
|
// Find supplemental documents
|
||||||
const supplementDocuments = await getSupplementDocuments('build', {
|
const supplementDocuments = await getSupplementDocuments('routes', {
|
||||||
excludeDirectories: ['experience', 'interaction', 'account', 'verification'],
|
excludeDirectories: ['experience', 'interaction', 'account', 'verification'],
|
||||||
});
|
});
|
||||||
const baseDocument = buildManagementApiBaseDocument(pathMap, tags, ctx.request.origin);
|
const baseDocument = buildManagementApiBaseDocument(pathMap, tags, ctx.request.origin);
|
||||||
|
|
Loading…
Reference in a new issue