dfx 0.110.2 → 0.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Interactions/commandHelper.d.ts +99 -0
- package/Interactions/commandHelper.d.ts.map +1 -0
- package/Interactions/commandHelper.js +54 -0
- package/Interactions/commandHelper.js.map +1 -0
- package/Interactions/context.d.ts +4 -18
- package/Interactions/context.d.ts.map +1 -1
- package/Interactions/context.js +1 -19
- package/Interactions/context.js.map +1 -1
- package/Interactions/definitions.d.ts +2 -88
- package/Interactions/definitions.d.ts.map +1 -1
- package/Interactions/definitions.js.map +1 -1
- package/Interactions/utils.d.ts +1 -1
- package/Interactions/utils.d.ts.map +1 -1
- package/Interactions/utils.js +2 -14
- package/Interactions/utils.js.map +1 -1
- package/mjs/Interactions/commandHelper.mjs +45 -0
- package/mjs/Interactions/commandHelper.mjs.map +1 -0
- package/mjs/Interactions/context.mjs +0 -14
- package/mjs/Interactions/context.mjs.map +1 -1
- package/mjs/Interactions/definitions.mjs.map +1 -1
- package/mjs/Interactions/utils.mjs +2 -14
- package/mjs/Interactions/utils.mjs.map +1 -1
- package/mjs/version.mjs +1 -1
- package/package.json +2 -2
- package/src/Interactions/commandHelper.ts +236 -0
- package/src/Interactions/context.ts +3 -72
- package/src/Interactions/definitions.ts +1 -185
- package/src/Interactions/utils.ts +3 -18
- package/src/version.ts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
|
@@ -3,8 +3,6 @@ import * as IxHelpers from "dfx/Helpers/interactions";
|
|
|
3
3
|
import { InteractionsErrorTypeId } from "dfx/Interactions/error";
|
|
4
4
|
import { GenericTag } from "effect/Context";
|
|
5
5
|
import * as Effect from "effect/Effect";
|
|
6
|
-
import * as Option from "effect/Option";
|
|
7
|
-
import * as Arr from "effect/Array";
|
|
8
6
|
export const Interaction = /*#__PURE__*/GenericTag("dfx/Interactions/Interaction");
|
|
9
7
|
export const ApplicationCommand = /*#__PURE__*/GenericTag("dfx/Interactions/ApplicationCommand");
|
|
10
8
|
export const MessageComponentData = /*#__PURE__*/GenericTag("dfx/Interactions/MessageComponentData");
|
|
@@ -15,13 +13,7 @@ export const resolvedValues = f => Effect.flatMap(Interaction, ix => IxHelpers.r
|
|
|
15
13
|
export const resolved = (name, f) => Effect.flatMap(Interaction, ix => IxHelpers.resolveOptionValue(name, f)(ix));
|
|
16
14
|
export const focusedOptionValue = /*#__PURE__*/Effect.map(FocusedOptionContext, _ => _.value ?? "");
|
|
17
15
|
export class SubCommandNotFound extends /*#__PURE__*/TypeIdError(InteractionsErrorTypeId, "SubCommandNotFound") {}
|
|
18
|
-
export const handleSubCommands = commands => ApplicationCommand.pipe(Effect.flatMap(data => Effect.mapError(Arr.findFirst(IxHelpers.allSubCommands(data), _ => !!commands[_.name]), () => new SubCommandNotFound({
|
|
19
|
-
data
|
|
20
|
-
}))), Effect.flatMap(command => Effect.provideService(commands[command.name], SubCommandContext, {
|
|
21
|
-
command
|
|
22
|
-
})));
|
|
23
16
|
export const currentSubCommand = /*#__PURE__*/Effect.map(SubCommandContext, _ => _.command);
|
|
24
|
-
export const optionsMap = /*#__PURE__*/Effect.map(ApplicationCommand, IxHelpers.optionsMap);
|
|
25
17
|
export class RequiredOptionNotFound {
|
|
26
18
|
data;
|
|
27
19
|
name;
|
|
@@ -31,12 +23,6 @@ export class RequiredOptionNotFound {
|
|
|
31
23
|
this.name = name;
|
|
32
24
|
}
|
|
33
25
|
}
|
|
34
|
-
export const option = name => Effect.map(ApplicationCommand, IxHelpers.getOption(name));
|
|
35
|
-
export const optionValue = name => Effect.flatMap(option(name), _ => Option.match(Option.flatMapNullable(_, a => a.value), {
|
|
36
|
-
onNone: () => Effect.flatMap(ApplicationCommand, data => Effect.fail(new RequiredOptionNotFound(data, name))),
|
|
37
|
-
onSome: Effect.succeed
|
|
38
|
-
}));
|
|
39
|
-
export const optionValueOptional = name => Effect.map(option(name), Option.flatMapNullable(o => o.value));
|
|
40
26
|
export const modalValues = /*#__PURE__*/Effect.map(ModalSubmitData, IxHelpers.componentsMap);
|
|
41
27
|
export const modalValueOption = name => Effect.map(ModalSubmitData, IxHelpers.componentValue(name));
|
|
42
28
|
export const modalValue = name => Effect.flatMap(ModalSubmitData, data => IxHelpers.componentValue(name)(data));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.mjs","names":["TypeIdError","IxHelpers","InteractionsErrorTypeId","GenericTag","Effect","
|
|
1
|
+
{"version":3,"file":"context.mjs","names":["TypeIdError","IxHelpers","InteractionsErrorTypeId","GenericTag","Effect","Interaction","ApplicationCommand","MessageComponentData","ModalSubmitData","FocusedOptionContext","SubCommandContext","resolvedValues","f","flatMap","ix","resolveValues","resolved","name","resolveOptionValue","focusedOptionValue","map","_","value","SubCommandNotFound","currentSubCommand","command","RequiredOptionNotFound","data","_tag","constructor","modalValues","componentsMap","modalValueOption","componentValue","modalValue"],"sources":["../../src/Interactions/context.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,WAAW,QAAQ,wBAAwB;AACpD,OAAO,KAAKC,SAAS,MAAM,0BAA0B;AACrD,SAASC,uBAAuB,QAAQ,wBAAwB;AAGhE,SAASC,UAAU,QAAQ,gBAAgB;AAC3C,OAAO,KAAKC,MAAM,MAAM,eAAe;AAQvC,OAAO,MAAMC,WAAW,gBAAGF,UAAU,CACnC,8BAA8B,CAC/B;AAKD,OAAO,MAAMG,kBAAkB,gBAAGH,UAAU,CAG1C,qCAAqC,CAAC;AAKxC,OAAO,MAAMI,oBAAoB,gBAAGJ,UAAU,CAG5C,uCAAuC,CAAC;AAK1C,OAAO,MAAMK,eAAe,gBAAGL,UAAU,CAGvC,kCAAkC,CAAC;AAKrC,OAAO,MAAMM,oBAAoB,gBAAGN,UAAU,CAG5C,uCAAuC,CAAC;AAQ1C,OAAO,MAAMO,iBAAiB,gBAAGP,UAAU,CAGzC,oCAAoC,CAAC;AAEvC,OAAO,MAAMQ,cAAc,GACzBC,CAAwE,IAKrER,MAAM,CAACS,OAAO,CAACR,WAAW,EAAES,EAAE,IAAIb,SAAS,CAACc,aAAa,CAACH,CAAC,CAAC,CAACE,EAAE,CAAC,CAAC;AAEtE,OAAO,MAAME,QAAQ,GAAGA,CACtBC,IAAY,EACZL,CAAwE,KAExER,MAAM,CAACS,OAAO,CAACR,WAAW,EAAES,EAAE,IAAIb,SAAS,CAACiB,kBAAkB,CAACD,IAAI,EAAEL,CAAC,CAAC,CAACE,EAAE,CAAC,CAAC;AAE9E,OAAO,MAAMK,kBAAkB,gBAAGf,MAAM,CAACgB,GAAG,CAC1CX,oBAAoB,EACpBY,CAAC,IAAIA,CAAC,CAACC,KAAK,IAAI,EAAE,CACnB;AAED,OAAM,MAAOC,kBAAmB,sBAAQvB,WAAW,CACjDE,uBAAuB,EACvB,oBAAoB,CAGpB;AAEF,OAAO,MAAMsB,iBAAiB,gBAI1BpB,MAAM,CAACgB,GAAG,CAACV,iBAAiB,EAAEW,CAAC,IAAIA,CAAC,CAACI,OAAO,CAAC;AAEjD,OAAM,MAAOC,sBAAsB;EAGtBC,IAAA;EAGAV,IAAA;EALFW,IAAI,GAAG,wBAAwB;EACxCC,YACWF,IAE0C,EAC1CV,IAAY;IAHZ,KAAAU,IAAI,GAAJA,IAAI;IAGJ,KAAAV,IAAI,GAAJA,IAAI;EACZ;;AAGL,OAAO,MAAMa,WAAW,gBAAG1B,MAAM,CAACgB,GAAG,CAACZ,eAAe,EAAEP,SAAS,CAAC8B,aAAa,CAAC;AAE/E,OAAO,MAAMC,gBAAgB,GAAIf,IAAY,IAC3Cb,MAAM,CAACgB,GAAG,CAACZ,eAAe,EAAEP,SAAS,CAACgC,cAAc,CAAChB,IAAI,CAAC,CAAC;AAE7D,OAAO,MAAMiB,UAAU,GACrBjB,IAAY,IAEZb,MAAM,CAACS,OAAO,CAACL,eAAe,EAAEmB,IAAI,IAAI1B,SAAS,CAACgC,cAAc,CAAChB,IAAI,CAAC,CAACU,IAAI,CAAC,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.mjs","names":["GlobalApplicationCommand","command","handle","_tag","constructor","global","GuildApplicationCommand","guild","MessageComponent","predicate","messageComponent","pred","ModalSubmit","modalSubmit","Autocomplete","autocomplete"],"sources":["../../src/Interactions/definitions.ts"],"sourcesContent":[null],"mappings":"
|
|
1
|
+
{"version":3,"file":"definitions.mjs","names":["GlobalApplicationCommand","command","handle","_tag","constructor","global","GuildApplicationCommand","guild","MessageComponent","predicate","messageComponent","pred","ModalSubmit","modalSubmit","Autocomplete","autocomplete"],"sources":["../../src/Interactions/definitions.ts"],"sourcesContent":[null],"mappings":"AAmBA,OAAM,MAAOA,wBAAwB;EAGxBC,OAAA;EACAC,MAAA;EAHFC,IAAI,GAAG,0BAA0B;EAC1CC,YACWH,OAAqD,EACrDC,MAA4B;IAD5B,KAAAD,OAAO,GAAPA,OAAO;IACP,KAAAC,MAAM,GAANA,MAAM;EACd;;AAGL,OAAO,MAAMG,MAAM,GAAGA,CAKpBJ,OAAU,EACVC,MAA+B,KAE/B,IAAIF,wBAAwB,CAG1BC,OAAc,EAAEC,MAAa,CAAC;AAElC,OAAM,MAAOI,uBAAuB;EAGvBL,OAAA;EACAC,MAAA;EAHFC,IAAI,GAAG,yBAAyB;EACzCC,YACWH,OAAoD,EACpDC,MAA4B;IAD5B,KAAAD,OAAO,GAAPA,OAAO;IACP,KAAAC,MAAM,GAANA,MAAM;EACd;;AAGL,OAAO,MAAMK,KAAK,GAAGA,CAKnBN,OAAU,EACVC,MAA+B,KAE/B,IAAII,uBAAuB,CAGzBL,OAAc,EAAEC,MAAa,CAAC;AAElC,OAAM,MAAOM,gBAAgB;EAGhBC,SAAA;EACAP,MAAA;EAHFC,IAAI,GAAG,kBAAkB;EAClCC,YACWK,SAAwC,EACxCP,MAAwD;IADxD,KAAAO,SAAS,GAATA,SAAS;IACT,KAAAP,MAAM,GAANA,MAAM;EACd;;AAGL,OAAO,MAAMQ,gBAAgB,GAAGA,CAC9BC,IAAmC,EACnCT,MAAyD,KAEzD,IAAIM,gBAAgB,CAGlBG,IAAI,EAAET,MAAa,CAAC;AAExB,OAAM,MAAOU,WAAW;EAGXH,SAAA;EACAP,MAAA;EAHFC,IAAI,GAAG,aAAa;EAC7BC,YACWK,SAAwC,EACxCP,MAAwD;IADxD,KAAAO,SAAS,GAATA,SAAS;IACT,KAAAP,MAAM,GAANA,MAAM;EACd;;AAGL,OAAO,MAAMW,WAAW,GAAGA,CACzBF,IAAmC,EACnCT,MAAwD,KAExD,IAAIU,WAAW,CAGbD,IAAI,EAAET,MAAa,CAAC;AAExB,OAAM,MAAOY,YAAY;EAGZL,SAAA;EAIAP,MAAA;EANFC,IAAI,GAAG,cAAc;EAC9BC,YACWK,SAGG,EACHP,MAAwD;IAJxD,KAAAO,SAAS,GAATA,SAAS;IAIT,KAAAP,MAAM,GAANA,MAAM;EACd;;AAGL,OAAO,MAAMa,YAAY,GAAGA,CAC1BJ,IAGY,EACZT,MAAwD,KAExD,IAAIY,YAAY,CASdH,IAAI,EAAET,MAAa,CAAC","ignoreList":[]}
|
|
@@ -1,22 +1,10 @@
|
|
|
1
1
|
import * as Chunk from "effect/Chunk";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as Ctx from "dfx/Interactions/context";
|
|
4
|
-
import * as Discord from "dfx/types";
|
|
5
3
|
import * as Array from "effect/Array";
|
|
6
|
-
import
|
|
7
|
-
const context = {
|
|
8
|
-
resolve: Ctx.resolved,
|
|
9
|
-
option: Ctx.option,
|
|
10
|
-
optionValue: Ctx.optionValue,
|
|
11
|
-
optionValueOptional: Ctx.optionValueOptional,
|
|
12
|
-
subCommands: Ctx.handleSubCommands
|
|
13
|
-
};
|
|
4
|
+
import { CommandHelper } from "./commandHelper";
|
|
14
5
|
export const flattenDefinitions = (definitions, handleResponse) => Array.map(Chunk.toReadonlyArray(definitions), ([definition, transform]) => ({
|
|
15
6
|
...definition,
|
|
16
|
-
handle: Effect.isEffect(definition.handle) ? i => Effect.scoped(transform(Effect.flatMap(definition.handle, _ => handleResponse(i, _)))) : i => Effect.scoped(transform(Effect.flatMap(definition.handle(
|
|
17
|
-
...context,
|
|
18
|
-
target: i.type === Discord.InteractionType.APPLICATION_COMMAND ? Helpers.target(i.data) : undefined
|
|
19
|
-
}), _ => handleResponse(i, _))))
|
|
7
|
+
handle: Effect.isEffect(definition.handle) ? i => Effect.scoped(transform(Effect.flatMap(definition.handle, _ => handleResponse(i, _)))) : i => Effect.scoped(transform(Effect.flatMap(definition.handle(new CommandHelper(i)), _ => handleResponse(i, _))))
|
|
20
8
|
}));
|
|
21
9
|
export const splitDefinitions = definitions => {
|
|
22
10
|
const grouped = Array.reduce(definitions, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":["Chunk","Effect","
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":["Chunk","Effect","Array","CommandHelper","flattenDefinitions","definitions","handleResponse","map","toReadonlyArray","definition","transform","handle","isEffect","i","scoped","flatMap","_","splitDefinitions","grouped","reduce","Autocomplete","GlobalApplicationCommand","GuildApplicationCommand","MessageComponent","ModalSubmit","Commands","acc","d","_tag","push","command","name"],"sources":["../../src/Interactions/utils.ts"],"sourcesContent":[null],"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,cAAc;AACrC,OAAO,KAAKC,MAAM,MAAM,eAAe;AAGvC,OAAO,KAAKC,KAAK,MAAM,cAAc;AACrC,SAASC,aAAa,QAAQ,iBAAiB;AAgB/C,OAAO,MAAMC,kBAAkB,GAAGA,CAChCC,WAKC,EACDC,cAG2B,KAE3BJ,KAAK,CAACK,GAAG,CAACP,KAAK,CAACQ,eAAe,CAACH,WAAW,CAAC,EAAE,CAAC,CAACI,UAAU,EAAEC,SAAS,CAAC,MAAM;EAC1E,GAAGD,UAAU;EACbE,MAAM,EAAEV,MAAM,CAACW,QAAQ,CAACH,UAAU,CAACE,MAAM,CAAC,GACrCE,CAAsB,IACrBZ,MAAM,CAACa,MAAM,CACXJ,SAAS,CACPT,MAAM,CAACc,OAAO,CACZN,UAAU,CAACE,MAAoD,EAC/DK,CAAC,IAAIV,cAAc,CAACO,CAAC,EAAEG,CAAC,CAAC,CAC1B,CACF,CACF,GACFH,CAAsB,IACrBZ,MAAM,CAACa,MAAM,CACXJ,SAAS,CACPT,MAAM,CAACc,OAAO,CAEVN,UAAU,CAACE,MAGZ,CAAC,IAAIR,aAAa,CAACU,CAAC,CAAC,CAAC,EACvBG,CAAC,IAAIV,cAAc,CAACO,CAAC,EAAEG,CAAC,CAAC,CAC1B,CACF;CAEV,CAAC,CAAC;AAEL,OAAO,MAAMC,gBAAgB,GAC3BZ,WAA4D,IAC1D;EACF,MAAMa,OAAO,GAAGhB,KAAK,CAACiB,MAAM,CAC1Bd,WAAW,EACX;IACEe,YAAY,EAAE,EAAE;IAChBC,wBAAwB,EAAE,EAAE;IAC5BC,uBAAuB,EAAE,EAAE;IAC3BC,gBAAgB,EAAE,EAAE;IACpBC,WAAW,EAAE,EAAE;IACfC,QAAQ,EAAE;GAOX,EACD,CAACC,GAAG,EAAEC,CAAC,KAAI;IACTD,GAAG,CAACC,CAAC,CAACC,IAAI,CAAC,CAACC,IAAI,CAACF,CAAQ,CAAC;IAC1B,IACEA,CAAC,CAACC,IAAI,KAAK,0BAA0B,IACrCD,CAAC,CAACC,IAAI,KAAK,yBAAyB,EACpC;MACAF,GAAG,CAACD,QAAQ,CAACE,CAAC,CAACG,OAAO,CAACC,IAAI,CAAC,GAAGJ,CAAQ;IACzC;IACA,OAAOD,GAAG;EACZ,CAAC,CACF;EAED,OAAOR,OAAO;AAChB,CAAC","ignoreList":[]}
|
package/mjs/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const LIB_VERSION = "0.
|
|
1
|
+
export const LIB_VERSION = "0.111.0";
|
|
2
2
|
//# sourceMappingURL=version.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dfx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.111.0",
|
|
4
4
|
"description": "Effect-TS discord library",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,6 +41,6 @@
|
|
|
41
41
|
"optionalDependencies": {
|
|
42
42
|
"discord-verify": "^1.2.0"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "e097ca2129cf44e65891f203a1299ed6a24cde31",
|
|
45
45
|
"main": "./index.js"
|
|
46
46
|
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import * as Option from "effect/Option"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
|
+
import {
|
|
4
|
+
SubCommandContext,
|
|
5
|
+
SubCommandNotFound,
|
|
6
|
+
type DiscordApplicationCommand,
|
|
7
|
+
type DiscordInteraction,
|
|
8
|
+
} from "dfx/Interactions/context"
|
|
9
|
+
import type * as Discord from "dfx/types"
|
|
10
|
+
import * as Helpers from "dfx/Helpers/interactions"
|
|
11
|
+
import * as Arr from "effect/Array"
|
|
12
|
+
import type { HashMap } from "effect/HashMap"
|
|
13
|
+
|
|
14
|
+
export class CommandHelper<A> {
|
|
15
|
+
constructor(readonly interaction: Discord.Interaction) {
|
|
16
|
+
this.target = Helpers.target(interaction.data as any) as any
|
|
17
|
+
this.data = interaction.data as any
|
|
18
|
+
}
|
|
19
|
+
readonly data: Discord.ApplicationCommandDatum
|
|
20
|
+
readonly target: CommandTypeMap<
|
|
21
|
+
A,
|
|
22
|
+
{
|
|
23
|
+
[Discord.ApplicationCommandType
|
|
24
|
+
.CHAT_INPUT]: Discord.ApplicationCommandDatum
|
|
25
|
+
[Discord.ApplicationCommandType.MESSAGE]: Discord.Message
|
|
26
|
+
[Discord.ApplicationCommandType.USER]: Discord.User
|
|
27
|
+
[Discord.ApplicationCommandType.PRIMARY_ENTRY_POINT]: undefined
|
|
28
|
+
}
|
|
29
|
+
>
|
|
30
|
+
|
|
31
|
+
resolve<T>(
|
|
32
|
+
name: AllResolvables<A>["name"],
|
|
33
|
+
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => T | undefined,
|
|
34
|
+
): Option.Option<T> {
|
|
35
|
+
return Helpers.resolveOptionValue(name, f)(this.interaction)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
resolvedValues<T>(
|
|
39
|
+
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => T | undefined,
|
|
40
|
+
): Option.Option<ReadonlyArray<T>> {
|
|
41
|
+
return Helpers.resolveValues(f)(this.interaction)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
option(
|
|
45
|
+
name: AllCommandOptions<A>["name"],
|
|
46
|
+
): Option.Option<Discord.ApplicationCommandInteractionDataOption> {
|
|
47
|
+
return Helpers.getOption(name)(this.data)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
optionValue<N extends AllRequiredCommandOptions<A>["name"]>(
|
|
51
|
+
name: N,
|
|
52
|
+
): CommandValue<A, N> {
|
|
53
|
+
return Option.getOrThrow(this.optionValueOptional(name))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
optionValueOptional<N extends AllCommandOptions<A>["name"]>(
|
|
57
|
+
name: N,
|
|
58
|
+
): Option.Option<CommandValue<A, N>> {
|
|
59
|
+
return Option.map(this.option(name), _ => _.value) as any
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
optionValueOrElse<N extends AllCommandOptions<A>["name"], const OrElse>(
|
|
63
|
+
name: N,
|
|
64
|
+
orElse: () => OrElse,
|
|
65
|
+
): Option.Option<CommandValue<A, N>> {
|
|
66
|
+
return Option.getOrElse(this.option(name), orElse) as any
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
subCommands<
|
|
70
|
+
NER extends SubCommandNames<A> extends never
|
|
71
|
+
? never
|
|
72
|
+
: Record<
|
|
73
|
+
SubCommandNames<A>,
|
|
74
|
+
Effect.Effect<Discord.InteractionResponse, any, any>
|
|
75
|
+
>,
|
|
76
|
+
>(
|
|
77
|
+
commands: NER,
|
|
78
|
+
): Effect.Effect<
|
|
79
|
+
Discord.InteractionResponse,
|
|
80
|
+
[NER[keyof NER]] extends [
|
|
81
|
+
{ [Effect.EffectTypeId]: { _E: (_: never) => infer E } },
|
|
82
|
+
]
|
|
83
|
+
? E
|
|
84
|
+
: never,
|
|
85
|
+
| Exclude<
|
|
86
|
+
[NER[keyof NER]] extends [
|
|
87
|
+
{ [Effect.EffectTypeId]: { _R: (_: never) => infer R } },
|
|
88
|
+
]
|
|
89
|
+
? R
|
|
90
|
+
: never,
|
|
91
|
+
SubCommandContext
|
|
92
|
+
>
|
|
93
|
+
| DiscordInteraction
|
|
94
|
+
| DiscordApplicationCommand
|
|
95
|
+
> {
|
|
96
|
+
const commands_ = commands as Record<string, any>
|
|
97
|
+
return Effect.mapError(
|
|
98
|
+
Arr.findFirst(
|
|
99
|
+
Helpers.allSubCommands(this.data),
|
|
100
|
+
_ => !!commands_[_.name],
|
|
101
|
+
),
|
|
102
|
+
() => new SubCommandNotFound({ data: this.data }),
|
|
103
|
+
).pipe(
|
|
104
|
+
Effect.flatMap(command =>
|
|
105
|
+
Effect.provideService(commands_[command.name], SubCommandContext, {
|
|
106
|
+
command,
|
|
107
|
+
}),
|
|
108
|
+
),
|
|
109
|
+
) as any
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get optionsMap(): HashMap<string, string | undefined> {
|
|
113
|
+
return Helpers.optionsMap(this.data)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type CommandHandlerFn<R, E, A> = (
|
|
118
|
+
i: CommandHelper<A>,
|
|
119
|
+
) => Effect.Effect<Discord.InteractionResponse, E, R>
|
|
120
|
+
|
|
121
|
+
interface CommandOption {
|
|
122
|
+
readonly type: any
|
|
123
|
+
readonly name: string
|
|
124
|
+
readonly options?: ReadonlyArray<CommandOption>
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
type CommandTypeMap<
|
|
128
|
+
A,
|
|
129
|
+
Options extends Record<Discord.ApplicationCommandType, any>,
|
|
130
|
+
> = A extends { readonly type: infer T }
|
|
131
|
+
? T extends keyof Options
|
|
132
|
+
? Options[T]
|
|
133
|
+
: never
|
|
134
|
+
: Options[Discord.ApplicationCommandType.CHAT_INPUT]
|
|
135
|
+
|
|
136
|
+
// == Sub commands
|
|
137
|
+
type SubCommands<A> = A extends {
|
|
138
|
+
readonly type: Discord.ApplicationCommandOptionType.SUB_COMMAND
|
|
139
|
+
readonly options?: ReadonlyArray<CommandOption>
|
|
140
|
+
}
|
|
141
|
+
? A
|
|
142
|
+
: A extends { readonly options: ReadonlyArray<CommandOption> }
|
|
143
|
+
? SubCommands<A["options"][number]>
|
|
144
|
+
: never
|
|
145
|
+
|
|
146
|
+
type SubCommandNames<A> = Option<SubCommands<A>>["name"]
|
|
147
|
+
|
|
148
|
+
// == Command options
|
|
149
|
+
type CommandOptionType = Exclude<
|
|
150
|
+
Discord.ApplicationCommandOptionType,
|
|
151
|
+
| Discord.ApplicationCommandOptionType.SUB_COMMAND
|
|
152
|
+
| Discord.ApplicationCommandOptionType.SUB_COMMAND_GROUP
|
|
153
|
+
>
|
|
154
|
+
|
|
155
|
+
type CommandOptions<A> = OptionsWithLiteral<
|
|
156
|
+
A,
|
|
157
|
+
{
|
|
158
|
+
readonly type: CommandOptionType
|
|
159
|
+
}
|
|
160
|
+
>
|
|
161
|
+
|
|
162
|
+
type SubCommandOptions<A> = Extract<
|
|
163
|
+
Option<Exclude<SubCommands<A>["options"], undefined>[number]>,
|
|
164
|
+
{
|
|
165
|
+
readonly type: CommandOptionType
|
|
166
|
+
}
|
|
167
|
+
>
|
|
168
|
+
|
|
169
|
+
type AllCommandOptions<A> = CommandOptions<A> | SubCommandOptions<A>
|
|
170
|
+
|
|
171
|
+
type CommandWithName<A, N> = Extract<AllCommandOptions<A>, { readonly name: N }>
|
|
172
|
+
|
|
173
|
+
type OptionTypeValue = {
|
|
174
|
+
[Discord.ApplicationCommandOptionType.BOOLEAN]: boolean
|
|
175
|
+
[Discord.ApplicationCommandOptionType.INTEGER]: number
|
|
176
|
+
[Discord.ApplicationCommandOptionType.NUMBER]: number
|
|
177
|
+
}
|
|
178
|
+
type CommandValue<A, N> = CommandWithName<
|
|
179
|
+
A,
|
|
180
|
+
N
|
|
181
|
+
>["type"] extends keyof OptionTypeValue
|
|
182
|
+
? OptionTypeValue[CommandWithName<A, N>["type"]]
|
|
183
|
+
: string
|
|
184
|
+
|
|
185
|
+
// == Required options
|
|
186
|
+
type RequiredCommandOptions<A> = OptionsWithLiteral<
|
|
187
|
+
A,
|
|
188
|
+
{
|
|
189
|
+
readonly type: CommandOptionType
|
|
190
|
+
readonly required: true
|
|
191
|
+
}
|
|
192
|
+
>
|
|
193
|
+
|
|
194
|
+
type RequiredSubCommandOptions<A> = Extract<
|
|
195
|
+
SubCommandOptions<A>,
|
|
196
|
+
{ readonly required: true }
|
|
197
|
+
>
|
|
198
|
+
|
|
199
|
+
type AllRequiredCommandOptions<A> =
|
|
200
|
+
| RequiredCommandOptions<A>
|
|
201
|
+
| RequiredSubCommandOptions<A>
|
|
202
|
+
|
|
203
|
+
// == Resolveables
|
|
204
|
+
type ResolvableType =
|
|
205
|
+
| Discord.ApplicationCommandOptionType.ROLE
|
|
206
|
+
| Discord.ApplicationCommandOptionType.USER
|
|
207
|
+
| Discord.ApplicationCommandOptionType.MENTIONABLE
|
|
208
|
+
| Discord.ApplicationCommandOptionType.CHANNEL
|
|
209
|
+
|
|
210
|
+
type Resolvables<A> = OptionsWithLiteral<A, { readonly type: ResolvableType }>
|
|
211
|
+
type SubCommandResolvables<A> = Extract<
|
|
212
|
+
Option<Exclude<SubCommands<A>["options"], undefined>[number]>,
|
|
213
|
+
{
|
|
214
|
+
readonly type: ResolvableType
|
|
215
|
+
}
|
|
216
|
+
>
|
|
217
|
+
type AllResolvables<A> = Resolvables<A> | SubCommandResolvables<A>
|
|
218
|
+
|
|
219
|
+
// == Utilities
|
|
220
|
+
type StringLiteral<T> = T extends string
|
|
221
|
+
? string extends T
|
|
222
|
+
? never
|
|
223
|
+
: T
|
|
224
|
+
: never
|
|
225
|
+
|
|
226
|
+
type Option<A> = A extends { readonly name: infer N }
|
|
227
|
+
? N extends StringLiteral<N>
|
|
228
|
+
? A
|
|
229
|
+
: never
|
|
230
|
+
: never
|
|
231
|
+
|
|
232
|
+
type OptionsWithLiteral<A, T> = A extends {
|
|
233
|
+
readonly options: ReadonlyArray<CommandOption>
|
|
234
|
+
}
|
|
235
|
+
? Extract<A["options"][number], Option<A["options"][number]> & T>
|
|
236
|
+
: never
|
|
@@ -5,9 +5,9 @@ import type * as Discord from "dfx/types"
|
|
|
5
5
|
import type { NoSuchElementException } from "effect/Cause"
|
|
6
6
|
import { GenericTag } from "effect/Context"
|
|
7
7
|
import * as Effect from "effect/Effect"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import * as
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10
|
+
import * as Types from "effect/Types"
|
|
11
11
|
|
|
12
12
|
export interface DiscordInteraction {
|
|
13
13
|
readonly _: unique symbol
|
|
@@ -85,58 +85,12 @@ export class SubCommandNotFound extends TypeIdError(
|
|
|
85
85
|
data: Discord.ApplicationCommandDatum
|
|
86
86
|
}> {}
|
|
87
87
|
|
|
88
|
-
export const handleSubCommands = <
|
|
89
|
-
NER extends Record<
|
|
90
|
-
string,
|
|
91
|
-
Effect.Effect<Discord.InteractionResponse, any, any>
|
|
92
|
-
>,
|
|
93
|
-
>(
|
|
94
|
-
commands: NER,
|
|
95
|
-
): Effect.Effect<
|
|
96
|
-
Discord.InteractionResponse,
|
|
97
|
-
| ([NER[keyof NER]] extends [
|
|
98
|
-
{ [Effect.EffectTypeId]: { _E: (_: never) => infer E } },
|
|
99
|
-
]
|
|
100
|
-
? E
|
|
101
|
-
: never)
|
|
102
|
-
| SubCommandNotFound,
|
|
103
|
-
| Exclude<
|
|
104
|
-
[NER[keyof NER]] extends [
|
|
105
|
-
{ [Effect.EffectTypeId]: { _R: (_: never) => infer R } },
|
|
106
|
-
]
|
|
107
|
-
? R
|
|
108
|
-
: never,
|
|
109
|
-
SubCommandContext
|
|
110
|
-
>
|
|
111
|
-
| Discord.Interaction
|
|
112
|
-
| Discord.ApplicationCommandDatum
|
|
113
|
-
> =>
|
|
114
|
-
ApplicationCommand.pipe(
|
|
115
|
-
Effect.flatMap(data =>
|
|
116
|
-
Effect.mapError(
|
|
117
|
-
Arr.findFirst(IxHelpers.allSubCommands(data), _ => !!commands[_.name]),
|
|
118
|
-
() => new SubCommandNotFound({ data }),
|
|
119
|
-
),
|
|
120
|
-
),
|
|
121
|
-
Effect.flatMap(command =>
|
|
122
|
-
Effect.provideService(commands[command.name], SubCommandContext, {
|
|
123
|
-
command,
|
|
124
|
-
}),
|
|
125
|
-
),
|
|
126
|
-
)
|
|
127
|
-
|
|
128
88
|
export const currentSubCommand: Effect.Effect<
|
|
129
89
|
Discord.ApplicationCommandInteractionDataOption,
|
|
130
90
|
never,
|
|
131
91
|
DiscordSubCommand
|
|
132
92
|
> = Effect.map(SubCommandContext, _ => _.command)
|
|
133
93
|
|
|
134
|
-
export const optionsMap: Effect.Effect<
|
|
135
|
-
HashMap.HashMap<string, string | undefined>,
|
|
136
|
-
never,
|
|
137
|
-
DiscordApplicationCommand
|
|
138
|
-
> = Effect.map(ApplicationCommand, IxHelpers.optionsMap)
|
|
139
|
-
|
|
140
94
|
export class RequiredOptionNotFound {
|
|
141
95
|
readonly _tag = "RequiredOptionNotFound"
|
|
142
96
|
constructor(
|
|
@@ -147,29 +101,6 @@ export class RequiredOptionNotFound {
|
|
|
147
101
|
) {}
|
|
148
102
|
}
|
|
149
103
|
|
|
150
|
-
export const option = (name: string) =>
|
|
151
|
-
Effect.map(ApplicationCommand, IxHelpers.getOption(name))
|
|
152
|
-
|
|
153
|
-
export const optionValue = (name: string) =>
|
|
154
|
-
Effect.flatMap(option(name), _ =>
|
|
155
|
-
Option.match(
|
|
156
|
-
Option.flatMapNullable(_, a => a.value),
|
|
157
|
-
{
|
|
158
|
-
onNone: () =>
|
|
159
|
-
Effect.flatMap(ApplicationCommand, data =>
|
|
160
|
-
Effect.fail(new RequiredOptionNotFound(data, name)),
|
|
161
|
-
),
|
|
162
|
-
onSome: Effect.succeed,
|
|
163
|
-
},
|
|
164
|
-
),
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
export const optionValueOptional = (name: string) =>
|
|
168
|
-
Effect.map(
|
|
169
|
-
option(name),
|
|
170
|
-
Option.flatMapNullable(o => o.value),
|
|
171
|
-
)
|
|
172
|
-
|
|
173
104
|
export const modalValues = Effect.map(ModalSubmitData, IxHelpers.componentsMap)
|
|
174
105
|
|
|
175
106
|
export const modalValueOption = (name: string) =>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type * as Option from "effect/Option"
|
|
2
1
|
import type * as Effect from "effect/Effect"
|
|
3
2
|
import type {
|
|
4
3
|
DiscordApplicationCommand,
|
|
@@ -6,11 +5,10 @@ import type {
|
|
|
6
5
|
DiscordInteraction,
|
|
7
6
|
DiscordMessageComponent,
|
|
8
7
|
DiscordModalSubmit,
|
|
9
|
-
SubCommandContext,
|
|
10
8
|
} from "dfx/Interactions/context"
|
|
11
9
|
import type * as Discord from "dfx/types"
|
|
12
|
-
import type { NoSuchElementException } from "effect/Cause"
|
|
13
10
|
import type { Scope } from "effect/Scope"
|
|
11
|
+
import type { CommandHelper } from "./commandHelper"
|
|
14
12
|
|
|
15
13
|
export type InteractionDefinition<R, E> =
|
|
16
14
|
| GlobalApplicationCommand<R, E>
|
|
@@ -129,188 +127,6 @@ export type CommandHandler<R, E, A = any> =
|
|
|
129
127
|
| Effect.Effect<Discord.InteractionResponse, E, R>
|
|
130
128
|
| CommandHandlerFn<R, E, A>
|
|
131
129
|
|
|
132
|
-
export interface CommandHelper<A> {
|
|
133
|
-
readonly target: CommandTypeMap<
|
|
134
|
-
A,
|
|
135
|
-
{
|
|
136
|
-
[Discord.ApplicationCommandType.CHAT_INPUT]: Discord.ApplicationCommand
|
|
137
|
-
[Discord.ApplicationCommandType.MESSAGE]: Discord.Message
|
|
138
|
-
[Discord.ApplicationCommandType.USER]: Discord.User
|
|
139
|
-
[Discord.ApplicationCommandType.PRIMARY_ENTRY_POINT]: undefined
|
|
140
|
-
}
|
|
141
|
-
>
|
|
142
|
-
|
|
143
|
-
resolve: <T>(
|
|
144
|
-
name: AllResolvables<A>["name"],
|
|
145
|
-
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => T | undefined,
|
|
146
|
-
) => Effect.Effect<T, NoSuchElementException, DiscordInteraction>
|
|
147
|
-
|
|
148
|
-
option: (
|
|
149
|
-
name: AllCommandOptions<A>["name"],
|
|
150
|
-
) => Effect.Effect<
|
|
151
|
-
Option.Option<Discord.ApplicationCommandInteractionDataOption>,
|
|
152
|
-
never,
|
|
153
|
-
DiscordApplicationCommand
|
|
154
|
-
>
|
|
155
|
-
|
|
156
|
-
optionValue: <N extends AllRequiredCommandOptions<A>["name"]>(
|
|
157
|
-
name: N,
|
|
158
|
-
) => Effect.Effect<CommandValue<A, N>, never, DiscordApplicationCommand>
|
|
159
|
-
|
|
160
|
-
optionValueOptional: <N extends AllCommandOptions<A>["name"]>(
|
|
161
|
-
name: N,
|
|
162
|
-
) => Effect.Effect<
|
|
163
|
-
Option.Option<CommandValue<A, N>>,
|
|
164
|
-
never,
|
|
165
|
-
DiscordApplicationCommand
|
|
166
|
-
>
|
|
167
|
-
|
|
168
|
-
subCommands: <
|
|
169
|
-
NER extends SubCommandNames<A> extends never
|
|
170
|
-
? never
|
|
171
|
-
: Record<
|
|
172
|
-
SubCommandNames<A>,
|
|
173
|
-
Effect.Effect<Discord.InteractionResponse, any, any>
|
|
174
|
-
>,
|
|
175
|
-
>(
|
|
176
|
-
commands: NER,
|
|
177
|
-
) => Effect.Effect<
|
|
178
|
-
Discord.InteractionResponse,
|
|
179
|
-
[NER[keyof NER]] extends [
|
|
180
|
-
{ [Effect.EffectTypeId]: { _E: (_: never) => infer E } },
|
|
181
|
-
]
|
|
182
|
-
? E
|
|
183
|
-
: never,
|
|
184
|
-
| Exclude<
|
|
185
|
-
[NER[keyof NER]] extends [
|
|
186
|
-
{ [Effect.EffectTypeId]: { _R: (_: never) => infer R } },
|
|
187
|
-
]
|
|
188
|
-
? R
|
|
189
|
-
: never,
|
|
190
|
-
SubCommandContext
|
|
191
|
-
>
|
|
192
|
-
| DiscordInteraction
|
|
193
|
-
| DiscordApplicationCommand
|
|
194
|
-
>
|
|
195
|
-
}
|
|
196
|
-
|
|
197
130
|
export type CommandHandlerFn<R, E, A> = (
|
|
198
131
|
i: CommandHelper<A>,
|
|
199
132
|
) => Effect.Effect<Discord.InteractionResponse, E, R>
|
|
200
|
-
|
|
201
|
-
interface CommandOption {
|
|
202
|
-
readonly type: any
|
|
203
|
-
readonly name: string
|
|
204
|
-
readonly options?: ReadonlyArray<CommandOption>
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// == Sub commands
|
|
208
|
-
type SubCommands<A> = A extends {
|
|
209
|
-
readonly type: Discord.ApplicationCommandOptionType.SUB_COMMAND
|
|
210
|
-
readonly options?: ReadonlyArray<CommandOption>
|
|
211
|
-
}
|
|
212
|
-
? A
|
|
213
|
-
: A extends { readonly options: ReadonlyArray<CommandOption> }
|
|
214
|
-
? SubCommands<A["options"][number]>
|
|
215
|
-
: never
|
|
216
|
-
|
|
217
|
-
type SubCommandNames<A> = Option<SubCommands<A>>["name"]
|
|
218
|
-
|
|
219
|
-
// == Command options
|
|
220
|
-
type CommandOptionType = Exclude<
|
|
221
|
-
Discord.ApplicationCommandOptionType,
|
|
222
|
-
| Discord.ApplicationCommandOptionType.SUB_COMMAND
|
|
223
|
-
| Discord.ApplicationCommandOptionType.SUB_COMMAND_GROUP
|
|
224
|
-
>
|
|
225
|
-
|
|
226
|
-
type CommandOptions<A> = OptionsWithLiteral<
|
|
227
|
-
A,
|
|
228
|
-
{
|
|
229
|
-
readonly type: CommandOptionType
|
|
230
|
-
}
|
|
231
|
-
>
|
|
232
|
-
|
|
233
|
-
type SubCommandOptions<A> = Extract<
|
|
234
|
-
Option<Exclude<SubCommands<A>["options"], undefined>[number]>,
|
|
235
|
-
{
|
|
236
|
-
readonly type: CommandOptionType
|
|
237
|
-
}
|
|
238
|
-
>
|
|
239
|
-
|
|
240
|
-
type AllCommandOptions<A> = CommandOptions<A> | SubCommandOptions<A>
|
|
241
|
-
|
|
242
|
-
type CommandWithName<A, N> = Extract<AllCommandOptions<A>, { readonly name: N }>
|
|
243
|
-
|
|
244
|
-
type OptionTypeValue = {
|
|
245
|
-
[Discord.ApplicationCommandOptionType.BOOLEAN]: boolean
|
|
246
|
-
[Discord.ApplicationCommandOptionType.INTEGER]: number
|
|
247
|
-
[Discord.ApplicationCommandOptionType.NUMBER]: number
|
|
248
|
-
}
|
|
249
|
-
type CommandValue<A, N> = CommandWithName<
|
|
250
|
-
A,
|
|
251
|
-
N
|
|
252
|
-
>["type"] extends keyof OptionTypeValue
|
|
253
|
-
? OptionTypeValue[CommandWithName<A, N>["type"]]
|
|
254
|
-
: string
|
|
255
|
-
|
|
256
|
-
type CommandTypeMap<
|
|
257
|
-
A,
|
|
258
|
-
Options extends Record<Discord.ApplicationCommandType, any>,
|
|
259
|
-
> = A extends { readonly type: infer T }
|
|
260
|
-
? T extends keyof Options
|
|
261
|
-
? Options[T]
|
|
262
|
-
: never
|
|
263
|
-
: Options[Discord.ApplicationCommandType.CHAT_INPUT]
|
|
264
|
-
|
|
265
|
-
// == Required options
|
|
266
|
-
type RequiredCommandOptions<A> = OptionsWithLiteral<
|
|
267
|
-
A,
|
|
268
|
-
{
|
|
269
|
-
readonly type: CommandOptionType
|
|
270
|
-
readonly required: true
|
|
271
|
-
}
|
|
272
|
-
>
|
|
273
|
-
|
|
274
|
-
type RequiredSubCommandOptions<A> = Extract<
|
|
275
|
-
SubCommandOptions<A>,
|
|
276
|
-
{ readonly required: true }
|
|
277
|
-
>
|
|
278
|
-
|
|
279
|
-
type AllRequiredCommandOptions<A> =
|
|
280
|
-
| RequiredCommandOptions<A>
|
|
281
|
-
| RequiredSubCommandOptions<A>
|
|
282
|
-
|
|
283
|
-
// == Resolveables
|
|
284
|
-
type ResolvableType =
|
|
285
|
-
| Discord.ApplicationCommandOptionType.ROLE
|
|
286
|
-
| Discord.ApplicationCommandOptionType.USER
|
|
287
|
-
| Discord.ApplicationCommandOptionType.MENTIONABLE
|
|
288
|
-
| Discord.ApplicationCommandOptionType.CHANNEL
|
|
289
|
-
|
|
290
|
-
type Resolvables<A> = OptionsWithLiteral<A, { readonly type: ResolvableType }>
|
|
291
|
-
type SubCommandResolvables<A> = Extract<
|
|
292
|
-
Option<Exclude<SubCommands<A>["options"], undefined>[number]>,
|
|
293
|
-
{
|
|
294
|
-
readonly type: ResolvableType
|
|
295
|
-
}
|
|
296
|
-
>
|
|
297
|
-
type AllResolvables<A> = Resolvables<A> | SubCommandResolvables<A>
|
|
298
|
-
|
|
299
|
-
// == Utilities
|
|
300
|
-
type StringLiteral<T> = T extends string
|
|
301
|
-
? string extends T
|
|
302
|
-
? never
|
|
303
|
-
: T
|
|
304
|
-
: never
|
|
305
|
-
|
|
306
|
-
type Option<A> = A extends { readonly name: infer N }
|
|
307
|
-
? N extends StringLiteral<N>
|
|
308
|
-
? A
|
|
309
|
-
: never
|
|
310
|
-
: never
|
|
311
|
-
|
|
312
|
-
type OptionsWithLiteral<A, T> = A extends {
|
|
313
|
-
readonly options: ReadonlyArray<CommandOption>
|
|
314
|
-
}
|
|
315
|
-
? Extract<A["options"][number], Option<A["options"][number]> & T>
|
|
316
|
-
: never
|