-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathutils.ts
More file actions
110 lines (93 loc) · 3.39 KB
/
utils.ts
File metadata and controls
110 lines (93 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { type CommandInteraction, MessageFlags } from 'discord.js';
import { logToChannel } from '../../util/channel-logging.js';
import type { FeatureData } from './baseline.js';
import type { ProviderConfig } from './types.js';
export const SEARCH_TERM = '%SEARCH%';
export const TERM = '%TERM%';
// Utility functions
export const getSearchUrl = (url: string, search: string) => {
return url.replace(SEARCH_TERM, encodeURIComponent(search));
};
export const createBaseConfig = (options: {
color: number;
icon: string;
commandDescription: string;
directUrl?: string;
}): Pick<ProviderConfig, 'color' | 'icon' | 'commandDescription' | 'directUrl'> => options;
export const executeDocCommand = async (
config: ProviderConfig,
interaction: CommandInteraction
): Promise<void> => {
if (interaction.replied || interaction.deferred) {
return;
}
try {
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
} catch (error) {
console.error(`deferReply FAILED:`, error);
return;
}
if (!interaction.isChatInputCommand()) {
return;
}
const query = interaction.options.getString('query', true).trim();
try {
const items = await config.getFilteredData(query);
if (items.length === 0) {
await interaction.editReply({ content: `No results found for "${query}"` });
return;
}
const collection = config.createCollection(items);
const { selectRow, buttonRow } = config.createActionBuilders(collection);
const choiceInteraction = await interaction.editReply({
content: config.getSelectionMessage(query),
components: [selectRow, buttonRow],
});
const collector = choiceInteraction.createMessageComponentCollector({
filter: (componentInteraction) => componentInteraction.user.id === interaction.user.id,
});
collector.once('collect', async (componentInteraction) => {
if (componentInteraction.isStringSelectMenu()) {
const selectedSet = new Set(componentInteraction.values);
const selectedItems = collection.filter((_, key) => selectedSet.has(key));
const selectedTitles = selectedItems.map(config.getDisplayTitle);
await interaction.editReply({
content: config.getDisplayMessage(selectedTitles),
components: [],
});
const embeds = config.createResultEmbeds(selectedItems);
logToChannel({
channel: interaction.channel,
content: {
type: 'embed',
embed: embeds,
content: interaction.options.getUser('user')
? `<@${interaction.options.getUser('user')?.id}>`
: undefined,
},
});
} else if (componentInteraction.isButton()) {
console.log('Documentation command cancelled by user.');
await interaction.deleteReply();
}
});
} catch (error) {
console.error(`executeDocCommand FAILED:`, error);
await interaction.editReply({ content: `Error: ${error}` });
}
};
export const NON_BASELINE_FEATURES = [
'numeric-seperators',
'open-closed',
'single-color-gradients',
];
export const getBaselineFeatures = (
originalFeatures: Record<string, unknown>,
nonFeatureKeys: string[] = NON_BASELINE_FEATURES
): Record<string, FeatureData> => {
const features = { ...originalFeatures };
for (const nonFeature of nonFeatureKeys) {
delete features[nonFeature];
}
return features as Record<string, FeatureData>;
};