@fraqjs/fraq 0.9.0 → 0.9.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/dist/index.d.mts CHANGED
@@ -5514,6 +5514,9 @@ interface Command<P extends Pattern> {
5514
5514
  name: string;
5515
5515
  pattern: P;
5516
5516
  execute: Executor<P>;
5517
+ description?: string;
5518
+ aliases?: string[];
5519
+ hidden?: boolean;
5517
5520
  }
5518
5521
  interface RawPattern<P extends Pattern> {
5519
5522
  pattern: P;
@@ -5528,6 +5531,9 @@ declare class CommandBuilder<P extends Pattern = {}, S = Command<P>> {
5528
5531
  private readonly sink;
5529
5532
  private readonly pattern;
5530
5533
  private executor?;
5534
+ private description?;
5535
+ private aliases?;
5536
+ private hidden?;
5531
5537
  constructor(name: string, sink?: (command: Command<P>) => S);
5532
5538
  arg<K extends string, T>(
5533
5539
  key: K,
@@ -5540,6 +5546,9 @@ declare class CommandBuilder<P extends Pattern = {}, S = Command<P>> {
5540
5546
  ? RawPattern<P & { [K2 in K]: Parameter<T> }>
5541
5547
  : S
5542
5548
  >;
5549
+ describe(description: string): CommandBuilder<P, S>;
5550
+ alias(...aliases: string[]): CommandBuilder<P, S>;
5551
+ hide(): CommandBuilder<P, S>;
5543
5552
  execute(executor: Executor<P>): S;
5544
5553
  }
5545
5554
  //#endregion
@@ -5598,6 +5607,7 @@ declare class Router {
5598
5607
  group(name: string): Router;
5599
5608
  filter(predicate: SessionPredicate): Router;
5600
5609
  routes(): RouteEntry[];
5610
+ aliasesOf(name: string): string[];
5601
5611
  branches(session: Session): RouteBranch[];
5602
5612
  match(session: Session, message: IncomingMessage): RouteMatchResult | undefined;
5603
5613
  dispatch(session: Session, message: IncomingMessage): Promise<boolean>;
@@ -5607,6 +5617,7 @@ declare class Router {
5607
5617
  private matchGroup;
5608
5618
  private matchRawPattern;
5609
5619
  private branchesFrom;
5620
+ private resolveAliasConflicts;
5610
5621
  private validatePattern;
5611
5622
  private capturePattern;
5612
5623
  }
package/dist/index.mjs CHANGED
@@ -70,6 +70,9 @@ var CommandBuilder = class {
70
70
  sink;
71
71
  pattern = {};
72
72
  executor;
73
+ description;
74
+ aliases;
75
+ hidden;
73
76
  constructor(name, sink = (command) => command) {
74
77
  this.name = name;
75
78
  this.sink = sink;
@@ -78,6 +81,19 @@ var CommandBuilder = class {
78
81
  this.pattern[key] = parameter;
79
82
  return this;
80
83
  }
84
+ describe(description) {
85
+ this.description = description;
86
+ return this;
87
+ }
88
+ alias(...aliases) {
89
+ if (!this.aliases) this.aliases = [];
90
+ this.aliases.push(...aliases);
91
+ return this;
92
+ }
93
+ hide() {
94
+ this.hidden = true;
95
+ return this;
96
+ }
81
97
  execute(executor) {
82
98
  this.executor = executor;
83
99
  const command = {
@@ -85,6 +101,9 @@ var CommandBuilder = class {
85
101
  pattern: this.pattern,
86
102
  execute: this.executor
87
103
  };
104
+ if (this.description !== void 0) command.description = this.description;
105
+ if (this.aliases !== void 0) command.aliases = this.aliases;
106
+ if (this.hidden !== void 0) command.hidden = this.hidden;
88
107
  return this.sink(command);
89
108
  }
90
109
  };
@@ -222,6 +241,7 @@ var Router = class Router {
222
241
  return builtCommand;
223
242
  });
224
243
  this.validatePattern(command.pattern);
244
+ this.resolveAliasConflicts(command);
225
245
  this.entries.push({
226
246
  type: "command",
227
247
  command
@@ -265,6 +285,10 @@ var Router = class Router {
265
285
  routes() {
266
286
  return this.entries;
267
287
  }
288
+ aliasesOf(name) {
289
+ for (const entry of this.entries) if (entry.type === "command" && entry.command.name === name) return entry.command.aliases ? [...entry.command.aliases] : [];
290
+ return [];
291
+ }
268
292
  branches(session) {
269
293
  return this.branchesFrom(session, []);
270
294
  }
@@ -306,7 +330,7 @@ var Router = class Router {
306
330
  }
307
331
  matchCommand(command, tokenizer, path) {
308
332
  const token = tokenizer.peek();
309
- if (typeof token !== "string" || token !== command.name) return;
333
+ if (typeof token !== "string" || token !== command.name && !command.aliases?.includes(token)) return;
310
334
  tokenizer.next();
311
335
  const params = this.capturePattern(command.pattern, tokenizer);
312
336
  if (params === void 0 || tokenizer.hasNext()) return;
@@ -337,7 +361,7 @@ var Router = class Router {
337
361
  const branches = [];
338
362
  for (const entry of this.entries) switch (entry.type) {
339
363
  case "command":
340
- branches.push({
364
+ if (!entry.command.hidden) branches.push({
341
365
  type: "command",
342
366
  path: [...path],
343
367
  command: entry.command
@@ -359,6 +383,27 @@ var Router = class Router {
359
383
  }
360
384
  return branches;
361
385
  }
386
+ resolveAliasConflicts(command) {
387
+ for (const entry of this.entries) {
388
+ if (entry.type !== "command") continue;
389
+ const existing = entry.command;
390
+ if (existing.aliases?.includes(command.name)) {
391
+ existing.aliases = existing.aliases.filter((a) => a !== command.name);
392
+ console.warn(`Command "${command.name}" conflicts with alias of existing command "${existing.name}". The alias "${command.name}" has been removed from "${existing.name}".`);
393
+ }
394
+ if (command.aliases) {
395
+ const dropped = [];
396
+ for (const alias of command.aliases) if (existing.name === alias) {
397
+ dropped.push(alias);
398
+ console.warn(`Alias "${alias}" of command "${command.name}" conflicts with existing command name "${existing.name}". The alias has been dropped.`);
399
+ } else if (existing.aliases?.includes(alias)) {
400
+ existing.aliases = existing.aliases.filter((a) => a !== alias);
401
+ console.warn(`Alias "${alias}" of command "${command.name}" conflicts with alias of existing command "${existing.name}". The alias has been removed from "${existing.name}".`);
402
+ }
403
+ if (dropped.length > 0) command.aliases = command.aliases.filter((a) => !dropped.includes(a));
404
+ }
405
+ }
406
+ }
362
407
  validatePattern(pattern, options) {
363
408
  const entries = Object.entries(pattern);
364
409
  if (options?.rawPattern && entries.length === 0) throw new Error("Raw pattern must have at least one parameter.");
@@ -681,7 +726,15 @@ and implement the dispose method to clean up resources when the context stops.
681
726
  for (const installedPlugin of sortedPlugins) {
682
727
  const { plugin, args } = installedPlugin;
683
728
  const providedBeforeApply = new Set(this.services.keys());
684
- this.logger.debug(`Applying plugin ${plugin.name}`);
729
+ let debugMessage = `Applying plugin ${plugin.name}`;
730
+ const requiredServices = [];
731
+ const providedServices = [];
732
+ if (plugin.requires) for (const service of plugin.requires) requiredServices.push(service.name);
733
+ if (plugin.optionalRequires) for (const service of plugin.optionalRequires) requiredServices.push(`${service.name}?`);
734
+ if (plugin.provides) for (const service of plugin.provides) providedServices.push(service.name);
735
+ if (requiredServices.length > 0) debugMessage += `, requires: [${requiredServices.join(", ")}]`;
736
+ if (providedServices.length > 0) debugMessage += `, provides: [${providedServices.join(", ")}]`;
737
+ this.logger.debug(debugMessage);
685
738
  await plugin.apply(this.getPluginContext(installedPlugin), ...args);
686
739
  for (const service of plugin.provides ?? []) if (!this.services.has(service) || providedBeforeApply.has(service)) throw new Error(`${plugin.name} declares service ${service.name} but did not provide it.`);
687
740
  }
@@ -780,10 +833,6 @@ and implement the dispose method to clean up resources when the context stops.
780
833
  }
781
834
  createProxyContextForPlugin(plugin) {
782
835
  const proxyLogger = new Logger((message) => this.logHandler?.(message), plugin.name);
783
- const proxyProvide = (service, instance) => {
784
- this.provide(service, instance);
785
- this.logger.debug(`Plugin ${plugin.name} provided ${service.name}`);
786
- };
787
836
  let proxyInjections;
788
837
  if (plugin.inject) {
789
838
  proxyInjections = {};
@@ -795,7 +844,6 @@ and implement the dispose method to clean up resources when the context stops.
795
844
  }
796
845
  return new Proxy(this, { get(target, prop, receiver) {
797
846
  if (prop === "logger") return proxyLogger;
798
- else if (prop === "provide") return proxyProvide;
799
847
  else if (proxyInjections && prop in proxyInjections) return proxyInjections[prop];
800
848
  else return Reflect.get(target, prop, receiver);
801
849
  } });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fraqjs/fraq",
3
3
  "type": "module",
4
- "version": "0.9.0",
4
+ "version": "0.9.1",
5
5
  "description": "Milky Bot framework",
6
6
  "files": [
7
7
  "dist"