abseil 0.1.0 → 0.3.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/README.md +56 -43
- package/dist/index.d.ts +37 -13
- package/dist/index.js +135 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/index.test.d.ts +0 -1
- package/dist/index.test.js +0 -131
- package/dist/index.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,58 +1,71 @@
|
|
|
1
1
|
# Abseil
|
|
2
2
|
|
|
3
|
-
Quickly traverse Discord [Components V2](https://docs.discord.com/developers/components/overview) trees.
|
|
3
|
+
Quickly traverse Discord [Components V2](https://docs.discord.com/developers/components/overview) trees. Either enter at the root with `abseil([...]).initial(type)` or jump to a specific node with `abseil([...]).find(query, type)`.
|
|
4
4
|
|
|
5
|
-
## Reference
|
|
5
|
+
## Node Reference
|
|
6
6
|
|
|
7
|
-
| function
|
|
8
|
-
|
|
|
9
|
-
| accessory
|
|
10
|
-
| child
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
7
|
+
| function | description |
|
|
8
|
+
| ------------ | ----------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| accessory | Access the accessory of a [Section](https://docs.discord.com/developers/components/reference#section) |
|
|
10
|
+
| child | Access the first child of a node |
|
|
11
|
+
| insertBefore | Insert a sibling before the current node |
|
|
12
|
+
| last | Jump to the last neighbouring node of a type in an array |
|
|
13
|
+
| next | Jump to the next neighbouring node of a type in an array |
|
|
14
|
+
| parent | Access the parent of a node |
|
|
15
|
+
| previous | Return to the previous node |
|
|
16
|
+
| sibling | Access the next node in an array |
|
|
17
|
+
| update | Shallow merge with the current component in place |
|
|
18
|
+
| value | The current component |
|
|
15
19
|
|
|
16
20
|
## Example
|
|
17
21
|
|
|
22
|
+
<details>
|
|
23
|
+
<summary>Sample message definition</summary>
|
|
24
|
+
|
|
18
25
|
```ts
|
|
19
|
-
import {
|
|
20
|
-
import { Button,
|
|
21
|
-
import abseil from "abseil";
|
|
26
|
+
import type { APIMessage } from "discord-api-types/v10";
|
|
27
|
+
import { ActionRow, Button, Container, Section, Separator, TextDisplay } from "dressed";
|
|
22
28
|
|
|
23
29
|
const message = {
|
|
24
30
|
components: [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
{ type: ComponentType.ActionRow, components: [{ type: ComponentType.UserSelect }] },
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
type: ComponentType.ActionRow,
|
|
40
|
-
components: [{ type: ComponentType.Button }, { type: ComponentType.Button }],
|
|
41
|
-
},
|
|
31
|
+
Container(
|
|
32
|
+
Section(["## Trivia!"], Button({ custom_id: "suggest", style: "Secondary" })),
|
|
33
|
+
TextDisplay("What is the meaning of life?"),
|
|
34
|
+
ActionRow(
|
|
35
|
+
Button({ custom_id: "guess-money", label: "💵" }),
|
|
36
|
+
Button({ custom_id: "guess-42", label: "🤖" }),
|
|
37
|
+
),
|
|
38
|
+
Separator(),
|
|
39
|
+
Section(["## 🟩🟩🟥🟥🟥⬛⬛⬛⬛⬛"], Button({ custom_id: "stats-3-2", style: "Secondary" })),
|
|
40
|
+
),
|
|
42
41
|
],
|
|
43
42
|
} as APIMessage;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
</details>
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import abseil, { removeNode } from "abseil";
|
|
49
|
+
import { editMessage } from "dressed";
|
|
50
|
+
|
|
51
|
+
const line = abseil(message.components ?? []);
|
|
52
|
+
|
|
53
|
+
let guessBtn = line.find(/guess-.+/, "Button");
|
|
54
|
+
|
|
55
|
+
while (guessBtn) {
|
|
56
|
+
guessBtn.update({ disabled: true });
|
|
57
|
+
guessBtn = guessBtn.next("Button");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const header = line.initial("Container").child("Section");
|
|
61
|
+
|
|
62
|
+
header.insertBefore(TextDisplay(header.child("TextDisplay").value.content));
|
|
63
|
+
removeNode(header);
|
|
64
|
+
|
|
65
|
+
// Insert-if-not-exists the warning message
|
|
66
|
+
if (!header.last("Section")?.sibling) {
|
|
67
|
+
header.previous.value.components.push(TextDisplay("-# This has expired!"));
|
|
68
|
+
}
|
|
44
69
|
|
|
45
|
-
|
|
46
|
-
.initial("TextDisplay")
|
|
47
|
-
.sibling("Container")
|
|
48
|
-
.update({ spoiler: true })
|
|
49
|
-
.sibling("ActionRow")
|
|
50
|
-
.update((p) => ({
|
|
51
|
-
components: p.components.concat(Button({ custom_id: "new", label: "I'm new!" })),
|
|
52
|
-
}))
|
|
53
|
-
.previous.child("Section")
|
|
54
|
-
.accessory(["Button", "Thumbnail"])
|
|
55
|
-
.update({ id: 32 });
|
|
56
|
-
|
|
57
|
-
editMessage("<CHANNEL_ID>", "<MESSAGE_ID>", message.components);
|
|
70
|
+
editMessage("<CHANNEL_ID>", "<MESSAGE_ID>", { components: message.components });
|
|
58
71
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -7,17 +7,19 @@ type CT = typeof ComponentType & {
|
|
|
7
7
|
type IComponentType = {
|
|
8
8
|
[K in keyof CT as CT[K]]: K;
|
|
9
9
|
};
|
|
10
|
+
type WithCustomIdType = Exclude<IComponentType[Extract<APIMessageComponent, {
|
|
11
|
+
custom_id: string;
|
|
12
|
+
}>["type"]], `Button:${string}`>;
|
|
10
13
|
type Pop<T extends any[]> = T extends [...infer Rest, any] ? Rest : never;
|
|
11
14
|
type Last<T extends any[]> = T extends [...any[], infer L] ? L : never;
|
|
12
15
|
type Arrable<T> = T | T[];
|
|
13
|
-
type Narr<T extends Arrable<string>> = T extends string ? T : T[number];
|
|
14
16
|
type Overwriter<T> = Partial<T> | ((prev: T) => Partial<T>);
|
|
15
17
|
interface ChildrenMap {
|
|
16
18
|
ActionRow: IComponentType[APIComponentInMessageActionRow["type"]] | "Button:URL" | "Button:SKU";
|
|
17
19
|
Container: IComponentType[APIComponentInContainer["type"]];
|
|
18
20
|
Section: "TextDisplay";
|
|
19
21
|
}
|
|
20
|
-
type TraverserFn<C extends keyof CT, H extends (keyof CT)[], O extends string = ""> = <
|
|
22
|
+
type TraverserFn<C extends keyof CT, H extends (keyof CT)[], O extends string = ""> = <T extends C>(type: Arrable<T>) => Omit<Traverser<T, H, C>, O>;
|
|
21
23
|
type Component<T extends keyof CT> = Extract<APIMessageComponent, {
|
|
22
24
|
type: CT[T extends "Button:URL" | "Button:SKU" ? "Button" : T];
|
|
23
25
|
} & (T extends "Button" ? {
|
|
@@ -27,26 +29,48 @@ type Component<T extends keyof CT> = Extract<APIMessageComponent, {
|
|
|
27
29
|
} : T extends "Button:SKU" ? {
|
|
28
30
|
sku_id: string;
|
|
29
31
|
} : object)>;
|
|
30
|
-
type Traverser<T extends keyof CT, H extends (keyof CT)[], ST extends keyof CT = keyof CT> = {
|
|
31
|
-
/** Shallow merge with the current component in place */
|
|
32
|
+
export type Traverser<T extends keyof CT, H extends (keyof CT)[], ST extends keyof CT = keyof CT> = {
|
|
33
|
+
/** Shallow merge with the current component in place. */
|
|
32
34
|
update: (value: Overwriter<Component<T>>) => Traverser<T, H, ST>;
|
|
33
|
-
/** The current component */
|
|
35
|
+
/** The current component. */
|
|
34
36
|
value: Component<T>;
|
|
37
|
+
/** Access the parent of the current node. */
|
|
38
|
+
parent: TraverserFn<keyof CT, [...H, T]>;
|
|
35
39
|
} & (T extends IComponentType[APISelectMenuComponent["type"]] ? object : {
|
|
36
|
-
/**
|
|
40
|
+
/** Insert a sibling before the current node. */
|
|
41
|
+
insertBefore: (component: Extract<APIMessageComponent, {
|
|
42
|
+
type: (typeof ComponentType)[Exclude<ST, "Button:URL" | "Button:SKU">];
|
|
43
|
+
}>) => Traverser<T, H, ST>;
|
|
44
|
+
/** Jump to the last neighbouring node of a type in an array. */
|
|
45
|
+
last: <N extends ST>(type: Arrable<N>) => Traverser<N, [...H, T], ST> | undefined;
|
|
46
|
+
/** Jump to the next neighbouring node of a type in an array. */
|
|
47
|
+
next: <N extends ST>(type: Arrable<N>) => Traverser<N, [...H, T], ST> | undefined;
|
|
48
|
+
/** Access the next node in an array. */
|
|
37
49
|
sibling: TraverserFn<ST, [...H, T]>;
|
|
38
50
|
}) & (T extends keyof ChildrenMap ? {
|
|
39
|
-
/** Access the first child of a node */
|
|
51
|
+
/** Access the first child of a node. */
|
|
40
52
|
child: TraverserFn<ChildrenMap[T], [...H, T]>;
|
|
41
53
|
} : object) & (T extends "Section" ? {
|
|
42
|
-
/** Access the accessory of a [Section](https://docs.discord.com/developers/components/reference#section) */
|
|
54
|
+
/** Access the accessory of a [Section](https://docs.discord.com/developers/components/reference#section). */
|
|
43
55
|
accessory: TraverserFn<IComponentType[APISectionAccessoryComponent["type"]], [...H, T], "sibling">;
|
|
44
56
|
} : object) & (H extends [] ? object : {
|
|
45
|
-
/** Return to the previous node */
|
|
57
|
+
/** Return to the previous node. */
|
|
46
58
|
previous: Traverser<Last<H>, Pop<H>>;
|
|
47
59
|
});
|
|
48
|
-
/** Initiate a tree traverser */
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
/** Initiate a tree traverser. */
|
|
61
|
+
export default function abseil<T extends APIMessageComponent>(components: T[]): {
|
|
62
|
+
/**
|
|
63
|
+
* Enter the tree at a specific node.
|
|
64
|
+
* @param query Either the component `id` or `custom_id`
|
|
65
|
+
*/
|
|
66
|
+
find<Q extends number | string | RegExp, F extends Q extends number ? keyof CT : WithCustomIdType>(query: Q, type: Arrable<F>): Omit<Traverser<F, [], "File" | "ActionRow" | "Button" | "StringSelect" | "TextInput" | "UserSelect" | "RoleSelect" | "MentionableSelect" | "ChannelSelect" | "Section" | "TextDisplay" | "Thumbnail" | "MediaGallery" | "Separator" | "ContentInventoryEntry" | "Container" | "Label" | "FileUpload" | "RadioGroup" | "CheckboxGroup" | "Checkbox" | "SelectMenu" | "Button:URL" | "Button:SKU">, "previous"> | undefined;
|
|
67
|
+
/** Entry point of the tree, visually this is the top-leftmost component. */
|
|
68
|
+
initial: TraverserFn<IComponentType[T["type"]], [], "parent" | "previous">;
|
|
51
69
|
};
|
|
52
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Destroy a node in the tree.
|
|
72
|
+
* Data on this node will be stripped, attempting to access most functions will throw.
|
|
73
|
+
* @important This may cause issues when you try to navigate {@link abseil} instances you've previously created
|
|
74
|
+
*/
|
|
75
|
+
export declare function removeNode<T extends keyof typeof ComponentType>(node: Traverser<T, any, any>): void;
|
|
76
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
/** biome-ignore-all lint/suspicious/noExplicitAny: Not worth my time */
|
|
2
2
|
import { ComponentType, } from "discord-api-types/v10";
|
|
3
3
|
const withChildren = new Set([ComponentType.ActionRow, ComponentType.Section, ComponentType.Container]);
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const selects = new Set([
|
|
5
|
+
ComponentType.StringSelect,
|
|
6
|
+
ComponentType.UserSelect,
|
|
7
|
+
ComponentType.RoleSelect,
|
|
8
|
+
ComponentType.MentionableSelect,
|
|
9
|
+
ComponentType.ChannelSelect,
|
|
10
|
+
]);
|
|
11
|
+
function matchTypes(component, expected, doNotThrow) {
|
|
12
|
+
const expectedTypes = new Set((Array.isArray(expected) ? expected : [expected]).filter(Boolean));
|
|
13
|
+
if (!expectedTypes.size) {
|
|
14
|
+
throw new Error("Selectors must specify expected type(s)");
|
|
15
|
+
}
|
|
6
16
|
let actualType = ComponentType[component.type];
|
|
7
17
|
if (actualType === "Button") {
|
|
8
18
|
if ("url" in component)
|
|
@@ -11,31 +21,132 @@ function createTraverser(component, expected, previous, siblings) {
|
|
|
11
21
|
actualType += ":SKU";
|
|
12
22
|
}
|
|
13
23
|
if (!expectedTypes.has(actualType)) {
|
|
14
|
-
|
|
24
|
+
if (!doNotThrow) {
|
|
25
|
+
throw new TypeError(`Type mismatch: expected ${[...expectedTypes].join(" or ")}, got ${actualType}`);
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
15
28
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
function find(query, components) {
|
|
32
|
+
for (const component of components) {
|
|
33
|
+
if ((typeof query === "number" && component.id === query) ||
|
|
34
|
+
("custom_id" in component &&
|
|
35
|
+
((typeof query === "string" && component.custom_id === query) ||
|
|
36
|
+
(query instanceof RegExp && query.test(component.custom_id))))) {
|
|
37
|
+
return component;
|
|
38
|
+
}
|
|
39
|
+
if ("components" in component) {
|
|
40
|
+
const found = find(query, component.components);
|
|
41
|
+
if (found)
|
|
42
|
+
return found;
|
|
43
|
+
}
|
|
44
|
+
if (component.type === ComponentType.Section && component.accessory) {
|
|
45
|
+
const found = find(query, [component.accessory]);
|
|
46
|
+
if (found)
|
|
47
|
+
return found;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function findParent(child, components) {
|
|
52
|
+
for (const component of components) {
|
|
53
|
+
if ("components" in component) {
|
|
54
|
+
if (component.components.includes(child))
|
|
55
|
+
return component;
|
|
56
|
+
const found = findParent(child, component.components);
|
|
57
|
+
if (found)
|
|
58
|
+
return found;
|
|
59
|
+
}
|
|
60
|
+
if (component.type === ComponentType.Section && component.accessory === child) {
|
|
61
|
+
return component;
|
|
62
|
+
}
|
|
27
63
|
}
|
|
28
|
-
|
|
29
|
-
|
|
64
|
+
}
|
|
65
|
+
/** Initiate a tree traverser. */
|
|
66
|
+
export default function abseil(components) {
|
|
67
|
+
function createTraverser(component, expected, previous, neighbours) {
|
|
68
|
+
matchTypes(component, expected);
|
|
69
|
+
const traverser = {
|
|
70
|
+
value: component,
|
|
71
|
+
update(v) {
|
|
72
|
+
Object.assign(component, typeof v === "function" ? v(component) : v);
|
|
73
|
+
return traverser;
|
|
74
|
+
},
|
|
75
|
+
parent(t) {
|
|
76
|
+
const parentComponent = findParent(component, components);
|
|
77
|
+
if (!parentComponent)
|
|
78
|
+
throw new Error("This node does not have a parent");
|
|
79
|
+
const parentParent = findParent(parentComponent, components);
|
|
80
|
+
return createTraverser(parentComponent, t, traverser, parentParent && "components" in parentParent ? parentParent.components : []);
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
if (previous)
|
|
84
|
+
traverser.previous = previous;
|
|
85
|
+
if (neighbours) {
|
|
86
|
+
if (!selects.has(component.type)) {
|
|
87
|
+
traverser.insertBefore = (v) => {
|
|
88
|
+
neighbours.splice(neighbours.indexOf(component), 0, v);
|
|
89
|
+
return traverser;
|
|
90
|
+
};
|
|
91
|
+
traverser.last = (t) => {
|
|
92
|
+
for (let i = neighbours.length - 1; i >= 0; --i) {
|
|
93
|
+
const sibling = neighbours[i];
|
|
94
|
+
if (!matchTypes(sibling, t, true))
|
|
95
|
+
continue;
|
|
96
|
+
return createTraverser(sibling, t, traverser, neighbours);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
traverser.next = (t) => {
|
|
100
|
+
const next = neighbours.slice(neighbours.indexOf(component) + 1).find((s) => matchTypes(s, t, true));
|
|
101
|
+
if (!next)
|
|
102
|
+
return undefined;
|
|
103
|
+
return createTraverser(next, t, traverser, neighbours);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (neighbours.length !== neighbours.indexOf(component) + 1) {
|
|
107
|
+
traverser.sibling = (t) => createTraverser(neighbours[neighbours.indexOf(component) + 1], t, traverser, neighbours);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (withChildren.has(component.type) && "components" in component) {
|
|
111
|
+
traverser.child = (t) => createTraverser(component.components[0], t, traverser, component.components);
|
|
112
|
+
}
|
|
113
|
+
if (component.type === ComponentType.Section) {
|
|
114
|
+
traverser.accessory = (t) => createTraverser(component.accessory, t, traverser);
|
|
115
|
+
}
|
|
116
|
+
return traverser;
|
|
30
117
|
}
|
|
31
|
-
|
|
32
|
-
|
|
118
|
+
return {
|
|
119
|
+
/**
|
|
120
|
+
* Enter the tree at a specific node.
|
|
121
|
+
* @param query Either the component `id` or `custom_id`
|
|
122
|
+
*/
|
|
123
|
+
find(query, type) {
|
|
124
|
+
const component = find(query, components);
|
|
125
|
+
if (!component || !matchTypes(component, type, true))
|
|
126
|
+
return undefined;
|
|
127
|
+
const parent = findParent(component, components);
|
|
128
|
+
return createTraverser(component, type, undefined, parent && "components" in parent ? parent.components : components);
|
|
129
|
+
},
|
|
130
|
+
/** Entry point of the tree, visually this is the top-leftmost component. */
|
|
131
|
+
initial: ((t) => createTraverser(components[0], t, undefined, components)),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Destroy a node in the tree.
|
|
136
|
+
* Data on this node will be stripped, attempting to access most functions will throw.
|
|
137
|
+
* @important This may cause issues when you try to navigate {@link abseil} instances you've previously created
|
|
138
|
+
*/
|
|
139
|
+
export function removeNode(node) {
|
|
140
|
+
const { components } = node.parent(["ActionRow", "Container", "Section"]).value;
|
|
141
|
+
components === null || components === void 0 ? void 0 : components.splice(components.indexOf(node.value), 1);
|
|
142
|
+
for (const key of Object.keys(node)) {
|
|
143
|
+
if (key === "previous" || key === "last")
|
|
144
|
+
continue;
|
|
145
|
+
node[key] = (key === "value"
|
|
146
|
+
? null
|
|
147
|
+
: () => {
|
|
148
|
+
throw new RangeError(`Unable to access ${key} on node as it was removed`);
|
|
149
|
+
});
|
|
33
150
|
}
|
|
34
|
-
return traverser;
|
|
35
151
|
}
|
|
36
|
-
/** Initiate a tree traverser */
|
|
37
|
-
const abseil = (components) => ({
|
|
38
|
-
initial: ((t) => createTraverser(components[0], t, undefined, components.slice(1))),
|
|
39
|
-
});
|
|
40
|
-
export default abseil;
|
|
41
152
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EAML,aAAa,GACd,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/dist/index.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/index.test.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import { ButtonStyle, ComponentType, } from "discord-api-types/v10";
|
|
3
|
-
import abseil from "./index.js";
|
|
4
|
-
const message = {
|
|
5
|
-
components: [
|
|
6
|
-
{ type: ComponentType.TextDisplay },
|
|
7
|
-
{
|
|
8
|
-
type: ComponentType.Container,
|
|
9
|
-
components: [
|
|
10
|
-
{
|
|
11
|
-
type: ComponentType.Section,
|
|
12
|
-
accessory: { type: ComponentType.Thumbnail },
|
|
13
|
-
components: [
|
|
14
|
-
{ type: ComponentType.TextDisplay },
|
|
15
|
-
{ type: ComponentType.TextDisplay },
|
|
16
|
-
],
|
|
17
|
-
},
|
|
18
|
-
{ type: ComponentType.Separator },
|
|
19
|
-
{
|
|
20
|
-
type: ComponentType.ActionRow,
|
|
21
|
-
components: [{ type: ComponentType.UserSelect }],
|
|
22
|
-
},
|
|
23
|
-
],
|
|
24
|
-
accent_color: 0,
|
|
25
|
-
spoiler: false,
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
type: ComponentType.ActionRow,
|
|
29
|
-
components: [
|
|
30
|
-
{ type: ComponentType.Button, custom_id: "b1" },
|
|
31
|
-
{ type: ComponentType.Button, custom_id: "b2" },
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
};
|
|
36
|
-
describe("abseil traverser", () => {
|
|
37
|
-
test("should traverse initial component", () => {
|
|
38
|
-
const t = abseil(message.components).initial("TextDisplay");
|
|
39
|
-
expect(t.value.type).toBe(ComponentType.TextDisplay);
|
|
40
|
-
});
|
|
41
|
-
test("should traverse sibling component", () => {
|
|
42
|
-
const t = abseil(message.components).initial("TextDisplay").sibling("Container");
|
|
43
|
-
expect(t.value.type).toBe(ComponentType.Container);
|
|
44
|
-
});
|
|
45
|
-
test("should traverse child component", () => {
|
|
46
|
-
const t = abseil(message.components).initial("TextDisplay").sibling("Container").child("Section");
|
|
47
|
-
expect(t.value.type).toBe(ComponentType.Section);
|
|
48
|
-
});
|
|
49
|
-
test("should traverse accessory component", () => {
|
|
50
|
-
const t = abseil(message.components)
|
|
51
|
-
.initial("TextDisplay")
|
|
52
|
-
.sibling("Container")
|
|
53
|
-
.child("Section")
|
|
54
|
-
.accessory("Thumbnail");
|
|
55
|
-
expect(t.value.type).toBe(ComponentType.Thumbnail);
|
|
56
|
-
});
|
|
57
|
-
test("should return to previous component", () => {
|
|
58
|
-
var _a;
|
|
59
|
-
const t = abseil(message.components).initial("TextDisplay").sibling("Container");
|
|
60
|
-
expect((_a = t.previous) === null || _a === void 0 ? void 0 : _a.value.type).toBe(ComponentType.TextDisplay);
|
|
61
|
-
});
|
|
62
|
-
test("should update component properties in-place", () => {
|
|
63
|
-
const traverser = abseil(message.components).initial("TextDisplay").sibling("Container").update({ spoiler: true });
|
|
64
|
-
expect(message.components[1].spoiler).toBe(true);
|
|
65
|
-
expect(traverser.value.spoiler).toBe(true);
|
|
66
|
-
});
|
|
67
|
-
test("should update component using a function in-place", () => {
|
|
68
|
-
const traverser = abseil(message.components)
|
|
69
|
-
.initial("TextDisplay")
|
|
70
|
-
.sibling("Container")
|
|
71
|
-
.update((prev) => ({ ...prev, accent_color: 42 }));
|
|
72
|
-
expect(message.components[1].accent_color).toBe(42);
|
|
73
|
-
expect(traverser.value.accent_color).toBe(42);
|
|
74
|
-
});
|
|
75
|
-
test("should handle URL button type correctly", () => {
|
|
76
|
-
const urlButton = {
|
|
77
|
-
type: ComponentType.Button,
|
|
78
|
-
url: "https://example.com",
|
|
79
|
-
style: ButtonStyle.Link,
|
|
80
|
-
};
|
|
81
|
-
const t = abseil([urlButton]).initial("Button:URL");
|
|
82
|
-
expect(t.value.url).toBe("https://example.com");
|
|
83
|
-
});
|
|
84
|
-
test("should handle SKU button type correctly", () => {
|
|
85
|
-
const skuButton = {
|
|
86
|
-
type: ComponentType.Button,
|
|
87
|
-
sku_id: "sku-123",
|
|
88
|
-
style: ButtonStyle.Premium,
|
|
89
|
-
};
|
|
90
|
-
const t = abseil([skuButton]).initial("Button:SKU");
|
|
91
|
-
expect(t.value.sku_id).toBe("sku-123");
|
|
92
|
-
});
|
|
93
|
-
test("should throw when initial type does not match", () => {
|
|
94
|
-
const btn = {
|
|
95
|
-
type: ComponentType.Button,
|
|
96
|
-
custom_id: "b1",
|
|
97
|
-
style: ButtonStyle.Primary,
|
|
98
|
-
};
|
|
99
|
-
expect(() => abseil([btn]).initial("Button:URL")).toThrow(TypeError);
|
|
100
|
-
});
|
|
101
|
-
test("should traverse sibling components sequentially", () => {
|
|
102
|
-
var _a;
|
|
103
|
-
const traverser = abseil(message.components).initial("TextDisplay").sibling("Container").sibling("ActionRow");
|
|
104
|
-
expect(traverser.value.type).toBe(ComponentType.ActionRow);
|
|
105
|
-
expect((_a = traverser.previous) === null || _a === void 0 ? void 0 : _a.value.type).toBe(ComponentType.Container);
|
|
106
|
-
});
|
|
107
|
-
test("should allow adding new components via update", () => {
|
|
108
|
-
const t = abseil(message.components)
|
|
109
|
-
.initial("TextDisplay")
|
|
110
|
-
.sibling("Container")
|
|
111
|
-
.sibling("ActionRow")
|
|
112
|
-
.update((prev) => ({
|
|
113
|
-
components: prev.components.concat({
|
|
114
|
-
type: ComponentType.Button,
|
|
115
|
-
custom_id: "new",
|
|
116
|
-
style: ButtonStyle.Primary,
|
|
117
|
-
}),
|
|
118
|
-
}));
|
|
119
|
-
expect(message.components[2].components.length).toBe(3);
|
|
120
|
-
expect(t.value.components[2].custom_id).toBe("new");
|
|
121
|
-
});
|
|
122
|
-
test("do not include child function if not a parent type", () => {
|
|
123
|
-
const t = abseil([{ type: ComponentType.TextDisplay, content: "" }]);
|
|
124
|
-
expect(t.initial("TextDisplay")).not.toHaveProperty("child");
|
|
125
|
-
});
|
|
126
|
-
test("do not include sibling function if no siblings", () => {
|
|
127
|
-
const t = abseil([{ type: ComponentType.TextDisplay, content: "" }]);
|
|
128
|
-
expect(t.initial("TextDisplay")).not.toHaveProperty("sibling");
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
//# sourceMappingURL=index.test.js.map
|
package/dist/index.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|