Skip to content
Merged
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
28 changes: 14 additions & 14 deletions apps/browser-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,31 @@
"@evaluate/helpers": "workspace:^",
"@evaluate/shapes": "workspace:^",
"@evaluate/styles": "workspace:^",
"@t3-oss/env-core": "^0.12.0",
"lucide-react": "^0.488.0",
"posthog-js": "^1.236.1",
"@t3-oss/env-core": "^0.13.8",
"lucide-react": "^0.525.0",
"posthog-js": "^1.257.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"sonner": "^2.0.3",
"tailwind-merge": "^3.2.0",
"sonner": "^2.0.6",
"tailwind-merge": "^3.3.1",
"webext-bridge": "^6.0.1",
"webextension-polyfill": "^0.12.0",
"zod": "3.25.20"
"zod": "4.0.5"
},
"devDependencies": {
"@babel/generator": "^7.27.0",
"@babel/parser": "^7.27.0",
"@babel/generator": "^7.28.0",
"@babel/parser": "^7.28.0",
"@babel/traverse": "^7.27.0",
"@babel/types": "^7.27.0",
"@babel/types": "^7.28.1",
"@crxjs/vite-plugin": "2.0.0-beta.30",
"@tailwindcss/vite": "^4.1.4",
"@tailwindcss/vite": "^4.1.11",
"@types/babel__generator": "^7.27.0",
"@types/babel__traverse": "^7.20.7",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@types/webextension-polyfill": "^0.12.3",
"@vitejs/plugin-react": "^4.4.0",
"tailwindcss": "^4.1.4",
"@vitejs/plugin-react": "^4.6.0",
"tailwindcss": "^4.1.11",
"vite": "3.2.11",
"vite-plugin-zip-pack": "^1.2.4",
"vite-tsconfig-paths": "^5.1.4"
Expand Down
1 change: 1 addition & 0 deletions apps/browser-extension/src/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => {
for (const runtime of runtimes) {
const initialPromise = executeCode({
runtime: runtime.id,
// TODO: Use the get runtime default file name function
files: { 'file.code': code },
entry: 'file.code',
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import { onMessage } from 'webext-bridge/content-script';
import { makePickRuntimeUrl } from '~/helpers/make-url';
import { ExecutionDialog } from './dialog';

export function Execution({
dialogPortal,
}: {
dialogPortal: HTMLElement;
}) {
export function Execution({ dialogPortal }: { dialogPortal: HTMLElement }) {
const [code, setCode] = useState('');
const [runtimes, setRuntimes] = useState<PartialRuntime[]>([]);
const [results, setResults] = useState<ExecuteResult[]>([]);
Expand Down
62 changes: 46 additions & 16 deletions apps/browser-extension/vite-plugins.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { readFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import generate_ from '@babel/generator';
import { parse } from '@babel/parser';
import traverse_ from '@babel/traverse';
import {
isArrowFunctionExpression,
isBlockStatement,
isIfStatement,
isReturnStatement,
} from '@babel/types';
import * as t from '@babel/types';
import type { Plugin } from 'vite';

const generate = Reflect.get(generate_, 'default') as typeof generate_;
const traverse = Reflect.get(traverse_, 'default') as typeof traverse_;

Expand All @@ -22,18 +20,20 @@ export function removeExternalScriptLoading(): Plugin {
transform(code, id) {
if (!id.includes('posthog-js/dist/module.js')) return null;

const ast = parse(code, { sourceType: 'module' });
const ast = parse(code, {
sourceType: 'module',
});

traverse(ast, {
VariableDeclarator(path) {
if (
isArrowFunctionExpression(path.node.init) &&
t.isArrowFunctionExpression(path.node.init) &&
path.node.init.params.length === 3 &&
isBlockStatement(path.node.init.body)
t.isBlockStatement(path.node.init.body)
) {
const ifStatement = path.node.init.body.body //
.find((node) => isIfStatement(node));
if (isReturnStatement(ifStatement?.consequent))
.find((node) => t.isIfStatement(node));
if (t.isReturnStatement(ifStatement?.consequent))
path.node.init.body = ifStatement.consequent.argument!;
}
},
Expand All @@ -45,14 +45,44 @@ export function removeExternalScriptLoading(): Plugin {
}

/**
* Vite plugin to remove import attributes from import statements.
* Vite plugin to inline JSON imports with attributes as const declarations.
*/
export function removeImportAttributes(): Plugin {
export function replaceJsonImports(): Plugin {
return {
name: 'remove-import-attributes',
name: 'replace-json-imports',
enforce: 'pre',
transform(code) {
return code.replaceAll(/(from\s['"](?:.*?)['"])(\swith\s\{.*?\})/g, '$1');
async transform(code, id) {
if (!code.includes('.json')) return null;

const ast = parse(code, {
sourceType: 'module',
plugins: ['importAttributes', 'typescript', 'jsx'],
});

traverse(ast, {
ImportDeclaration(path) {
const importNode = path.node;

if (importNode.source.value.endsWith('.json')) {
const varName = importNode.specifiers[0].local.name;
const jsonPath = resolve(dirname(id), importNode.source.value);
if (!jsonPath.startsWith(process.cwd())) {
throw new Error(`JSON import path '${jsonPath}' is outside project root`);
const jsonContent = JSON.parse(readFileSync(jsonPath, 'utf8'));

path.replaceWith(
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(varName),
t.valueToNode(jsonContent),
),
]),
);
}
},
});

return generate(ast);
},
};
}
4 changes: 2 additions & 2 deletions apps/browser-extension/vite.config.chrome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import tsconfigPaths from 'vite-tsconfig-paths';
import manifest from './manifest.json';
import {
removeExternalScriptLoading,
removeImportAttributes,
replaceJsonImports,
} from './vite-plugins';

export default defineConfig({
plugins: [
removeExternalScriptLoading(),
removeImportAttributes(),
replaceJsonImports(),
tailwindCss(),
tsconfigPaths(),
react(),
Expand Down
4 changes: 2 additions & 2 deletions apps/browser-extension/vite.config.firefox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import tsconfigPaths from 'vite-tsconfig-paths';
import manifest from './manifest.json';
import {
removeExternalScriptLoading,
removeImportAttributes,
replaceJsonImports,
} from './vite-plugins';

export default defineConfig({
plugins: [
removeExternalScriptLoading(),
removeImportAttributes(),
replaceJsonImports(),
tailwindCss(),
tsconfigPaths(),
react(),
Expand Down
10 changes: 5 additions & 5 deletions apps/discord-bot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
"build": "pnpm tsup"
},
"dependencies": {
"@buape/carbon": "0.7.0",
"@buape/carbon": "0.9.0",
"@evaluate/engine": "workspace:^",
"@evaluate/helpers": "workspace:^",
"@evaluate/shapes": "workspace:^",
"@t3-oss/env-core": "^0.12.0",
"@t3-oss/env-core": "^0.13.8",
"date-fns": "^4.1.0",
"es-toolkit": "^1.34.1",
"posthog-node": "^4.11.6",
"zod": "3.25.20"
"es-toolkit": "^1.39.7",
"posthog-node": "^5.5.1",
"zod": "4.0.5"
},
"devDependencies": {
"tsup": "^8.4.0"
Expand Down
6 changes: 1 addition & 5 deletions apps/discord-bot/src/commands/evaluate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import {
type CommandOptions,
} from '@buape/carbon';
import { fetchRuntimes, searchRuntimes } from '@evaluate/engine/runtimes';
import { EditEvaluationButton } from '~/components/edit-evaluation-button';
import { EvaluateModal, EvaluateModalEdit } from '~/components/evaluate-modal';
import { EvaluateModal } from '~/components/evaluate-modal';
import { handleEvaluating } from '~/handlers/evaluate';
import { captureEvent } from '~/services/posthog';
import { getInteractionContext } from '~/utilities/session-context';
Expand Down Expand Up @@ -44,9 +43,6 @@ export class EvaluateCommand extends Command {
},
];

components = [EditEvaluationButton];
modals = [EvaluateModal, EvaluateModalEdit];

async autocomplete(interaction: AutocompleteInteraction) {
const runtime = interaction.options.getString('runtime');

Expand Down
2 changes: 1 addition & 1 deletion apps/discord-bot/src/components/edit-evaluation-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getInteractionContext } from '~/utilities/session-context';
import { EvaluateModalEdit } from './evaluate-modal';

export class EditEvaluationButton extends Button {
customId = 'evaluate:edit';
customId = 'evaluate,edit';
style = ButtonStyle.Success;
label = 'Edit';
emoji = resolveEmoji('pencil', true);
Expand Down
4 changes: 2 additions & 2 deletions apps/discord-bot/src/components/evaluate-modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { getInteractionContext } from '~/utilities/session-context';

export class EvaluateModal extends Modal {
title = 'Evaluate';
customId = 'evaluate:new';
customId = 'evaluate,new';

components = [
new Row([new RuntimeInput()]),
Expand Down Expand Up @@ -44,7 +44,7 @@ export class EvaluateModal extends Modal {
}

export class EvaluateModalEdit extends EvaluateModal {
customId = 'evaluate:edit';
customId = 'evaluate,edit';
title = 'Edit Evaluation';
}

Expand Down
17 changes: 7 additions & 10 deletions apps/discord-bot/src/events/application-authorised.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import {
ApplicationIntegrationType,
ApplicationWebhookEventType,
Listener,
ApplicationAuthorizedListener,
type ApplicationWebhookEventType,
type ListenerEventData,
} from '@buape/carbon';
import { captureEvent } from '~/services/posthog';
import { getUserContext } from '~/utilities/session-context';

export class ApplicationAuthorisedListener extends Listener {
type = ApplicationWebhookEventType.ApplicationAuthorized;

export class ApplicationAuthorisedListener extends ApplicationAuthorizedListener {
async handle(
data: ListenerEventData<ApplicationWebhookEventType.ApplicationAuthorized>,
data: ListenerEventData[ApplicationWebhookEventType.ApplicationAuthorized],
) {
if (data.integration_type === ApplicationIntegrationType.GuildInstall)
if (data.guild)
captureEvent(getUserContext(data.user), 'installed_app', {
install_type: 'guild',
guild_id: data.guild?.id,
guild_id: data.guild.id,
});
else if (data.integration_type === ApplicationIntegrationType.UserInstall)
else if (data.user)
captureEvent(getUserContext(data.user), 'installed_app', {
install_type: 'user',
user_id: data.user.id,
Expand Down
28 changes: 20 additions & 8 deletions apps/discord-bot/src/handlers/evaluate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
CommandInteraction,
Embed,
MessageFlags,
ModalInteraction,
Row,
type User,
Expand All @@ -23,21 +24,21 @@ function isNew(
interaction: CommandInteraction | ModalInteraction,
): interaction is
| CommandInteraction
| (ModalInteraction & { rawData: { data: { custom_id: `evaluate:new` } } }) {
| (ModalInteraction & { rawData: { data: { custom_id: `evaluate,new` } } }) {
return (
interaction instanceof CommandInteraction ||
interaction.rawData.data.custom_id === 'evaluate:new'
interaction.rawData.data.custom_id === 'evaluate,new'
);
}

function isEdit(
interaction: CommandInteraction | ModalInteraction,
): interaction is ModalInteraction & {
rawData: { data: { custom_id: `evaluate:edit` } };
rawData: { data: { custom_id: `evaluate,edit` } };
} {
return (
interaction instanceof ModalInteraction &&
interaction.rawData.data.custom_id === 'evaluate:edit'
interaction.rawData.data.custom_id === 'evaluate,edit'
);
}

Expand Down Expand Up @@ -70,7 +71,7 @@ export async function handleEvaluating(
interaction.rawData.message.interaction_metadata?.user.id !==
interaction.user?.id
)
Reflect.set(interaction.rawData.data, 'custom_id', 'evaluate:new');
Reflect.set(interaction.rawData.data, 'custom_id', 'evaluate,new');

if (isNew(interaction)) await interaction.defer();
if (isEdit(interaction)) await interaction.acknowledge();
Expand All @@ -79,8 +80,16 @@ export async function handleEvaluating(
if (!runtime) {
const message =
'I was unable to find the runtime you were looking for, try again with another name.';
if (isNew(interaction)) return interaction.reply({ content: message });
if (isEdit(interaction)) return interaction.followUp({ content: message });
if (isNew(interaction))
return interaction.reply({
content: message,
flags: MessageFlags.Ephemeral,
});
if (isEdit(interaction))
return interaction.followUp({
content: message,
flags: MessageFlags.Ephemeral,
});
throw new Error(message);
}

Expand All @@ -96,7 +105,10 @@ export async function handleEvaluating(
...executeOptions,
}).catch(async (error) => {
if (error instanceof Error)
await interaction.reply({ content: error.message });
await interaction.reply({
content: error.message,
flags: MessageFlags.Ephemeral,
});
throw error;
});

Expand Down
Loading