mirror of
https://github.com/jaronpate/unicord.git
synced 2026-10-18 21:47:40 +00:00
Some build proccess stuff
This commit is contained in:
+11
-3
@@ -1,15 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "discord.ts-rewrite",
|
"name": "discord.ts",
|
||||||
"module": "src/index.ts",
|
"module": "src/index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"main": "out/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "bun run testing/demo.test.ts",
|
"test": "bun run testing/demo.test.ts",
|
||||||
"test:inspect": "bun --inspect testing/demo.test.ts"
|
"test:inspect": "bun --inspect testing/demo.test.ts",
|
||||||
|
"build": "bun run build:types && bun build src/index.ts --outdir out",
|
||||||
|
"build:types": "tsc --emitDeclarationOnly --project tsconfig.json --noCheck",
|
||||||
|
"build:watch": "concurrently \"tsc --emitDeclarationOnly --project tsconfig.json --noCheck --watch\" \"bun build src/index.ts --outdir out --watch\""
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest",
|
||||||
|
"concurrently": "^9.1.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ws": "^8.18.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { exists, log } from "../utils";
|
||||||
import type { Client } from "./client";
|
import type { Client } from "./client";
|
||||||
|
|
||||||
export class API {
|
export class API {
|
||||||
@@ -32,6 +33,30 @@ export class API {
|
|||||||
// console.log(`API Body: ${JSON.stringify(data, null, 4)}`);
|
// console.log(`API Body: ${JSON.stringify(data, null, 4)}`);
|
||||||
// console.log('API Response:', JSON.stringify(body, null, 4));
|
// console.log('API Response:', JSON.stringify(body, null, 4));
|
||||||
|
|
||||||
|
// Extract rate limit headers
|
||||||
|
const remaining = response.headers.get('X-RateLimit-Remaining');
|
||||||
|
const limit = response.headers.get('X-RateLimit-Limit');
|
||||||
|
const reset = response.headers.get('X-RateLimit-Reset');
|
||||||
|
const resetSeconds = response.headers.get('X-RateLimit-Reset-After');
|
||||||
|
const limitBucket = response.headers.get('X-RateLimit-Bucket');
|
||||||
|
|
||||||
|
// Log rate limit info for debugging
|
||||||
|
log(`Rate Limit: ${remaining}/${limit} - Reset: ${reset} (${resetSeconds}s) - Bucket: ${limitBucket}`);
|
||||||
|
|
||||||
|
// If status is 429, we are being rate limited
|
||||||
|
if (response.status === 429) {
|
||||||
|
// Look for the retry-after header
|
||||||
|
const retryAfter = response.headers.get('Retry-After');
|
||||||
|
if (exists(retryAfter)) {
|
||||||
|
// Wait for the retry-after time
|
||||||
|
await new Promise(resolve => setTimeout(resolve, parseInt(retryAfter) * 1000));
|
||||||
|
} else {
|
||||||
|
// TODO: Handle this case better
|
||||||
|
// Maybe wait some arbitrary time??
|
||||||
|
throw new Error('Rate limited without Retry-After header');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,14 @@ export async function hydrate<T extends Hydrateable | Hydrated<any, any>, K exte
|
|||||||
|
|
||||||
if (data instanceof Context) {
|
if (data instanceof Context) {
|
||||||
for (const expectation of expectations) {
|
for (const expectation of expectations) {
|
||||||
if (expectation === Expectation.Guild && exists(data.guild_id)) {
|
if (expectation === Expectation.Message && exists(data.message_id)) {
|
||||||
|
let context = data as unknown as HydratedContext<[Expectation.Message, ...Expectation[]]>;
|
||||||
|
context.message = await client.messages.get(data.channel_id, data.message_id);
|
||||||
|
} else if (expectation === Expectation.Guild && exists(data.guild_id)) {
|
||||||
let context = data as unknown as HydratedContext<[Expectation.Guild, ...Expectation[]]>;
|
let context = data as unknown as HydratedContext<[Expectation.Guild, ...Expectation[]]>;
|
||||||
context.guild = await client.guilds.get(data.guild_id);
|
context.guild = await client.guilds.get(data.guild_id);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Could not resolve expectation: ${expectation}`);
|
throw new Error(`Invalid expectation requested for Context: ${expectation}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (data instanceof Message) {
|
} else if (data instanceof Message) {
|
||||||
@@ -54,7 +57,7 @@ export async function hydrate<T extends Hydrateable | Hydrated<any, any>, K exte
|
|||||||
let message = data as unknown as HydratedMessage<[Expectation.Guild, ...Expectation[]]>;
|
let message = data as unknown as HydratedMessage<[Expectation.Guild, ...Expectation[]]>;
|
||||||
message.guild = await client.guilds.get(data.guild_id);
|
message.guild = await client.guilds.get(data.guild_id);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Could not resolve expectation: ${expectation}`);
|
throw new Error(`Invalid expectation requested for Message: ${expectation}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,8 +102,6 @@ export class Context<D extends ContextData = ContextData> {
|
|||||||
* @returns The message that was sent
|
* @returns The message that was sent
|
||||||
*/
|
*/
|
||||||
public reply = async (message: Message | string, reference: boolean = true): Promise<MessagePayload> => {
|
public reply = async (message: Message | string, reference: boolean = true): Promise<MessagePayload> => {
|
||||||
console.log('this.interaction', this.interaction)
|
|
||||||
|
|
||||||
if (isNil(this.message)) {
|
if (isNil(this.message)) {
|
||||||
throw new Error('Cannot reply without a message');
|
throw new Error('Cannot reply without a message');
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-1
@@ -1,4 +1,4 @@
|
|||||||
import { isNil } from '../utils';
|
import { exists, isNil } from '../utils';
|
||||||
import { GatewayObject } from './base';
|
import { GatewayObject } from './base';
|
||||||
import { fromDiscord, Trait, type Expectation, type Expects } from './common';
|
import { fromDiscord, Trait, type Expectation, type Expects } from './common';
|
||||||
import { Embed } from './embed';
|
import { Embed } from './embed';
|
||||||
@@ -125,9 +125,17 @@ export class Message extends GatewayObject {
|
|||||||
this.channel_id = data?.channel_id;
|
this.channel_id = data?.channel_id;
|
||||||
this.guild_id = data?.guild_id;
|
this.guild_id = data?.guild_id;
|
||||||
this.content = data?.content ?? '';
|
this.content = data?.content ?? '';
|
||||||
|
this.message_reference = data?.message_reference;
|
||||||
this.timestamp = data?.timestamp;
|
this.timestamp = data?.timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NOTE: Overriden here because the `fromDiscord` method returns a `MessagePayload` object
|
||||||
|
// and the GatewayObject getter overrides the return type to `Message`
|
||||||
|
// TODO: Fix type in GatewayObject so this override is not needed
|
||||||
|
public static get fromDiscord() {
|
||||||
|
return this[Trait.fromDiscord];
|
||||||
|
}
|
||||||
|
|
||||||
public static [Trait.fromDiscord]<T = MessagePayload>(data: DiscordMessage): T {
|
public static [Trait.fromDiscord]<T = MessagePayload>(data: DiscordMessage): T {
|
||||||
return new Message({
|
return new Message({
|
||||||
id: data.id,
|
id: data.id,
|
||||||
@@ -135,6 +143,15 @@ export class Message extends GatewayObject {
|
|||||||
channel_id: data.channel_id,
|
channel_id: data.channel_id,
|
||||||
guild_id: data.guild_id,
|
guild_id: data.guild_id,
|
||||||
content: data.content,
|
content: data.content,
|
||||||
|
// TODO: Add embeds
|
||||||
|
// embeds: data.embeds.map(embed => Embed.fromDiscord(embed)),
|
||||||
|
// TODO: Add components
|
||||||
|
// components: data.components,
|
||||||
|
message_reference: exists(data.message_reference) ? {
|
||||||
|
id: data.message_reference.message_id,
|
||||||
|
channel_id: data.message_reference.channel_id,
|
||||||
|
guild_id: data.message_reference.guild_id
|
||||||
|
} : undefined,
|
||||||
timestamp: new Date(data.timestamp)
|
timestamp: new Date(data.timestamp)
|
||||||
}) as T;
|
}) as T;
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-22
@@ -10,7 +10,7 @@ const client = new Client({
|
|||||||
Intent.GUILD_MESSAGE_REACTIONS,
|
Intent.GUILD_MESSAGE_REACTIONS,
|
||||||
Intent.MESSAGE_CONTENT
|
Intent.MESSAGE_CONTENT
|
||||||
],
|
],
|
||||||
prefix: '??'
|
prefix: '!'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Register arbitrary event handler to the client bus
|
// Register arbitrary event handler to the client bus
|
||||||
@@ -105,25 +105,4 @@ client.chatCommands.register('here', async (context: Context, _args: any[]) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Quote command
|
|
||||||
client.chatCommands.register('quote', async (context: Context, _args: any[]) => {
|
|
||||||
const { message } = await context.hydrate(context, [Expectation.Message]);
|
|
||||||
const reference = (await context.hydrator(message, [Expectation.Message]))(message);
|
|
||||||
|
|
||||||
let reply: MessagePayload;
|
|
||||||
|
|
||||||
if (reference) {
|
|
||||||
reply = await context.reply(`> "${message.reference.content}"\n> — ${message.reference.author.display_name ?? message.reference.author.username}`, true);
|
|
||||||
// Save to quote database
|
|
||||||
// TODO
|
|
||||||
} else {
|
|
||||||
reply = await context.reply('No message to quote', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait 3 seconds then delete the quote
|
|
||||||
setTimeout(() => {
|
|
||||||
context.deleteMessage(reply.id);
|
|
||||||
}, 3000);
|
|
||||||
});
|
|
||||||
|
|
||||||
client.connect();
|
client.connect();
|
||||||
+6
-1
@@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"files": ["src/index.ts"],
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
// Enable latest features
|
// Enable latest features
|
||||||
"lib": ["ESNext", "DOM"],
|
"lib": ["ESNext", "DOM"],
|
||||||
@@ -8,11 +10,14 @@
|
|||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
|
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "out",
|
||||||
|
|
||||||
// Bundler mode
|
// Bundler mode
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
"verbatimModuleSyntax": true,
|
"verbatimModuleSyntax": true,
|
||||||
"noEmit": true,
|
"emitDeclarationOnly": true,
|
||||||
|
|
||||||
// Best practices
|
// Best practices
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user