Skip to content
Open
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
30 changes: 15 additions & 15 deletions src/apis/cache/cache.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as path from "@std/path";

function getCacheDir(): string {
function doGetCacheDir(): string {
const cacheHome = Deno.env.get('XDG_CACHE_HOME');
if (cacheHome) {
return path.join(cacheHome, 'justbot');
Expand All @@ -14,15 +14,15 @@ function getCacheDir(): string {
return path.join('/', 'tmp', 'jb-cache');
}

export async function init() {
await Deno.mkdir(getCacheDir(), { recursive: true });
export async function doInit() {
await Deno.mkdir(doGetCacheDir(), { recursive: true });
}

function getBoxFilepath(box: string): string {
return path.join(getCacheDir(), box + '.json');
function doGetBoxFilepath(box: string): string {
return path.join(doGetCacheDir(), box + '.json');
}

async function readBox(boxpath: string): Promise<Record<string, unknown>> {
async function doReadBox(boxpath: string): Promise<Record<string, unknown>> {
try {
const content = await Deno.readTextFile(boxpath);
return JSON.parse(content);
Expand All @@ -34,26 +34,26 @@ async function readBox(boxpath: string): Promise<Record<string, unknown>> {
}
}

export async function store<T>(box: string, key: string, value: T) {
const boxpath = getBoxFilepath(box);
export async function doStore<T>(box: string, key: string, value: T) {
const boxpath = doGetBoxFilepath(box);

const json = await readBox(boxpath);
const json = await doReadBox(boxpath);
json[key] = value;

await Deno.writeTextFile(boxpath, JSON.stringify(json, null, 2));
}

export async function load<T>(box: string, key: string): Promise<T | undefined> {
const boxpath = getBoxFilepath(box);
export async function doLoad<T>(box: string, key: string): Promise<T | undefined> {
const boxpath = doGetBoxFilepath(box);

const json = await readBox(boxpath);
const json = await doReadBox(boxpath);
return json[key] as T | undefined;
}

export async function del(box: string, key: string) {
const boxpath = getBoxFilepath(box);
export async function doDel(box: string, key: string) {
const boxpath = doGetBoxFilepath(box);

const json = await readBox(boxpath);
const json = await doReadBox(boxpath);
delete json[key];

await Deno.writeTextFile(boxpath, JSON.stringify(json, null, 2));
Expand Down
2 changes: 1 addition & 1 deletion src/apis/cdecl/cdecl.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class CdeclError extends Error {}

export default async function cdecl(query: string): Promise<string> {
export default async function doCdecl(query: string): Promise<string> {
const [mode, actualQuery]
= query.startsWith('declare ')
? ['declare', query.slice(8)]
Expand Down
16 changes: 8 additions & 8 deletions src/apis/compile/auto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { ZapCompilerDriver } from './zapbox.ts';

import { cfg } from '@/bot/cfg.ts';

const getReplaceMap = () => cfg.features.compilation.replaceCompilerMap;
const doGetReplaceMap = () => cfg.features.compilation.replaceCompilerMap;

function findWandboxCompilerName(lang: string): string {
const replaceMap = Object.entries(getReplaceMap());
function doFindWandboxCompilerName(lang: string): string {
const replaceMap = Object.entries(doGetReplaceMap());
const langNormalized = lang.trim().toLowerCase();
for (const [compiler, aliases] of replaceMap) {
const compilerNormalized = compiler.toLowerCase();
Expand All @@ -19,18 +19,18 @@ function findWandboxCompilerName(lang: string): string {
return lang;
}

async function isWandbox(lang: string): Promise<boolean> {
async function doIsWandbox(lang: string): Promise<boolean> {
const available = await WandboxCompilerDriver.fetchCompilerNames();
const isInReplaceMap = Object.values(getReplaceMap()).some(s => s.includes(lang));
const isInReplaceMap = Object.values(doGetReplaceMap()).some(s => s.includes(lang));
return available.includes(lang) || isInReplaceMap;
}

export async function getCompilerForLang(lang: string): Promise<compile.Driver> {
export async function doGetCompilerForLang(lang: string): Promise<compile.Driver> {
if (['zap', 'zp', 'zapc'].includes(lang)) {
return new ZapCompilerDriver();
}
if (await isWandbox(lang)) {
return new WandboxCompilerDriver({ compiler: findWandboxCompilerName(lang) });
if (await doIsWandbox(lang)) {
return new WandboxCompilerDriver({ compiler: doFindWandboxCompilerName(lang) });
}
return new GodBoltCompilerDriver(lang);
}
4 changes: 2 additions & 2 deletions src/apis/compile/zapbox.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as compile from '@/apis/compile/driver.ts';
import { output } from '@/bot/logging.ts';

export function isAvailable(): boolean {
export function doIsAvailable(): boolean {
return Deno.env.get('JB_ZAPBOX_PATH') != undefined;
}

let initialized: boolean = false;

export async function init() {
export async function doInit() {
const exePath = Deno.env.get('JB_ZAPBOX_PATH')
if (!exePath) return;

Expand Down
10 changes: 5 additions & 5 deletions src/apis/db/bot-db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { DB, QueryParameterSet } from 'sqlite';
import type { AIMemory, ContentEntry, ContentEntryRaw, Reminder, UserDataRaw, Warn, WarnRaw } from './db-defs.ts';

import type { Balance, Cooldown, Cooldowns } from './db-defs.ts';
import { contentFromRaw, warnFromRaw } from './db-defs.ts';
import { doContentFromRaw, doWarnFromRaw } from './db-defs.ts';

export type { ContentEntry, ContentEntryRaw, UserDataRaw, Warn, WarnRaw };
export type { Balance, Cooldown, Cooldowns };
export { contentFromRaw, warnFromRaw };
export { doContentFromRaw, doWarnFromRaw };

import User from './user.ts';
import { output } from '@/bot/logging.ts';
Expand Down Expand Up @@ -287,7 +287,7 @@ export class BotDatabase {
`SELECT * FROM warns ${max ? 'LIMIT ?' : ''}`,
max ? [max] : [],
);
return rows.map(warnFromRaw);
return rows.map(doWarnFromRaw);
},
};

Expand Down Expand Up @@ -328,15 +328,15 @@ export class BotDatabase {
`SELECT * FROM content_database WHERE key = ? ORDER BY RANDOM() LIMIT 1`,
[key],
);
return row ? contentFromRaw(row) : undefined;
return row ? doContentFromRaw(row) : undefined;
},

getEntriesByUser: async (userId: string, key: string): Promise<ContentEntry[]> => {
const rows = await this.selectMany<ContentEntryRaw>(
`SELECT * FROM content_database WHERE author_id = ? AND key = ?`,
[userId, key],
);
return rows.map(contentFromRaw);
return rows.map(doContentFromRaw);
},

batchAddEntries: async (entries: ContentEntry[]): Promise<void> => {
Expand Down
4 changes: 2 additions & 2 deletions src/apis/db/db-defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export interface AIMemory {
memory: string;
};

export function warnFromRaw(raw: WarnRaw): Warn {
export function doWarnFromRaw(raw: WarnRaw): Warn {
return {
id: raw.id,
moderatorId: raw.moderator_id,
Expand All @@ -69,7 +69,7 @@ export interface ContentEntry {
contentUrl: string;
}

export function contentFromRaw(raw: ContentEntryRaw): ContentEntry {
export function doContentFromRaw(raw: ContentEntryRaw): ContentEntry {
return {
authorId: raw.author_id,
contentUrl: raw.content_url,
Expand Down
4 changes: 2 additions & 2 deletions src/apis/db/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { db } from '@/apis/db/bot-db.ts';

import { Balance, UserDataRaw, Warn, WarnRaw } from './db-defs.ts';
import { Cooldowns } from './db-defs.ts';
import { warnFromRaw } from './db-defs.ts';
import { doWarnFromRaw } from './db-defs.ts';
import Money from '@/util/money.ts';
import { output } from '@/bot/logging.ts';

Expand Down Expand Up @@ -439,7 +439,7 @@ export default class User {
`SELECT * FROM warns WHERE user_id = ? ORDER BY id DESC`,
[this.id],
);
return rawWarns.map(warnFromRaw);
return rawWarns.map(doWarnFromRaw);
},

clearExpired: async () => {
Expand Down
4 changes: 2 additions & 2 deletions src/apis/email/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export interface ReceivedNewEmail {
}
export const ReceivedNewEmailEvent = actionsManager.mkEvent('ReceivedNewEmailEvent');

export async function initEmailActionsIntegration() {
email.listenForNewEmails((email) => {
export async function doInitEmailActionsIntegration() {
email.doListenForNewEmails((email) => {
actionsManager.emit<ReceivedNewEmail>(ReceivedNewEmailEvent, { email });
});
}
Expand Down
8 changes: 4 additions & 4 deletions src/apis/email/mail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import mp from 'mailparser';
let transporter: nm.Transporter | null = null;
let imapClient: im.ImapFlow | null = null;

export async function init() {
export async function doInit() {
transporter = nm.createTransport({
service: 'gmail',
auth: {
Expand Down Expand Up @@ -34,7 +34,7 @@ export interface SendEmail {

export type ReceivedEmail = mp.ParsedMail;

export async function sendMessage({ receiver, subject, content }: SendEmail) {
export async function doSendMessage({ receiver, subject, content }: SendEmail) {
if (transporter == null) {
throw new Error('Email not initialized');
}
Expand All @@ -49,7 +49,7 @@ export async function sendMessage({ receiver, subject, content }: SendEmail) {

export type NewMailCallback = (mail: ReceivedEmail) => void;

export async function listenForNewEmails(onNewMail: NewMailCallback) {
export async function doListenForNewEmails(onNewMail: NewMailCallback) {
if (imapClient == null) {
throw new Error('IMAP not initialized');
}
Expand All @@ -76,7 +76,7 @@ export async function listenForNewEmails(onNewMail: NewMailCallback) {
lock.release();
}

export async function stopListening() {
export async function doStopListening() {
if (imapClient) {
await imapClient.logout();
}
Expand Down
2 changes: 1 addition & 1 deletion src/apis/gemini/ask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ const compilerTools: gemini.Tool = {
],
};

export function getTools(): gemini.Tool[] {
export function doGetTools(): gemini.Tool[] {
const conf = cfg.features.ai;
return [
basicTools,
Expand Down
20 changes: 10 additions & 10 deletions src/apis/gemini/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,35 @@ type PromptResolvable = string | string[] | gemini.Part[] | gemini.Content[] | O
let genai: gemini.GoogleGenAI | null = null;
let models: Record<string, BaseModelParams[]> = {};

export async function init() {
export async function doInit() {
const apiKey = Deno.env.get('JB_GEMINI_API_KEY');
if (apiKey) {
genai = new gemini.GoogleGenAI({ apiKey });
models = {};
}
}

export function isInitialized(): boolean {
export function doIsInitialized(): boolean {
return genai != null;
}

export function initModel(id: string, params: BaseModelParams): BaseModelParams | null {
export function doInitModel(id: string, params: BaseModelParams): BaseModelParams | null {
if (!models[id]) models[id] = [];
models[id].push(params);
return params;
}

export function getModels(id: string): BaseModelParams[] {
export function doGetModels(id: string): BaseModelParams[] {
return models[id] ?? [];
}

export function getModel(id: string): BaseModelParams | null {
export function doGetModel(id: string): BaseModelParams | null {
return models[id]?.[0] ?? null;
}

// (don't ask me what this type even is)
type Payload = PromptResolvable | (Partial<gemini.GenerateContentParameters> & { contents: gemini.Content[] | string });
async function executeWithFallback<T>(
async function doExecuteWithFallback<T>(
id: string,
payload: Payload,
action: (params: gemini.GenerateContentParameters) => Promise<T>
Expand Down Expand Up @@ -73,16 +73,16 @@ async function executeWithFallback<T>(
throw lastError;
}

export async function askModel(
export async function doAskModel(
id: string,
prompt: PromptResolvable
): Promise<AsyncIterable<gemini.GenerateContentResponse>> {
return executeWithFallback(id, prompt, p => genai!.models.generateContentStream(p));
return doExecuteWithFallback(id, prompt, p => genai!.models.generateContentStream(p));
}

export async function generateContent(
export async function doGenerateContent(
id: string,
params: PromptResolvable,
): Promise<gemini.GenerateContentResponse> {
return executeWithFallback(id, params, p => genai!.models.generateContent(p));
return doExecuteWithFallback(id, params, p => genai!.models.generateContent(p));
}
Loading
Loading