Skip to content

fix: Do not generate undocumented routes and endpoints #315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 73 additions & 12 deletions generate-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async function main(): Promise<void> {
])
}

const openapiResponseKeyProp = 'x-fern-sdk-return-value'
const openapiResponseKeyProp = 'x-response-key'

const routePaths = [
'/access_codes',
Expand Down Expand Up @@ -124,9 +124,9 @@ interface ClassMeta {
}

const createRoutes = (): Route[] => {
const paths = Object.keys(openapi.paths)
const allOpenapiPaths = Object.keys(openapi.paths)

const unmatchedEndpointPaths = paths
const unmatchedEndpointPaths = allOpenapiPaths
.filter(
(path) =>
!routePaths.some((routePath) => isEndpointUnderRoute(path, routePath)),
Expand All @@ -141,19 +141,42 @@ const createRoutes = (): Route[] => {
)
}

return routePaths.map(createRoute)
}
const routesToGenerate = routePaths.filter(
(routePath) =>
hasAtLeastOneDocumentedEndpoint(routePath) || isNamespaceRoute(routePath),
)

const createRoute = (routePath: (typeof routePaths)[number]): Route => {
const endpointPaths = Object.keys(openapi.paths).filter((path) =>
isEndpointUnderRoute(path, routePath),
return routesToGenerate.map((routePath) =>
createRoute(routePath, routesToGenerate),
)
}

const createRoute = (
routePath: (typeof routePaths)[number],
documentedRoutePaths: ReadonlyArray<(typeof routePaths)[number]>,
): Route => {
const endpointPaths = Object.entries(openapi.paths)
.filter(([path, pathSchema]) => {
if (!isEndpointUnderRoute(path, routePath)) {
return false
}

return 'post' in pathSchema && !('x-undocumented' in pathSchema.post)
})
.map(([path]) => path)

const namespace = routePath.split('/').join('_').slice(1)

const subresources = (routePathSubresources[routePath] ?? []).filter(
(subresource) => {
const subresourcePath = `${routePath}/${subresource}`
return documentedRoutePaths.some((path) => path === subresourcePath)
},
)

return {
namespace,
subresources: routePathSubresources[routePath] ?? [],
subresources,
endpoints: endpointPaths.map((endpointPath) =>
createEndpoint(namespace, routePath, endpointPath),
),
Expand Down Expand Up @@ -245,6 +268,46 @@ const isEndpointUnderRoute = (
endpointPath.startsWith(routePath) &&
endpointPath.split('/').length - 1 === routePath.split('/').length

const hasAtLeastOneDocumentedEndpoint = (
routePath: (typeof routePaths)[number],
): boolean => {
const endpointsUnderRoute = Object.keys(openapi.paths).filter((path) =>
isEndpointUnderRoute(path, routePath),
)

if (endpointsUnderRoute.length === 0) {
return false
}

return endpointsUnderRoute.some((path) => {
if (!isOpenapiPath(path)) return false

const pathSchema = openapi.paths[path]
if (!('post' in pathSchema)) return false

return !('x-undocumented' in pathSchema.post)
})
}

/**
* Determines if a route is a namespace route by checking if it has defined subresources
* and if any of those subresources have corresponding route paths.
* (e.g., "/acs" which contains "/acs/users", "/acs/systems", etc.)
* These routes should be generated even if they don't have direct endpoints themselves.
*/
function isNamespaceRoute(routePath: (typeof routePaths)[number]): boolean {
const subresources = routePathSubresources[routePath] ?? []
if (subresources.length === 0) {
return false
}

return subresources.some((subresource) => {
const subresourcePath =
`${routePath}/${subresource}` as (typeof routePaths)[number]
return routePaths.includes(subresourcePath)
})
}

const renderRoute = (route: Route, { constructors }: ClassMeta): string => `
/*
* Automatically generated by generate-routes.ts.
Expand Down Expand Up @@ -386,9 +449,7 @@ const renderClassMethodOptions = ({
resource,
}: Pick<Endpoint, 'resource'>): string => {
if (resource === 'action_attempt') {
return `options: ${renderClassMethodOptionsTypeDef({
resource,
})} = {},`
return `options: ${renderClassMethodOptionsTypeDef({ resource })} = {},`
}
return ''
}
Expand Down
209 changes: 0 additions & 209 deletions src/lib/seam/connect/routes/acs-access-groups-unmanaged.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/lib/seam/connect/routes/acs-access-groups.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading