docs: split docs.api.json into multiple json files

This commit is contained in:
iCrawl 2024-02-06 17:24:18 +01:00
parent ae57d7facb
commit 597340f288
No known key found for this signature in database
GPG key ID: 1AB888B16355FBB2
28 changed files with 1144 additions and 62 deletions

36
biome.json Normal file
View file

@ -0,0 +1,36 @@
{
"$schema": "https://biomejs.dev/schemas/1.5.3/schema.json",
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "tab",
"indentWidth": 2,
"lineWidth": 120,
"lineEnding": "lf",
"ignore": [
".turbo",
".vercel",
".contentlayer",
".next",
"coverage",
"dist",
"dist-docs",
"docs",
"CHANGELOG.md",
"tsup.config.bundled*"
]
},
"javascript": {
"formatter": {
"enabled": true,
"quoteStyle": "single",
"quoteProperties": "asNeeded",
"trailingComma": "all",
"semicolons": "always"
}
},
"files": {
"ignoreUnknown": true,
"maxSize": 1000000
}
}

View file

@ -6,6 +6,7 @@ import node from 'eslint-config-neon/flat/node.js';
import prettier from 'eslint-config-neon/flat/prettier.js';
import react from 'eslint-config-neon/flat/react.js';
import typescript from 'eslint-config-neon/flat/typescript.js';
// import oxlint from 'eslint-plugin-oxlint';
import merge from 'lodash.merge';
const commonFiles = '{js,mjs,cjs,ts,mts,cts,jsx,tsx}';
@ -63,6 +64,8 @@ const edgeRuleset = merge(...edge, { files: [`apps/**/*${commonFiles}`] });
const prettierRuleset = merge(...prettier, { files: [`**/*${commonFiles}`] });
// const oxlintRuleset = merge({ rules: oxlint.rules }, { files: [`**/*${commonFiles}`] });
/** @type {import('eslint').Linter.FlatConfig[]} */
export default [
{
@ -133,4 +136,5 @@ export default [
rules: { 'tsdoc/syntax': 0 },
},
prettierRuleset,
// oxlintRuleset,
];

View file

@ -1,5 +1,5 @@
name: 'Upload documentation'
description: 'Uploads the docs.api.json file to a planetscale database'
description: 'Uploads the docs.api.json file to a neon postgresql database'
inputs:
package:
description: 'The package string'

View file

@ -0,0 +1,10 @@
name: 'Upload split documentation'
description: 'Splits and uploads the docs.api.json file into more fine-grained [item].api.json files'
inputs:
package:
description: 'The package string'
version:
description: 'The semver string'
runs:
using: node20
main: ../../dist/uploadSplitDocumentation/index.js

View file

@ -0,0 +1,34 @@
import { readFile } from 'node:fs/promises';
import { basename } from 'node:path';
import process from 'node:process';
import { getInput, setFailed } from '@actions/core';
import { create } from '@actions/glob';
import { put } from '@vercel/blob';
import { createPool } from '@vercel/postgres';
if (!process.env.DATABASE_URL) {
setFailed('DATABASE_URL is not set');
}
const pkg = getInput('package') || '*';
const version = getInput('version') || 'main';
const pool = createPool({
connectionString: process.env.DATABASE_URL,
});
const globber = await create(`packages/${pkg}/docs/split/main.*.*.api.json`);
for await (const file of globber.globGenerator()) {
const data = await readFile(file, 'utf8');
try {
console.log(`Uploading ${file} with ${version}...`);
const name = basename(file).replace('main.', '');
const { url } = await put(`${version}.${name}`, data, {
access: 'public',
addRandomSuffix: false,
});
await pool.sql`insert into documentation (name, version, url) values (${name}, ${version}, ${url}) on conflict (name, version) do update set url = EXCLUDED.url`;
} catch (error) {
console.log(error);
}
}

View file

@ -2,6 +2,7 @@ import { createTsupConfig } from '../../tsup.config.js';
export default createTsupConfig({
entry: [
'src/buildSplitDocumentation/index.ts',
'src/index.ts',
'src/formatTag/index.ts',
'src/uploadDocumentation/index.ts',

View file

@ -10,7 +10,7 @@
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"fmt": "pnpm run format",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run lint && pnpm run test && pnpm run build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/brokers/*'",
"release": "cliff-jumper"
@ -72,6 +72,7 @@
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "18.18.8",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -10,7 +10,7 @@
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"fmt": "pnpm run format",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run lint && pnpm run test && pnpm run build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/builders/*'",
"release": "cliff-jumper"
@ -74,6 +74,7 @@
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "16.18.60",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -10,7 +10,7 @@
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"fmt": "pnpm run format",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run lint && pnpm run test && pnpm run build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/collection/*'",
"release": "cliff-jumper"
@ -61,6 +61,7 @@
"homepage": "https://discord.js.org",
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "18.18.8",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -9,7 +9,7 @@
"build:docs": "tsc -p tsconfig.docs.json",
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run build && pnpm run lint",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/core/*'",
"release": "cliff-jumper"
@ -73,6 +73,7 @@
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "18.18.8",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -11,7 +11,7 @@
"fmt": "pnpm run format",
"docs": "docgen -i \"./src/*.js\" \"./src/**/*.js\" -c ./docs/index.json -r ../../ -o ./docs/docs.json && pnpm run docs:new",
"docs:test": "docgen -i \"./src/*.js\" \"./src/**/*.js\" -c ./docs/index.json -r ../../",
"docs:new": "api-extractor run --local --minify",
"docs:new": "api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run lint && pnpm run test && node ./scripts/esmDts.mjs",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/discord.js/*'",
"release": "cliff-jumper"
@ -82,6 +82,7 @@
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/docgen": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "2.2.3",
"@types/node": "16.18.60",
"@typescript-eslint/eslint-plugin": "^6.21.0",

View file

@ -31,6 +31,7 @@
"lib": "src"
},
"files": [
"bin/index.js",
"dist"
],
"contributors": [

View file

@ -9,7 +9,7 @@
"build:docs": "tsc -p tsconfig.docs.json",
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run build && pnpm run lint",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/formatters/*'",
"release": "cliff-jumper"
@ -58,6 +58,7 @@
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "16.18.60",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -9,7 +9,7 @@
"build:docs": "tsc -p tsconfig.docs.json",
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run build && pnpm run lint",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/next/*'",
"release": "cliff-jumper"
@ -75,6 +75,7 @@
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "18.18.8",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -10,7 +10,7 @@
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"fmt": "pnpm run format",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run lint && pnpm run test && pnpm run build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/proxy/*'",
"release": "cliff-jumper"
@ -71,6 +71,7 @@
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "18.18.8",
"@types/supertest": "^6.0.2",

View file

@ -10,7 +10,7 @@
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"fmt": "pnpm run format",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run lint && pnpm run test && pnpm run build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/rest/*'",
"release": "cliff-jumper"
@ -94,6 +94,7 @@
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "18.17.9",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -0,0 +1,2 @@
#!/usr/bin/env node
require('../dist/bin/generateSplitDocumentation.js');

View file

@ -0,0 +1,31 @@
#!/usr/bin/env node
/* eslint-disable n/shebang */
import { readFile } from 'node:fs/promises';
import process from 'node:process';
import { createCommand } from 'commander';
import packageFile from '../package.json';
import { generateSplitDocumentation } from '../src/index.js';
export interface CLIOptions {
custom: string;
input: string[];
newOutput: string;
output: string;
root: string;
typescript: boolean;
}
const command = createCommand().version(packageFile.version);
const program = command.parse(process.argv);
program.opts<CLIOptions>();
console.log('Generating split documentation...');
void generateSplitDocumentation({
fetchPackageVersions: async (_) => {
return ['main'];
},
fetchPackageVersionDocs: async (_, __) => {
return JSON.parse(await readFile(`${process.cwd()}/docs/docs.api.json`, 'utf8'));
},
}).then(() => console.log('Generated split documentation.'));

View file

@ -10,26 +10,31 @@
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src turbo/generators/config.ts",
"fmt": "pnpm run format"
},
"bin": {
"generate-split-documentation": "./bin/generateSplitDocumentation.js"
},
"exports": {
".": {
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
"types": "./dist/src/index.d.mts",
"default": "./dist/src/index.mjs"
}
}
},
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"main": "./dist/src/index.js",
"module": "./dist/src/index.mjs",
"types": "./dist/src/index.d.ts",
"directories": {
"bin": "bin",
"lib": "src",
"example": "turbo"
},
"files": [
"bin/generateSplitDocumentation.js",
"dist"
],
"contributors": [
@ -60,6 +65,7 @@
"@microsoft/tsdoc-config": "0.16.2",
"@vercel/blob": "^0.20.0",
"@vercel/postgres": "^0.7.2",
"commander": "^11.1.0",
"tslib": "^2.6.2",
"undici": "6.6.1",
"yaml": "2.3.4"

View file

@ -12,7 +12,7 @@ import {
import { generatePath } from '@discordjs/api-extractor-utils';
import { DocNodeKind } from '@microsoft/tsdoc';
import type { DocLinkTag, DocCodeSpan, DocNode, DocParagraph, DocPlainText } from '@microsoft/tsdoc';
import { request } from 'undici';
import { PACKAGES, fetchVersionDocs, fetchVersions } from './shared.js';
export interface MemberJSON {
kind: string;
@ -21,20 +21,6 @@ export interface MemberJSON {
summary: string | null;
}
export const PACKAGES = [
'discord.js',
'brokers',
'builders',
'collection',
'core',
'formatters',
'next',
'proxy',
'rest',
'util',
'voice',
'ws',
];
let idx = 0;
/**
@ -150,16 +136,6 @@ export async function writeIndexToFileSystem(
);
}
export async function fetchVersions(pkg: string) {
const response = await request(`https://docs.discordjs.dev/api/info?package=${pkg}`);
return response.body.json() as Promise<string[]>;
}
export async function fetchVersionDocs(pkg: string, version: string) {
const response = await request(`https://docs.discordjs.dev/docs/${pkg}/${version}.api.json`);
return response.body.json();
}
export async function generateAllIndices({
fetchPackageVersions = fetchVersions,
fetchPackageVersionDocs = fetchVersionDocs,

View file

@ -0,0 +1,902 @@
import { mkdir, stat, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { cwd } from 'node:process';
import type {
ApiClass,
ApiConstructor,
ApiDeclaredItem,
ApiDocumentedItem,
ApiEntryPoint,
ApiEnum,
ApiEnumMember,
ApiEvent,
ApiInterface,
ApiItem,
ApiItemContainerMixin,
ApiMethod,
ApiMethodSignature,
ApiProperty,
ApiPropertySignature,
ApiTypeAlias,
ApiTypeParameterListMixin,
ApiVariable,
} from '@discordjs/api-extractor-model';
import {
Excerpt,
Meaning,
ApiAbstractMixin,
ApiFunction,
ApiItemKind,
ApiModel,
ApiPackage,
ApiParameterListMixin,
ApiProtectedMixin,
ApiReadonlyMixin,
ApiStaticMixin,
ExcerptTokenKind,
ExcerptToken,
} from '@discordjs/api-extractor-model';
import { DocNodeKind, SelectorKind, StandardTags } from '@microsoft/tsdoc';
import type {
DocNode,
DocNodeContainer,
DocDeclarationReference,
DocPlainText,
DocLinkTag,
DocFencedCode,
DocComment,
} from '@microsoft/tsdoc';
import type { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference.js';
import { PACKAGES, fetchVersionDocs, fetchVersions } from './shared.js';
function resolvePackageName(packageName: string) {
return packageName === 'discord.js' ? packageName : `@discordjs/${packageName}`;
}
function findMemberByKey(model: ApiModel, packageName: string, containerKey: string) {
const pkg = model.tryGetPackageByName(resolvePackageName(packageName))!;
return (pkg.members[0] as ApiEntryPoint).tryGetMemberByKey(containerKey);
}
function findMember(model: ApiModel, packageName: string, memberName: string | undefined) {
if (!memberName) {
return undefined;
}
const pkg = model.tryGetPackageByName(resolvePackageName(packageName))!;
return pkg.entryPoints[0]?.findMembersByName(memberName)[0];
}
/**
* Resolves all inherited members (including merged members) of a given parent.
*
* @param parent - The parent to resolve the inherited members of.
* @param predicate - A predicate to filter the members by.
*/
export function resolveMembers<WantedItem extends ApiItem>(
parent: ApiItemContainerMixin,
predicate: (item: ApiItem) => item is WantedItem,
) {
const seenItems = new Set<string>();
const inheritedMembers = parent.findMembersWithInheritance().items.reduce((acc, item) => {
if (predicate(item) && !seenItems.has(item.displayName)) {
acc.push({
item,
inherited:
item.parent?.containerKey === parent.containerKey
? undefined
: (item.parent as ApiItemContainerMixin | undefined),
});
seenItems.add(item.displayName);
}
return acc;
}, new Array<{ inherited?: ApiItemContainerMixin | undefined; item: WantedItem }>());
const mergedMembers = parent
.getMergedSiblings()
.filter((sibling) => sibling.containerKey !== parent.containerKey)
.flatMap((sibling) => (sibling as ApiItemContainerMixin).findMembersWithInheritance().items)
.filter((item) => predicate(item) && !seenItems.has(item.containerKey))
.map((item) => ({
item: item as WantedItem,
inherited: item.parent ? (item.parent as ApiItemContainerMixin) : undefined,
}));
return [...inheritedMembers, ...mergedMembers];
}
const kindToMeaning = new Map([
[ApiItemKind.CallSignature, Meaning.CallSignature],
[ApiItemKind.Class, Meaning.Class],
[ApiItemKind.ConstructSignature, Meaning.ConstructSignature],
[ApiItemKind.Constructor, Meaning.Constructor],
[ApiItemKind.Enum, Meaning.Enum],
[ApiItemKind.Event, Meaning.Event],
[ApiItemKind.Function, Meaning.Function],
[ApiItemKind.IndexSignature, Meaning.IndexSignature],
[ApiItemKind.Interface, Meaning.Interface],
[ApiItemKind.Property, Meaning.Member],
[ApiItemKind.Namespace, Meaning.Namespace],
[ApiItemKind.None, Meaning.ComplexType],
[ApiItemKind.TypeAlias, Meaning.TypeAlias],
[ApiItemKind.Variable, Meaning.Variable],
]);
function mapMeaningToKind(meaning: Meaning): ApiItemKind {
return [...kindToMeaning.entries()].find((mapping) => mapping[1] === meaning)?.[0] ?? ApiItemKind.None;
}
// function mapKindToMeaning(kind: ApiItemKind): Meaning {
// return kindToMeaning.get(kind) ?? Meaning.Variable;
// }
function resolveCanonicalReference(
canonicalReference: DeclarationReference | DocDeclarationReference,
apiPackage: ApiPackage | undefined,
) {
if (
'source' in canonicalReference &&
canonicalReference.source &&
'packageName' in canonicalReference.source &&
canonicalReference.symbol?.componentPath &&
canonicalReference.symbol.meaning
)
return {
package: canonicalReference.source.packageName,
unscopedPackage: canonicalReference.source.unscopedPackageName,
item: {
kind: mapMeaningToKind(canonicalReference.symbol.meaning as unknown as Meaning),
displayName: canonicalReference.symbol.componentPath.component.toString(),
containerKey: `|${
canonicalReference.symbol.meaning
}|${canonicalReference.symbol.componentPath.component.toString()}`,
},
// eslint-disable-next-line unicorn/better-regex
version: apiPackage?.dependencies?.[canonicalReference.source.packageName]?.replace(/[~^]/, ''),
};
else if (
'memberReferences' in canonicalReference &&
canonicalReference.memberReferences.length &&
canonicalReference.memberReferences[0]?.memberIdentifier &&
canonicalReference.memberReferences[0]?.selector?.selectorKind === SelectorKind.System
) {
const member = canonicalReference.memberReferences[0]!;
return {
package: canonicalReference.packageName?.replace('@discordjs/', ''),
item: {
kind: member.selector!.selector,
displayName: member.memberIdentifier!.identifier,
containerKey: `|${member.selector!.selector}|${member.memberIdentifier!.identifier}`,
members: canonicalReference.memberReferences
.slice(1)
.map((member) => ({ kind: member.kind, displayName: member.memberIdentifier!.identifier! })),
},
// eslint-disable-next-line unicorn/better-regex
version: apiPackage?.dependencies?.[canonicalReference.packageName ?? '']?.replace(/[~^]/, ''),
};
}
return null;
}
export function memberPredicate(
item: ApiItem,
): item is ApiEvent | ApiMethod | ApiMethodSignature | ApiProperty | ApiPropertySignature {
return (
item.kind === ApiItemKind.Property ||
item.kind === ApiItemKind.PropertySignature ||
item.kind === ApiItemKind.Method ||
item.kind === ApiItemKind.MethodSignature ||
item.kind === ApiItemKind.Event
);
}
export function hasProperties(item: ApiItemContainerMixin) {
return resolveMembers(item, memberPredicate).some(
({ item: member }) => member.kind === ApiItemKind.Property || member.kind === ApiItemKind.PropertySignature,
);
}
export function hasMethods(item: ApiItemContainerMixin) {
return resolveMembers(item, memberPredicate).some(
({ item: member }) => member.kind === ApiItemKind.Method || member.kind === ApiItemKind.MethodSignature,
);
}
export function hasEvents(item: ApiItemContainerMixin) {
return resolveMembers(item, memberPredicate).some(({ item: member }) => member.kind === ApiItemKind.Event);
}
interface ApiItemLike {
containerKey?: string;
displayName: string;
kind: string;
members?: readonly ApiItemLike[];
parent?: ApiItemLike | undefined;
}
function resolveItemURI(item: ApiItemLike): string {
return !item.parent || item.parent.kind === ApiItemKind.EntryPoint
? `${item.displayName}:${item.kind}`
: `${item.parent.displayName}:${item.parent.kind}#${item.displayName}`;
}
function itemExcerptText(excerpt: Excerpt, apiPackage: ApiPackage) {
const DISCORD_API_TYPES_VERSION = 'v10';
const DISCORD_API_TYPES_DOCS_URL = `https://discord-api-types.dev/api/discord-api-types-${DISCORD_API_TYPES_VERSION}`;
return excerpt.spannedTokens.map((token) => {
if (token.kind === ExcerptTokenKind.Reference) {
const source = token.canonicalReference?.source;
const symbol = token.canonicalReference?.symbol;
if (source && 'packageName' in source && source.packageName === 'discord-api-types' && symbol) {
const { meaning, componentPath: path } = symbol;
let href = DISCORD_API_TYPES_DOCS_URL;
// dapi-types doesn't have routes for class members
// so we can assume this member is for an enum
if (meaning === 'member' && path && 'parent' in path) {
href += `/enum/${path.parent}#${path.component}`;
} else if (meaning === 'type' || meaning === 'var') {
href += `#${token.text}`;
} else {
href += `/${meaning}/${token.text}`;
}
return {
text: token.text,
href,
};
}
const resolved = token.canonicalReference
? resolveCanonicalReference(token.canonicalReference, apiPackage)
: null;
if (!resolved) {
return {
text: token.text,
};
}
return {
text: token.text,
resolvedItem: {
kind: resolved.item.kind,
displayName: resolved.item.displayName,
containerKey: resolved.item.containerKey,
uri: resolveItemURI(resolved.item),
packageName: resolved.package,
version: resolved.version,
},
};
}
return {
text: token.text,
};
});
}
function itemTsDoc(item: DocNode, apiItem: ApiItem) {
const DISCORD_API_TYPES_VERSION = 'v10';
const DISCORD_API_TYPES_DOCS_URL = `https://discord-api-types.dev/api/discord-api-types-${DISCORD_API_TYPES_VERSION}`;
const createNode = (node: DocNode): any => {
switch (node.kind) {
case DocNodeKind.PlainText:
return {
kind: DocNodeKind.PlainText,
text: (node as DocPlainText).text,
};
case DocNodeKind.Section:
case DocNodeKind.Paragraph:
return (node as DocNodeContainer).nodes.map((node) => createNode(node));
case DocNodeKind.SoftBreak:
return {
kind: DocNodeKind.SoftBreak,
text: null,
};
case DocNodeKind.LinkTag: {
const { codeDestination, urlDestination, linkText } = node as DocLinkTag;
if (codeDestination) {
if (
!codeDestination.importPath &&
!codeDestination.packageName &&
codeDestination.memberReferences.length === 1 &&
codeDestination.memberReferences[0]!.memberIdentifier
) {
const typeName = codeDestination.memberReferences[0]!.memberIdentifier.identifier;
return {
kind: DocNodeKind.LinkTag,
text: typeName,
};
}
const declarationReference = apiItem
.getAssociatedModel()
?.resolveDeclarationReference(codeDestination, apiItem);
const foundItem = declarationReference?.resolvedApiItem;
const resolved = resolveCanonicalReference(codeDestination, apiItem.getAssociatedPackage());
if (!foundItem && !resolved) {
return {
kind: DocNodeKind.LinkTag,
text: null,
};
}
if (resolved && resolved.package === 'discord-api-types') {
const { displayName, kind, members, containerKey } = resolved.item;
let href = DISCORD_API_TYPES_DOCS_URL;
// dapi-types doesn't have routes for class members
// so we can assume this member is for an enum
if (kind === 'enum' && members?.[0]) {
href += `/enum/${displayName}#${members[0].displayName}`;
} else if (kind === 'type' || kind === 'var') {
href += `#${displayName}`;
} else {
href += `/${kind}/${displayName}`;
}
return {
kind: DocNodeKind.LinkTag,
text: displayName,
containerKey,
uri: href,
members: members?.map((member) => `.${member.displayName}`).join('') ?? '',
};
}
return {
kind: DocNodeKind.LinkTag,
text: linkText ?? foundItem?.displayName ?? resolved!.item.displayName,
uri: resolveItemURI(foundItem ?? resolved!.item),
resolvedPackage: {
packageName: resolved?.package ?? apiItem.getAssociatedPackage()?.displayName,
version: resolved?.package
? apiItem.getAssociatedPackage()?.dependencies?.[resolved.package] ?? null
: null,
},
};
}
if (urlDestination) {
return {
kind: DocNodeKind.LinkTag,
text: linkText ?? urlDestination,
uri: urlDestination,
};
}
return {
kind: DocNodeKind.LinkTag,
text: null,
};
}
case DocNodeKind.CodeSpan: {
const { code } = node as DocFencedCode;
return {
kind: DocNodeKind.CodeSpan,
text: code,
};
}
case DocNodeKind.FencedCode: {
const { language, code } = node as DocFencedCode;
return {
kind: DocNodeKind.FencedCode,
text: code,
language,
};
}
case DocNodeKind.Comment: {
const comment = node as DocComment;
const exampleBlocks = comment.customBlocks.filter(
(block) => block.blockTag.tagName.toUpperCase() === StandardTags.example.tagNameWithUpperCase,
);
const defaultValueBlock = comment.customBlocks.find(
(block) => block.blockTag.tagName.toUpperCase() === StandardTags.defaultValue.tagNameWithUpperCase,
);
return {
kind: DocNodeKind.Comment,
deprecatedBlock: comment.deprecatedBlock ? createNode(comment.deprecatedBlock.content) : null,
summarySection: comment.summarySection ? createNode(comment.summarySection) : null,
remarksBlock: comment.remarksBlock ? createNode(comment.remarksBlock.content) : null,
defaultValueBlock: defaultValueBlock ? createNode(defaultValueBlock.content) : null,
returnsBlock: comment.returnsBlock ? createNode(comment.returnsBlock.content) : null,
exampleBlocks: exampleBlocks.map((block) => createNode(block.content)),
seeBlocks: comment.seeBlocks.map((block) => createNode(block.content)),
};
}
default:
return {};
}
};
return item.kind === DocNodeKind.Paragraph || item.kind === DocNodeKind.Section
? (item as DocNodeContainer).nodes.flatMap((node) => createNode(node))
: createNode(item);
}
function itemInfo(item: ApiDeclaredItem) {
const sourceExcerpt = item.excerpt.text.trim();
const isStatic = ApiStaticMixin.isBaseClassOf(item) && item.isStatic;
const isProtected = ApiProtectedMixin.isBaseClassOf(item) && item.isProtected;
const isReadonly = ApiReadonlyMixin.isBaseClassOf(item) && item.isReadonly;
const isAbstract = ApiAbstractMixin.isBaseClassOf(item) && item.isAbstract;
const isDeprecated = Boolean(item.tsdocComment?.deprecatedBlock);
const hasSummary = Boolean(item.tsdocComment?.summarySection);
return {
kind: item.kind,
displayName: item.displayName,
sourceURL: item.sourceLocation.fileUrl,
sourceLine: item.sourceLocation.fileLine,
sourceExcerpt,
summary: hasSummary ? itemTsDoc(item.tsdocComment!.summarySection!, item) : null,
isStatic,
isProtected,
isReadonly,
isAbstract,
isDeprecated,
};
}
/**
* This takes an api item with a parameter list and resolves the names and descriptions of all the parameters.
*
* @remarks
* This is different from accessing `Parameter#name` or `Parameter.tsdocBlockComment` as this method cross-references the associated tsdoc
* parameter names and descriptions and uses them as a higher precedence to the source code.
* @param item - The api item to resolve parameter data for
* @returns An array of parameters
*/
function resolveParameters(item: ApiDocumentedItem & ApiParameterListMixin) {
return item.parameters.map((param, idx) => {
const tsdocAnalog =
item.tsdocComment?.params.blocks[idx] ??
item
.getMergedSiblings()
.find(
(paramList): paramList is ApiDocumentedItem & ApiParameterListMixin =>
ApiParameterListMixin.isBaseClassOf(paramList) && paramList.overloadIndex === 1,
)?.tsdocComment?.params.blocks[idx];
return {
name: param.tsdocParamBlock?.parameterName ?? tsdocAnalog?.parameterName ?? param.name,
description: param.tsdocParamBlock?.content ?? tsdocAnalog?.content,
isOptional: param.isOptional,
isRest: param.isRest,
parameterTypeExcerpt: param.parameterTypeExcerpt,
};
});
}
function itemTypeParameters(item: ApiTypeParameterListMixin) {
// {
// Name: typeParam.name,
// Constraints: <ExcerptText excerpt={typeParam.constraintExcerpt} apiPackage={item.getAssociatedPackage()!} />,
// Optional: typeParam.isOptional ? 'Yes' : 'No',
// Default: <ExcerptText excerpt={typeParam.defaultTypeExcerpt} apiPackage={item.getAssociatedPackage()!} />,
// Description: typeParam.tsdocTypeParamBlock ? (
// <TSDoc item={item} tsdoc={typeParam.tsdocTypeParamBlock.content} />
// ) : (
// 'None'
// ),
// }
return item.typeParameters.map((typeParam) => ({
name: typeParam.name,
constraintsExcerpt: itemExcerptText(typeParam.constraintExcerpt, item.getAssociatedPackage()!),
optional: typeParam.isOptional,
defaultExcerpt: itemExcerptText(typeParam.defaultTypeExcerpt, item.getAssociatedPackage()!),
description: typeParam.tsdocTypeParamBlock ? itemTsDoc(typeParam.tsdocTypeParamBlock.content, item) : null,
}));
}
function itemParameters(item: ApiDocumentedItem & ApiParameterListMixin) {
const params = resolveParameters(item);
// {
// Name: param.isRest ? `...${param.name}` : param.name,
// Type: <ExcerptText excerpt={param.parameterTypeExcerpt} apiPackage={item.getAssociatedPackage()!} />,
// Optional: param.isOptional ? 'Yes' : 'No',
// Description: param.description ? <TSDoc item={item} tsdoc={param.description} /> : 'None',
// }
return params.map((param) => ({
name: param.isRest ? `...${param.name}` : param.name,
typeExcerpt: itemExcerptText(param.parameterTypeExcerpt, item.getAssociatedPackage()!),
optional: param.isOptional,
description: param.description ? itemTsDoc(param.description, item) : null,
}));
}
function itemConstructor(item: ApiConstructor) {
return {
kind: item.kind,
name: item.displayName,
sourceURL: item.sourceLocation.fileUrl,
sourceLine: item.sourceLocation.fileLine,
summary: item.tsdocComment ? itemTsDoc(item.tsdocComment, item) : null,
parameters: itemParameters(item),
};
}
function isEventLike(item: ApiItem): item is ApiEvent {
return item.kind === ApiItemKind.Event;
}
function itemEvent(item: ApiItemContainerMixin) {
const members = resolveMembers(item, isEventLike);
return members.map((event) => {
const hasSummary = Boolean(event.item.tsdocComment?.summarySection);
return {
...itemInfo(event.item),
inheritedFrom: event.inherited?.displayName,
summary: hasSummary ? itemTsDoc(event.item.tsdocComment!, event.item) : null,
parameters: itemParameters(event.item),
};
});
}
function isPropertyLike(item: ApiItem): item is ApiProperty | ApiPropertySignature {
return item.kind === ApiItemKind.Property || item.kind === ApiItemKind.PropertySignature;
}
function itemProperty(item: ApiItemContainerMixin) {
const members = resolveMembers(item, isPropertyLike);
return members.map((property) => {
const hasSummary = Boolean(property.item.tsdocComment?.summarySection);
return {
...itemInfo(property.item),
inheritedFrom: property.inherited?.displayName,
typeExcerpt: itemExcerptText(property.item.propertyTypeExcerpt, property.item.getAssociatedPackage()!),
summary: hasSummary ? itemTsDoc(property.item.tsdocComment!, property.item) : null,
};
});
}
function parametersString(item: ApiDocumentedItem & ApiParameterListMixin) {
return resolveParameters(item).reduce((prev, cur, index) => {
if (index === 0) {
return `${prev}${cur.isRest ? '...' : ''}${cur.isOptional ? `${cur.name}?` : cur.name}`;
}
return `${prev}, ${cur.isRest ? '...' : ''}${cur.isOptional ? `${cur.name}?` : cur.name}`;
}, '');
}
function isMethodLike(item: ApiItem): item is ApiMethod | ApiMethodSignature {
return (
item.kind === ApiItemKind.Method ||
(item.kind === ApiItemKind.MethodSignature && (item as ApiMethod).overloadIndex <= 1)
);
}
function itemMethod(item: ApiItemContainerMixin) {
const members = resolveMembers(item, isMethodLike);
return members.map((method) => {
const parent = method.item.parent as ApiDeclaredItem;
const firstOverload = method.item
.getMergedSiblings()
.find(
(meth): meth is ApiMethod => meth.kind === ApiItemKind.Method && (meth as ApiMethod).overloadIndex === 1,
)?.tsdocComment;
const hasSummary = Boolean(method.item.tsdocComment?.summarySection ?? firstOverload?.summarySection);
return {
...itemInfo(method.item),
parametersString: parametersString(method.item),
returnTypeExcerpt: itemExcerptText(method.item.returnTypeExcerpt, method.item.getAssociatedPackage()!),
inheritedFrom: parent ? method.inherited?.displayName : null,
typeParameters: itemTypeParameters(method.item),
parameters: itemParameters(method.item),
summary: hasSummary ? itemTsDoc(method.item.tsdocComment ?? firstOverload!, method.item) : null,
};
});
}
function itemMembers(item: ApiDeclaredItem & ApiItemContainerMixin) {
const events = hasEvents(item) ? itemEvent(item) : [];
const properties = hasProperties(item) ? itemProperty(item) : [];
const methods = hasMethods(item) ? itemMethod(item) : [];
return {
events,
properties,
methods,
};
}
export function itemHierarchyText({
item,
type,
}: {
readonly item: ApiClass | ApiInterface;
readonly type: 'Extends' | 'Implements';
}) {
if (
(item.kind === ApiItemKind.Class &&
(item as ApiClass).extendsType === undefined &&
(item as ApiClass).implementsTypes.length === 0) ||
(item.kind === ApiItemKind.Interface && !(item as ApiInterface).extendsTypes)
) {
return null;
}
let excerpts: Excerpt[];
if (item.kind === ApiItemKind.Class) {
if (type === 'Implements') {
if ((item as ApiClass).implementsTypes.length === 0) {
return null;
}
excerpts = (item as ApiClass).implementsTypes.map((typeExcerpt) => typeExcerpt.excerpt);
} else {
if (!(item as ApiClass).extendsType) {
return null;
}
excerpts = [(item as ApiClass).extendsType!.excerpt];
}
} else {
if ((item as ApiInterface).extendsTypes.length === 0) {
return null;
}
excerpts = (item as ApiInterface).extendsTypes.map((typeExcerpt) => typeExcerpt.excerpt);
}
// return (
// <div className="flex flex-col gap-4">
// {excerpts.map((excerpt, idx) => (
// <div className="flex flex-row place-items-center gap-4" key={`${type}-${idx}`}>
// <h3 className="text-xl font-bold">{type}</h3>
// <span className="break-all font-mono space-y-2">
// <ExcerptText excerpt={excerpt} apiPackage={item.getAssociatedPackage()!} />
// </span>
// </div>
// ))}
// </div>
// );
return excerpts.map((excerpt) => {
return {
type,
excerpts: itemExcerptText(excerpt, item.getAssociatedPackage()!),
};
});
}
function itemClass(item: ApiClass) {
const constructor = item.members.find((member) => member.kind === ApiItemKind.Constructor) as
| ApiConstructor
| undefined;
return {
...itemInfo(item),
extends: itemHierarchyText({ item, type: 'Extends' }),
implements: itemHierarchyText({ item, type: 'Implements' }),
typeParameters: itemTypeParameters(item),
constructor: constructor ? itemConstructor(constructor) : null,
members: itemMembers(item),
};
}
function itemFunction(item: ApiFunction) {
return {
...itemInfo(item),
typeParameters: itemTypeParameters(item),
parameters: itemParameters(item),
};
}
function itemInterface(item: ApiInterface) {
return {
...itemInfo(item),
extends: itemHierarchyText({ item, type: 'Extends' }),
typeParameters: itemTypeParameters(item),
members: itemMembers(item),
};
}
function itemUnion(item: ApiTypeAlias) {
const union: ExcerptToken[][] = [];
let currentUnionMember: ExcerptToken[] = [];
let depth = 0;
for (const token of item.typeExcerpt.spannedTokens) {
if (token.text.includes('?')) {
return [item.typeExcerpt.spannedTokens];
}
depth += token.text.split('<').length - token.text.split('>').length;
if (token.text.trim() === '|' && depth === 0) {
if (currentUnionMember.length) {
union.push(currentUnionMember);
currentUnionMember = [];
}
} else if (depth === 0 && token.kind === ExcerptTokenKind.Content && token.text.includes('|')) {
for (const [idx, tokenpart] of token.text.split('|').entries()) {
if (currentUnionMember.length && depth === 0 && idx === 0) {
currentUnionMember.push(new ExcerptToken(ExcerptTokenKind.Content, tokenpart));
union.push(currentUnionMember);
currentUnionMember = [];
} else if (currentUnionMember.length && depth === 0) {
union.push(currentUnionMember);
currentUnionMember = [new ExcerptToken(ExcerptTokenKind.Content, tokenpart)];
} else if (tokenpart.length) {
currentUnionMember.push(new ExcerptToken(ExcerptTokenKind.Content, tokenpart));
}
}
} else {
currentUnionMember.push(token);
}
}
if (currentUnionMember.length) {
union.push(currentUnionMember);
}
return union;
}
function itemTypeAlias(item: ApiTypeAlias) {
return {
...itemInfo(item),
unionMembers: itemUnion(item).map((member) =>
itemExcerptText(new Excerpt(member, { startIndex: 0, endIndex: member.length }), item.getAssociatedPackage()!),
),
};
}
function itemVariable(item: ApiVariable) {
return {
...itemInfo(item),
};
}
function itemEnumMember(item: ApiEnumMember) {
return {
...itemInfo(item),
name: item.name,
initializerExcerpt: item.initializerExcerpt
? itemExcerptText(item.initializerExcerpt, item.getAssociatedPackage()!)
: null,
};
}
function itemEnum(item: ApiEnum) {
return {
...itemInfo(item),
members: item.members.map((member) => itemEnumMember(member)),
};
}
function memberKind(member: ApiItem | null) {
switch (member?.kind) {
case 'Class': {
const classMember = member as ApiClass;
return itemClass(classMember);
}
case 'Function': {
const functionMember = member as ApiFunction;
return itemFunction(functionMember);
}
case 'Interface': {
const interfaceMember = member as ApiInterface;
return itemInterface(interfaceMember);
}
case 'TypeAlias': {
const typeAliasMember = member as ApiTypeAlias;
return itemTypeAlias(typeAliasMember);
}
case 'Variable': {
const variableMember = member as ApiVariable;
return itemVariable(variableMember);
}
case 'Enum': {
const enumMember = member as ApiEnum;
return itemEnum(enumMember);
}
default:
return null;
}
}
async function writeSplitDocsToFileSystem(member: Record<string, any>, tag = 'main') {
const dir = 'split';
try {
(await stat(join(cwd(), 'docs', dir))).isDirectory();
} catch {
await mkdir(join(cwd(), 'docs', dir));
}
await writeFile(
join(cwd(), 'docs', dir, `${tag}.${member.displayName}.${member.kind}.api.json`),
JSON.stringify(member),
);
}
export async function generateSplitDocumentation({
fetchPackageVersions = fetchVersions,
fetchPackageVersionDocs = fetchVersionDocs,
} = {}) {
for (const pkgName of PACKAGES) {
const versions = await fetchPackageVersions(pkgName);
for (const version of versions) {
const data = await fetchPackageVersionDocs(pkgName, version);
const model = new ApiModel();
model.addMember(ApiPackage.loadFromJson(data));
const pkg = model.tryGetPackageByName(pkgName);
const entry = pkg?.entryPoints[0];
if (!entry) {
continue;
}
const members = entry.members.map((item) => ({
kind: item.kind,
name: item.displayName,
href: resolveItemURI(item),
overloadIndex: 'overloadIndex' in item ? (item.overloadIndex as number) : undefined,
}));
// await writeSplitDocsToFileSystem(members, version);
for (const member of members) {
const item = `${member.name}:${member.kind}`;
const [memberName, overloadIndex] = decodeURIComponent(item).split(':');
// eslint-disable-next-line prefer-const
let { containerKey, displayName: name } = findMember(model, pkgName, memberName) ?? {};
if (name && overloadIndex && !Number.isNaN(Number.parseInt(overloadIndex, 10))) {
containerKey = ApiFunction.getContainerKey(name, Number.parseInt(overloadIndex, 10));
}
const foundMember = memberName && containerKey ? findMemberByKey(model, pkgName, containerKey) ?? null : null;
const returnValue = memberKind(foundMember);
if (!returnValue) {
continue;
}
await writeSplitDocsToFileSystem(returnValue, version);
}
}
}
}

View file

@ -1 +1,2 @@
export * from './generateIndex.js';
export * from './generateSplitDocumentation.js';

View file

@ -0,0 +1,26 @@
import { request } from 'undici';
export const PACKAGES = [
'discord.js',
'brokers',
'builders',
'collection',
'core',
'formatters',
'next',
'proxy',
'rest',
'util',
'voice',
'ws',
];
export async function fetchVersions(pkg: string) {
const response = await request(`https://docs.discordjs.dev/api/info?package=${pkg}`);
return response.body.json() as Promise<string[]>;
}
export async function fetchVersionDocs(pkg: string, version: string) {
const response = await request(`https://docs.discordjs.dev/docs/${pkg}/${version}.api.json`);
return response.body.json();
}

View file

@ -2,6 +2,7 @@ import { createTsupConfig } from '../../tsup.config.js';
export default [
createTsupConfig({
entry: ['src/index.ts', 'bin/generateSplitDocumentation.ts'],
minify: 'terser',
}),
createTsupConfig({

View file

@ -10,7 +10,7 @@
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src",
"fmt": "pnpm run format",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run lint && pnpm run test && pnpm run build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/util/*'",
"release": "cliff-jumper"
@ -62,6 +62,7 @@
"homepage": "https://discord.js.org",
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "16.18.60",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -10,7 +10,7 @@
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"fmt": "pnpm run format",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run lint && pnpm run test && pnpm run build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/voice/*'",
"release": "cliff-jumper"
@ -73,6 +73,7 @@
"@babel/preset-env": "^7.23.9",
"@babel/preset-typescript": "^7.23.3",
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/jest": "^29.5.12",
"@types/node": "16.18.60",

View file

@ -9,7 +9,7 @@
"build:docs": "tsc -p tsconfig.docs.json",
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"docs": "pnpm run build:docs && api-extractor run --local --minify",
"docs": "pnpm run build:docs && api-extractor run --local --minify && generate-split-documentation",
"prepack": "pnpm run build && pnpm run lint",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/ws/*'",
"release": "cliff-jumper"
@ -84,6 +84,7 @@
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
"@discordjs/scripts": "workspace:^",
"@favware/cliff-jumper": "^2.2.3",
"@types/node": "18.17.9",
"@vitest/coverage-v8": "^1.2.2",

View file

@ -619,6 +619,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -686,6 +689,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -734,6 +740,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -798,6 +807,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -953,6 +965,9 @@ importers:
'@discordjs/docgen':
specifier: workspace:^
version: link:../docgen
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: 2.2.3
version: 2.2.3
@ -1054,6 +1069,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -1124,6 +1142,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -1182,6 +1203,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -1301,6 +1325,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -1364,6 +1391,9 @@ importers:
'@vercel/postgres':
specifier: ^0.7.2
version: 0.7.2
commander:
specifier: ^11.1.0
version: 11.1.0
tslib:
specifier: ^2.6.2
version: 2.6.2
@ -1525,6 +1555,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -1598,6 +1631,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -1680,6 +1716,9 @@ importers:
'@discordjs/api-extractor':
specifier: workspace:^
version: link:../api-extractor
'@discordjs/scripts':
specifier: workspace:^
version: link:../scripts
'@favware/cliff-jumper':
specifier: ^2.2.3
version: 2.2.3
@ -4020,7 +4059,7 @@ packages:
dependencies:
'@definitelytyped/typescript-versions': 0.1.0
'@definitelytyped/utils': 0.1.1
semver: 7.6.0
semver: 7.5.4
dev: true
/@definitelytyped/typescript-packages@0.1.0:
@ -4036,7 +4075,7 @@ packages:
typescript-5.1: /typescript@5.1.6
typescript-5.2: /typescript@5.2.2
typescript-5.3: /typescript@5.3.3
typescript-5.4: /typescript@5.4.0-dev.20240205
typescript-5.4: /typescript@5.4.0-dev.20240206
dev: true
/@definitelytyped/typescript-versions@0.1.0:
@ -5591,7 +5630,7 @@ packages:
nopt: 7.2.0
proc-log: 3.0.0
read-package-json-fast: 3.0.2
semver: 7.6.0
semver: 7.5.4
walk-up-path: 3.0.1
dev: true
@ -5599,7 +5638,7 @@ packages:
resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
dependencies:
semver: 7.6.0
semver: 7.5.4
dev: true
/@npmcli/map-workspaces@3.0.4:
@ -5947,7 +5986,7 @@ packages:
request: 2.88.2
retry: 0.12.0
safe-buffer: 5.2.1
semver: 7.6.0
semver: 7.5.4
slide: 1.1.6
ssri: 8.0.1
optionalDependencies:
@ -7736,7 +7775,7 @@ packages:
pretty-hrtime: 1.0.3
prompts: 2.4.2
read-pkg-up: 7.0.1
semver: 7.6.0
semver: 7.5.4
telejson: 7.2.0
tiny-invariant: 1.3.1
ts-dedent: 2.2.0
@ -9028,7 +9067,7 @@ packages:
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
semver: 7.6.0
semver: 7.5.4
tsutils: 3.21.0(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@ -9050,7 +9089,7 @@ packages:
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.3
semver: 7.6.0
semver: 7.5.4
ts-api-utils: 1.2.0(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@ -9096,7 +9135,7 @@ packages:
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.3)
eslint: 8.56.0
eslint-scope: 5.1.1
semver: 7.6.0
semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
@ -9692,7 +9731,7 @@ packages:
std-env: 3.7.0
test-exclude: 6.0.0
v8-to-istanbul: 9.2.0
vitest: 1.2.2(@types/node@18.18.8)(happy-dom@13.3.8)
vitest: 1.2.2(@types/node@18.17.9)
transitivePeerDependencies:
- supports-color
dev: true
@ -11757,7 +11796,7 @@ packages:
handlebars: 4.7.8
json-stringify-safe: 5.0.1
meow: 12.1.1
semver: 7.6.0
semver: 7.5.4
split2: 4.2.0
dev: true
@ -12505,7 +12544,7 @@ packages:
dependencies:
semver: 7.5.4
shelljs: 0.8.5
typescript: 5.4.0-dev.20240205
typescript: 5.4.0-dev.20240206
dev: true
/dts-critic@3.3.11(typescript@5.3.3):
@ -13445,7 +13484,7 @@ packages:
get-tsconfig: 4.7.2
is-glob: 4.0.3
minimatch: 3.1.2
semver: 7.6.0
semver: 7.5.4
transitivePeerDependencies:
- '@typescript-eslint/parser'
- eslint-import-resolver-typescript
@ -19045,7 +19084,7 @@ packages:
dependencies:
hosted-git-info: 7.0.1
is-core-module: 2.13.1
semver: 7.6.0
semver: 7.5.4
validate-npm-package-license: 3.0.4
dev: true
@ -19073,7 +19112,7 @@ packages:
engines: {node: '>=10'}
dependencies:
hosted-git-info: 4.1.0
semver: 7.6.0
semver: 7.5.4
validate-npm-package-name: 3.0.0
dev: true
@ -23016,8 +23055,8 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
/typescript@5.4.0-dev.20240205:
resolution: {integrity: sha512-waxaX9QSNlTxyhaeS398h73fWzOr0DOq2rV6ZQSDywcabZjxeiCv18hYDIZXRk4dT0Q0DxhbNAL/THzjKjtDlQ==}
/typescript@5.4.0-dev.20240206:
resolution: {integrity: sha512-8P1XYxDbG/AyGE5tB8+JpeiQfS5ye1BTvIVDZaHhoK9nJuCn4nkB0L66lvfwYB+46hA4rLo3vE3WkIToSYtqQA==}
engines: {node: '>=14.17'}
hasBin: true
dev: true