diff --git a/package.json b/package.json index 75100f5f0..53eda65d8 100644 --- a/package.json +++ b/package.json @@ -53,8 +53,8 @@ "@types/react": "~18.2.79", "@types/react-dom": "~18.2.25", "@types/yazl": "^2.4.5", - "@typescript-eslint/eslint-plugin": "^7.15.0", - "@typescript-eslint/parser": "^7.15.0", + "@typescript-eslint/eslint-plugin": "^7.16.0", + "@typescript-eslint/parser": "^7.16.0", "@vencord/discord-types": "workspace:^", "diff": "^5.2.0", "discord-types": "^1.3.3", diff --git a/packages/discord-types/package.json b/packages/discord-types/package.json index ae47ae06f..9152303f2 100644 --- a/packages/discord-types/package.json +++ b/packages/discord-types/package.json @@ -33,7 +33,7 @@ "@stylistic/eslint-plugin": "^2.3.0", "@types/node": "^20.14.10", "@types/semver": "^7.5.8", - "@typescript-eslint/typescript-estree": "^8.0.0-alpha.39", + "@typescript-eslint/typescript-estree": "^8.0.0-alpha.41", "eslint": "^9.6.0", "eslint-plugin-check-file": "^2.8.0", "eslint-plugin-headers": "^1.1.2", @@ -45,6 +45,6 @@ "semver": "^7.6.2", "tsx": "^4.16.2", "typescript": "^5.5.3", - "typescript-eslint": "^8.0.0-alpha.39" + "typescript-eslint": "^8.0.0-alpha.41" } } diff --git a/packages/discord-types/scripts/changeReporter/finds.mts b/packages/discord-types/scripts/changeReporter/finds.mts new file mode 100644 index 000000000..5758f67e7 --- /dev/null +++ b/packages/discord-types/scripts/changeReporter/finds.mts @@ -0,0 +1,372 @@ +/* + * discord-types + * Copyright (C) 2024 Vencord project contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +// eslint-disable-next-line import/no-relative-packages +import type * as Vencord from "../../../../src/Vencord.ts"; +import type { CR } from "./types.mts"; + +export function autoFindStore(this: typeof Vencord, name: string, source: CR.ClassMembers) { + const persistKeyRE = new RegExp(`^${name}(?:V\\d+)?$`); + + const store: { constructor: CR.Class; } | undefined = this.Webpack.find((exp: any) => { + // Find stores from exported instances + const { constructor } = exp; + return typeof constructor === "function" && ( + constructor.displayName === name + || persistKeyRE.test(constructor.persistKey) + ); + }); + + if (store) + return getClassChanges(store.constructor, source); +} + +export function autoFindClass(this: typeof Vencord, source: CR.ClassMembers) { + let bestMatch: CR.ClassChanges | undefined; + let lowestChangedCount = Infinity; + + const checked = new WeakSet(); + this.Webpack.find((exps: any) => { + for (const name in exps) { + let constructor: CR.Class; + // Some getters throw errors + try { + // Find classes from exported constructors + if (isValidClass(exps[name])) + constructor = exps[name]; + // Find classes from exported instances + else if (isValidClass(exps[name]?.constructor)) + ({ constructor } = exps[name]); + else + continue; + } catch { + continue; + } + + if (!checked.has(constructor)) { + checked.add(constructor); + + const changes = getClassChanges(constructor, source); + const { changedCount } = changes; + if (changedCount < lowestChangedCount) { + lowestChangedCount = changedCount; + bestMatch = changes; + } + } + } + + return false; + }, { isIndirect: true }); + + return bestMatch; +} + +export function isValidClass(constructor: unknown): constructor is CR.Class { + if (typeof constructor !== "function") + return false; + const { prototype } = constructor; + return typeof prototype === "object" && prototype !== null; +} + +export function getClassChanges( + constructors: [CR.Class, ...CR.Class[]] | CR.Class, + source: CR.ClassMembers +): CR.ClassChanges { + if (!Array.isArray(constructors)) + constructors = [constructors]; + + let hasConstructorDefinition = false; + + const constructorKeys = new Set(); + const constructorDescriptors = new Map(); + + const prototypeKeys = new Set(); + const prototypeDescriptors = new Map(); + + const matchedFields = new Set(); + + // Ignore constructor definitions without parameters + const constructorRE = /[{}]constructor\([^)]/; + const fieldRE = /(?<=[{}]constructor\(.+?{.+\(this,")[^"]+(?=",)/g; + for (const constructor of constructors) { + const constructorString = constructor.toString(); + + if (constructorRE.test(constructorString)) + hasConstructorDefinition = true; + + const constDescriptors = Object.getOwnPropertyDescriptors(constructor); + for (const key of Object.getOwnPropertyNames(constructor)) { + constructorKeys.add(key); + constructorDescriptors.set(key, constDescriptors[key]!); + } + for (const key of Object.getOwnPropertySymbols(constructor)) { + constructorKeys.add(key); + constructorDescriptors.set(key, constDescriptors[key]!); + } + + const { prototype } = constructor; + const protoDescriptors = Object.getOwnPropertyDescriptors(prototype); + for (const key of Object.getOwnPropertyNames(prototype)) { + prototypeKeys.add(key); + prototypeDescriptors.set(key, protoDescriptors[key]!); + } + for (const key of Object.getOwnPropertySymbols(prototype)) { + prototypeKeys.add(key); + prototypeDescriptors.set(key, protoDescriptors[key]!); + } + + for (const [field] of constructorString.matchAll(fieldRE)) + matchedFields.add(field); + } + + const additions: CR.ClassMembers = { + constructorDefinition: false, + staticMethodsAndFields: [], + staticGetters: [], + staticSetters: [], + methods: [], + getters: [], + setters: [], + fields: [] + }; + let unchangedCount = 0; + let changedCount = 0; + + // Constructor definition with parameters removal + let constructorDefinition = false; + + if (hasConstructorDefinition) { + if (source.constructorDefinition) { + unchangedCount++; + } else { + additions.constructorDefinition = true; + changedCount++; + } + } else if (source.constructorDefinition) { + constructorDefinition = true; + changedCount++; + } else { + unchangedCount++; + } + + // Static member removals + const staticMethodsAndFields = new Set(source.staticMethodsAndFields); + const staticGetters = new Set(source.staticGetters); + const staticSetters = new Set(source.staticSetters); + + const ignoredConstructorKeys = new Set(["length", "name", "prototype"]); + for (const rawKey of constructorKeys) { + if (ignoredConstructorKeys.has(rawKey)) continue; + + const descriptor = constructorDescriptors.get(rawKey)!; + const key = rawKey.toString(); + + if (descriptor.get) { + if (staticGetters.has(key)) { + staticGetters.delete(key); + unchangedCount++; + } else { + additions.staticGetters.push(key); + changedCount++; + } + + if (descriptor.set) { + if (staticSetters.has(key)) { + staticSetters.delete(key); + unchangedCount++; + } else { + additions.staticSetters.push(key); + changedCount++; + } + } + + continue; + } + + if (descriptor.set) { + if (staticSetters.has(key)) { + staticSetters.delete(key); + unchangedCount++; + } else { + additions.staticSetters.push(key); + changedCount++; + } + continue; + } + + if (staticMethodsAndFields.has(key)) { + staticMethodsAndFields.delete(key); + unchangedCount++; + } else { + additions.staticMethodsAndFields.push(key); + changedCount++; + } + } + + changedCount += staticMethodsAndFields.size + staticGetters.size + staticSetters.size; + + // Instance method and accessor removals + const methods = new Set(source.methods); + const getters = new Set(source.getters); + const setters = new Set(source.setters); + + const ignoredPrototypeKeys = new Set(["constructor"]); + for (const rawKey of prototypeKeys) { + if (ignoredPrototypeKeys.has(rawKey)) continue; + + const descriptor = prototypeDescriptors.get(rawKey)!; + const key = rawKey.toString(); + + if (descriptor.get) { + if (getters.has(key)) { + getters.delete(key); + unchangedCount++; + } else { + additions.getters.push(key); + changedCount++; + } + + if (descriptor.set) { + if (setters.has(key)) { + setters.delete(key); + unchangedCount++; + } else { + additions.setters.push(key); + changedCount++; + } + } + + continue; + } + + if (descriptor.set) { + if (setters.has(key)) { + setters.delete(key); + unchangedCount++; + } else { + additions.setters.push(key); + changedCount++; + } + continue; + } + + if (methods.has(key)) { + methods.delete(key); + unchangedCount++; + } else { + additions.methods.push(key); + changedCount++; + } + } + + changedCount += methods.size + getters.size + setters.size; + + // Field removals + const fields = new Set(source.fields); + + for (const field of matchedFields) { + if (fields.has(field)) { + fields.delete(field); + unchangedCount++; + } else { + additions.fields.push(field); + changedCount++; + } + } + + changedCount += fields.size; + + return { + additions, + removals: { + constructorDefinition, + staticMethodsAndFields: [...staticMethodsAndFields], + staticGetters: [...staticGetters], + staticSetters: [...staticSetters], + methods: [...methods], + getters: [...getters], + setters: [...setters], + fields: [...fields] + }, + unchangedCount, + changedCount + }; +} + +export function autoFindEnum(this: typeof Vencord, source: CR.EnumSource) { + let bestMatch: CR.EnumChanges | undefined; + let lowestChangedCount = Infinity; + + const checked = new WeakSet(); + this.Webpack.find((exps: any) => { + for (const name in exps) { + let exp: unknown; + // Some getters throw errors + try { + exp = exps[name]; + } catch { + continue; + } + + if (isValidEnum(exp) && !checked.has(exp)) { + checked.add(exp); + + const changes = getEnumChanges(exp, source); + const { changedCount } = changes; + if (changedCount < lowestChangedCount) { + lowestChangedCount = changedCount; + bestMatch = changes; + } + } + } + + return false; + }, { isIndirect: true }); + + return bestMatch; +} + +export function isValidEnum(obj: unknown): obj is CR.EnumMembers { + return typeof obj === "object" + && obj !== null + && !Array.isArray(obj); +} + +export function getEnumChanges(obj: CR.EnumMembers, source: CR.EnumSource): CR.EnumChanges { + const additions: CR.EnumMembers = {}; + const removals: CR.EnumMembers = { ...source }; + let unchangedCount = 0; + let changedCount = 0; + + for (const key in obj) { + // Ignore numeric enum reverse mapping + if (parseFloat(key) === Number(key)) continue; + + // Some getters throw errors + try { + const value = obj[key]!; + if (key in source && value === source[key]) { + delete removals[key]; + unchangedCount++; + } else { + additions[key] = value; + changedCount++; + } + } catch { + changedCount = Infinity; + break; + } + } + + changedCount += Object.keys(removals).length; + + return { + additions, + removals, + unchangedCount, + changedCount + }; +} diff --git a/packages/discord-types/scripts/changeReporter/getChangeReport.mts b/packages/discord-types/scripts/changeReporter/getChangeReport.mts index 07a0f0e11..9c3de04c4 100644 --- a/packages/discord-types/scripts/changeReporter/getChangeReport.mts +++ b/packages/discord-types/scripts/changeReporter/getChangeReport.mts @@ -13,8 +13,8 @@ import { satisfies, subset, valid, validRange } from "semver"; import type { JsonObject, JsonValue } from "type-fest"; import { config } from "./config.mjs"; +import type { autoFindClass, autoFindEnum, autoFindStore } from "./finds.mts"; import type { CR } from "./types.mts"; -import type { autoFindClass, autoFindEnum, autoFindStore } from "./utils.mts"; export async function getChangeReport(page: Page): Promise { const { rootDir, deps, src } = config; @@ -290,7 +290,7 @@ async function getClassReport( changes.unchangedCount > 1 || changes.unchangedCount > 0 && (changes.additions.constructorDefinition - || changes.removals.constructorDefinition) + || changes.removals.constructorDefinition) ) { checkClassIgnores(changes, config, report); report.changes = changes; diff --git a/packages/discord-types/scripts/changeReporter/index.mts b/packages/discord-types/scripts/changeReporter/index.mts index 2a15b2d51..cf2f64216 100644 --- a/packages/discord-types/scripts/changeReporter/index.mts +++ b/packages/discord-types/scripts/changeReporter/index.mts @@ -9,12 +9,18 @@ import { join } from "path"; import puppeteer from "puppeteer-core"; -import { validateEnv } from "../utils.mjs"; +import { assertEnvValidity } from "../utils.mjs"; +import { autoFindClass, autoFindEnum, autoFindStore, getClassChanges, getEnumChanges, isValidClass, isValidEnum } from "./finds.mjs"; import { getChangeReport } from "./getChangeReport.mjs"; import { logSummary } from "./logSummary.mjs"; -import { autoFindClass, autoFindEnum, autoFindStore, getClassChanges, getEnumChanges, isValidClass, isValidEnum } from "./utils.mjs"; +import { postError, postReport } from "./webhooks.mjs"; -validateEnv(process.env, { +process.on("uncaughtExceptionMonitor", error => { + const { DISCORD_WEBHOOK, CHANNEL } = process.env; + postError(error, DISCORD_WEBHOOK, CHANNEL); +}); + +assertEnvValidity(process.env, { CHANNEL: ["stable", "ptb", "canary"], CHROMIUM_BIN: true, DISCORD_TOKEN: true, @@ -69,6 +75,5 @@ browser.close(); logSummary(report, CHANNEL); -if (DISCORD_WEBHOOK) { - // TODO -} +if (DISCORD_WEBHOOK) + postReport(report, DISCORD_WEBHOOK, CHANNEL); diff --git a/packages/discord-types/scripts/changeReporter/logSummary.mts b/packages/discord-types/scripts/changeReporter/logSummary.mts index 8c670da9d..cc67692f7 100644 --- a/packages/discord-types/scripts/changeReporter/logSummary.mts +++ b/packages/discord-types/scripts/changeReporter/logSummary.mts @@ -5,11 +5,12 @@ */ import type { CR } from "./types.mts"; +import { capitalize, codeBlock, formatChannel, formatEnumEntryList, formatKeyList, formatWarnList } from "./utils.mjs"; -export function logSummary(report: CR.ChangeReport, channel: "stable" | "ptb" | "canary") { +export function logSummary(report: CR.ChangeReport, channel?: string | undefined) { const { deps, src } = report; - let summary = `# Change Report (${channel === "ptb" ? channel.toUpperCase() : capitalize(channel)})\n`; + let summary = `# Change Report (${formatChannel(channel)})\n`; let sections = ""; @@ -77,12 +78,12 @@ export function logSummary(report: CR.ChangeReport, channel: "stable" | "ptb" | section += `* The report for \`${name}\` has ${warns.length} warning${warns.length === 1 ? "" : "s"}:\n` + formatWarnList(warns); - section += `* The report for \`${name}\` has an error:\n` + formatError(error); + section += `* The report for \`${name}\` has an error:\n` + codeBlock(error); } } else section += ". \n"; } else - section += `\`${fileName}\` has a file-level error:\n` + formatError(fileError); + section += `\`${fileName}\` has a file-level error:\n` + codeBlock(fileError); } if (fileToLogCount > 0) { @@ -252,12 +253,12 @@ export function logSummary(report: CR.ChangeReport, channel: "stable" | "ptb" | section += `* The report for ${type} \`${identifier}\` has ${warns.length} warning${warns.length === 1 ? "" : "s"}:\n` + formatWarnList(warns); - section += `* The report for ${type} \`${identifier}\` has an error:\n${formatError(error)}`; + section += `* The report for ${type} \`${identifier}\` has an error:\n` + codeBlock(error); } } else section += ". \n"; } else - section += `\`${fileName}\` has a file-level error:\n${formatError(fileError)}`; + section += `\`${fileName}\` has a file-level error:\n` + codeBlock(fileError); } if (fileToLogCount > 0) { @@ -268,29 +269,7 @@ export function logSummary(report: CR.ChangeReport, channel: "stable" | "ptb" | sections += "### All watched declarations are unchanged without warnings.\n"; } - summary += sections || "## There are 0 watched dependencies and declarations."; + summary += sections || "## There are 0 watched dependencies and declarations.\n"; console.log(summary); } - -function capitalize(string: string) { - return string.replace(/^./, c => c.toUpperCase()); -} - -function formatWarnList(warns: string[]) { - return warns.map(formatError).join(""); -} - -function formatError(error: string) { - return `\`\`\`\n${error}\n\`\`\`\n`; -} - -function formatKeyList(keys: string[], indentLevel = 0) { - const indent = " ".repeat(indentLevel); - return keys.map(key => indent + `* \`${key}\`\n`).join(""); -} - -function formatEnumEntryList(entries: [key: string, value: unknown][], indentLevel = 0) { - const indent = " ".repeat(indentLevel); - return entries.map(([key, value]) => indent + `* \`${key} = ${JSON.stringify(value)}\`\n`).join(""); -} diff --git a/packages/discord-types/scripts/changeReporter/utils.mts b/packages/discord-types/scripts/changeReporter/utils.mts index 5758f67e7..0dc8ecca7 100644 --- a/packages/discord-types/scripts/changeReporter/utils.mts +++ b/packages/discord-types/scripts/changeReporter/utils.mts @@ -4,369 +4,43 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -// eslint-disable-next-line import/no-relative-packages -import type * as Vencord from "../../../../src/Vencord.ts"; -import type { CR } from "./types.mts"; - -export function autoFindStore(this: typeof Vencord, name: string, source: CR.ClassMembers) { - const persistKeyRE = new RegExp(`^${name}(?:V\\d+)?$`); - - const store: { constructor: CR.Class; } | undefined = this.Webpack.find((exp: any) => { - // Find stores from exported instances - const { constructor } = exp; - return typeof constructor === "function" && ( - constructor.displayName === name - || persistKeyRE.test(constructor.persistKey) - ); - }); - - if (store) - return getClassChanges(store.constructor, source); +export function capitalize(string: string) { + return string.replace(/^./, c => c.toUpperCase()); } -export function autoFindClass(this: typeof Vencord, source: CR.ClassMembers) { - let bestMatch: CR.ClassChanges | undefined; - let lowestChangedCount = Infinity; - - const checked = new WeakSet(); - this.Webpack.find((exps: any) => { - for (const name in exps) { - let constructor: CR.Class; - // Some getters throw errors - try { - // Find classes from exported constructors - if (isValidClass(exps[name])) - constructor = exps[name]; - // Find classes from exported instances - else if (isValidClass(exps[name]?.constructor)) - ({ constructor } = exps[name]); - else - continue; - } catch { - continue; - } - - if (!checked.has(constructor)) { - checked.add(constructor); - - const changes = getClassChanges(constructor, source); - const { changedCount } = changes; - if (changedCount < lowestChangedCount) { - lowestChangedCount = changedCount; - bestMatch = changes; - } - } - } - - return false; - }, { isIndirect: true }); - - return bestMatch; +export function codeBlock(content: unknown) { + return `\`\`\`\n${content}\n\`\`\`\n`; } -export function isValidClass(constructor: unknown): constructor is CR.Class { - if (typeof constructor !== "function") - return false; - const { prototype } = constructor; - return typeof prototype === "object" && prototype !== null; -} - -export function getClassChanges( - constructors: [CR.Class, ...CR.Class[]] | CR.Class, - source: CR.ClassMembers -): CR.ClassChanges { - if (!Array.isArray(constructors)) - constructors = [constructors]; - - let hasConstructorDefinition = false; - - const constructorKeys = new Set(); - const constructorDescriptors = new Map(); - - const prototypeKeys = new Set(); - const prototypeDescriptors = new Map(); - - const matchedFields = new Set(); - - // Ignore constructor definitions without parameters - const constructorRE = /[{}]constructor\([^)]/; - const fieldRE = /(?<=[{}]constructor\(.+?{.+\(this,")[^"]+(?=",)/g; - for (const constructor of constructors) { - const constructorString = constructor.toString(); - - if (constructorRE.test(constructorString)) - hasConstructorDefinition = true; - - const constDescriptors = Object.getOwnPropertyDescriptors(constructor); - for (const key of Object.getOwnPropertyNames(constructor)) { - constructorKeys.add(key); - constructorDescriptors.set(key, constDescriptors[key]!); - } - for (const key of Object.getOwnPropertySymbols(constructor)) { - constructorKeys.add(key); - constructorDescriptors.set(key, constDescriptors[key]!); - } - - const { prototype } = constructor; - const protoDescriptors = Object.getOwnPropertyDescriptors(prototype); - for (const key of Object.getOwnPropertyNames(prototype)) { - prototypeKeys.add(key); - prototypeDescriptors.set(key, protoDescriptors[key]!); - } - for (const key of Object.getOwnPropertySymbols(prototype)) { - prototypeKeys.add(key); - prototypeDescriptors.set(key, protoDescriptors[key]!); - } - - for (const [field] of constructorString.matchAll(fieldRE)) - matchedFields.add(field); +export function formatChannel(channel?: string | undefined) { + switch (channel) { + case "stable": + case "canary": + return capitalize(channel); + case "ptb": + return channel.toUpperCase(); + default: + return "Unknown"; } - - const additions: CR.ClassMembers = { - constructorDefinition: false, - staticMethodsAndFields: [], - staticGetters: [], - staticSetters: [], - methods: [], - getters: [], - setters: [], - fields: [] - }; - let unchangedCount = 0; - let changedCount = 0; - - // Constructor definition with parameters removal - let constructorDefinition = false; - - if (hasConstructorDefinition) { - if (source.constructorDefinition) { - unchangedCount++; - } else { - additions.constructorDefinition = true; - changedCount++; - } - } else if (source.constructorDefinition) { - constructorDefinition = true; - changedCount++; - } else { - unchangedCount++; - } - - // Static member removals - const staticMethodsAndFields = new Set(source.staticMethodsAndFields); - const staticGetters = new Set(source.staticGetters); - const staticSetters = new Set(source.staticSetters); - - const ignoredConstructorKeys = new Set(["length", "name", "prototype"]); - for (const rawKey of constructorKeys) { - if (ignoredConstructorKeys.has(rawKey)) continue; - - const descriptor = constructorDescriptors.get(rawKey)!; - const key = rawKey.toString(); - - if (descriptor.get) { - if (staticGetters.has(key)) { - staticGetters.delete(key); - unchangedCount++; - } else { - additions.staticGetters.push(key); - changedCount++; - } - - if (descriptor.set) { - if (staticSetters.has(key)) { - staticSetters.delete(key); - unchangedCount++; - } else { - additions.staticSetters.push(key); - changedCount++; - } - } - - continue; - } - - if (descriptor.set) { - if (staticSetters.has(key)) { - staticSetters.delete(key); - unchangedCount++; - } else { - additions.staticSetters.push(key); - changedCount++; - } - continue; - } - - if (staticMethodsAndFields.has(key)) { - staticMethodsAndFields.delete(key); - unchangedCount++; - } else { - additions.staticMethodsAndFields.push(key); - changedCount++; - } - } - - changedCount += staticMethodsAndFields.size + staticGetters.size + staticSetters.size; - - // Instance method and accessor removals - const methods = new Set(source.methods); - const getters = new Set(source.getters); - const setters = new Set(source.setters); - - const ignoredPrototypeKeys = new Set(["constructor"]); - for (const rawKey of prototypeKeys) { - if (ignoredPrototypeKeys.has(rawKey)) continue; - - const descriptor = prototypeDescriptors.get(rawKey)!; - const key = rawKey.toString(); - - if (descriptor.get) { - if (getters.has(key)) { - getters.delete(key); - unchangedCount++; - } else { - additions.getters.push(key); - changedCount++; - } - - if (descriptor.set) { - if (setters.has(key)) { - setters.delete(key); - unchangedCount++; - } else { - additions.setters.push(key); - changedCount++; - } - } - - continue; - } - - if (descriptor.set) { - if (setters.has(key)) { - setters.delete(key); - unchangedCount++; - } else { - additions.setters.push(key); - changedCount++; - } - continue; - } - - if (methods.has(key)) { - methods.delete(key); - unchangedCount++; - } else { - additions.methods.push(key); - changedCount++; - } - } - - changedCount += methods.size + getters.size + setters.size; - - // Field removals - const fields = new Set(source.fields); - - for (const field of matchedFields) { - if (fields.has(field)) { - fields.delete(field); - unchangedCount++; - } else { - additions.fields.push(field); - changedCount++; - } - } - - changedCount += fields.size; - - return { - additions, - removals: { - constructorDefinition, - staticMethodsAndFields: [...staticMethodsAndFields], - staticGetters: [...staticGetters], - staticSetters: [...staticSetters], - methods: [...methods], - getters: [...getters], - setters: [...setters], - fields: [...fields] - }, - unchangedCount, - changedCount - }; } -export function autoFindEnum(this: typeof Vencord, source: CR.EnumSource) { - let bestMatch: CR.EnumChanges | undefined; - let lowestChangedCount = Infinity; - - const checked = new WeakSet(); - this.Webpack.find((exps: any) => { - for (const name in exps) { - let exp: unknown; - // Some getters throw errors - try { - exp = exps[name]; - } catch { - continue; - } - - if (isValidEnum(exp) && !checked.has(exp)) { - checked.add(exp); - - const changes = getEnumChanges(exp, source); - const { changedCount } = changes; - if (changedCount < lowestChangedCount) { - lowestChangedCount = changedCount; - bestMatch = changes; - } - } - } - - return false; - }, { isIndirect: true }); - - return bestMatch; +export function formatWarnList(warns: string[]) { + return warns.map(codeBlock).join(""); } -export function isValidEnum(obj: unknown): obj is CR.EnumMembers { - return typeof obj === "object" - && obj !== null - && !Array.isArray(obj); +export function formatKeyList(keys: string[], indentLevel = 0) { + const indent = " ".repeat(indentLevel); + return keys.map(key => indent + `* \`${key}\`\n`).join(""); } -export function getEnumChanges(obj: CR.EnumMembers, source: CR.EnumSource): CR.EnumChanges { - const additions: CR.EnumMembers = {}; - const removals: CR.EnumMembers = { ...source }; - let unchangedCount = 0; - let changedCount = 0; - - for (const key in obj) { - // Ignore numeric enum reverse mapping - if (parseFloat(key) === Number(key)) continue; - - // Some getters throw errors - try { - const value = obj[key]!; - if (key in source && value === source[key]) { - delete removals[key]; - unchangedCount++; - } else { - additions[key] = value; - changedCount++; - } - } catch { - changedCount = Infinity; - break; - } - } - - changedCount += Object.keys(removals).length; - - return { - additions, - removals, - unchangedCount, - changedCount - }; +export function formatEnumEntryList(entries: [key: string, value: unknown][], indentLevel = 0) { + const indent = " ".repeat(indentLevel); + return entries.map(([key, value]) => indent + `* \`${key} = ${JSON.stringify(value)}\`\n`).join(""); +} + +export function getSummaryURL(channel?: string | undefined) { + const { GITHUB_SERVER_URL, GITHUB_REPOSITORY, GITHUB_RUN_ID, GITHUB_RUN_ATTEMPT } = process.env; + if (GITHUB_SERVER_URL && GITHUB_REPOSITORY && GITHUB_RUN_ID && GITHUB_RUN_ATTEMPT) + return `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}` + + `#:~:text=Change%20Report%20%28${formatChannel(channel)}%29`; } diff --git a/packages/discord-types/scripts/changeReporter/webhooks.mts b/packages/discord-types/scripts/changeReporter/webhooks.mts new file mode 100644 index 000000000..c6be26dd0 --- /dev/null +++ b/packages/discord-types/scripts/changeReporter/webhooks.mts @@ -0,0 +1,117 @@ +/* + * discord-types + * Copyright (C) 2024 Vencord project contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import type { CR } from "./types.mts"; +import { codeBlock, formatChannel, getSummaryURL } from "./utils.mjs"; + +export async function postError( + error: Error, + webhookURL: string | undefined, + channel?: string | undefined +) { + if (!webhookURL) return; + + const res = await fetch(webhookURL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + username: "Change Reporter", + embeds: [{ + title: `Change Report (${formatChannel(channel)})`, + description: "### Fatal error:\n" + codeBlock(error.stack), + url: getSummaryURL(channel), + color: 0xF23F42 + }] + }) + }); + + if (!res.ok) + console.error(`Failed to exectute webhook (status '${res.status} ${res.statusText}').`); +} + +export async function postReport( + report: CR.ChangeReport, + webhookURL: string, + channel?: string | undefined +) { + const { deps, src } = report; + + let areChanges = false; + let description = ""; + + if (deps.length > 0) { + let passedCount = 0; + let warnedCount = 0; + let failedCount = 0; + let erroredCount = 0; + for (const report of deps) { + passedCount += report.passed.length; + warnedCount += report.warned.length; + failedCount += report.failed.length; + erroredCount += report.errored.length; + } + const toLogCount = warnedCount + failedCount + erroredCount; + const count = passedCount + toLogCount; + if (count > 0) { + description += "### Dependencies:\n"; + if (toLogCount > 0) { + areChanges = true; + description += `${count} watched dependenc${count === 1 ? "y" : "ies"} in ${deps.length} file${deps.length === 1 ? "" : "s"}:\n` + + `* ${passedCount} passed without warnings.\n` + + `* ${warnedCount} passed with warnings.\n` + + `* ${failedCount} failed.\n` + + `* ${erroredCount} errored.\n`; + } else + description += "All watched dependencies passed without warnings.\n"; + } + } + + if (src.length > 0) { + let unchangedCount = 0; + let warnedCount = 0; + let changedCount = 0; + let erroredCount = 0; + for (const report of src) { + unchangedCount += report.unchanged.length; + warnedCount += report.warned.length; + changedCount += report.changed.length; + erroredCount += report.errored.length; + } + const toLogCount = warnedCount + changedCount + erroredCount; + const count = unchangedCount + toLogCount; + if (count > 0) { + description += "### Declarations:\n"; + if (toLogCount > 0) { + areChanges = true; + description += `${count} watched declaration${count === 1 ? "" : "s"} in ${src.length} file${src.length === 1 ? "" : "s"}:\n` + + `* ${unchangedCount} ${unchangedCount === 1 ? "is" : "are"} unchanged without warnings.\n` + + `* ${warnedCount} ${warnedCount === 1 ? "is" : "are"} unchanged with warnings.\n` + + `* ${changedCount} ha${changedCount === 1 ? "s" : "ve"} changes.\n` + + `* ${erroredCount} errored.\n`; + } else + description += "All watched declarations are unchanged without warnings.\n"; + } + } + + description ||= "### There are 0 watched dependencies and declarations.\n"; + + const res = await fetch(webhookURL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + username: "Change Reporter", + embeds: [{ + title: `Change Report (${formatChannel(channel)})`, + description, + url: getSummaryURL(channel), + color: areChanges ? 0xF0B132 : 0x23A559 + }] + }) + }); + + if (!res.ok) + console.error(`Failed to exectute webhook (status '${res.status} ${res.statusText}').`); +} diff --git a/packages/discord-types/scripts/utils.mts b/packages/discord-types/scripts/utils.mts index 7800af00f..e2c81be1e 100644 --- a/packages/discord-types/scripts/utils.mts +++ b/packages/discord-types/scripts/utils.mts @@ -12,7 +12,7 @@ type ValidEnv = NodeJS.ProcessEnv & { : string; } & { [Key in keyof Config as false extends Config[Key] ? Key : never]?: string; }; -export function validateEnv( +export function assertEnvValidity( env: NodeJS.ProcessEnv, config: Config ): asserts env is ValidEnv { diff --git a/packages/discord-types/src/general/messages/MinimalMessageRecord.ts b/packages/discord-types/src/general/messages/MinimalMessageRecord.ts index 97db76795..08a364290 100644 --- a/packages/discord-types/src/general/messages/MinimalMessageRecord.ts +++ b/packages/discord-types/src/general/messages/MinimalMessageRecord.ts @@ -80,7 +80,7 @@ export enum CodedLinkType { TEMPLATE = "TEMPLATE", } -export type MessageComponent = MessageActionRowComponent | MessageButtonComponent | MessageSelectComponent | MessageTextInputComponent | MessageTextComponent | MessageMediaGalleryComponent | MessageSeparatorComponent; +export type MessageComponent = MessageActionRowComponent | MessageButtonComponent | MessageSelectComponent | MessageTextInputComponent | MessageTextComponent | MessageMediaGalleryComponent | MessageSeparatorComponent | MessageContentInventoryEntryComponent; export interface MessageComponentBase { id: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11bb83bb1..27c518d59 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,11 +69,11 @@ importers: specifier: ^2.4.5 version: 2.4.5 '@typescript-eslint/eslint-plugin': - specifier: ^7.15.0 - version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + specifier: ^7.16.0 + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) '@typescript-eslint/parser': - specifier: ^7.15.0 - version: 7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + specifier: ^7.16.0 + version: 7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) '@vencord/discord-types': specifier: workspace:^ version: link:packages/discord-types @@ -91,7 +91,7 @@ importers: version: 8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi) eslint-import-resolver-alias: specifier: ^1.1.2 - version: 1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))) + version: 1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))) eslint-plugin-path-alias: specifier: ^2.1.0 version: 2.1.0(patch_hash=japuwsqfkulviwgkm4kd2oi3ky)(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) @@ -100,7 +100,7 @@ importers: version: 12.1.1(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) eslint-plugin-unused-imports: specifier: ^3.2.0 - version: 3.2.0(@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) + version: 3.2.0(@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) highlight.js: specifier: 11.8.0 version: 11.8.0 @@ -178,8 +178,8 @@ importers: specifier: ^7.5.8 version: 7.5.8 '@typescript-eslint/typescript-estree': - specifier: ^8.0.0-alpha.39 - version: 8.0.0-alpha.40(typescript@5.5.3) + specifier: ^8.0.0-alpha.41 + version: 8.0.0-alpha.41(typescript@5.5.3) eslint: specifier: ^9.6.0 version: 9.6.0 @@ -200,7 +200,7 @@ importers: version: 54.0.0(eslint@9.6.0) eslint-plugin-unused-imports: specifier: ^4.0.0 - version: 4.0.0(@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@9.6.0) + version: 4.0.0(@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@9.6.0) puppeteer-core: specifier: ^22.12.1 version: 22.12.1 @@ -214,8 +214,8 @@ importers: specifier: ^5.5.3 version: 5.5.3 typescript-eslint: - specifier: ^8.0.0-alpha.39 - version: 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3) + specifier: ^8.0.0-alpha.41 + version: 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3) packages/vencord-types: dependencies: @@ -777,8 +777,8 @@ packages: '@types/yazl@2.4.5': resolution: {integrity: sha512-qpmPfx32HS7vlGJf7EsoM9qJnLZhXJBf1KH0hzfdc+D794rljQWh4H0I/UrZy+6Nhqn0l2jdBZXBGZtR1vnHqw==} - '@typescript-eslint/eslint-plugin@7.15.0': - resolution: {integrity: sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==} + '@typescript-eslint/eslint-plugin@7.16.0': + resolution: {integrity: sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -788,8 +788,8 @@ packages: typescript: optional: true - '@typescript-eslint/eslint-plugin@8.0.0-alpha.39': - resolution: {integrity: sha512-ILv1vDA8M9ah1vzYpnOs4UOLRdB63Ki/rsxedVikjMLq68hFfpsDR25bdMZ4RyUkzLJwOhcg3Jujm/C1nupXKA==} + '@typescript-eslint/eslint-plugin@8.0.0-alpha.41': + resolution: {integrity: sha512-WePtbzWMaQO4qtGAXp3zzEN8yYZCEuAHVCERCUXgoSUTQ80F5UB7T5lYyA9ySpFDB7rqJ2ev98DtnbS4U3Ms+w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -799,8 +799,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@7.15.0': - resolution: {integrity: sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==} + '@typescript-eslint/parser@7.16.0': + resolution: {integrity: sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -809,8 +809,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.0.0-alpha.39': - resolution: {integrity: sha512-5k+pwV91plJojHgZkWlq4/TQdOrnEaeSvt48V0m8iEwdMJqX/63BXYxy8BUOSghWcjp05s73vy9HJjovAKmHkQ==} + '@typescript-eslint/parser@8.0.0-alpha.41': + resolution: {integrity: sha512-7HMXwy/q/59ZASBXz2FtdIsR7LgABrR8j2dTKq9GMR8OkjjdO4klxWSY/uOBozVt4UxlMRYsBdBDhEq4/tHRiw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -823,16 +823,16 @@ packages: resolution: {integrity: sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@7.15.0': - resolution: {integrity: sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==} + '@typescript-eslint/scope-manager@7.16.0': + resolution: {integrity: sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@8.0.0-alpha.39': - resolution: {integrity: sha512-HCBlKQROY+JIgWolucdFMj1W3VUnnIQTdxAhxJTAj3ix2nASmvKIFgrdo5KQMrXxQj6tC4l3zva10L+s0dUIIw==} + '@typescript-eslint/scope-manager@8.0.0-alpha.41': + resolution: {integrity: sha512-iNxuQ0TMVfFiMJ2al4bGd/mY9+aLtBxnHfo7B2xoVzR6cRFgUdBLlMa//MSIjSmVRpCEqNLQnkxpJb96tFG+xw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@7.15.0': - resolution: {integrity: sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==} + '@typescript-eslint/type-utils@7.16.0': + resolution: {integrity: sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -841,8 +841,8 @@ packages: typescript: optional: true - '@typescript-eslint/type-utils@8.0.0-alpha.39': - resolution: {integrity: sha512-alO13fRU6yVeJbwl9ESI3AYhq5dQdz3Dpd0I5B4uezs2lvgYp44dZsj5hWyPz/kL7JFEsjbn+4b/CZA0OQJzjA==} + '@typescript-eslint/type-utils@8.0.0-alpha.41': + resolution: {integrity: sha512-+QIA1z/jrox6bbvqlyqBQjotpevieLTycfiuoKuqGcKoskFZV5Rma51BV8LCJacnOafwJtSi+7b8zDo8OsXUvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -854,16 +854,12 @@ packages: resolution: {integrity: sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@7.15.0': - resolution: {integrity: sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==} + '@typescript-eslint/types@7.16.0': + resolution: {integrity: sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@8.0.0-alpha.39': - resolution: {integrity: sha512-yINN7j0/+S1VGSp0IgH52oQvUx49vkOug6xbrDA/9o+U55yCAQKSvYWvzYjNa+SZE3hXI0zwvYtMVsIAAMmKIQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/types@8.0.0-alpha.40': - resolution: {integrity: sha512-44mUq4VZVydxNlOM8Xtp/BXDkyfuvvjgPIBf7vRQDutrLDeNS0pJ9pcSloSbop5MwKLfJjBU+PbwnJPQM+DWNg==} + '@typescript-eslint/types@8.0.0-alpha.41': + resolution: {integrity: sha512-n0P2FP3YC3pD3yoiCf4lHqbUP45xlnOk8HkjB+LtKSUZZWLLJ8k1ZXZtQj7MEX22tytCMj//Bmq403xFuCwfIg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@7.14.1': @@ -875,8 +871,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@7.15.0': - resolution: {integrity: sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==} + '@typescript-eslint/typescript-estree@7.16.0': + resolution: {integrity: sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -884,17 +880,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.0.0-alpha.39': - resolution: {integrity: sha512-S8gREuP8r8PCxGegeojeXntx0P50ul9YH7c7JYpbLIIsEPNr5f7UHlm+I1NUbL04CBin4kvZ60TG4eWr/KKN9A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/typescript-estree@8.0.0-alpha.40': - resolution: {integrity: sha512-bz1rX5GXvGdx686FghDxPqGwgntlseZCQSRrVGDDOZlLSoWJnbfkzxXGOWch9c3ttcGkdFy/DiCyKKga3hrq0g==} + '@typescript-eslint/typescript-estree@8.0.0-alpha.41': + resolution: {integrity: sha512-adCr+vbLYTFhwhIwjIjjMxTdUYiPA2Jlyuhnbj092IzgLHtT79bvuwcgPWeTyLbFb/13SMKmOEka00xHiqLpig==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -908,14 +895,14 @@ packages: peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/utils@7.15.0': - resolution: {integrity: sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==} + '@typescript-eslint/utils@7.16.0': + resolution: {integrity: sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/utils@8.0.0-alpha.39': - resolution: {integrity: sha512-Nr2PrlfNhrNQTlFHlD7XJdTGw/Vt8qY44irk6bfjn9LxGdSG5e4c1R2UN6kvGMhhx20DBPbM7q3Z3r+huzmL1w==} + '@typescript-eslint/utils@8.0.0-alpha.41': + resolution: {integrity: sha512-DTxc9VdERS6iloiw1P5tgRDqRArmp/sIuvgdHBvGh2SiltEFc3VjLGnHHGSTr6GfH7tjFWvcCnCtxx+pjWfp5Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -924,16 +911,12 @@ packages: resolution: {integrity: sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@7.15.0': - resolution: {integrity: sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==} + '@typescript-eslint/visitor-keys@7.16.0': + resolution: {integrity: sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@8.0.0-alpha.39': - resolution: {integrity: sha512-DVJ0UdhucZy+/1GlIy7FX2+CFhCeNAi4VwaEAe7u2UDenQr9/kGqvzx00UlpWibmEVDw4KsPOI7Aqa1+2Vqfmw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/visitor-keys@8.0.0-alpha.40': - resolution: {integrity: sha512-y1stojSPb5D3M8VlGGpaiBU5XxGLe+sPuW0YbLe09Lxvo4AwKGvhAr5lhqJZo4z6qHNz385+6+BS63+qIQdYLw==} + '@typescript-eslint/visitor-keys@8.0.0-alpha.41': + resolution: {integrity: sha512-uetCAUBVC+YarBdZnWzDDgX11PpAEGV8Cw31I3d1xNrhx6/bJGThKX+holEmd3amMdnr4w/XUKH/4YuQOgtjDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.2.0': @@ -2918,8 +2901,8 @@ packages: resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} - typescript-eslint@8.0.0-alpha.39: - resolution: {integrity: sha512-bsuR1BVJfHr7sBh7Cca962VPIcP+5UWaIa/+6PpnFZ+qtASjGTxKWIF5dG2o73BX9NsyqQfvRWujb3M9CIoRXA==} + typescript-eslint@8.0.0-alpha.41: + resolution: {integrity: sha512-+e7D2XDZeHLe9D3bP7S0Va8YdLHzn3YcesoxMS9SjMWhtaSb5ylxk2txqT84sUS0WIDQetZlvDg2/UmY5B/ycg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -3484,14 +3467,14 @@ snapshots: dependencies: '@types/node': 18.19.39 - '@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3)': + '@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) - '@typescript-eslint/scope-manager': 7.15.0 - '@typescript-eslint/type-utils': 7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) - '@typescript-eslint/utils': 7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 7.15.0 + '@typescript-eslint/parser': 7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + '@typescript-eslint/scope-manager': 7.16.0 + '@typescript-eslint/type-utils': 7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + '@typescript-eslint/utils': 7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 7.16.0 eslint: 8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi) graphemer: 1.4.0 ignore: 5.3.1 @@ -3502,14 +3485,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.0.0-alpha.39(@typescript-eslint/parser@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3)': + '@typescript-eslint/eslint-plugin@8.0.0-alpha.41(@typescript-eslint/parser@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3) - '@typescript-eslint/scope-manager': 8.0.0-alpha.39 - '@typescript-eslint/type-utils': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3) - '@typescript-eslint/utils': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 8.0.0-alpha.39 + '@typescript-eslint/parser': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/scope-manager': 8.0.0-alpha.41 + '@typescript-eslint/type-utils': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/utils': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 8.0.0-alpha.41 eslint: 9.6.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -3520,12 +3503,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3)': + '@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3)': dependencies: - '@typescript-eslint/scope-manager': 7.15.0 - '@typescript-eslint/types': 7.15.0 - '@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 7.15.0 + '@typescript-eslint/scope-manager': 7.16.0 + '@typescript-eslint/types': 7.16.0 + '@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 7.16.0 debug: 4.3.5 eslint: 8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi) optionalDependencies: @@ -3533,12 +3516,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3)': + '@typescript-eslint/parser@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3)': dependencies: - '@typescript-eslint/scope-manager': 8.0.0-alpha.39 - '@typescript-eslint/types': 8.0.0-alpha.39 - '@typescript-eslint/typescript-estree': 8.0.0-alpha.39(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 8.0.0-alpha.39 + '@typescript-eslint/scope-manager': 8.0.0-alpha.41 + '@typescript-eslint/types': 8.0.0-alpha.41 + '@typescript-eslint/typescript-estree': 8.0.0-alpha.41(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 8.0.0-alpha.41 debug: 4.3.5 eslint: 9.6.0 optionalDependencies: @@ -3551,20 +3534,20 @@ snapshots: '@typescript-eslint/types': 7.14.1 '@typescript-eslint/visitor-keys': 7.14.1 - '@typescript-eslint/scope-manager@7.15.0': + '@typescript-eslint/scope-manager@7.16.0': dependencies: - '@typescript-eslint/types': 7.15.0 - '@typescript-eslint/visitor-keys': 7.15.0 + '@typescript-eslint/types': 7.16.0 + '@typescript-eslint/visitor-keys': 7.16.0 - '@typescript-eslint/scope-manager@8.0.0-alpha.39': + '@typescript-eslint/scope-manager@8.0.0-alpha.41': dependencies: - '@typescript-eslint/types': 8.0.0-alpha.39 - '@typescript-eslint/visitor-keys': 8.0.0-alpha.39 + '@typescript-eslint/types': 8.0.0-alpha.41 + '@typescript-eslint/visitor-keys': 8.0.0-alpha.41 - '@typescript-eslint/type-utils@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3)': + '@typescript-eslint/type-utils@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3)': dependencies: - '@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3) - '@typescript-eslint/utils': 7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + '@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3) + '@typescript-eslint/utils': 7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) debug: 4.3.5 eslint: 8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi) ts-api-utils: 1.3.0(typescript@5.5.3) @@ -3573,10 +3556,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3)': + '@typescript-eslint/type-utils@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.0.0-alpha.39(typescript@5.5.3) - '@typescript-eslint/utils': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/typescript-estree': 8.0.0-alpha.41(typescript@5.5.3) + '@typescript-eslint/utils': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3) debug: 4.3.5 ts-api-utils: 1.3.0(typescript@5.5.3) optionalDependencies: @@ -3587,11 +3570,9 @@ snapshots: '@typescript-eslint/types@7.14.1': {} - '@typescript-eslint/types@7.15.0': {} + '@typescript-eslint/types@7.16.0': {} - '@typescript-eslint/types@8.0.0-alpha.39': {} - - '@typescript-eslint/types@8.0.0-alpha.40': {} + '@typescript-eslint/types@8.0.0-alpha.41': {} '@typescript-eslint/typescript-estree@7.14.1(typescript@5.5.3)': dependencies: @@ -3608,10 +3589,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@7.15.0(typescript@5.5.3)': + '@typescript-eslint/typescript-estree@7.16.0(typescript@5.5.3)': dependencies: - '@typescript-eslint/types': 7.15.0 - '@typescript-eslint/visitor-keys': 7.15.0 + '@typescript-eslint/types': 7.16.0 + '@typescript-eslint/visitor-keys': 7.16.0 debug: 4.3.5 globby: 11.1.0 is-glob: 4.0.3 @@ -3623,25 +3604,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.0.0-alpha.39(typescript@5.5.3)': + '@typescript-eslint/typescript-estree@8.0.0-alpha.41(typescript@5.5.3)': dependencies: - '@typescript-eslint/types': 8.0.0-alpha.39 - '@typescript-eslint/visitor-keys': 8.0.0-alpha.39 - debug: 4.3.5 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.5.3) - optionalDependencies: - typescript: 5.5.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/typescript-estree@8.0.0-alpha.40(typescript@5.5.3)': - dependencies: - '@typescript-eslint/types': 8.0.0-alpha.40 - '@typescript-eslint/visitor-keys': 8.0.0-alpha.40 + '@typescript-eslint/types': 8.0.0-alpha.41 + '@typescript-eslint/visitor-keys': 8.0.0-alpha.41 debug: 4.3.5 globby: 11.1.0 is-glob: 4.0.3 @@ -3664,23 +3630,23 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3)': + '@typescript-eslint/utils@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) - '@typescript-eslint/scope-manager': 7.15.0 - '@typescript-eslint/types': 7.15.0 - '@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3) + '@typescript-eslint/scope-manager': 7.16.0 + '@typescript-eslint/types': 7.16.0 + '@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3) eslint: 8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3)': + '@typescript-eslint/utils@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) - '@typescript-eslint/scope-manager': 8.0.0-alpha.39 - '@typescript-eslint/types': 8.0.0-alpha.39 - '@typescript-eslint/typescript-estree': 8.0.0-alpha.39(typescript@5.5.3) + '@typescript-eslint/scope-manager': 8.0.0-alpha.41 + '@typescript-eslint/types': 8.0.0-alpha.41 + '@typescript-eslint/typescript-estree': 8.0.0-alpha.41(typescript@5.5.3) eslint: 9.6.0 transitivePeerDependencies: - supports-color @@ -3691,19 +3657,14 @@ snapshots: '@typescript-eslint/types': 7.14.1 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@7.15.0': + '@typescript-eslint/visitor-keys@7.16.0': dependencies: - '@typescript-eslint/types': 7.15.0 + '@typescript-eslint/types': 7.16.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.0.0-alpha.39': + '@typescript-eslint/visitor-keys@8.0.0-alpha.41': dependencies: - '@typescript-eslint/types': 8.0.0-alpha.39 - eslint-visitor-keys: 3.4.3 - - '@typescript-eslint/visitor-keys@8.0.0-alpha.40': - dependencies: - '@typescript-eslint/types': 8.0.0-alpha.40 + '@typescript-eslint/types': 8.0.0-alpha.41 eslint-visitor-keys: 3.4.3 '@ungap/structured-clone@1.2.0': {} @@ -4312,9 +4273,9 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))): dependencies: - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) eslint-import-resolver-node@0.3.9: dependencies: @@ -4324,11 +4285,11 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + '@typescript-eslint/parser': 7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) eslint: 8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: @@ -4361,7 +4322,7 @@ snapshots: - supports-color - typescript - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -4371,7 +4332,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)) hasown: 2.0.2 is-core-module: 2.14.0 is-glob: 4.0.3 @@ -4382,7 +4343,7 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + '@typescript-eslint/parser': 7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -4429,19 +4390,19 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-unused-imports@3.2.0(@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)): + eslint-plugin-unused-imports@3.2.0(@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi)): dependencies: eslint: 8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi) eslint-rule-composer: 0.3.0 optionalDependencies: - '@typescript-eslint/eslint-plugin': 7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + '@typescript-eslint/eslint-plugin': 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) - eslint-plugin-unused-imports@4.0.0(@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@9.6.0): + eslint-plugin-unused-imports@4.0.0(@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@9.6.0): dependencies: eslint: 9.6.0 eslint-rule-composer: 0.3.0 optionalDependencies: - '@typescript-eslint/eslint-plugin': 7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) + '@typescript-eslint/eslint-plugin': 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3))(eslint@8.57.0(patch_hash=wy5a2dwvtxac2ygzwebqqjurgi))(typescript@5.5.3) eslint-rule-composer@0.3.0: {} @@ -5988,11 +5949,11 @@ snapshots: is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 - typescript-eslint@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3): + typescript-eslint@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.0.0-alpha.39(@typescript-eslint/parser@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3) - '@typescript-eslint/parser': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3) - '@typescript-eslint/utils': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/eslint-plugin': 8.0.0-alpha.41(@typescript-eslint/parser@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/parser': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/utils': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.3) optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: diff --git a/scripts/generateReport.mts b/scripts/generateReport.mts index f007d17cc..6a6fabc14 100644 --- a/scripts/generateReport.mts +++ b/scripts/generateReport.mts @@ -79,7 +79,7 @@ const IGNORED_DISCORD_ERRORS: (RegExp | string)[] = [ function toCodeBlock(s: string, indentation = 0, isDiscord = false) { s = s.replace(/```/g, "`\u200B`\u200B`"); - const indentationStr = Array(!isDiscord ? indentation : 0).fill(" ").join(""); + const indentationStr = " ".repeat(!isDiscord ? indentation : 0); return `\`\`\`\n${s.split("\n").map(s => indentationStr + s).join("\n")}\n${indentationStr}\`\`\``; }