mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 04:23:31 +01:00
feat: endpoint to retriveve memeber info
This commit is contained in:
35
apps/website/src/app/api/[package]/[version]/[item]/route.ts
Normal file
35
apps/website/src/app/api/[package]/[version]/[item]/route.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { generatePath } from '@discordjs/api-extractor-utils';
|
||||||
|
import { tryResolveSummaryText } from '@discordjs/scripts';
|
||||||
|
import type { ApiDeclaredItem, ApiItemContainerMixin } from '@microsoft/api-extractor-model';
|
||||||
|
import type { NextRequest } from 'next/server';
|
||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
import { memberPredicate } from '~/components/documentation/util';
|
||||||
|
import { fetchMember } from '~/util/fetchMember';
|
||||||
|
import { resolveMembers } from '~/util/members';
|
||||||
|
|
||||||
|
export const revalidate = 3_600;
|
||||||
|
|
||||||
|
export async function GET(_: NextRequest, { params }: { params: { item: string; package: string; version: string } }) {
|
||||||
|
const member = await fetchMember({
|
||||||
|
package: params.package,
|
||||||
|
version: params.version,
|
||||||
|
item: params.item,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!member) {
|
||||||
|
return new Response(null, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
name: member.displayName,
|
||||||
|
kind: member.kind,
|
||||||
|
summary: tryResolveSummaryText(member as ApiDeclaredItem) ?? '',
|
||||||
|
path: generatePath(member.getHierarchy(), params.version),
|
||||||
|
members: resolveMembers(member as ApiItemContainerMixin, memberPredicate).map((member) => ({
|
||||||
|
name: member.item.displayName,
|
||||||
|
kind: member.item.kind,
|
||||||
|
summary: tryResolveSummaryText(member.item as ApiDeclaredItem) ?? '',
|
||||||
|
path: generatePath(member.item.getHierarchy(), params.version),
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -12,8 +12,9 @@ import type {
|
|||||||
ApiPropertySignature,
|
ApiPropertySignature,
|
||||||
ApiTypeAlias,
|
ApiTypeAlias,
|
||||||
ApiVariable,
|
ApiVariable,
|
||||||
|
ApiFunction,
|
||||||
} from '@microsoft/api-extractor-model';
|
} from '@microsoft/api-extractor-model';
|
||||||
import { ApiItemKind, ApiModel, ApiFunction } from '@microsoft/api-extractor-model';
|
import { ApiItemKind, ApiModel } from '@microsoft/api-extractor-model';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
import type { Metadata } from 'next/types';
|
import type { Metadata } from 'next/types';
|
||||||
import { fetchModelJSON } from '~/app/docAPI';
|
import { fetchModelJSON } from '~/app/docAPI';
|
||||||
@@ -23,14 +24,10 @@ import { TypeAlias } from '~/components/model/TypeAlias';
|
|||||||
import { Variable } from '~/components/model/Variable';
|
import { Variable } from '~/components/model/Variable';
|
||||||
import { Enum } from '~/components/model/enum/Enum';
|
import { Enum } from '~/components/model/enum/Enum';
|
||||||
import { Function } from '~/components/model/function/Function';
|
import { Function } from '~/components/model/function/Function';
|
||||||
import { OVERLOAD_SEPARATOR, PACKAGES } from '~/util/constants';
|
import { OVERLOAD_SEPARATOR } from '~/util/constants';
|
||||||
import { findMember, findMemberByKey } from '~/util/model';
|
import type { ItemRouteParams } from '~/util/fetchMember';
|
||||||
|
import { fetchMember } from '~/util/fetchMember';
|
||||||
export interface ItemRouteParams {
|
import { findMember } from '~/util/model';
|
||||||
item: string;
|
|
||||||
package: string;
|
|
||||||
version: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchHeadMember({ package: packageName, version, item }: ItemRouteParams): Promise<ApiItem | undefined> {
|
async function fetchHeadMember({ package: packageName, version, item }: ItemRouteParams): Promise<ApiItem | undefined> {
|
||||||
const modelJSON = await fetchModelJSON(packageName, version);
|
const modelJSON = await fetchModelJSON(packageName, version);
|
||||||
@@ -124,35 +121,6 @@ export async function generateStaticParams({ params: { package: packageName, ver
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchMember({ package: packageName, version: branchName = 'main', item }: ItemRouteParams) {
|
|
||||||
if (!PACKAGES.includes(packageName)) {
|
|
||||||
notFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
const model = new ApiModel();
|
|
||||||
|
|
||||||
if (branchName === 'main') {
|
|
||||||
const modelJSONFiles = await Promise.all(PACKAGES.map(async (pkg) => fetchModelJSON(pkg, branchName)));
|
|
||||||
|
|
||||||
for (const modelJSONFile of modelJSONFiles) {
|
|
||||||
addPackageToModel(model, modelJSONFile);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const modelJSON = await fetchModelJSON(packageName, branchName);
|
|
||||||
addPackageToModel(model, modelJSON);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [memberName, overloadIndex] = decodeURIComponent(item).split(OVERLOAD_SEPARATOR);
|
|
||||||
|
|
||||||
// eslint-disable-next-line prefer-const
|
|
||||||
let { containerKey, displayName: name } = findMember(model, packageName, memberName) ?? {};
|
|
||||||
if (name && overloadIndex && !Number.isNaN(Number.parseInt(overloadIndex, 10))) {
|
|
||||||
containerKey = ApiFunction.getContainerKey(name, Number.parseInt(overloadIndex, 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
return memberName && containerKey ? findMemberByKey(model, packageName, containerKey) ?? null : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Member({ member }: { member?: ApiItem }) {
|
function Member({ member }: { member?: ApiItem }) {
|
||||||
switch (member?.kind) {
|
switch (member?.kind) {
|
||||||
case 'Class':
|
case 'Class':
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ export function resolveItemURI(item: ApiItem): string {
|
|||||||
: `${item.parent.displayName}${OVERLOAD_SEPARATOR}${item.parent.kind}${METHOD_SEPARATOR}${item.displayName}`;
|
: `${item.parent.displayName}${OVERLOAD_SEPARATOR}${item.parent.kind}${METHOD_SEPARATOR}${item.displayName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function memberPredicate(item: ApiItem): item is ApiMethod | ApiMethodSignature | ApiProperty | ApiPropertySignature {
|
export function memberPredicate(
|
||||||
|
item: ApiItem,
|
||||||
|
): item is ApiMethod | ApiMethodSignature | ApiProperty | ApiPropertySignature {
|
||||||
return (
|
return (
|
||||||
item.kind === ApiItemKind.Property ||
|
item.kind === ApiItemKind.Property ||
|
||||||
item.kind === ApiItemKind.PropertySignature ||
|
item.kind === ApiItemKind.PropertySignature ||
|
||||||
|
|||||||
41
apps/website/src/util/fetchMember.ts
Normal file
41
apps/website/src/util/fetchMember.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { addPackageToModel } from '@discordjs/scripts';
|
||||||
|
import { ApiModel, ApiFunction } from '@microsoft/api-extractor-model';
|
||||||
|
import { notFound } from 'next/navigation';
|
||||||
|
import { OVERLOAD_SEPARATOR, PACKAGES } from './constants';
|
||||||
|
import { findMember, findMemberByKey } from './model';
|
||||||
|
import { fetchModelJSON } from '~/app/docAPI';
|
||||||
|
|
||||||
|
export interface ItemRouteParams {
|
||||||
|
item: string;
|
||||||
|
package: string;
|
||||||
|
version: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchMember({ package: packageName, version: branchName = 'main', item }: ItemRouteParams) {
|
||||||
|
if (!PACKAGES.includes(packageName)) {
|
||||||
|
notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
const model = new ApiModel();
|
||||||
|
|
||||||
|
if (branchName === 'main') {
|
||||||
|
const modelJSONFiles = await Promise.all(PACKAGES.map(async (pkg) => fetchModelJSON(pkg, branchName)));
|
||||||
|
|
||||||
|
for (const modelJSONFile of modelJSONFiles) {
|
||||||
|
addPackageToModel(model, modelJSONFile);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const modelJSON = await fetchModelJSON(packageName, branchName);
|
||||||
|
addPackageToModel(model, modelJSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [memberName, overloadIndex] = decodeURIComponent(item).split(OVERLOAD_SEPARATOR);
|
||||||
|
|
||||||
|
// eslint-disable-next-line prefer-const
|
||||||
|
let { containerKey, displayName: name } = findMember(model, packageName, memberName) ?? {};
|
||||||
|
if (name && overloadIndex && !Number.isNaN(Number.parseInt(overloadIndex, 10))) {
|
||||||
|
containerKey = ApiFunction.getContainerKey(name, Number.parseInt(overloadIndex, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
return memberName && containerKey ? findMemberByKey(model, packageName, containerKey) ?? null : null;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user