seyfert 4.4.1 → 5.0.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 +7 -1
- package/lib/api/Routes/cdn.d.ts +2 -2
- package/lib/api/Routes/guilds.d.ts +2 -2
- package/lib/api/Routes/invites.d.ts +2 -2
- package/lib/api/api.d.ts +20 -8
- package/lib/api/api.js +198 -44
- package/lib/api/shared.d.ts +30 -1
- package/lib/api/utils/constants.d.ts +1 -1
- package/lib/api/utils/constants.js +1 -1
- package/lib/api/utils/utils.d.ts +2 -1
- package/lib/api/utils/utils.js +1 -1
- package/lib/builders/Attachment.d.ts +1 -1
- package/lib/builders/Attachment.js +30 -8
- package/lib/builders/MediaGallery.d.ts +2 -2
- package/lib/builders/MediaGallery.js +10 -0
- package/lib/builders/Modal.d.ts +18 -8
- package/lib/builders/Modal.js +36 -7
- package/lib/builders/Poll.js +18 -0
- package/lib/builders/RadioGroup.d.ts +4 -3
- package/lib/builders/RadioGroup.js +24 -3
- package/lib/builders/SelectMenu.d.ts +8 -6
- package/lib/builders/SelectMenu.js +24 -3
- package/lib/builders/types.d.ts +3 -2
- package/lib/cache/adapters/default.d.ts +1 -1
- package/lib/cache/adapters/default.js +23 -26
- package/lib/cache/adapters/limited.d.ts +1 -0
- package/lib/cache/adapters/limited.js +47 -33
- package/lib/cache/index.d.ts +19 -25
- package/lib/cache/index.js +58 -6
- package/lib/cache/resources/bans.d.ts +1 -1
- package/lib/cache/resources/bans.js +4 -4
- package/lib/cache/resources/channels.d.ts +1 -1
- package/lib/cache/resources/channels.js +4 -4
- package/lib/cache/resources/default/base.d.ts +1 -1
- package/lib/cache/resources/default/base.js +8 -8
- package/lib/cache/resources/default/guild-based.d.ts +5 -5
- package/lib/cache/resources/default/guild-based.js +29 -16
- package/lib/cache/resources/default/guild-related.d.ts +5 -5
- package/lib/cache/resources/default/guild-related.js +14 -14
- package/lib/cache/resources/emojis.d.ts +1 -1
- package/lib/cache/resources/emojis.js +4 -4
- package/lib/cache/resources/guilds.js +28 -15
- package/lib/cache/resources/members.d.ts +1 -1
- package/lib/cache/resources/members.js +6 -6
- package/lib/cache/resources/messages.d.ts +7 -2
- package/lib/cache/resources/messages.js +43 -20
- package/lib/cache/resources/overwrites.d.ts +1 -1
- package/lib/cache/resources/overwrites.js +5 -8
- package/lib/cache/resources/roles.d.ts +1 -1
- package/lib/cache/resources/roles.js +4 -4
- package/lib/cache/resources/stickers.d.ts +1 -1
- package/lib/cache/resources/stickers.js +4 -4
- package/lib/cache/resources/users.js +4 -4
- package/lib/cache/resources/voice-states.d.ts +1 -1
- package/lib/cache/resources/voice-states.js +4 -4
- package/lib/client/base.d.ts +83 -24
- package/lib/client/base.js +594 -39
- package/lib/client/client.d.ts +29 -4
- package/lib/client/client.js +38 -13
- package/lib/client/collectors.d.ts +9 -8
- package/lib/client/collectors.js +19 -52
- package/lib/client/httpclient.d.ts +3 -0
- package/lib/client/index.d.ts +3 -1
- package/lib/client/index.js +4 -0
- package/lib/client/intents.d.ts +3 -0
- package/lib/client/intents.js +9 -0
- package/lib/client/plugins/api.d.ts +4 -0
- package/lib/client/plugins/api.js +550 -0
- package/lib/client/plugins/errors.d.ts +25 -0
- package/lib/client/plugins/errors.js +79 -0
- package/lib/client/plugins/order.d.ts +10 -0
- package/lib/client/plugins/order.js +32 -0
- package/lib/client/plugins/registry.d.ts +273 -0
- package/lib/client/plugins/registry.js +868 -0
- package/lib/client/plugins/shared.d.ts +23 -0
- package/lib/client/plugins/shared.js +193 -0
- package/lib/client/plugins/types.d.ts +398 -0
- package/lib/client/plugins/types.js +8 -0
- package/lib/client/plugins.d.ts +78 -0
- package/lib/client/plugins.js +558 -0
- package/lib/client/transformers.d.ts +33 -33
- package/lib/client/workerclient.d.ts +11 -2
- package/lib/client/workerclient.js +33 -22
- package/lib/collection.d.ts +10 -8
- package/lib/collection.js +19 -25
- package/lib/commands/applications/chat.d.ts +20 -18
- package/lib/commands/applications/chat.js +39 -14
- package/lib/commands/applications/chatcontext.d.ts +23 -15
- package/lib/commands/applications/chatcontext.js +23 -2
- package/lib/commands/applications/entryPoint.d.ts +4 -3
- package/lib/commands/applications/entryPoint.js +1 -1
- package/lib/commands/applications/entrycontext.d.ts +7 -9
- package/lib/commands/applications/entrycontext.js +3 -1
- package/lib/commands/applications/menu.d.ts +4 -3
- package/lib/commands/applications/menucontext.d.ts +7 -9
- package/lib/commands/applications/menucontext.js +3 -1
- package/lib/commands/applications/options.d.ts +23 -23
- package/lib/commands/applications/shared.d.ts +39 -17
- package/lib/commands/decorators.d.ts +50 -38
- package/lib/commands/decorators.js +15 -5
- package/lib/commands/handle.d.ts +19 -8
- package/lib/commands/handle.js +224 -143
- package/lib/commands/handler.d.ts +21 -8
- package/lib/commands/handler.js +157 -69
- package/lib/commands/index.d.ts +1 -0
- package/lib/commands/optionresolver.d.ts +2 -2
- package/lib/common/it/colors.js +12 -2
- package/lib/common/it/error.d.ts +9 -0
- package/lib/common/it/error.js +8 -0
- package/lib/common/it/fake-promise.d.ts +4 -0
- package/lib/common/it/fake-promise.js +10 -0
- package/lib/common/it/formatter.d.ts +14 -11
- package/lib/common/it/formatter.js +4 -3
- package/lib/common/it/logger.d.ts +7 -1
- package/lib/common/it/logger.js +24 -6
- package/lib/common/it/utils.d.ts +6 -8
- package/lib/common/it/utils.js +44 -42
- package/lib/common/shorters/application.d.ts +3 -3
- package/lib/common/shorters/application.js +3 -2
- package/lib/common/shorters/bans.d.ts +8 -4
- package/lib/common/shorters/bans.js +13 -5
- package/lib/common/shorters/channels.d.ts +4 -4
- package/lib/common/shorters/channels.js +4 -4
- package/lib/common/shorters/emojis.js +1 -0
- package/lib/common/shorters/guilds.d.ts +8 -8
- package/lib/common/shorters/guilds.js +14 -31
- package/lib/common/shorters/interaction.d.ts +1 -1
- package/lib/common/shorters/invites.d.ts +201 -201
- package/lib/common/shorters/members.d.ts +7 -7
- package/lib/common/shorters/members.js +13 -14
- package/lib/common/shorters/messages.d.ts +2 -2
- package/lib/common/shorters/soundboard.d.ts +5 -5
- package/lib/common/shorters/users.d.ts +1 -1
- package/lib/common/shorters/webhook.d.ts +3 -2
- package/lib/common/shorters/webhook.js +0 -7
- package/lib/common/types/options.d.ts +4 -0
- package/lib/common/types/util.d.ts +8 -0
- package/lib/common/types/write.d.ts +2 -1
- package/lib/components/BaseSelectMenuComponent.d.ts +1 -1
- package/lib/components/BaseSelectMenuComponent.js +1 -1
- package/lib/components/ButtonComponent.d.ts +3 -3
- package/lib/components/ChannelSelectMenuComponent.d.ts +2 -2
- package/lib/components/File.d.ts +1 -1
- package/lib/components/MediaGallery.d.ts +1 -1
- package/lib/components/MentionableSelectMenuComponent.d.ts +1 -1
- package/lib/components/RoleSelectMenuComponent.d.ts +1 -1
- package/lib/components/Separator.d.ts +1 -1
- package/lib/components/StringSelectMenuComponent.d.ts +1 -1
- package/lib/components/TextInputComponent.d.ts +1 -1
- package/lib/components/Thumbnail.d.ts +1 -1
- package/lib/components/UserSelectMenuComponent.d.ts +1 -1
- package/lib/components/componentcommand.d.ts +8 -7
- package/lib/components/componentcontext.d.ts +24 -36
- package/lib/components/componentcontext.js +7 -17
- package/lib/components/handler.d.ts +17 -7
- package/lib/components/handler.js +108 -49
- package/lib/components/index.d.ts +1 -0
- package/lib/components/index.js +1 -0
- package/lib/components/interactioncontext.d.ts +45 -0
- package/lib/components/interactioncontext.js +93 -0
- package/lib/components/modalcommand.d.ts +5 -4
- package/lib/components/modalcontext.d.ts +39 -20
- package/lib/components/modalcontext.js +59 -6
- package/lib/events/event.d.ts +9 -3
- package/lib/events/handler.d.ts +51 -6
- package/lib/events/handler.js +165 -36
- package/lib/events/hooks/application_command.d.ts +1 -1
- package/lib/events/hooks/auto_moderation.d.ts +2 -2
- package/lib/events/hooks/guild.d.ts +150 -150
- package/lib/events/hooks/interactions.d.ts +1 -1
- package/lib/events/hooks/invite.d.ts +20 -20
- package/lib/events/hooks/message.d.ts +27 -27
- package/lib/events/hooks/presence.d.ts +11 -11
- package/lib/events/hooks/soundboard.d.ts +6 -6
- package/lib/events/hooks/stage.d.ts +2 -2
- package/lib/events/hooks/subscriptions.d.ts +3 -3
- package/lib/events/hooks/thread.d.ts +30 -30
- package/lib/events/hooks/voice.d.ts +3 -4
- package/lib/events/hooks/voice.js +2 -1
- package/lib/events/utils.d.ts +4 -0
- package/lib/events/utils.js +59 -0
- package/lib/index.d.ts +9 -4
- package/lib/index.js +14 -8
- package/lib/langs/handler.d.ts +14 -11
- package/lib/langs/handler.js +46 -9
- package/lib/langs/router.d.ts +10 -3
- package/lib/structures/Application.d.ts +1 -1
- package/lib/structures/Emoji.d.ts +3 -3
- package/lib/structures/Emoji.js +2 -2
- package/lib/structures/Guild.d.ts +154 -154
- package/lib/structures/GuildBan.d.ts +4 -4
- package/lib/structures/GuildBan.js +3 -3
- package/lib/structures/GuildMember.d.ts +7 -7
- package/lib/structures/GuildMember.js +28 -7
- package/lib/structures/GuildRole.d.ts +1 -1
- package/lib/structures/GuildRole.js +2 -2
- package/lib/structures/Interaction.d.ts +11 -9
- package/lib/structures/Interaction.js +33 -12
- package/lib/structures/Message.d.ts +21 -14
- package/lib/structures/Message.js +29 -14
- package/lib/structures/User.d.ts +1 -1
- package/lib/structures/VoiceState.d.ts +4 -0
- package/lib/structures/VoiceState.js +13 -1
- package/lib/structures/Webhook.d.ts +9 -1
- package/lib/structures/Webhook.js +4 -1
- package/lib/structures/channels.d.ts +148 -134
- package/lib/structures/channels.js +27 -26
- package/lib/structures/extra/BitField.d.ts +4 -4
- package/lib/structures/extra/BitField.js +20 -4
- package/lib/structures/extra/DiscordBase.js +1 -1
- package/lib/structures/extra/Permissions.d.ts +2 -4
- package/lib/structures/extra/Permissions.js +1 -17
- package/lib/types/payloads/_interactions/responses.d.ts +2 -2
- package/lib/types/payloads/components.d.ts +4 -4
- package/lib/websocket/SharedTypes.d.ts +4 -4
- package/lib/websocket/constants/index.d.ts +1 -1
- package/lib/websocket/constants/index.js +3 -2
- package/lib/websocket/discord/events/memberUpdate.js +2 -2
- package/lib/websocket/discord/heartbeater.d.ts +1 -0
- package/lib/websocket/discord/heartbeater.js +7 -0
- package/lib/websocket/discord/shard.d.ts +2 -2
- package/lib/websocket/discord/shard.js +16 -14
- package/lib/websocket/discord/sharder.d.ts +8 -7
- package/lib/websocket/discord/sharder.js +26 -6
- package/lib/websocket/discord/shared.d.ts +19 -6
- package/lib/websocket/discord/socket/custom.js +5 -0
- package/lib/websocket/discord/worker.d.ts +1 -0
- package/lib/websocket/discord/worker.js +2 -0
- package/lib/websocket/discord/workermanager.d.ts +25 -11
- package/lib/websocket/discord/workermanager.js +41 -10
- package/package.json +13 -17
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPluginRuntimeRegistry = createPluginRuntimeRegistry;
|
|
4
|
+
exports.runPluginRegister = runPluginRegister;
|
|
5
|
+
exports.bindPluginClient = bindPluginClient;
|
|
6
|
+
exports.removePluginEventContribution = removePluginEventContribution;
|
|
7
|
+
exports.removePluginAnyEventContribution = removePluginAnyEventContribution;
|
|
8
|
+
exports.removePluginEventErrorContribution = removePluginEventErrorContribution;
|
|
9
|
+
exports.removePluginCommandObserverContribution = removePluginCommandObserverContribution;
|
|
10
|
+
exports.removePluginRestObserverContribution = removePluginRestObserverContribution;
|
|
11
|
+
exports.removePluginGatewayDispatchInterceptorContribution = removePluginGatewayDispatchInterceptorContribution;
|
|
12
|
+
exports.removePluginHookContribution = removePluginHookContribution;
|
|
13
|
+
exports.activatePluginEventListeners = activatePluginEventListeners;
|
|
14
|
+
exports.cleanupPluginEventListeners = cleanupPluginEventListeners;
|
|
15
|
+
exports.cleanupPluginDynamicContributionMutations = cleanupPluginDynamicContributionMutations;
|
|
16
|
+
exports.hasPluginRequirement = hasPluginRequirement;
|
|
17
|
+
exports.pluginIdentity = pluginIdentity;
|
|
18
|
+
exports.resolvePluginIntents = resolvePluginIntents;
|
|
19
|
+
exports.addPluginGlobalMiddlewares = addPluginGlobalMiddlewares;
|
|
20
|
+
exports.addPluginOptionFragment = addPluginOptionFragment;
|
|
21
|
+
exports.addPluginDiagnostic = addPluginDiagnostic;
|
|
22
|
+
exports.clonePluginOptions = clonePluginOptions;
|
|
23
|
+
exports.readonlyPluginOptions = readonlyPluginOptions;
|
|
24
|
+
exports.assertSafePluginResourceName = assertSafePluginResourceName;
|
|
25
|
+
exports.assertCanMutatePluginContribution = assertCanMutatePluginContribution;
|
|
26
|
+
exports.recordContributionMutationDiagnostic = recordContributionMutationDiagnostic;
|
|
27
|
+
exports.createPluginContextFragment = createPluginContextFragment;
|
|
28
|
+
exports.installPluginClientMaps = installPluginClientMaps;
|
|
29
|
+
exports.installPluginMiddlewares = installPluginMiddlewares;
|
|
30
|
+
exports.resolveGatewayIntent = resolveGatewayIntent;
|
|
31
|
+
exports.unknownGatewayIntentBits = unknownGatewayIntentBits;
|
|
32
|
+
exports.validatePluginRequirements = validatePluginRequirements;
|
|
33
|
+
const types_1 = require("../../types");
|
|
34
|
+
const api_1 = require("./api");
|
|
35
|
+
const errors_1 = require("./errors");
|
|
36
|
+
const order_1 = require("./order");
|
|
37
|
+
function createPluginRuntimeRegistry(plugins = []) {
|
|
38
|
+
const ordered = resolvePluginOrder(plugins);
|
|
39
|
+
const records = ordered.map((plugin, index) => ({
|
|
40
|
+
plugin,
|
|
41
|
+
identity: pluginIdentity(plugin),
|
|
42
|
+
index,
|
|
43
|
+
imports: plugin.imports ?? [],
|
|
44
|
+
clientKeys: Object.keys(plugin.client ?? {}),
|
|
45
|
+
ctxKeys: Object.keys(plugin.ctx ?? {}),
|
|
46
|
+
optionFragments: [],
|
|
47
|
+
status: 'registered',
|
|
48
|
+
}));
|
|
49
|
+
assertSafePluginIdentities(records);
|
|
50
|
+
assertSafeStaticKeys(records, 'clientKeys', 'client');
|
|
51
|
+
assertSafeStaticKeys(records, 'ctxKeys', 'ctx');
|
|
52
|
+
assertUniqueStaticKeys(records, 'clientKeys', 'client');
|
|
53
|
+
assertUniqueStaticKeys(records, 'ctxKeys', 'ctx');
|
|
54
|
+
const resolved = ordered.slice();
|
|
55
|
+
const registry = {
|
|
56
|
+
plugins: resolved,
|
|
57
|
+
records,
|
|
58
|
+
commands: [],
|
|
59
|
+
components: [],
|
|
60
|
+
modals: [],
|
|
61
|
+
events: [],
|
|
62
|
+
anyEvents: [],
|
|
63
|
+
eventErrors: [],
|
|
64
|
+
middlewares: [],
|
|
65
|
+
globalMiddlewares: [],
|
|
66
|
+
installedMiddlewares: new Map(),
|
|
67
|
+
contributionMutationDiagnostics: new Set(),
|
|
68
|
+
autocompleteWrappers: [],
|
|
69
|
+
gatewayIntents: [],
|
|
70
|
+
gatewaySendPayloadWrappers: [],
|
|
71
|
+
gatewayDispatchInterceptors: [],
|
|
72
|
+
restObservers: [],
|
|
73
|
+
hooks: [],
|
|
74
|
+
cacheResources: [],
|
|
75
|
+
shared: new Map(),
|
|
76
|
+
sharedOwners: new Map(),
|
|
77
|
+
sharedMutations: [],
|
|
78
|
+
sharedDisposals: [],
|
|
79
|
+
langs: [],
|
|
80
|
+
diagnostics: [],
|
|
81
|
+
requirements: [],
|
|
82
|
+
nextContributionSequence: 0,
|
|
83
|
+
commandRemovals: [],
|
|
84
|
+
componentRemovals: [],
|
|
85
|
+
modalRemovals: [],
|
|
86
|
+
middlewareRemovals: [],
|
|
87
|
+
commandObservers: [],
|
|
88
|
+
pluginDefaults: [],
|
|
89
|
+
handlerCreators: [],
|
|
90
|
+
handlerTransformers: [],
|
|
91
|
+
};
|
|
92
|
+
addStaticKeyMultiInstanceDiagnostics(registry);
|
|
93
|
+
validatePluginRequirements(registry, 'plugin');
|
|
94
|
+
Object.defineProperties(resolved, {
|
|
95
|
+
resolved: {
|
|
96
|
+
value: Object.freeze(ordered.slice()),
|
|
97
|
+
},
|
|
98
|
+
diagnostics: {
|
|
99
|
+
get: () => createPluginDiagnostics(registry),
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
Object.freeze(resolved);
|
|
103
|
+
return registry;
|
|
104
|
+
}
|
|
105
|
+
function runPluginRegister(record, registry) {
|
|
106
|
+
try {
|
|
107
|
+
const result = record.plugin.register?.((0, api_1.createPluginApi)(record, registry));
|
|
108
|
+
if (isPromiseLike(result)) {
|
|
109
|
+
Promise.resolve(result).catch(() => undefined);
|
|
110
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, 'register', record.index, 'register(api) must be synchronous.', record.plugin.instanceId);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
throw (0, errors_1.wrapPluginError)(record.plugin.name, 'register', record.index, error, undefined, record.plugin.instanceId);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function bindPluginClient(registry, client) {
|
|
118
|
+
registry.client = client;
|
|
119
|
+
}
|
|
120
|
+
function removePluginEventContribution(registry, contribution) {
|
|
121
|
+
removeContribution(registry.events, contribution);
|
|
122
|
+
}
|
|
123
|
+
function removePluginAnyEventContribution(registry, contribution) {
|
|
124
|
+
removeContribution(registry.anyEvents, contribution);
|
|
125
|
+
}
|
|
126
|
+
function removePluginEventErrorContribution(registry, contribution) {
|
|
127
|
+
removeContribution(registry.eventErrors, contribution);
|
|
128
|
+
}
|
|
129
|
+
function removePluginCommandObserverContribution(registry, contribution) {
|
|
130
|
+
removeContribution(registry.commandObservers, contribution);
|
|
131
|
+
}
|
|
132
|
+
function removePluginRestObserverContribution(registry, contribution) {
|
|
133
|
+
removeContribution(registry.restObservers, contribution);
|
|
134
|
+
}
|
|
135
|
+
function removePluginGatewayDispatchInterceptorContribution(registry, contribution) {
|
|
136
|
+
removeContribution(registry.gatewayDispatchInterceptors, contribution);
|
|
137
|
+
}
|
|
138
|
+
function removePluginHookContribution(registry, contribution) {
|
|
139
|
+
removeContribution(registry.hooks, contribution);
|
|
140
|
+
}
|
|
141
|
+
function activatePluginEventListeners(registry, record) {
|
|
142
|
+
for (const contribution of eventContributions(registry)) {
|
|
143
|
+
if (contribution.record === record && contribution.scope === 'register')
|
|
144
|
+
contribution.active = true;
|
|
145
|
+
}
|
|
146
|
+
for (const contribution of registry.commandObservers) {
|
|
147
|
+
if (contribution.record === record && contribution.scope === 'register')
|
|
148
|
+
contribution.active = true;
|
|
149
|
+
}
|
|
150
|
+
for (const contribution of registry.restObservers) {
|
|
151
|
+
if (contribution.record === record && contribution.scope === 'register')
|
|
152
|
+
contribution.active = true;
|
|
153
|
+
}
|
|
154
|
+
for (const contribution of registry.hooks) {
|
|
155
|
+
if (contribution.record === record && contribution.scope === 'register')
|
|
156
|
+
contribution.active = true;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function cleanupPluginEventListeners(registry, record) {
|
|
160
|
+
cleanupEventContributions(registry.events, record);
|
|
161
|
+
cleanupEventContributions(registry.anyEvents, record);
|
|
162
|
+
cleanupEventContributions(registry.eventErrors, record);
|
|
163
|
+
cleanupCommandObserverContributions(registry.commandObservers, record);
|
|
164
|
+
cleanupRestObserverContributions(registry.restObservers, record);
|
|
165
|
+
cleanupHookContributions(registry.hooks, record);
|
|
166
|
+
}
|
|
167
|
+
function cleanupPluginDynamicContributionMutations(registry, record) {
|
|
168
|
+
cleanupScopedContributions(registry.commands, record);
|
|
169
|
+
cleanupScopedContributions(registry.commandRemovals, record);
|
|
170
|
+
cleanupScopedContributions(registry.components, record);
|
|
171
|
+
cleanupScopedContributions(registry.componentRemovals, record);
|
|
172
|
+
cleanupScopedContributions(registry.modals, record);
|
|
173
|
+
cleanupScopedContributions(registry.modalRemovals, record);
|
|
174
|
+
cleanupScopedContributions(registry.handlerCreators, record);
|
|
175
|
+
cleanupScopedContributions(registry.handlerTransformers, record);
|
|
176
|
+
cleanupScopedContributions(registry.autocompleteWrappers, record);
|
|
177
|
+
cleanupScopedContributions(registry.gatewaySendPayloadWrappers, record);
|
|
178
|
+
cleanupScopedContributions(registry.gatewayDispatchInterceptors, record);
|
|
179
|
+
cleanupScopedContributions(registry.gatewayIntents, record);
|
|
180
|
+
cleanupScopedContributions(registry.pluginDefaults, record);
|
|
181
|
+
cleanupScopedContributions(registry.middlewares, record);
|
|
182
|
+
cleanupScopedContributions(registry.middlewareRemovals, record);
|
|
183
|
+
cleanupScopedContributions(registry.langs, record);
|
|
184
|
+
cleanupScopedContributions(registry.cacheResources, record);
|
|
185
|
+
cleanupScopedContributions(record.optionFragments, record);
|
|
186
|
+
if (registry.globalMiddlewareOptions) {
|
|
187
|
+
cleanupScopedContributions(registry.globalMiddlewareOptions.pluginOptions, record);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function hasPluginRequirement(registry, req) {
|
|
191
|
+
if (req.startsWith('plugin:')) {
|
|
192
|
+
const identity = req.slice('plugin:'.length);
|
|
193
|
+
return registry.records.some(record => record.identity === identity);
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
function pluginIdentity(plugin) {
|
|
198
|
+
return plugin.instanceId ? `${plugin.name}#${plugin.instanceId}` : plugin.name;
|
|
199
|
+
}
|
|
200
|
+
function resolvePluginIntents(registry, base) {
|
|
201
|
+
return registry.gatewayIntents.reduce((intents, contribution) => contribution.intents.reduce((current, intent) => current | intent, intents), base);
|
|
202
|
+
}
|
|
203
|
+
function addPluginGlobalMiddlewares(registry, record, names) {
|
|
204
|
+
for (const name of names) {
|
|
205
|
+
registry.globalMiddlewares.push({
|
|
206
|
+
record,
|
|
207
|
+
name,
|
|
208
|
+
sequence: registry.nextContributionSequence++,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function addPluginOptionFragment(registry, record, fragment, scope) {
|
|
213
|
+
const contribution = {
|
|
214
|
+
record,
|
|
215
|
+
fragment: clonePluginOptions(fragment),
|
|
216
|
+
sequence: (0, order_1.nextPluginContributionSequence)(registry),
|
|
217
|
+
scope,
|
|
218
|
+
};
|
|
219
|
+
record.optionFragments.push(contribution);
|
|
220
|
+
registry.globalMiddlewareOptions?.pluginOptions.push(contribution);
|
|
221
|
+
}
|
|
222
|
+
function addPluginDiagnostic(registry, record, diagnostic) {
|
|
223
|
+
registry.diagnostics.push({
|
|
224
|
+
plugin: record.plugin.name,
|
|
225
|
+
instanceId: record.plugin.instanceId,
|
|
226
|
+
index: record.index,
|
|
227
|
+
...diagnostic,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function clonePluginOptions(value) {
|
|
231
|
+
return clonePlainValue(value);
|
|
232
|
+
}
|
|
233
|
+
function readonlyPluginOptions(value) {
|
|
234
|
+
return deepFreezePlain(clonePlainValue(value));
|
|
235
|
+
}
|
|
236
|
+
function assertSafePluginResourceName(record, phase, name, reserved) {
|
|
237
|
+
if (!isSafePluginKey(name) || reserved.has(name)) {
|
|
238
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, phase, record.index, `Plugin key "${name}" is reserved or unsafe.`, record.plugin.instanceId);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function assertCanMutatePluginContribution(registry, record, action, kind, name, owner, phase) {
|
|
242
|
+
if (!owner) {
|
|
243
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, phase, record.index, `${capitalize(kind)} "${name}" is already registered outside the plugin registry and cannot be ${action}d by a plugin.`, record.plugin.instanceId);
|
|
244
|
+
}
|
|
245
|
+
if (owner === record)
|
|
246
|
+
return;
|
|
247
|
+
if (hasSatisfiedPluginRequirement(registry, record, owner))
|
|
248
|
+
return;
|
|
249
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, phase, record.index, `${capitalize(kind)} "${name}" is owned by plugin "${owner.identity}"; ${action} requires plugin "${owner.identity}".`, record.plugin.instanceId);
|
|
250
|
+
}
|
|
251
|
+
function recordContributionMutationDiagnostic(registry, contribution, action, kind, name, owner, phase) {
|
|
252
|
+
const key = [
|
|
253
|
+
contribution.sequence,
|
|
254
|
+
action,
|
|
255
|
+
kind,
|
|
256
|
+
name,
|
|
257
|
+
owner?.identity ?? 'external',
|
|
258
|
+
contribution.record.identity,
|
|
259
|
+
].join(':');
|
|
260
|
+
if (registry.contributionMutationDiagnostics.has(key))
|
|
261
|
+
return;
|
|
262
|
+
registry.contributionMutationDiagnostics.add(key);
|
|
263
|
+
addPluginDiagnostic(registry, contribution.record, {
|
|
264
|
+
phase,
|
|
265
|
+
severity: 'info',
|
|
266
|
+
code: action === 'override' ? 'contribution-override' : 'contribution-removed',
|
|
267
|
+
message: `Plugin "${contribution.record.plugin.name}" ${action}d ${kind} "${name}".`,
|
|
268
|
+
data: {
|
|
269
|
+
kind,
|
|
270
|
+
name,
|
|
271
|
+
owner: owner?.identity,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function addStaticKeyMultiInstanceDiagnostics(registry) {
|
|
276
|
+
for (const record of registry.records) {
|
|
277
|
+
const instanceId = record.plugin.instanceId;
|
|
278
|
+
if (!instanceId)
|
|
279
|
+
continue;
|
|
280
|
+
const clientKeys = record.clientKeys.filter(key => !key.includes(instanceId));
|
|
281
|
+
const ctxKeys = record.ctxKeys.filter(key => !key.includes(instanceId));
|
|
282
|
+
const middlewareKeys = Object.keys(record.plugin.middlewares ?? {}).filter(key => !key.includes(instanceId));
|
|
283
|
+
const globalMiddlewares = (record.plugin.globalMiddlewares ?? [])
|
|
284
|
+
.map(String)
|
|
285
|
+
.filter(key => !key.includes(instanceId));
|
|
286
|
+
if (!(clientKeys.length || ctxKeys.length || middlewareKeys.length || globalMiddlewares.length))
|
|
287
|
+
continue;
|
|
288
|
+
addPluginDiagnostic(registry, record, {
|
|
289
|
+
phase: 'resolve',
|
|
290
|
+
severity: 'warn',
|
|
291
|
+
code: 'static-keys-multi-instance',
|
|
292
|
+
message: `Plugin "${record.identity}" declares static keys that do not include instanceId "${instanceId}".`,
|
|
293
|
+
data: {
|
|
294
|
+
instanceId,
|
|
295
|
+
clientKeys,
|
|
296
|
+
ctxKeys,
|
|
297
|
+
middlewareKeys,
|
|
298
|
+
globalMiddlewares,
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function assertSafePluginIdentities(records) {
|
|
304
|
+
for (const record of records) {
|
|
305
|
+
assertSafePluginResourceName(record, 'resolve', record.plugin.name, emptyReservedKeys);
|
|
306
|
+
if (record.plugin.instanceId) {
|
|
307
|
+
assertSafePluginResourceName(record, 'resolve', record.plugin.instanceId, emptyReservedKeys);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function assertSafeStaticKeys(records, key, phase) {
|
|
312
|
+
const reserved = phase === 'ctx' ? reservedContextKeys : emptyReservedKeys;
|
|
313
|
+
for (const record of records) {
|
|
314
|
+
for (const value of record[key]) {
|
|
315
|
+
assertSafePluginResourceName(record, `${phase}.${value}`, value, reserved);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function createPluginContextFragment(record, registry) {
|
|
320
|
+
const map = record.plugin.ctx;
|
|
321
|
+
if (!map)
|
|
322
|
+
return undefined;
|
|
323
|
+
return {
|
|
324
|
+
context(interaction) {
|
|
325
|
+
if (!registry.client) {
|
|
326
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, 'ctx', record.index, 'Plugin context used before client bind.', record.plugin.instanceId);
|
|
327
|
+
}
|
|
328
|
+
const context = {};
|
|
329
|
+
for (const [key, factory] of Object.entries(map)) {
|
|
330
|
+
try {
|
|
331
|
+
context[key] = factory(interaction, registry.client);
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
throw (0, errors_1.wrapPluginError)(record.plugin.name, `ctx.${key}`, record.index, error, undefined, record.plugin.instanceId);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return context;
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function installPluginClientMaps(client, registry) {
|
|
342
|
+
const claimed = new Map();
|
|
343
|
+
for (const record of registry.records) {
|
|
344
|
+
for (const [key, factory] of Object.entries(record.plugin.client ?? {})) {
|
|
345
|
+
if (key in client) {
|
|
346
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, `client.${key}`, record.index, `Client key "${key}" is reserved or already exists.`, record.plugin.instanceId);
|
|
347
|
+
}
|
|
348
|
+
const owner = claimed.get(key);
|
|
349
|
+
if (owner) {
|
|
350
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, `client.${key}`, record.index, `Client key "${key}" is already claimed by plugin "${owner.plugin.name}".`, record.plugin.instanceId);
|
|
351
|
+
}
|
|
352
|
+
claimed.set(key, record);
|
|
353
|
+
try {
|
|
354
|
+
Object.defineProperty(client, key, {
|
|
355
|
+
configurable: true,
|
|
356
|
+
enumerable: true,
|
|
357
|
+
value: factory(client),
|
|
358
|
+
writable: false,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
throw (0, errors_1.wrapPluginError)(record.plugin.name, `client.${key}`, record.index, error, undefined, record.plugin.instanceId);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
function installPluginMiddlewares(client, registry) {
|
|
368
|
+
const declared = registry.records.flatMap(record => Object.entries(record.plugin.middlewares ?? {}).map(([name, middleware]) => ({
|
|
369
|
+
record,
|
|
370
|
+
name,
|
|
371
|
+
middleware: middleware,
|
|
372
|
+
global: (record.plugin.globalMiddlewares ?? []).includes(name),
|
|
373
|
+
override: false,
|
|
374
|
+
scope: 'register',
|
|
375
|
+
sequence: record.index - registry.records.length,
|
|
376
|
+
})));
|
|
377
|
+
const mutations = (0, order_1.orderedPluginContributions)([
|
|
378
|
+
...declared.map(contribution => ({ ...contribution, kind: 'add' })),
|
|
379
|
+
...registry.middlewares.map(contribution => ({ ...contribution, kind: 'add' })),
|
|
380
|
+
...registry.middlewareRemovals.map(contribution => ({ ...contribution, kind: 'remove' })),
|
|
381
|
+
]);
|
|
382
|
+
if (!mutations.length && !registry.installedMiddlewares.size)
|
|
383
|
+
return;
|
|
384
|
+
const middlewares = new Map();
|
|
385
|
+
for (const [name, middleware] of Object.entries(client.middlewares ?? {})) {
|
|
386
|
+
const installed = registry.installedMiddlewares.get(name);
|
|
387
|
+
if (installed?.middleware === middleware)
|
|
388
|
+
continue;
|
|
389
|
+
middlewares.set(name, { middleware });
|
|
390
|
+
}
|
|
391
|
+
for (const contribution of mutations) {
|
|
392
|
+
if (contribution.kind === 'remove') {
|
|
393
|
+
for (const name of contribution.names) {
|
|
394
|
+
const existing = middlewares.get(name);
|
|
395
|
+
if (!existing)
|
|
396
|
+
continue;
|
|
397
|
+
assertCanMutatePluginContribution(registry, contribution.record, 'remove', 'middleware', name, existing.owner, `middlewares.${name}`);
|
|
398
|
+
middlewares.delete(name);
|
|
399
|
+
recordMiddlewareMutationDiagnostic(registry, contribution, 'remove', name, existing.owner, `middlewares.${name}`);
|
|
400
|
+
}
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
const existing = middlewares.get(contribution.name);
|
|
404
|
+
if (existing && !contribution.override) {
|
|
405
|
+
throw (0, errors_1.createPluginConflictError)(contribution.record.plugin.name, `middlewares.${contribution.name}`, contribution.record.index, `Middleware "${contribution.name}" is already registered.`, contribution.record.plugin.instanceId);
|
|
406
|
+
}
|
|
407
|
+
if (existing) {
|
|
408
|
+
assertCanMutatePluginContribution(registry, contribution.record, 'override', 'middleware', contribution.name, existing.owner, `middlewares.${contribution.name}`);
|
|
409
|
+
recordMiddlewareMutationDiagnostic(registry, contribution, 'override', contribution.name, existing.owner, `middlewares.${contribution.name}`);
|
|
410
|
+
}
|
|
411
|
+
middlewares.set(contribution.name, { middleware: contribution.middleware, owner: contribution.record });
|
|
412
|
+
}
|
|
413
|
+
registry.installedMiddlewares = new Map([...middlewares]
|
|
414
|
+
.filter((entry) => !!entry[1].owner)
|
|
415
|
+
.map(([name, contribution]) => [name, { middleware: contribution.middleware, owner: contribution.owner }]));
|
|
416
|
+
client.middlewares = Object.fromEntries([...middlewares].map(([name, contribution]) => [name, contribution.middleware]));
|
|
417
|
+
}
|
|
418
|
+
function recordMiddlewareMutationDiagnostic(registry, contribution, action, name, owner, phase) {
|
|
419
|
+
recordContributionMutationDiagnostic(registry, contribution, action, 'middleware', name, owner, phase);
|
|
420
|
+
}
|
|
421
|
+
function resolvePluginOrder(plugins) {
|
|
422
|
+
const ordered = [];
|
|
423
|
+
const seen = new Set();
|
|
424
|
+
const visiting = new Set();
|
|
425
|
+
const identities = new Map();
|
|
426
|
+
const visit = (plugin, chain, index) => {
|
|
427
|
+
if (!plugin.name) {
|
|
428
|
+
throw (0, errors_1.createPluginConflictError)('<anonymous>', 'resolve', index, 'Seyfert plugins must have a name.');
|
|
429
|
+
}
|
|
430
|
+
const identity = pluginIdentity(plugin);
|
|
431
|
+
const existing = identities.get(identity);
|
|
432
|
+
if (existing && existing !== plugin) {
|
|
433
|
+
const duplicateMessage = plugin.instanceId
|
|
434
|
+
? `Duplicate plugin identity "${identity}".`
|
|
435
|
+
: `Duplicate plugin name "${plugin.name}". Use instanceId to register multiple instances of the same plugin.`;
|
|
436
|
+
throw (0, errors_1.createPluginConflictError)(plugin.name, 'resolve', ordered.length, duplicateMessage, plugin.instanceId);
|
|
437
|
+
}
|
|
438
|
+
identities.set(identity, plugin);
|
|
439
|
+
if (seen.has(plugin))
|
|
440
|
+
return;
|
|
441
|
+
if (visiting.has(plugin)) {
|
|
442
|
+
throw (0, errors_1.createPluginConflictError)(plugin.name, 'resolve', ordered.length, `Circular plugin import detected: ${[...chain, identity].join(' -> ')}.`, plugin.instanceId);
|
|
443
|
+
}
|
|
444
|
+
visiting.add(plugin);
|
|
445
|
+
for (const imported of plugin.imports ?? [])
|
|
446
|
+
visit(imported, [...chain, identity], ordered.length);
|
|
447
|
+
visiting.delete(plugin);
|
|
448
|
+
seen.add(plugin);
|
|
449
|
+
ordered.push(plugin);
|
|
450
|
+
};
|
|
451
|
+
for (const [index, plugin] of plugins.entries())
|
|
452
|
+
visit(plugin, [], index);
|
|
453
|
+
return ordered;
|
|
454
|
+
}
|
|
455
|
+
function assertUniqueStaticKeys(records, key, phase) {
|
|
456
|
+
const owners = new Map();
|
|
457
|
+
for (const record of records) {
|
|
458
|
+
for (const value of record[key]) {
|
|
459
|
+
const owner = owners.get(value);
|
|
460
|
+
if (owner) {
|
|
461
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, `${phase}.${value}`, record.index, `${phase} key "${value}" is already claimed by plugin "${owner.plugin.name}".`, record.plugin.instanceId);
|
|
462
|
+
}
|
|
463
|
+
owners.set(value, record);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
const pluginDiagnosticsListLimit = 50;
|
|
468
|
+
function snapshotDiagnosticList(values, truncated, key) {
|
|
469
|
+
if (values.length > pluginDiagnosticsListLimit)
|
|
470
|
+
truncated[key] = values.length - pluginDiagnosticsListLimit;
|
|
471
|
+
return Object.freeze(values.slice(0, pluginDiagnosticsListLimit));
|
|
472
|
+
}
|
|
473
|
+
function createPluginDiagnostics(registry) {
|
|
474
|
+
return Object.freeze(registry.records.map(record => {
|
|
475
|
+
const truncated = {};
|
|
476
|
+
const events = registry.events
|
|
477
|
+
.filter(contribution => contribution.record === record)
|
|
478
|
+
.map(contribution => contribution.name);
|
|
479
|
+
const eventErrors = registry.eventErrors.filter(contribution => contribution.record === record).length;
|
|
480
|
+
const middlewares = registry.middlewares
|
|
481
|
+
.filter(contribution => contribution.record === record)
|
|
482
|
+
.map(contribution => contribution.name)
|
|
483
|
+
.concat(Object.keys(record.plugin.middlewares ?? {}));
|
|
484
|
+
const requirements = registry.requirements
|
|
485
|
+
.filter(contribution => contribution.record === record)
|
|
486
|
+
.map(({ kind, req, range, resolvedVersion, optional, satisfied }) => Object.freeze({
|
|
487
|
+
kind,
|
|
488
|
+
req,
|
|
489
|
+
range,
|
|
490
|
+
resolvedVersion,
|
|
491
|
+
optional,
|
|
492
|
+
satisfied,
|
|
493
|
+
}));
|
|
494
|
+
const shared = [...registry.shared.entries()]
|
|
495
|
+
.filter(([, contribution]) => contribution.record === record)
|
|
496
|
+
.map(([name]) => name);
|
|
497
|
+
const cacheResources = registry.cacheResources
|
|
498
|
+
.filter(contribution => contribution.record === record)
|
|
499
|
+
.map(contribution => contribution.name);
|
|
500
|
+
const langs = registry.langs
|
|
501
|
+
.filter(contribution => contribution.record === record)
|
|
502
|
+
.map(contribution => `${contribution.locale}:${contribution.prefix}`);
|
|
503
|
+
const hooks = registry.hooks
|
|
504
|
+
.filter(contribution => contribution.record === record)
|
|
505
|
+
.map(contribution => contribution.name);
|
|
506
|
+
const messages = registry.diagnostics
|
|
507
|
+
.filter(message => message.index === record.index)
|
|
508
|
+
.map(message => Object.freeze({
|
|
509
|
+
...message,
|
|
510
|
+
data: message.data ? Object.freeze({ ...message.data }) : undefined,
|
|
511
|
+
}));
|
|
512
|
+
return Object.freeze({
|
|
513
|
+
name: record.plugin.name,
|
|
514
|
+
instanceId: record.plugin.instanceId,
|
|
515
|
+
index: record.index,
|
|
516
|
+
status: record.status,
|
|
517
|
+
imports: snapshotDiagnosticList(record.imports.map(pluginIdentity), truncated, 'imports'),
|
|
518
|
+
clientKeys: snapshotDiagnosticList(record.clientKeys, truncated, 'clientKeys'),
|
|
519
|
+
ctxKeys: snapshotDiagnosticList(record.ctxKeys, truncated, 'ctxKeys'),
|
|
520
|
+
commands: registry.commands.filter(contribution => contribution.record === record).flatMap(c => c.commands)
|
|
521
|
+
.length,
|
|
522
|
+
components: registry.components
|
|
523
|
+
.filter(contribution => contribution.record === record)
|
|
524
|
+
.flatMap(c => c.components).length,
|
|
525
|
+
modals: registry.modals.filter(contribution => contribution.record === record).flatMap(c => c.modals).length,
|
|
526
|
+
events: snapshotDiagnosticList(events, truncated, 'events'),
|
|
527
|
+
anyEvents: registry.anyEvents.filter(contribution => contribution.record === record).length,
|
|
528
|
+
eventErrors,
|
|
529
|
+
middlewares: snapshotDiagnosticList(middlewares, truncated, 'middlewares'),
|
|
530
|
+
autocompleteWrappers: registry.autocompleteWrappers.filter(contribution => contribution.record === record)
|
|
531
|
+
.length,
|
|
532
|
+
gatewayIntents: registry.gatewayIntents.filter(contribution => contribution.record === record).length,
|
|
533
|
+
gatewaySendPayloadWrappers: registry.gatewaySendPayloadWrappers.filter(contribution => contribution.record === record).length,
|
|
534
|
+
gatewayDispatchInterceptors: registry.gatewayDispatchInterceptors.filter(contribution => contribution.record === record).length,
|
|
535
|
+
requirements: snapshotDiagnosticList(requirements, truncated, 'requirements'),
|
|
536
|
+
shared: snapshotDiagnosticList(shared, truncated, 'shared'),
|
|
537
|
+
cacheResources: snapshotDiagnosticList(cacheResources, truncated, 'cacheResources'),
|
|
538
|
+
langs: snapshotDiagnosticList(langs, truncated, 'langs'),
|
|
539
|
+
hooks: snapshotDiagnosticList(hooks, truncated, 'hooks'),
|
|
540
|
+
restObservers: registry.restObservers.filter(contribution => contribution.record === record).length,
|
|
541
|
+
commandObservers: registry.commandObservers.filter(contribution => contribution.record === record).length,
|
|
542
|
+
handlerCreators: registry.handlerCreators.filter(contribution => contribution.record === record).length,
|
|
543
|
+
handlerTransformers: registry.handlerTransformers.filter(contribution => contribution.record === record).length,
|
|
544
|
+
messages: snapshotDiagnosticList(messages, truncated, 'messages'),
|
|
545
|
+
truncated: Object.keys(truncated).length ? Object.freeze({ ...truncated }) : undefined,
|
|
546
|
+
});
|
|
547
|
+
}));
|
|
548
|
+
}
|
|
549
|
+
function resolveGatewayIntent(intent) {
|
|
550
|
+
if (typeof intent !== 'string')
|
|
551
|
+
return intent;
|
|
552
|
+
const value = types_1.GatewayIntentBits[intent];
|
|
553
|
+
return typeof value === 'number' ? value : undefined;
|
|
554
|
+
}
|
|
555
|
+
function unknownGatewayIntentBits(intent) {
|
|
556
|
+
if (typeof intent !== 'number')
|
|
557
|
+
return 0;
|
|
558
|
+
return intent & ~knownGatewayIntentMask;
|
|
559
|
+
}
|
|
560
|
+
function normalizeRequirement(input, record) {
|
|
561
|
+
if (typeof input === 'string')
|
|
562
|
+
return { kind: 'plugin', req: input, optional: false, satisfied: false };
|
|
563
|
+
if ('capability' in input && 'req' in input && input.req !== undefined) {
|
|
564
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, 'requires', record.index, 'Plugin requirement objects must use either "req" or "capability", not both.', record.plugin.instanceId);
|
|
565
|
+
}
|
|
566
|
+
const capability = 'capability' in input ? input.capability : undefined;
|
|
567
|
+
if (capability) {
|
|
568
|
+
return {
|
|
569
|
+
kind: 'capability',
|
|
570
|
+
req: capability.name,
|
|
571
|
+
optional: input.optional === true,
|
|
572
|
+
satisfied: false,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
if (!input.req) {
|
|
576
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, 'requires', record.index, 'Plugin requirement objects must include "req" or "capability".', record.plugin.instanceId);
|
|
577
|
+
}
|
|
578
|
+
return {
|
|
579
|
+
kind: 'plugin',
|
|
580
|
+
req: input.req,
|
|
581
|
+
range: input.range,
|
|
582
|
+
optional: input.optional === true,
|
|
583
|
+
satisfied: false,
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
function validatePluginRequirements(registry, kind = 'all') {
|
|
587
|
+
for (const record of registry.records) {
|
|
588
|
+
for (const input of record.plugin.requires ?? []) {
|
|
589
|
+
const requirement = normalizeRequirement(input, record);
|
|
590
|
+
if (kind !== 'all' && requirement.kind !== kind)
|
|
591
|
+
continue;
|
|
592
|
+
resolveRequirement(registry, requirement);
|
|
593
|
+
registry.requirements.push({ record, ...requirement });
|
|
594
|
+
if (requirement.satisfied) {
|
|
595
|
+
const target = requiredPluginRecord(registry, requirement);
|
|
596
|
+
if (target && target.index > record.index) {
|
|
597
|
+
addPluginDiagnostic(registry, record, {
|
|
598
|
+
phase: 'requires',
|
|
599
|
+
severity: 'warn',
|
|
600
|
+
code: 'requires-unordered',
|
|
601
|
+
message: `Plugin requirement "${requirement.req}" is ordered after "${record.identity}". Add it to imports when mutating its contributions.`,
|
|
602
|
+
data: requirementDiagnosticData(requirement),
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
continue;
|
|
606
|
+
}
|
|
607
|
+
if (requirement.optional) {
|
|
608
|
+
addPluginDiagnostic(registry, record, {
|
|
609
|
+
phase: 'requires',
|
|
610
|
+
severity: 'warn',
|
|
611
|
+
code: 'missing-optional-requirement',
|
|
612
|
+
message: optionalRequirementMessage(requirement),
|
|
613
|
+
data: requirementDiagnosticData(requirement),
|
|
614
|
+
});
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
throw (0, errors_1.createPluginConflictError)(record.plugin.name, 'requires', record.index, requiredRequirementMessage(requirement), record.plugin.instanceId);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
function resolveRequirement(registry, requirement) {
|
|
622
|
+
if (requirement.kind === 'capability') {
|
|
623
|
+
requirement.satisfied = registry.shared.has(requirement.req);
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
if (!String(requirement.req).startsWith('plugin:'))
|
|
627
|
+
return;
|
|
628
|
+
const target = requiredPluginRecord(registry, requirement);
|
|
629
|
+
if (!target)
|
|
630
|
+
return;
|
|
631
|
+
const version = pluginVersion(target.plugin);
|
|
632
|
+
requirement.resolvedVersion = version;
|
|
633
|
+
requirement.satisfied = requirement.range ? !!version && satisfiesSemverRange(version, requirement.range) : true;
|
|
634
|
+
}
|
|
635
|
+
function optionalRequirementMessage(requirement) {
|
|
636
|
+
if (requirement.kind === 'capability') {
|
|
637
|
+
return `Optional capability requirement "${requirement.req}" is not registered.`;
|
|
638
|
+
}
|
|
639
|
+
if (requirement.range && requirement.resolvedVersion) {
|
|
640
|
+
return `Optional plugin requirement "${requirement.req}" does not satisfy range "${requirement.range}" (resolved "${requirement.resolvedVersion}").`;
|
|
641
|
+
}
|
|
642
|
+
if (requirement.range) {
|
|
643
|
+
return `Optional plugin requirement "${requirement.req}" is missing version range "${requirement.range}".`;
|
|
644
|
+
}
|
|
645
|
+
return `Optional plugin requirement "${requirement.req}" is not registered.`;
|
|
646
|
+
}
|
|
647
|
+
function requiredRequirementMessage(requirement) {
|
|
648
|
+
if (requirement.kind === 'capability') {
|
|
649
|
+
return `Capability requirement "${requirement.req}" is not registered.`;
|
|
650
|
+
}
|
|
651
|
+
if (requirement.range && requirement.resolvedVersion) {
|
|
652
|
+
return `Plugin requirement "${requirement.req}" does not satisfy range "${requirement.range}" (resolved "${requirement.resolvedVersion}").`;
|
|
653
|
+
}
|
|
654
|
+
if (requirement.range) {
|
|
655
|
+
return `Plugin requirement "${requirement.req}" is missing version range "${requirement.range}".`;
|
|
656
|
+
}
|
|
657
|
+
return `Plugin requirement "${requirement.req}" is not registered.`;
|
|
658
|
+
}
|
|
659
|
+
function requirementDiagnosticData(requirement) {
|
|
660
|
+
if (requirement.kind === 'capability')
|
|
661
|
+
return { kind: requirement.kind, capability: requirement.req };
|
|
662
|
+
return {
|
|
663
|
+
kind: requirement.kind,
|
|
664
|
+
req: requirement.req,
|
|
665
|
+
range: requirement.range,
|
|
666
|
+
resolvedVersion: requirement.resolvedVersion,
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
function pluginVersion(plugin) {
|
|
670
|
+
if (typeof plugin.version === 'string')
|
|
671
|
+
return plugin.version;
|
|
672
|
+
const meta = plugin.meta;
|
|
673
|
+
if (!meta || typeof meta !== 'object' || !('version' in meta))
|
|
674
|
+
return undefined;
|
|
675
|
+
const version = meta.version;
|
|
676
|
+
return typeof version === 'string' ? version : undefined;
|
|
677
|
+
}
|
|
678
|
+
function requiredPluginRecord(registry, requirement) {
|
|
679
|
+
if (requirement.kind !== 'plugin')
|
|
680
|
+
return undefined;
|
|
681
|
+
if (!String(requirement.req).startsWith('plugin:'))
|
|
682
|
+
return undefined;
|
|
683
|
+
const identity = String(requirement.req).slice('plugin:'.length);
|
|
684
|
+
return registry.records.find(record => record.identity === identity);
|
|
685
|
+
}
|
|
686
|
+
function satisfiesSemverRange(version, range) {
|
|
687
|
+
const parsed = parseSemver(version);
|
|
688
|
+
if (!parsed)
|
|
689
|
+
return false;
|
|
690
|
+
const trimmed = range.trim();
|
|
691
|
+
if (!trimmed)
|
|
692
|
+
return true;
|
|
693
|
+
if (trimmed.startsWith('>=')) {
|
|
694
|
+
const minimum = parseSemver(trimmed.slice(2).trim());
|
|
695
|
+
return !!minimum && compareSemver(parsed, minimum) >= 0;
|
|
696
|
+
}
|
|
697
|
+
if (trimmed.startsWith('^')) {
|
|
698
|
+
const minimum = parseSemver(trimmed.slice(1).trim());
|
|
699
|
+
if (!minimum || compareSemver(parsed, minimum) < 0)
|
|
700
|
+
return false;
|
|
701
|
+
if (minimum.major > 0)
|
|
702
|
+
return parsed.major === minimum.major;
|
|
703
|
+
if (minimum.minor > 0)
|
|
704
|
+
return parsed.major === 0 && parsed.minor === minimum.minor;
|
|
705
|
+
return parsed.major === 0 && parsed.minor === 0 && parsed.patch === minimum.patch;
|
|
706
|
+
}
|
|
707
|
+
if (trimmed.startsWith('~')) {
|
|
708
|
+
const minimum = parseSemver(trimmed.slice(1).trim());
|
|
709
|
+
if (!minimum || compareSemver(parsed, minimum) < 0)
|
|
710
|
+
return false;
|
|
711
|
+
return parsed.major === minimum.major && parsed.minor === minimum.minor;
|
|
712
|
+
}
|
|
713
|
+
const exact = parseSemver(trimmed);
|
|
714
|
+
return !!exact && compareSemver(parsed, exact) === 0;
|
|
715
|
+
}
|
|
716
|
+
function parseSemver(version) {
|
|
717
|
+
const match = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(version.trim());
|
|
718
|
+
if (!match)
|
|
719
|
+
return undefined;
|
|
720
|
+
return {
|
|
721
|
+
major: Number(match[1]),
|
|
722
|
+
minor: Number(match[2]),
|
|
723
|
+
patch: Number(match[3]),
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
function compareSemver(left, right) {
|
|
727
|
+
return left.major - right.major || left.minor - right.minor || left.patch - right.patch;
|
|
728
|
+
}
|
|
729
|
+
const knownGatewayIntentMask = Object.values(types_1.GatewayIntentBits)
|
|
730
|
+
.filter((value) => typeof value === 'number')
|
|
731
|
+
.reduce((mask, value) => mask | value, 0);
|
|
732
|
+
function eventContributions(registry) {
|
|
733
|
+
return [...registry.events, ...registry.anyEvents, ...registry.eventErrors];
|
|
734
|
+
}
|
|
735
|
+
function cleanupEventContributions(contributions, record) {
|
|
736
|
+
for (let index = contributions.length - 1; index >= 0; index--) {
|
|
737
|
+
const contribution = contributions[index];
|
|
738
|
+
if (contribution.record !== record)
|
|
739
|
+
continue;
|
|
740
|
+
if (contribution.scope === 'setup') {
|
|
741
|
+
contributions.splice(index, 1);
|
|
742
|
+
continue;
|
|
743
|
+
}
|
|
744
|
+
contribution.active = false;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
function cleanupCommandObserverContributions(contributions, record) {
|
|
748
|
+
for (let index = contributions.length - 1; index >= 0; index--) {
|
|
749
|
+
const contribution = contributions[index];
|
|
750
|
+
if (contribution.record !== record)
|
|
751
|
+
continue;
|
|
752
|
+
if (contribution.scope === 'setup') {
|
|
753
|
+
contributions.splice(index, 1);
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
contribution.active = false;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
function cleanupRestObserverContributions(contributions, record) {
|
|
760
|
+
for (let index = contributions.length - 1; index >= 0; index--) {
|
|
761
|
+
const contribution = contributions[index];
|
|
762
|
+
if (contribution.record !== record)
|
|
763
|
+
continue;
|
|
764
|
+
if (contribution.scope === 'setup') {
|
|
765
|
+
contributions.splice(index, 1);
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
contribution.active = false;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
function cleanupHookContributions(contributions, record) {
|
|
772
|
+
for (let index = contributions.length - 1; index >= 0; index--) {
|
|
773
|
+
const contribution = contributions[index];
|
|
774
|
+
if (contribution.record !== record)
|
|
775
|
+
continue;
|
|
776
|
+
if (contribution.scope === 'setup') {
|
|
777
|
+
contributions.splice(index, 1);
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
contribution.active = false;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
function cleanupScopedContributions(contributions, record) {
|
|
784
|
+
for (let index = contributions.length - 1; index >= 0; index--) {
|
|
785
|
+
const contribution = contributions[index];
|
|
786
|
+
if (contribution.record === record && contribution.scope !== 'register')
|
|
787
|
+
contributions.splice(index, 1);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
function removeContribution(contributions, contribution) {
|
|
791
|
+
const index = contributions.indexOf(contribution);
|
|
792
|
+
if (index !== -1)
|
|
793
|
+
contributions.splice(index, 1);
|
|
794
|
+
}
|
|
795
|
+
function declaresPluginRequirement(record, owner) {
|
|
796
|
+
const requirement = `plugin:${owner.identity}`;
|
|
797
|
+
return (record.plugin.requires ?? []).some(input => {
|
|
798
|
+
if (typeof input === 'string')
|
|
799
|
+
return input === requirement;
|
|
800
|
+
if ('req' in input)
|
|
801
|
+
return input.req === requirement;
|
|
802
|
+
return false;
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
function hasSatisfiedPluginRequirement(registry, record, owner) {
|
|
806
|
+
if (!declaresPluginRequirement(record, owner))
|
|
807
|
+
return false;
|
|
808
|
+
const requirement = `plugin:${owner.identity}`;
|
|
809
|
+
return registry.requirements.some(contribution => contribution.record === record &&
|
|
810
|
+
contribution.kind === 'plugin' &&
|
|
811
|
+
contribution.req === requirement &&
|
|
812
|
+
contribution.satisfied &&
|
|
813
|
+
owner.index < record.index);
|
|
814
|
+
}
|
|
815
|
+
function clonePlainValue(value) {
|
|
816
|
+
if (Array.isArray(value))
|
|
817
|
+
return value.map(clonePlainValue);
|
|
818
|
+
if (!isPlainObject(value))
|
|
819
|
+
return value;
|
|
820
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, clonePlainValue(entry)]));
|
|
821
|
+
}
|
|
822
|
+
function deepFreezePlain(value) {
|
|
823
|
+
if (Array.isArray(value)) {
|
|
824
|
+
for (const entry of value)
|
|
825
|
+
deepFreezePlain(entry);
|
|
826
|
+
return Object.freeze(value);
|
|
827
|
+
}
|
|
828
|
+
if (!isPlainObject(value))
|
|
829
|
+
return value;
|
|
830
|
+
for (const entry of Object.values(value))
|
|
831
|
+
deepFreezePlain(entry);
|
|
832
|
+
return Object.freeze(value);
|
|
833
|
+
}
|
|
834
|
+
function isPlainObject(value) {
|
|
835
|
+
if (typeof value !== 'object' || value === null)
|
|
836
|
+
return false;
|
|
837
|
+
const prototype = Object.getPrototypeOf(value);
|
|
838
|
+
return prototype === Object.prototype || prototype === null;
|
|
839
|
+
}
|
|
840
|
+
function isSafePluginKey(key) {
|
|
841
|
+
return !!key && !unsafeObjectKeys.has(key) && !(key in Object.prototype);
|
|
842
|
+
}
|
|
843
|
+
const emptyReservedKeys = new Set();
|
|
844
|
+
const unsafeObjectKeys = new Set(['__proto__', 'constructor', 'prototype']);
|
|
845
|
+
const reservedContextKeys = new Set([
|
|
846
|
+
'author',
|
|
847
|
+
'channel',
|
|
848
|
+
'channelId',
|
|
849
|
+
'client',
|
|
850
|
+
'command',
|
|
851
|
+
'constructor',
|
|
852
|
+
'guild',
|
|
853
|
+
'guildId',
|
|
854
|
+
'interaction',
|
|
855
|
+
'me',
|
|
856
|
+
'member',
|
|
857
|
+
'metadata',
|
|
858
|
+
'shardId',
|
|
859
|
+
]);
|
|
860
|
+
function capitalize(value) {
|
|
861
|
+
return value[0]?.toUpperCase() + value.slice(1);
|
|
862
|
+
}
|
|
863
|
+
function isPromiseLike(value) {
|
|
864
|
+
return (typeof value === 'object' &&
|
|
865
|
+
value !== null &&
|
|
866
|
+
'then' in value &&
|
|
867
|
+
typeof value.then === 'function');
|
|
868
|
+
}
|