util.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import { GuildMember } from "discord.js";
  2. import { getRepository, In } from "typeorm";
  3. import { KnownUser } from "@shared/db/entity/KnownUser";
  4. import humanizeDuration from "humanize-duration";
  5. const VALID_EXTENSIONS = new Set([
  6. "png",
  7. "jpg",
  8. "jpeg",
  9. "bmp",
  10. ]);
  11. export type EsModuleClass<T> = { prototype: T; new(...params: unknown[]): T; };
  12. export function isModuleClass<T>(obj: unknown) : obj is EsModuleClass<T> {
  13. return Object.prototype.hasOwnProperty.call(obj, "prototype");
  14. }
  15. export function isDevelopment(): boolean {
  16. return process.env.NODE_ENV == "dev";
  17. }
  18. export function isValidImage(fileName?: string | null): boolean {
  19. if (!fileName)
  20. return false;
  21. const extPosition = fileName.lastIndexOf(".");
  22. if (extPosition < 0)
  23. return false;
  24. const ext = fileName.substring(extPosition + 1).toLowerCase();
  25. return VALID_EXTENSIONS.has(ext);
  26. }
  27. export async function isAuthorisedAsync(member: GuildMember | null | undefined): Promise<boolean> {
  28. if (!member)
  29. return false;
  30. const repo = getRepository(KnownUser);
  31. const user = await repo.findOne({
  32. where: { userID: member.id },
  33. select: ["canModerate"]
  34. });
  35. if (user && user.canModerate)
  36. return true;
  37. const role = await repo.findOne({
  38. select: ["userID"],
  39. where: {
  40. userID: In(member.roles.cache.keyArray()),
  41. canModerate: true
  42. }
  43. });
  44. if (role)
  45. return true;
  46. return false;
  47. }
  48. export function compareNumbers<T>(prop: (o: T) => number) {
  49. return (a: T, b: T): -1 | 0 | 1 => {
  50. const ap = prop(a);
  51. const bp = prop(b);
  52. if (ap < bp)
  53. return 1;
  54. else if (ap > bp)
  55. return -1;
  56. return 0;
  57. };
  58. }
  59. export type Dict<TVal> = { [key: string]: TVal };
  60. export function getNumberEnums<E>(e : Record<keyof E, number>) : number[] {
  61. return Object.keys(e).filter(k => typeof e[k as keyof E] === "number").map(k => e[k as keyof E]);
  62. }
  63. export function formatString(str: string, vars: Record<string, string>): string {
  64. return Object.keys(vars).filter(s => Object.prototype.hasOwnProperty.call(vars, s)).reduce((s, cur) => s.replace(`{${cur}}`, vars[cur]), str);
  65. }
  66. export function parseArgs(str: string): string[] {
  67. const result: string[] = [];
  68. let quoteMode = false;
  69. let escapeNext = false;
  70. let buffer = "";
  71. for (const char of str) {
  72. if (!escapeNext)
  73. if (char == "\"") {
  74. if (!quoteMode) {
  75. quoteMode = true;
  76. } else {
  77. quoteMode = false;
  78. result.push(buffer);
  79. buffer = "";
  80. }
  81. continue;
  82. } else if (char == "\\") {
  83. escapeNext = true;
  84. continue;
  85. } else if (/\s/.test(char)) {
  86. if (buffer.length == 0)
  87. continue;
  88. if (!quoteMode) {
  89. result.push(buffer);
  90. buffer = "";
  91. continue;
  92. }
  93. }
  94. buffer += char;
  95. escapeNext = false;
  96. }
  97. if (buffer.length != 0)
  98. result.push(buffer);
  99. return result;
  100. }
  101. export const UNIT_MEASURES: humanizeDuration.UnitMeasuresOptions = {
  102. ms: 1,
  103. s: 1000,
  104. m: 60 * 1000,
  105. h: 60 * 60 * 1000,
  106. d: 24 * 60 * 60 * 1000,
  107. w: 7 * 24 * 60 * 60 * 1000,
  108. mo: 30 * 24 * 60 * 60 * 1000,
  109. y: 365 * 24 * 60 * 60 * 1000
  110. };
  111. const durationUnits = UNIT_MEASURES as Record<string, number>;
  112. const durationPattern = new RegExp(`(\\d+(?:[.,]?\\d+)?)\\s*(${Object.keys(durationUnits).sort((a, b) => b.length - a.length).join("|")})`, "g");
  113. export function parseDuration(s: string): number | undefined {
  114. if (!s)
  115. return undefined;
  116. s = s.trim();
  117. let buffer = s;
  118. let result = 0;
  119. let match;
  120. while ((match = durationPattern.exec(s))) {
  121. buffer = buffer.replace(match[0], "").trim();
  122. result += +match[1] * durationUnits[match[2]];
  123. }
  124. if (buffer.length != 0)
  125. return undefined;
  126. return result;
  127. }