Skip to content

Commit

Permalink
Merge pull request #74 from slash-create/feat/discordjs-docs-query
Browse files Browse the repository at this point in the history
Add discord.js to providers
  • Loading branch information
sudojunior authored Dec 14, 2024
2 parents ce03e5f + 99905ff commit a2bb01d
Show file tree
Hide file tree
Showing 14 changed files with 426 additions and 101 deletions.
Binary file modified bun.lockb
Binary file not shown.
18 changes: 11 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,20 @@
"lint:fix": "npx eslint --ext .ts ./src --fix"
},
"dependencies": {
"chrono-node": "^2.7.3",
"convert-units": "^3.0.0-beta.6",
"chrono-node": "^2.7.7",
"convert-units": "^3.0.0-beta.7",
"fuzzy": "^0.1.3",
"slash-create": "^6.1.2"
"slash-create": "^6.3.0"
},
"devDependencies": {
"@biomejs/biome": "^1.7.0",
"@types/bun": "^1.0.8",
"@biomejs/biome": "^1.9.4",
"@types/bun": "^1.1.14",
"eventemitter3": "^5.0.1",
"lodash.isequal": "^4.5.0",
"slash-up": "^1.4.2",
"ts-node": "^10.9.1",
"typescript": "5.4.1-rc"
"ts-node": "^10.9.2",
"tweetnacl": "^1.0.3",
"typescript": "5.4.1-rc",
"undici": "^6.21.0"
}
}
17 changes: 10 additions & 7 deletions src/commands/code.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
ApplicationIntegrationType,
ButtonStyle,
CommandOptionType,
ComponentType,
Expand Down Expand Up @@ -105,13 +104,17 @@ export default class CodeCommand extends BaseCommand {
const results = focusedOption.length
? Provider.filter(focusedOption)
: Provider.all.map((provider) => {
return { original: provider, string: provider.label };
return { original: provider };
});

return results.map((result) => ({
name: `${result.original.label} (${result.original.docsHost})`,
value: result.string,
}));
return results
.map(({ original: provider }) => {
return {
name: `${provider.label} (${provider.docs.host})`,
value: provider.label,
};
})
.slice(0, 20);
}
case "version": {
const provider = Provider.get(options.library.split("(")[0].trim());
Expand Down Expand Up @@ -219,7 +222,7 @@ export default class CodeCommand extends BaseCommand {
}

const res = await typeNavigator.aggregator.provider.fetchGitHubRaw(
typeNavigator.rawFileURL(file),
typeNavigator.aggregator.provider.rawRepoURL(file),
);
const body = await res.text();
const lines = body.split("\n");
Expand Down
2 changes: 1 addition & 1 deletion src/commands/debug/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export default class ChatDebugCommand extends BaseCommand {
| ResolvedRole
| { id: string };

if (!ctx.guildID && ["role","guild"].includes(subCommand)) {
if (!ctx.guildID && ["role", "guild"].includes(subCommand)) {
return `</${this.commandName} ${subCommand}:${this.ids.get(
"global",
)}> is not in a guild context, you should not be here.`;
Expand Down
26 changes: 20 additions & 6 deletions src/commands/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import {
type SlashCreator,
} from "slash-create";

import { ephemeralResponse as _ } from "&common/helpers";
import {
ephemeralResponse as _,
debugContentLength,
trimUntilAccumulatedLength,
} from "&common/helpers";
import BaseCommand from "&discord/base-command";
import {
libraryOption,
Expand Down Expand Up @@ -75,7 +79,7 @@ export default class DocumentationCommand extends BaseCommand {
return filter(options.library ?? "", Provider.all, {
extract: (input) => input.label,
}).map((result) => ({
name: `${result.original.label} (${result.original.docsHost})`,
name: `${result.original.label} (${result.original.docs.host})`,
value: result.string,
}));
}
Expand Down Expand Up @@ -160,6 +164,7 @@ export default class DocumentationCommand extends BaseCommand {
const typeNavigator = provider.aggregator.getTag(
(options.version ?? "latest").split("(")[0].trim(),
);

if (!typeNavigator) return _(responses.unknown.name);
if (!typeNavigator.ready) {
await ctx.defer(!options.share);
Expand All @@ -172,13 +177,13 @@ export default class DocumentationCommand extends BaseCommand {
if (!descriptor) return _("Entity was `null`, please check arguments.");

const embed: MessageEmbedOptions = {
color: provider.embedColor,
color: provider.docs.embedColor,
title: `\`${descriptor.toString()}\``,
url: typeNavigator.docsURL(descriptor),
fields: [],
timestamp: new Date(ctx.invokedAt),
footer: {
text: `${provider.label} 🏷️ ${typeNavigator.tag} (🌐 ${provider.docsHost})`,
text: `${provider.label} 🏷️ ${typeNavigator.tag} (🌐 ${provider.docs.host})`,
icon_url: provider.iconURL,
},
};
Expand Down Expand Up @@ -334,7 +339,16 @@ export default class DocumentationCommand extends BaseCommand {
.join("\n") || "None",
inline: true,
},
].filter((field) => field && field.value !== "None");
]
.filter((field) => field && field.value !== "None")
.map((field) => ({
...field,
value: trimUntilAccumulatedLength(
900,
field.value.split("\n"),
true,
).join("\n"),
}));

private parseDocString = (
navigator: TypeNavigator,
Expand All @@ -352,7 +366,7 @@ export default class DocumentationCommand extends BaseCommand {
.flat(2)
.map((fragment) => {
if (navigator.map.has(fragment))
return `[${fragment}](${navigator.aggregator.provider.rawDocsURL(
return `[${fragment}](${navigator.aggregator.provider.partDocsURL(
navigator.tag,
"typedef",
fragment,
Expand Down
50 changes: 50 additions & 0 deletions src/experiments/ProxyMatrix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Option 1
*
* Calling 'branch', 'tag' or 'latest' will update the target key with the argument provided.
* If the target key already exists, it will be overwritten.
* If the proxy call follows with 'hours', 'minutes' or 'seconds', the value with be multiplied with the appropriate time unit.
* If the proxy call follows with 'build', it returns the object inside the proxy - ending the chain.
*
* @example
* expires()
* .branch(3).hours()
* .tag(30).minutes()
* .latest(2).minutes()
* .build()
*/
function expires() {
let key: string;

const context = { branch: 0, tag: 0, latest: 0 };

const handler: ProxyHandler<typeof context> = {
get(target, prop) {
if (prop === "branch" || prop === "tag" || prop === "latest") {
key = prop;
return new Proxy(this, handler);
}

if (prop === "hours") {
context[key] *= 60;
}

if (prop === "minutes") {
context[key] *= 60;
}

if (prop === "seconds") {
context[key] *= 60;
}
},
apply(target, thisArg, argArray) {
if (key === "build") {
return Object.freeze({ ...context });
}

return this;
},
};

return new Proxy(context, handler);
}
19 changes: 14 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import {
CommandOptionType,
type ApplicationCommandOption,
BunServer,
ChannelType,
BaseInteractionContext,
} from "slash-create";
import path from "node:path";

import { hashMapToString, titleCase } from "&common/helpers";
import { calculateContentLength, hashMapToString, titleCase } from "&common/helpers";
import registerComponents from "./components";

import { logPrefix, stringResolver } from "&console/context";
Expand Down Expand Up @@ -46,8 +44,9 @@ creator.on("commandRun", async (command, promise, ctx) => {
)} }`;

const wrappedTimer = duration();
await promise;
console.info(`${logPrefix(ctx)} ran ${commandString} in ${wrappedTimer()}`);
const res = await promise;
const contentLength = res ? `($${calculateContentLength(res)})` : "";
console.info(`${logPrefix(ctx)} ran ${commandString} in ${wrappedTimer()} ${contentLength}`);
});

creator.on("autocompleteInteraction", (ctx, command) => {
Expand Down Expand Up @@ -145,3 +144,13 @@ await Promise.allSettled(
Provider.all.map((provider) => provider.aggregator.onReady),
);
RequestQuota.debug();

process.on("uncaughtException", (error, origin) => {
console.log(JSON.stringify(error));
console.log(error);
console.log(origin);
});

process.on("unhandledRejection", (reason, promise) => {
console.log(reason);
});
84 changes: 84 additions & 0 deletions src/modules/common/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type MessageOptions, User } from "slash-create";
import type { MessageCharacterCount } from "./types";

export function capitalize(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
Expand Down Expand Up @@ -68,3 +69,86 @@ export function isEmpty(val: unknown) {

return empties.includes(val);
}

export function calculateContentLength(message: MessageOptions) {
let total = 0;

total += message.content?.length ?? 0;

for (const embed of message.embeds ?? []) {
total += embed.title?.length ?? 0;
total += embed.description?.length ?? 0;
total += embed.url?.length ?? 0;
total += embed.footer.text?.length ?? 0;

for (const field of embed.fields ?? []) {
total += field.name?.length ?? 0;
total += field.value?.length ?? 0;
}
}

return total;
}

export function debugContentLength(message: MessageOptions) {
const totals: Partial<MessageCharacterCount> = {
embeds: [],
};

totals.content = message.content?.length ?? 0;

for (const embed of message.embeds ?? []) {
const embedTotals: Partial<(typeof totals)["embeds"][number]> = {
fields: [],
};

embedTotals.title = embed.title?.length ?? 0;
embedTotals.description = embed.description?.length ?? 0;
embedTotals.url = embed.url?.length ?? 0;
embedTotals.footer = embed.footer.text?.length ?? 0;

for (const field of embed.fields ?? []) {
const fieldTotals: Partial<(typeof embedTotals)["fields"][number]> = {};

fieldTotals.name = field.name?.length ?? 0;
fieldTotals.value = field.value?.length ?? 0;
fieldTotals.$total = fieldTotals.name + fieldTotals.value;

embedTotals.fields.push(fieldTotals);
}

embedTotals.$total =
embedTotals.title +
embedTotals.description +
embedTotals.url +
embedTotals.footer +
embedTotals.fields.reduce((acc, field) => acc + field.$total, 0);

totals.embeds.push(embedTotals);
}

totals.$total =
totals.content +
totals.embeds.reduce((acc, embed) => acc + embed.$total, 0);

return totals;
}

export function trimUntilAccumulatedLength(
maxLength: number,
strings: string[],
addMessage: boolean,
) {
let trimmed = 0;
const total = () => strings.reduce((acc, str) => acc + str.length, 0);
const getMsg = () => `... and ${trimmed} more.`;

while (total() + getMsg().length >= maxLength) {
trimmed++;
strings.pop();
}

if (trimmed && addMessage) strings.push(getMsg());

return strings;
}
17 changes: 17 additions & 0 deletions src/modules/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,20 @@ export interface FileCacheEntry {
fetchedAt: number;
resolvedAs: string;
}

export interface MessageCharacterCount {
$total?: number;
content?: number;
embeds?: {
$total?: number;
title?: number;
description?: number;
url?: number;
footer?: number;
fields?: {
$total?: number;
name?: number;
value?: number;
}[];
}[];
}
2 changes: 1 addition & 1 deletion src/modules/docs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ export const GITHUB_WEB_URL = "https://github.com";
export const GITHUB_API_URL = "https://api.github.com";
export const GITHUB_RAW_URL = "https://raw.githubusercontent.com";

export const VERSION_REGEX = /v?\d\.\d+\.\d+/;
export const VERSION_REGEX = /^v?\d\.\d+\.\d+$/;
Loading

0 comments on commit a2bb01d

Please sign in to comment.