@wolfstar/http-framework 6.0.1 → 6.1.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/dist/esm/index.js CHANGED
@@ -685,6 +685,28 @@ let PluginHook = /* @__PURE__ */ function(PluginHook) {
685
685
  return PluginHook;
686
686
  }({});
687
687
 
688
+ //#endregion
689
+ //#region src/lib/plugins/definePlugin.ts
690
+ function definePlugin(plugin) {
691
+ return plugin;
692
+ }
693
+ /**
694
+ * The error a {@link StarsPlugin} hook is wrapped in, so a failure points at the plugin that threw. The original
695
+ * error is available as `cause`.
696
+ *
697
+ * @since 6.1.0
698
+ */
699
+ var PluginHookError = class extends Error {
700
+ constructor(pluginName, hook, cause) {
701
+ super(`The "${hook}" hook of the plugin "${pluginName}" failed: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
702
+ _defineProperty(this, "pluginName", void 0);
703
+ _defineProperty(this, "hook", void 0);
704
+ this.name = "PluginHookError";
705
+ this.pluginName = pluginName;
706
+ this.hook = hook;
707
+ }
708
+ };
709
+
688
710
  //#endregion
689
711
  //#region src/lib/plugins/symbols.ts
690
712
  const preGenericsInitialization = Symbol("HttpFrameworkPluginsPreGenericsInitialization");
@@ -693,16 +715,118 @@ const postInitialization = Symbol("HttpFrameworkPluginsPostInitialization");
693
715
  const preLoad = Symbol("HttpFrameworkPluginsPreLoad");
694
716
  const postListen = Symbol("HttpFrameworkPluginsPostListen");
695
717
 
718
+ //#endregion
719
+ //#region \0@oxc-project+runtime@0.151.0/helpers/esm/classPrivateMethodInitSpec.js
720
+ function _classPrivateMethodInitSpec(e, a) {
721
+ _checkPrivateRedeclaration(e, a), a.add(e);
722
+ }
723
+
696
724
  //#endregion
697
725
  //#region src/lib/plugins/PluginManager.ts
726
+ const HOOK_NAMES = [
727
+ "preGenericsInitialization",
728
+ "preInitialization",
729
+ "postInitialization",
730
+ "preLoad",
731
+ "postListen"
732
+ ];
733
+ const LEGACY_SYMBOLS = [
734
+ [preGenericsInitialization, "preGenericsInitialization"],
735
+ [preInitialization, "preInitialization"],
736
+ [postInitialization, "postInitialization"],
737
+ [preLoad, "preLoad"],
738
+ [postListen, "postListen"]
739
+ ];
740
+ const warnedLegacyNames = /* @__PURE__ */ new Set();
741
+ function warnLegacy(name) {
742
+ const label = name ?? "anonymous";
743
+ if (warnedLegacyNames.has(label)) return;
744
+ warnedLegacyNames.add(label);
745
+ process.emitWarning(`The plugin "${label}" uses the legacy class/symbol plugin API (Plugin, Client.use(Class), registerXHook), which is deprecated. Port it to definePlugin.`, {
746
+ type: "DeprecationWarning",
747
+ code: "HTTP_FRAMEWORK_LEGACY_PLUGIN"
748
+ });
749
+ }
750
+ function isThenable(value) {
751
+ return typeof value?.then === "function";
752
+ }
753
+ function flatten(option, into) {
754
+ if (!option) return into;
755
+ if (Array.isArray(option)) for (const entry of option) flatten(entry, into);
756
+ else into.push(option);
757
+ return into;
758
+ }
759
+ /**
760
+ * Converts plugin options into hook entries, one per defined hook.
761
+ *
762
+ * @param option The plugin(s) to convert.
763
+ * @returns The entries, in the plugin order and in {@link PluginHook} order inside each plugin.
764
+ */
765
+ function toPluginEntries(option) {
766
+ const entries = [];
767
+ for (const plugin of flatten(option, [])) {
768
+ if (typeof plugin?.name !== "string" || plugin.name === "") throw new TypeError("A plugin must have a non-empty name");
769
+ for (const type of HOOK_NAMES) {
770
+ const hook = plugin[type];
771
+ if (hook === void 0) continue;
772
+ if (typeof hook !== "function") throw new TypeError(`The "${type}" hook of the plugin "${plugin.name}" is not a function`);
773
+ const name = plugin.name;
774
+ const invoker = (client, options) => {
775
+ try {
776
+ const result = hook.call(plugin, client, options);
777
+ return isThenable(result) ? Promise.resolve(result).then(void 0, (error) => {
778
+ throw new PluginHookError(name, type, error);
779
+ }) : result;
780
+ } catch (error) {
781
+ throw new PluginHookError(name, type, error);
782
+ }
783
+ };
784
+ entries.push({
785
+ hook: function(options) {
786
+ return invoker(this, options);
787
+ },
788
+ run: invoker,
789
+ type,
790
+ name,
791
+ enforce: plugin.enforce,
792
+ apply: plugin.apply,
793
+ plugin
794
+ });
795
+ }
796
+ }
797
+ return entries;
798
+ }
799
+ /**
800
+ * Decides whether an entry applies. A function is called once per plugin per `decisions` map (one per client) and its
801
+ * answer kept, so every hook of a plugin sees the same decision: a predicate that is not stable cannot leave a plugin
802
+ * half-applied, with its early hooks run and its later ones skipped. The decision is the plugin's own, never shared
803
+ * with another plugin that happens to use the same function, because each is asked with the options it will receive.
804
+ */
805
+ function isApplicable(entry, options, decisions) {
806
+ const { apply } = entry;
807
+ if (apply === void 0) return true;
808
+ if (apply === "development") return process.env.NODE_ENV === "development";
809
+ if (apply === "production") return process.env.NODE_ENV === "production";
810
+ const owner = entry.plugin ?? entry;
811
+ let decision = decisions.get(owner);
812
+ if (decision === void 0) {
813
+ decision = apply(options);
814
+ decisions.set(owner, decision);
815
+ }
816
+ return decision;
817
+ }
818
+ var _PluginManager_brand = /* @__PURE__ */ new WeakSet();
698
819
  var PluginManager = class {
699
820
  constructor() {
821
+ _classPrivateMethodInitSpec(this, _PluginManager_brand);
700
822
  _defineProperty(this, "registry", /* @__PURE__ */ new Set());
701
823
  }
702
824
  registerHook(hook, type, name) {
703
825
  if (typeof hook !== "function") throw new TypeError(`The provided hook ${name ? `(${name}) ` : ""}is not a function`);
826
+ warnLegacy(name);
704
827
  this.registry.add({
705
828
  hook,
829
+ run: (client, options) => hook.call(client, options),
706
830
  type,
707
831
  name
708
832
  });
@@ -723,28 +847,42 @@ var PluginManager = class {
723
847
  registerPostListenHook(hook, name) {
724
848
  return this.registerHook(hook, "postListen", name);
725
849
  }
726
- use(plugin) {
727
- const possibleSymbolHooks = [
728
- [preGenericsInitialization, "preGenericsInitialization"],
729
- [preInitialization, "preInitialization"],
730
- [postInitialization, "postInitialization"],
731
- [preLoad, "preLoad"],
732
- [postListen, "postListen"]
733
- ];
734
- for (const [hookSymbol, hookType] of possibleSymbolHooks) {
735
- const hook = Reflect.get(plugin, hookSymbol);
736
- if (typeof hook !== "function") continue;
737
- this.registerHook(hook, hookType, plugin.name);
738
- }
850
+ /**
851
+ * Registers plugins: {@link StarsPlugin} objects (possibly nested in arrays, with falsy entries dropped) or, for
852
+ * backwards compatibility, legacy {@link Plugin} classes.
853
+ *
854
+ * @param plugins The plugins to register.
855
+ */
856
+ use(...plugins) {
857
+ for (const plugin of plugins) if (typeof plugin === "function") _assertClassBrand(_PluginManager_brand, this, _useLegacy).call(this, plugin);
858
+ else for (const entry of toPluginEntries(plugin)) this.registry.add(entry);
739
859
  return this;
740
860
  }
741
- *values(hook) {
742
- for (const plugin of this.registry) {
743
- if (hook && plugin.type !== hook) continue;
744
- yield plugin;
745
- }
861
+ *values(hook, extra = []) {
862
+ const entries = [...this.registry, ...extra].filter((entry) => !hook || entry.type === hook);
863
+ for (const enforce of [
864
+ "pre",
865
+ void 0,
866
+ "post"
867
+ ]) for (const entry of entries) if (entry.enforce === enforce) yield entry;
868
+ }
869
+ /**
870
+ * Like {@link PluginManager.values}, but only the entries whose `apply` accepts the client's options.
871
+ *
872
+ * @param decisions The answers of `apply` functions already given for this client, by plugin. Pass the same map for
873
+ * every phase of one client so a plugin is accepted or rejected as a whole.
874
+ */
875
+ *applicable(hook, options, extra = [], decisions = /* @__PURE__ */ new Map()) {
876
+ for (const entry of this.values(hook, extra)) if (isApplicable(entry, options, decisions)) yield entry;
746
877
  }
747
878
  };
879
+ function _useLegacy(plugin) {
880
+ for (const [hookSymbol, hookType] of LEGACY_SYMBOLS) {
881
+ const hook = Reflect.get(plugin, hookSymbol);
882
+ if (typeof hook !== "function") continue;
883
+ this.registerHook(hook, hookType, plugin.name);
884
+ }
885
+ }
748
886
 
749
887
  //#endregion
750
888
  //#region src/lib/utils/decorators.ts
@@ -1083,12 +1221,6 @@ function getLinkedMethod(object) {
1083
1221
  return Reflect.get(object, linkSymbol) ?? null;
1084
1222
  }
1085
1223
 
1086
- //#endregion
1087
- //#region \0@oxc-project+runtime@0.151.0/helpers/esm/classPrivateMethodInitSpec.js
1088
- function _classPrivateMethodInitSpec(e, a) {
1089
- _checkPrivateRedeclaration(e, a), a.add(e);
1090
- }
1091
-
1092
1224
  //#endregion
1093
1225
  //#region src/lib/interactions/resolvers/ChatInputCommandResolver.ts
1094
1226
  var _data$1 = /* @__PURE__ */ new WeakMap();
@@ -3900,6 +4032,8 @@ container$1.stores.register(new ListenerStore());
3900
4032
  container$1.logger ??= new Logger();
3901
4033
  var _discordPublicKey = /* @__PURE__ */ new WeakMap();
3902
4034
  var _fetchKey = /* @__PURE__ */ new WeakMap();
4035
+ var _pluginEntries = /* @__PURE__ */ new WeakMap();
4036
+ var _applyDecisions = /* @__PURE__ */ new WeakMap();
3903
4037
  var Client = class Client extends AsyncEventEmitter {
3904
4038
  constructor(options = {}) {
3905
4039
  super();
@@ -3912,19 +4046,22 @@ var Client = class Client extends AsyncEventEmitter {
3912
4046
  _defineProperty(this, "httpReplyOnError", void 0);
3913
4047
  _classPrivateFieldInitSpec(this, _discordPublicKey, void 0);
3914
4048
  _classPrivateFieldInitSpec(this, _fetchKey, null);
4049
+ _classPrivateFieldInitSpec(this, _pluginEntries, void 0);
4050
+ _classPrivateFieldInitSpec(this, _applyDecisions, /* @__PURE__ */ new Map());
3915
4051
  this.options = {
3916
4052
  ...options,
3917
4053
  discordToken: void 0,
3918
4054
  discordPublicKey: void 0
3919
4055
  };
3920
- for (const plugin of Client.plugins.values("preGenericsInitialization")) {
3921
- plugin.hook.call(this, this.options);
4056
+ _classPrivateFieldSet2(_pluginEntries, this, toPluginEntries(options.plugins));
4057
+ for (const plugin of Client.plugins.applicable("preGenericsInitialization", this.options, _classPrivateFieldGet2(_pluginEntries, this), _classPrivateFieldGet2(_applyDecisions, this))) {
4058
+ plugin.run(this, this.options);
3922
4059
  this.emit("pluginLoaded", plugin.type, plugin.name);
3923
4060
  }
3924
4061
  this.logger = this.options.logger?.instance ?? new Logger(this.options.logger?.level ?? 30);
3925
4062
  container$1.logger = this.logger;
3926
- for (const plugin of Client.plugins.values("preInitialization")) {
3927
- plugin.hook.call(this, this.options);
4063
+ for (const plugin of Client.plugins.applicable("preInitialization", this.options, _classPrivateFieldGet2(_pluginEntries, this), _classPrivateFieldGet2(_applyDecisions, this))) {
4064
+ plugin.run(this, this.options);
3928
4065
  this.emit("pluginLoaded", plugin.type, plugin.name);
3929
4066
  }
3930
4067
  this.bodySizeLimit = options.bodySizeLimit ?? 1048576;
@@ -3944,19 +4081,20 @@ var Client = class Client extends AsyncEventEmitter {
3944
4081
  rest: container$1.rest,
3945
4082
  authPrefix: options.authPrefix
3946
4083
  });
3947
- for (const plugin of Client.plugins.values("postInitialization")) {
3948
- plugin.hook.call(this, this.options);
4084
+ for (const plugin of Client.plugins.applicable("postInitialization", this.options, _classPrivateFieldGet2(_pluginEntries, this), _classPrivateFieldGet2(_applyDecisions, this))) {
4085
+ plugin.run(this, this.options);
3949
4086
  this.emit("pluginLoaded", plugin.type, plugin.name);
3950
4087
  }
3951
4088
  }
3952
4089
  /**
3953
- * Registers a plugin onto the {@link Client}, applying all of its hooks.
4090
+ * Registers plugins onto the {@link Client}, applying all of their hooks. Accepts {@link StarsPlugin} objects
4091
+ * (see {@link definePlugin}) and, deprecated, legacy {@link Plugin} classes.
3954
4092
  *
3955
4093
  * @since 2.4.0
3956
- * @param plugin The plugin to register.
4094
+ * @param plugins The plugins to register.
3957
4095
  */
3958
- static use(plugin) {
3959
- this.plugins.use(plugin);
4096
+ static use(...plugins) {
4097
+ this.plugins.use(...plugins);
3960
4098
  return this;
3961
4099
  }
3962
4100
  /**
@@ -3973,8 +4111,8 @@ var Client = class Client extends AsyncEventEmitter {
3973
4111
  * @param options The load options.
3974
4112
  */
3975
4113
  async load(options = {}) {
3976
- for (const plugin of Client.plugins.values("preLoad")) {
3977
- await plugin.hook.call(this, this.options);
4114
+ for (const plugin of Client.plugins.applicable("preLoad", this.options, _classPrivateFieldGet2(_pluginEntries, this), _classPrivateFieldGet2(_applyDecisions, this))) {
4115
+ await plugin.run(this, this.options);
3978
4116
  this.emit("pluginLoaded", plugin.type, plugin.name);
3979
4117
  }
3980
4118
  if (options.baseUserDirectory !== null) container$1.stores.registerPath(options.baseUserDirectory);
@@ -3999,8 +4137,8 @@ var Client = class Client extends AsyncEventEmitter {
3999
4137
  host: address
4000
4138
  }, resolve));
4001
4139
  try {
4002
- for (const plugin of Client.plugins.values("postListen")) {
4003
- await plugin.hook.call(this, this.options);
4140
+ for (const plugin of Client.plugins.applicable("postListen", this.options, _classPrivateFieldGet2(_pluginEntries, this), _classPrivateFieldGet2(_applyDecisions, this))) {
4141
+ await plugin.run(this, this.options);
4004
4142
  this.emit("pluginLoaded", plugin.type, plugin.name);
4005
4143
  }
4006
4144
  } catch (error) {
@@ -4210,5 +4348,5 @@ function toPermissionNames(bits) {
4210
4348
  }
4211
4349
 
4212
4350
  //#endregion
4213
- export { AliasPiece, AliasStore, ApplicationCommandRegistry, ApplicationCommandRegistryEntry, ArgumentError, AutocompleteInteraction, BaseInteraction, ChatInputCommandInteraction, ChatInputRouterError, ChatInputRouterErrors, Client, Command, CommandInteraction, CommandLoaderStrategy, CommandRegistry, CommandRouter, CommandStore, CommandStoreRouter, Events, HotModuleReloader, HttpCodes, Identifiers, InteractionHandler, InteractionHandlerStore, Listener, ListenerLoaderStrategy, ListenerStore, LoaderError, LogLevel, Logger, Message, MessageComponentButtonInteraction, MessageComponentChannelSelectInteraction, MessageComponentInteraction, MessageComponentMentionableSelectInteraction, MessageComponentRoleSelectInteraction, MessageComponentStringSelectInteraction as MessageComponentSelectMenuInteraction, MessageComponentStringSelectInteraction, MessageComponentUserSelectInteraction, MessageContextMenuCommandInteraction, MissingExportsError, ModalSubmitInteraction, PartialMessage, Piece, Plugin, PluginHook, PluginManager, PreconditionError, RegisterCommand, RegisterMessageCommand, RegisterSubcommand, RegisterSubcommandGroup, RegisterUserCommand, RestrictGuildIds, Store, StoreRegistry, StringIdParser, UserContextMenuCommandInteraction, UserError, applicationCommandRegistry, container, extractTopLevelOptions, getMissingPermissions, makeInteraction, postInitialization, postListen, preGenericsInitialization, preInitialization, preLoad, resolvePermissions, restrictedGuildIdRegistry, toPermissionNames, transformAutocompleteInteraction, transformInteraction, transformMessageInteraction, transformUserInteraction };
4351
+ export { AliasPiece, AliasStore, ApplicationCommandRegistry, ApplicationCommandRegistryEntry, ArgumentError, AutocompleteInteraction, BaseInteraction, ChatInputCommandInteraction, ChatInputRouterError, ChatInputRouterErrors, Client, Command, CommandInteraction, CommandLoaderStrategy, CommandRegistry, CommandRouter, CommandStore, CommandStoreRouter, Events, HotModuleReloader, HttpCodes, Identifiers, InteractionHandler, InteractionHandlerStore, Listener, ListenerLoaderStrategy, ListenerStore, LoaderError, LogLevel, Logger, Message, MessageComponentButtonInteraction, MessageComponentChannelSelectInteraction, MessageComponentInteraction, MessageComponentMentionableSelectInteraction, MessageComponentRoleSelectInteraction, MessageComponentStringSelectInteraction as MessageComponentSelectMenuInteraction, MessageComponentStringSelectInteraction, MessageComponentUserSelectInteraction, MessageContextMenuCommandInteraction, MissingExportsError, ModalSubmitInteraction, PartialMessage, Piece, Plugin, PluginHook, PluginHookError, PluginManager, PreconditionError, RegisterCommand, RegisterMessageCommand, RegisterSubcommand, RegisterSubcommandGroup, RegisterUserCommand, RestrictGuildIds, Store, StoreRegistry, StringIdParser, UserContextMenuCommandInteraction, UserError, applicationCommandRegistry, container, definePlugin, extractTopLevelOptions, getMissingPermissions, makeInteraction, postInitialization, postListen, preGenericsInitialization, preInitialization, preLoad, resolvePermissions, restrictedGuildIdRegistry, toPermissionNames, toPluginEntries, transformAutocompleteInteraction, transformInteraction, transformMessageInteraction, transformUserInteraction };
4214
4352
  //# sourceMappingURL=index.js.map