Skip to content

Commit 3361e29

Browse files
committed
Add code execution
- Add `.code` - Add support for code execution in tags
1 parent 1c0a84f commit 3361e29

File tree

19 files changed

+487
-14
lines changed

19 files changed

+487
-14
lines changed

src/api/endpoints.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ export const Api = Object.freeze({
151151
'/image/tools/background/remove',
152152
IMAGE_TOOLS_CONVERT:
153153
'/image/tools/convert',
154+
IMAGE_TOOLS_CROP:
155+
'/image/tools/crop',
154156
IMAGE_TOOLS_GIF_REVERSE:
155157
'/image/tools/gif/reverse',
156158
IMAGE_TOOLS_GIF_SEE_SAW:
@@ -225,6 +227,10 @@ export const Api = Object.freeze({
225227
USER_TAGS:
226228
'/users/:userId/tags',
227229

230+
UTILITIES_CODE_RUN:
231+
'/utilities/code/run',
232+
UTILITIES_CODE_RUN2:
233+
'/utilities/code/run2',
228234
UTILITIES_FETCH_DATA:
229235
'/utilities/fetch/data',
230236
UTILITIES_FETCH_IMAGE:

src/api/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,14 @@ export async function imageToolsConvert(
701701
}
702702

703703

704+
export async function imageToolsCrop(
705+
context: RequestContext,
706+
options: RestOptions.ImageToolsCrop,
707+
) {
708+
return raw.imageToolsCrop(context, options);
709+
}
710+
711+
704712
export async function imageToolsGifReverse(
705713
context: RequestContext,
706714
options: RestOptions.ImageBaseOptions,
@@ -968,6 +976,13 @@ export async function uploadCommands(
968976
}
969977

970978

979+
export async function utilitiesCodeRun2(
980+
context: RequestContext,
981+
options: RestOptions.UtilitiesCodeRun2,
982+
) {
983+
return raw.utilitiesCodeRun2(context, options);
984+
}
985+
971986
export async function utilitiesFetchData(
972987
context: RequestContext,
973988
options: RestOptions.UtilitiesFetchData,

src/api/raw.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,25 @@ export async function imageToolsConvert(
14301430
}
14311431

14321432

1433+
export async function imageToolsCrop(
1434+
context: RequestContext,
1435+
options: RestOptions.ImageToolsCrop,
1436+
): Promise<Response> {
1437+
const query = {
1438+
size: options.size,
1439+
url: options.url,
1440+
};
1441+
return request(context, {
1442+
dataOnly: false,
1443+
query,
1444+
route: {
1445+
method: HTTPMethods.POST,
1446+
path: Api.IMAGE_TOOLS_CROP,
1447+
},
1448+
});
1449+
}
1450+
1451+
14331452
export async function imageToolsGifReverse(
14341453
context: RequestContext,
14351454
options: RestOptions.ImageBaseOptions,
@@ -1995,6 +2014,25 @@ export async function uploadCommands(
19952014
}
19962015

19972016

2017+
export async function utilitiesCodeRun2(
2018+
context: RequestContext,
2019+
options: RestOptions.UtilitiesCodeRun2,
2020+
): Promise<RestResponsesRaw.UtilitiesCodeRun2> {
2021+
const body = {
2022+
code: options.code,
2023+
input: options.input,
2024+
language: options.language,
2025+
};
2026+
return request(context, {
2027+
body,
2028+
route: {
2029+
method: HTTPMethods.POST,
2030+
path: Api.UTILITIES_CODE_RUN2,
2031+
},
2032+
});
2033+
}
2034+
2035+
19982036
export async function utilitiesFetchData(
19992037
context: RequestContext,
20002038
options: RestOptions.UtilitiesFetchData,

src/api/types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ export namespace RestOptions {
212212
to: string,
213213
}
214214

215+
export interface ImageToolsCrop extends ImageBaseOptions {
216+
size?: string,
217+
}
218+
215219
export interface ImageToolsGifSpeed extends ImageBaseOptions {
216220
loop?: boolean,
217221
speed: number,
@@ -387,6 +391,12 @@ export namespace RestOptions {
387391
}
388392

389393

394+
export interface UtilitiesCodeRun2 {
395+
code: string,
396+
input?: string,
397+
language: string,
398+
}
399+
390400
export interface UtilitiesFetchData {
391401
maxFileSize?: number,
392402
url: string,
@@ -1246,6 +1256,19 @@ export namespace RestResponsesRaw {
12461256
type: YoutubeResultTypes.VIDEO,
12471257
}
12481258

1259+
export interface UtilitiesCodeRun2 {
1260+
content: string,
1261+
error: string | null,
1262+
files: Array<string>,
1263+
stats: {
1264+
memory: string,
1265+
time_cpu: number,
1266+
time_running: number,
1267+
time_service: number,
1268+
},
1269+
warnings: string | null,
1270+
}
1271+
12491272
export interface UtilitiesQrScan {
12501273
scanned: Array<{
12511274
data: string,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Interaction } from 'detritus-client';
2+
3+
import { Formatter } from '../../../../../utils';
4+
5+
import { BaseInteractionImageCommandOption } from '../../../basecommand';
6+
7+
8+
export const COMMAND_NAME = 'crop';
9+
10+
export class ImageToolsCropCommand extends BaseInteractionImageCommandOption {
11+
description = 'Crop an Image';
12+
name = COMMAND_NAME;
13+
14+
async run(context: Interaction.InteractionContext, args: Formatter.Commands.ImageToolsCrop.CommandArgs) {
15+
return Formatter.Commands.ImageToolsCrop.createMessage(context, args);
16+
}
17+
}

src/commands/interactions/slash/image/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { BaseInteractionCommandOptionGroup } from '../../../basecommand';
22

33
import { ImageToolsConvertCommand } from './convert';
4+
import { ImageToolsCropCommand } from './crop';
45
import { ImageToolsResizeCommand } from './resize';
56

67

@@ -12,6 +13,7 @@ export class ImageToolsGroupCommand extends BaseInteractionCommandOptionGroup {
1213
super({
1314
options: [
1415
new ImageToolsConvertCommand(),
16+
new ImageToolsCropCommand(),
1517
new ImageToolsResizeCommand(),
1618
],
1719
});

src/commands/interactions/slash/owner/eval.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ export class OwnerEvalCommand extends BaseInteractionCommandOption<CommandArgs>
5757
let errored: boolean = false;
5858
try {
5959
if (args.async) {
60-
const func = new AsyncFunction('context', code);
60+
const func = new AsyncFunction('context', code.text);
6161
message = await func(context);
6262
} else {
63-
message = await Promise.resolve(eval(code));
63+
message = await Promise.resolve(eval(code.text));
6464
}
6565
if (typeof(message) === 'object') {
6666
message = JSON.stringify(message, null, args.jsonspacing);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Command, CommandClient } from 'detritus-client';
2+
3+
import { CommandTypes } from '../../../constants';
4+
import { Formatter } from '../../../utils';
5+
6+
import { BaseImageCommand } from '../basecommand';
7+
8+
9+
export const COMMAND_NAME = 'crop';
10+
11+
export default class CropCommand extends BaseImageCommand<Formatter.Commands.ImageToolsCrop.CommandArgs> {
12+
constructor(client: CommandClient) {
13+
super(client, {
14+
name: COMMAND_NAME,
15+
16+
metadata: {
17+
description: 'Crop an image',
18+
examples: [
19+
COMMAND_NAME,
20+
`${COMMAND_NAME} notsobot`,
21+
],
22+
type: CommandTypes.IMAGE,
23+
usage: '?<emoji,user:id|mention|name,url>',
24+
},
25+
});
26+
}
27+
28+
async run(context: Command.Context, args: Formatter.Commands.ImageToolsCrop.CommandArgs) {
29+
return Formatter.Commands.ImageToolsCrop.createMessage(context, args);
30+
}
31+
}

src/commands/prefixed/owner/eval.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
1212

1313
export interface CommandArgs {
1414
async: boolean,
15-
code: string,
15+
code: {language?: string, text: string},
1616
jsonspacing: number,
1717
noembed: boolean,
1818
noreply: boolean,
@@ -60,10 +60,10 @@ export default class EvalCommand extends BaseCommand {
6060
let errored: boolean = false;
6161
try {
6262
if (args.async) {
63-
const func = new AsyncFunction('context', code);
63+
const func = new AsyncFunction('context', code.text);
6464
message = await func(context);
6565
} else {
66-
message = await Promise.resolve(eval(code));
66+
message = await Promise.resolve(eval(code.text));
6767
}
6868
if (typeof(message) === 'object') {
6969
message = JSON.stringify(message, null, args.jsonspacing);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Command, CommandClient } from 'detritus-client';
2+
3+
import { CommandTypes } from '../../../constants';
4+
import { Formatter, Parameters, editOrReply, getCodeRextesterLanguage } from '../../../utils';
5+
6+
import { BaseCommand } from '../basecommand';
7+
8+
9+
export interface CommandArgsBefore {
10+
code: {language?: string, text: string},
11+
language?: string,
12+
}
13+
14+
export interface CommandArgs {
15+
code: {language?: string, text: string},
16+
language: string,
17+
}
18+
19+
export const COMMAND_NAME = 'code';
20+
21+
export default class CodeCommand extends BaseCommand<CommandArgs> {
22+
constructor(client: CommandClient) {
23+
super(client, {
24+
name: COMMAND_NAME,
25+
26+
args: [
27+
{name: 'language', aliases: ['l']},
28+
],
29+
metadata: {
30+
description: 'Execute code',
31+
examples: [
32+
COMMAND_NAME,
33+
`${COMMAND_NAME} \`\`\`js console.log('lol')\`\`\``,
34+
`${COMMAND_NAME} console.log('lol'); -language js`,
35+
],
36+
type: CommandTypes.TOOLS,
37+
usage: '<code> (-language <language>)',
38+
},
39+
type: Parameters.codeblock,
40+
});
41+
}
42+
43+
async run(context: Command.Context, args: CommandArgs) {
44+
const language = getCodeRextesterLanguage(args.code.language || args.language);
45+
if (!language) {
46+
return editOrReply(context, 'Give me a valid language!');
47+
}
48+
return Formatter.Commands.ToolsCode.createMessage(context, {
49+
code: args.code.text,
50+
language,
51+
});
52+
}
53+
}

0 commit comments

Comments
 (0)