abseil 0.2.0 → 0.3.1
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 +19 -18
- package/dist/index.d.ts +39 -23
- package/dist/index.js +121 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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
7
|
| function | description |
|
|
8
8
|
| ------------ | ----------------------------------------------------------------------------------------------------- |
|
|
@@ -11,6 +11,7 @@ Quickly traverse Discord [Components V2](https://docs.discord.com/developers/com
|
|
|
11
11
|
| insertBefore | Insert a sibling before the current node |
|
|
12
12
|
| last | Jump to the last neighbouring node of a type in an array |
|
|
13
13
|
| next | Jump to the next neighbouring node of a type in an array |
|
|
14
|
+
| parent | Access the parent of a node |
|
|
14
15
|
| previous | Return to the previous node |
|
|
15
16
|
| sibling | Access the next node in an array |
|
|
16
17
|
| update | Shallow merge with the current component in place |
|
|
@@ -31,11 +32,11 @@ const message = {
|
|
|
31
32
|
Section(["## Trivia!"], Button({ custom_id: "suggest", style: "Secondary" })),
|
|
32
33
|
TextDisplay("What is the meaning of life?"),
|
|
33
34
|
ActionRow(
|
|
34
|
-
Button({ custom_id: "money", label: "💵" }),
|
|
35
|
-
Button({ custom_id: "42", label: "🤖" }),
|
|
35
|
+
Button({ custom_id: "guess-money", label: "💵" }),
|
|
36
|
+
Button({ custom_id: "guess-42", label: "🤖" }),
|
|
36
37
|
),
|
|
37
38
|
Separator(),
|
|
38
|
-
Section(["## 🟩🟩🟥🟥🟥⬛⬛⬛⬛⬛"], Button({ custom_id: "stats", style: "Secondary" })),
|
|
39
|
+
Section(["## 🟩🟩🟥🟥🟥⬛⬛⬛⬛⬛"], Button({ custom_id: "stats-3-2", style: "Secondary" })),
|
|
39
40
|
),
|
|
40
41
|
],
|
|
41
42
|
} as APIMessage;
|
|
@@ -44,26 +45,26 @@ const message = {
|
|
|
44
45
|
</details>
|
|
45
46
|
|
|
46
47
|
```ts
|
|
47
|
-
import abseil from "abseil";
|
|
48
|
+
import abseil, { removeNode } from "abseil";
|
|
48
49
|
import { editMessage } from "dressed";
|
|
49
50
|
|
|
50
|
-
const
|
|
51
|
-
.initial("Container")
|
|
52
|
-
.child("Section");
|
|
51
|
+
const line = abseil(message.components ?? []);
|
|
53
52
|
|
|
54
|
-
let
|
|
53
|
+
let guessBtn = line.find(/guess-.+/, "Button");
|
|
55
54
|
|
|
56
|
-
while (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
button = button.sibling?.("Button");
|
|
55
|
+
while (guessBtn) {
|
|
56
|
+
guessBtn.update({ disabled: true });
|
|
57
|
+
guessBtn = guessBtn.next("Button");
|
|
60
58
|
}
|
|
61
59
|
|
|
60
|
+
const header = line.initial("Container").child("Section");
|
|
61
|
+
|
|
62
|
+
header.insertBefore(TextDisplay(header.child("TextDisplay").value.content));
|
|
63
|
+
removeNode(header);
|
|
64
|
+
|
|
62
65
|
// Insert-if-not-exists the warning message
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
components: prev.components.concat(TextDisplay("-# This has expired!")),
|
|
66
|
-
}));
|
|
66
|
+
if (!header.last("Section")?.sibling) {
|
|
67
|
+
header.previous.value.components.push(TextDisplay("-# This has expired!"));
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
editMessage("<CHANNEL_ID>", "<MESSAGE_ID>", { components: message.components });
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
/** biome-ignore-all lint/suspicious/noExplicitAny: Not worth my time */
|
|
2
2
|
import { type APIComponentInContainer, type APIComponentInMessageActionRow, type APIMessageComponent, type APISectionAccessoryComponent, type APISelectMenuComponent, ComponentType } from "discord-api-types/v10";
|
|
3
|
-
type CT = typeof ComponentType & {
|
|
3
|
+
type CT = Omit<typeof ComponentType, "SelectMenu"> & {
|
|
4
4
|
"Button:URL": ComponentType.Button;
|
|
5
5
|
"Button:SKU": ComponentType.Button;
|
|
6
6
|
};
|
|
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
|
-
ActionRow: IComponentType[APIComponentInMessageActionRow["type"]]
|
|
18
|
+
ActionRow: IComponentType[APIComponentInMessageActionRow["type"]];
|
|
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,34 +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
|
-
/** Insert a sibling before the current node */
|
|
37
|
-
insertBefore: (component:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
/** Jump to the
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
next: <const N extends Arrable<ST>>(type: N) => Traverser<Narr<N>, [...H, T], ST> | undefined;
|
|
44
|
-
/** Access the next node in an array */
|
|
40
|
+
/** Insert a sibling before the current node. */
|
|
41
|
+
insertBefore: <V extends Component<ST>>(component: V) => Traverser<T, H, ST>;
|
|
42
|
+
/** Jump to the last neighbouring node of a type in an array. */
|
|
43
|
+
last: <N extends ST>(type: Arrable<N>) => Traverser<N, [...H, T], ST> | undefined;
|
|
44
|
+
/** Jump to the next neighbouring node of a type in an array. */
|
|
45
|
+
next: <N extends ST>(type: Arrable<N>) => Traverser<N, [...H, T], ST> | undefined;
|
|
46
|
+
/** Access the next node in an array. */
|
|
45
47
|
sibling: TraverserFn<ST, [...H, T]>;
|
|
46
48
|
}) & (T extends keyof ChildrenMap ? {
|
|
47
|
-
/** Access the first child of a node */
|
|
49
|
+
/** Access the first child of a node. */
|
|
48
50
|
child: TraverserFn<ChildrenMap[T], [...H, T]>;
|
|
49
51
|
} : object) & (T extends "Section" ? {
|
|
50
|
-
/** Access the accessory of a [Section](https://docs.discord.com/developers/components/reference#section) */
|
|
52
|
+
/** Access the accessory of a [Section](https://docs.discord.com/developers/components/reference#section). */
|
|
51
53
|
accessory: TraverserFn<IComponentType[APISectionAccessoryComponent["type"]], [...H, T], "sibling">;
|
|
52
54
|
} : object) & (H extends [] ? object : {
|
|
53
|
-
/** Return to the previous node */
|
|
55
|
+
/** Return to the previous node. */
|
|
54
56
|
previous: Traverser<Last<H>, Pop<H>>;
|
|
55
57
|
});
|
|
56
|
-
/** Initiate a tree traverser */
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
/** Initiate a tree traverser. */
|
|
59
|
+
export default function abseil<T extends APIMessageComponent>(components: T[]): {
|
|
60
|
+
/**
|
|
61
|
+
* Enter the tree at a specific node.
|
|
62
|
+
* @param query Either the component `id` or `custom_id`
|
|
63
|
+
*/
|
|
64
|
+
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" | "Button:URL" | "Button:SKU">, "previous"> | undefined;
|
|
65
|
+
/** Entry point of the tree, visually this is the top-leftmost component. */
|
|
66
|
+
initial: TraverserFn<IComponentType[T["type"]], [], "parent" | "previous">;
|
|
59
67
|
};
|
|
60
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Destroy a node in the tree.
|
|
70
|
+
* Data on this node will be stripped, attempting to access most functions will throw.
|
|
71
|
+
* @important This may cause issues when you try to navigate {@link abseil} instances you've previously created
|
|
72
|
+
*/
|
|
73
|
+
export declare function removeNode<T extends keyof CT>(node: Traverser<T, any, any>): void;
|
|
74
|
+
/** Assert that a component is of certain type(s). */
|
|
75
|
+
export declare const assert: <T extends keyof CT>(component: APIMessageComponent, type: Arrable<T>) => component is Component<T>;
|
|
76
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ const selects = new Set([
|
|
|
8
8
|
ComponentType.MentionableSelect,
|
|
9
9
|
ComponentType.ChannelSelect,
|
|
10
10
|
]);
|
|
11
|
-
function
|
|
11
|
+
function typesMatch(component, expected, throwOnMismatch) {
|
|
12
12
|
const expectedTypes = new Set((Array.isArray(expected) ? expected : [expected]).filter(Boolean));
|
|
13
13
|
if (!expectedTypes.size) {
|
|
14
14
|
throw new Error("Selectors must specify expected type(s)");
|
|
@@ -20,62 +20,137 @@ function matchTypes(component, expected, doNotThrow) {
|
|
|
20
20
|
else if ("sku_id" in component)
|
|
21
21
|
actualType += ":SKU";
|
|
22
22
|
}
|
|
23
|
+
else if (actualType === "SelectMenu")
|
|
24
|
+
actualType = "StringSelect";
|
|
23
25
|
if (!expectedTypes.has(actualType)) {
|
|
24
|
-
if (
|
|
26
|
+
if (throwOnMismatch) {
|
|
25
27
|
throw new TypeError(`Type mismatch: expected ${[...expectedTypes].join(" or ")}, got ${actualType}`);
|
|
26
28
|
}
|
|
27
29
|
return false;
|
|
28
30
|
}
|
|
29
31
|
return true;
|
|
30
32
|
}
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (!next)
|
|
60
|
-
return undefined;
|
|
61
|
-
return createTraverser(next, t, traverser, neighbours);
|
|
62
|
-
};
|
|
33
|
+
function find(query, components) {
|
|
34
|
+
for (const component of components) {
|
|
35
|
+
if ((typeof query === "number" && component.id === query) ||
|
|
36
|
+
("custom_id" in component &&
|
|
37
|
+
((typeof query === "string" && component.custom_id === query) ||
|
|
38
|
+
(query instanceof RegExp && query.test(component.custom_id))))) {
|
|
39
|
+
return component;
|
|
40
|
+
}
|
|
41
|
+
if ("components" in component) {
|
|
42
|
+
const found = find(query, component.components);
|
|
43
|
+
if (found)
|
|
44
|
+
return found;
|
|
45
|
+
}
|
|
46
|
+
if (component.type === ComponentType.Section && component.accessory) {
|
|
47
|
+
const found = find(query, [component.accessory]);
|
|
48
|
+
if (found)
|
|
49
|
+
return found;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function findParent(child, components) {
|
|
54
|
+
for (const component of components) {
|
|
55
|
+
if ("components" in component) {
|
|
56
|
+
if (component.components.includes(child))
|
|
57
|
+
return component;
|
|
58
|
+
const found = findParent(child, component.components);
|
|
59
|
+
if (found)
|
|
60
|
+
return found;
|
|
63
61
|
}
|
|
64
|
-
if (
|
|
65
|
-
|
|
62
|
+
if (component.type === ComponentType.Section && component.accessory === child) {
|
|
63
|
+
return component;
|
|
66
64
|
}
|
|
67
65
|
}
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
}
|
|
67
|
+
/** Initiate a tree traverser. */
|
|
68
|
+
export default function abseil(components) {
|
|
69
|
+
function createTraverser(component, expected, previous, neighbours) {
|
|
70
|
+
typesMatch(component, expected, true);
|
|
71
|
+
const traverser = {
|
|
72
|
+
value: component,
|
|
73
|
+
update(v) {
|
|
74
|
+
Object.assign(component, typeof v === "function" ? v(component) : v);
|
|
75
|
+
return traverser;
|
|
76
|
+
},
|
|
77
|
+
parent(t) {
|
|
78
|
+
const parentComponent = findParent(component, components);
|
|
79
|
+
if (!parentComponent)
|
|
80
|
+
throw new Error("This node does not have a parent");
|
|
81
|
+
const parentParent = findParent(parentComponent, components);
|
|
82
|
+
return createTraverser(parentComponent, t, traverser, parentParent && "components" in parentParent ? parentParent.components : []);
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
if (previous)
|
|
86
|
+
traverser.previous = previous;
|
|
87
|
+
if (neighbours) {
|
|
88
|
+
if (!selects.has(component.type)) {
|
|
89
|
+
traverser.insertBefore = (v) => {
|
|
90
|
+
neighbours.splice(neighbours.indexOf(component), 0, v);
|
|
91
|
+
return traverser;
|
|
92
|
+
};
|
|
93
|
+
traverser.last = (t) => {
|
|
94
|
+
for (let i = neighbours.length - 1; i >= 0; --i) {
|
|
95
|
+
const sibling = neighbours[i];
|
|
96
|
+
if (!typesMatch(sibling, t))
|
|
97
|
+
continue;
|
|
98
|
+
return createTraverser(sibling, t, traverser, neighbours);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
traverser.next = (t) => {
|
|
102
|
+
const next = neighbours.slice(neighbours.indexOf(component) + 1).find((s) => typesMatch(s, t));
|
|
103
|
+
if (!next)
|
|
104
|
+
return undefined;
|
|
105
|
+
return createTraverser(next, t, traverser, neighbours);
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (neighbours.length !== neighbours.indexOf(component) + 1) {
|
|
109
|
+
traverser.sibling = (t) => createTraverser(neighbours[neighbours.indexOf(component) + 1], t, traverser, neighbours);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (withChildren.has(component.type) && "components" in component) {
|
|
113
|
+
traverser.child = (t) => createTraverser(component.components[0], t, traverser, component.components);
|
|
114
|
+
}
|
|
115
|
+
if (component.type === ComponentType.Section) {
|
|
116
|
+
traverser.accessory = (t) => createTraverser(component.accessory, t, traverser);
|
|
117
|
+
}
|
|
118
|
+
return traverser;
|
|
70
119
|
}
|
|
71
|
-
|
|
72
|
-
|
|
120
|
+
return {
|
|
121
|
+
/**
|
|
122
|
+
* Enter the tree at a specific node.
|
|
123
|
+
* @param query Either the component `id` or `custom_id`
|
|
124
|
+
*/
|
|
125
|
+
find(query, type) {
|
|
126
|
+
const component = find(query, components);
|
|
127
|
+
if (!component || !typesMatch(component, type))
|
|
128
|
+
return undefined;
|
|
129
|
+
const parent = findParent(component, components);
|
|
130
|
+
return createTraverser(component, type, undefined, parent && "components" in parent ? parent.components : components);
|
|
131
|
+
},
|
|
132
|
+
/** Entry point of the tree, visually this is the top-leftmost component. */
|
|
133
|
+
initial: ((t) => createTraverser(components[0], t, undefined, components)),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Destroy a node in the tree.
|
|
138
|
+
* Data on this node will be stripped, attempting to access most functions will throw.
|
|
139
|
+
* @important This may cause issues when you try to navigate {@link abseil} instances you've previously created
|
|
140
|
+
*/
|
|
141
|
+
export function removeNode(node) {
|
|
142
|
+
const { components } = node.parent(["ActionRow", "Container", "Section"]).value;
|
|
143
|
+
components === null || components === void 0 ? void 0 : components.splice(components.indexOf(node.value), 1);
|
|
144
|
+
for (const key of Object.keys(node)) {
|
|
145
|
+
if (key === "previous" || key === "last")
|
|
146
|
+
continue;
|
|
147
|
+
node[key] = (key === "value"
|
|
148
|
+
? null
|
|
149
|
+
: () => {
|
|
150
|
+
throw new RangeError(`Unable to access ${key} on node as it was removed`);
|
|
151
|
+
});
|
|
73
152
|
}
|
|
74
|
-
return traverser;
|
|
75
153
|
}
|
|
76
|
-
/**
|
|
77
|
-
const
|
|
78
|
-
initial: ((t) => createTraverser(components[0], t, undefined, components)),
|
|
79
|
-
});
|
|
80
|
-
export default abseil;
|
|
154
|
+
/** Assert that a component is of certain type(s). */
|
|
155
|
+
export const assert = (component, type) => typesMatch(component, type);
|
|
81
156
|
//# 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;AA8E/B,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;AAExG,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;IACtB,aAAa,CAAC,YAAY;IAC1B,aAAa,CAAC,UAAU;IACxB,aAAa,CAAC,UAAU;IACxB,aAAa,CAAC,iBAAiB;IAC/B,aAAa,CAAC,aAAa;CAC5B,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,SAA8B,EAAE,QAA2B,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|