mirror of https://github.com/acid-info/lpe-cms.git
feat: implement discord notification extension
This commit is contained in:
parent
d18abbe2d9
commit
de9db23003
|
@ -21,6 +21,8 @@
|
|||
"@strapi/plugin-i18n": "4.16.2",
|
||||
"@strapi/plugin-users-permissions": "4.16.2",
|
||||
"@strapi/strapi": "4.16.2",
|
||||
"discord.js": "^14.14.1",
|
||||
"ejs": "^3.1.9",
|
||||
"pg": "8.8.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
|
@ -28,6 +30,7 @@
|
|||
"styled-components": "5.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ejs": "^3.1.5",
|
||||
"patch-package": "^8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { Attribute } from "@strapi/strapi";
|
||||
import { DiscordNotificationConfig } from "./types";
|
||||
|
||||
const DISCORD_NOTIFICATION_USERNAME =
|
||||
process.env.DISCORD_NOTIFICATION_USERNAME || "Logos Press Engine";
|
||||
const DISCORD_NOTIFICATION_AVATAR_URL =
|
||||
process.env.DISCORD_NOTIFICATION_AVATAR_URL ||
|
||||
"https://press.logos.co/logo.png";
|
||||
const DISCORD_NOTIFICATION_WEBHOOK_URL =
|
||||
process.env.DISCORD_NOTIFICATION_WEBHOOK_URL || "";
|
||||
const LPE_WEBSITE_URL = process.env.LPE_WEBSITE_URL || "https://press.logos.co";
|
||||
|
||||
export const discordNotificationConfig: DiscordNotificationConfig = {
|
||||
username: DISCORD_NOTIFICATION_USERNAME,
|
||||
avatarUrl: DISCORD_NOTIFICATION_AVATAR_URL,
|
||||
webhookUrl: DISCORD_NOTIFICATION_WEBHOOK_URL,
|
||||
dataTypes: [
|
||||
{
|
||||
uid: "api::post.post",
|
||||
enabled: true,
|
||||
titleField: "title",
|
||||
ignoreFields: ["summary", "body", "channels", "credits", "updatedAt"],
|
||||
getUrl: (data: Attribute.GetValues<"api::post.post">) =>
|
||||
data.type === "Article"
|
||||
? `${LPE_WEBSITE_URL}/articles/${data.slug}`
|
||||
: `${LPE_WEBSITE_URL}/podcasts/${data.podcast_show?.slug}/${data.slug}`,
|
||||
getPreviewUrl: (data: Attribute.GetValues<"api::post.post">) =>
|
||||
`${LPE_WEBSITE_URL}/preview/post/${data.slug}`,
|
||||
},
|
||||
{
|
||||
uid: "api::author.author",
|
||||
enabled: false,
|
||||
titleField: "name",
|
||||
},
|
||||
{
|
||||
uid: "api::podcast-show.podcast-show",
|
||||
enabled: true,
|
||||
titleField: "name",
|
||||
getUrl: (data: Attribute.GetValues<"api::podcast-show.podcast-show">) =>
|
||||
`${LPE_WEBSITE_URL}/podcasts/${data.slug}`,
|
||||
ignoreFields: ["description"],
|
||||
},
|
||||
{
|
||||
uid: "api::page.page",
|
||||
enabled: true,
|
||||
titleField: "title",
|
||||
ignoreFields: ["body", "updatedAt"],
|
||||
getUrl: (data: Attribute.GetValues<"api::page.page">) =>
|
||||
`${LPE_WEBSITE_URL}/${data.slug}`,
|
||||
getPreviewUrl: (data: Attribute.GetValues<"api::page.page">) =>
|
||||
`${LPE_WEBSITE_URL}/preview/page/${data.slug}`,
|
||||
},
|
||||
{
|
||||
uid: "api::tag.tag",
|
||||
enabled: false,
|
||||
titleField: "name",
|
||||
},
|
||||
{
|
||||
uid: "admin::user",
|
||||
enabled: false,
|
||||
titleField: "username",
|
||||
},
|
||||
{
|
||||
uid: "plugin::upload.file",
|
||||
enabled: false,
|
||||
titleField: "name",
|
||||
},
|
||||
],
|
||||
};
|
|
@ -0,0 +1,350 @@
|
|||
import { Event } from "@strapi/database/dist/lifecycles/types";
|
||||
import { Common, Strapi } from "@strapi/strapi";
|
||||
import { WebhookClient } from "discord.js";
|
||||
import ejs from "ejs";
|
||||
import { isEqual } from "lodash";
|
||||
import { settle } from "../../utils/async.utils";
|
||||
import { DataType, DiscordNotificationConfig } from "./types";
|
||||
|
||||
const template = ejs.compile(`
|
||||
<% if (action === "deleted") { -%>
|
||||
:x: **<%- singularName %> deleted**
|
||||
<% } -%>
|
||||
<% if (action === "created") { -%>
|
||||
:white_check_mark: **New <%- singularName.toLowerCase() %> created**
|
||||
<% } -%>
|
||||
<% if (action === "updated") { -%>
|
||||
:pencil: **<%- singularName %> updated**
|
||||
<% } -%>
|
||||
<% if (action === "published") { -%>
|
||||
:fire: **<%- singularName %> published**
|
||||
<% } -%>
|
||||
<% if (action === "unpublished") { -%>
|
||||
:bangbang: **<%- singularName %> unpublished**
|
||||
<% } -%>
|
||||
|
||||
**[Info]**
|
||||
*Title:* <%- title -%>
|
||||
<% if (action === "updated" || action === "created") { %>
|
||||
*Publication status:* <%= isPublished ? "published" : "draft" -%>
|
||||
<% } %>
|
||||
|
||||
<% if (changes) { -%>
|
||||
**[Changes]**
|
||||
<%- changes -%>
|
||||
<% } %>
|
||||
|
||||
<% if (url && isPublished) { -%>
|
||||
You can visit the <%- singularName.toLowerCase() %> here: <%- url -%>
|
||||
<% } else if (url && !isPublished) { -%>
|
||||
You can visit the preview of the <%- singularName.toLowerCase() %> here: <%- url -%>
|
||||
<% } -%>
|
||||
`);
|
||||
|
||||
export class DiscordNotification {
|
||||
private client: WebhookClient;
|
||||
|
||||
constructor(
|
||||
private readonly strapi: Strapi,
|
||||
private readonly config: DiscordNotificationConfig
|
||||
) {}
|
||||
|
||||
init = () => {
|
||||
this.client = new WebhookClient({
|
||||
url: this.config.webhookUrl,
|
||||
});
|
||||
|
||||
this.config.dataTypes.forEach((dataType) => {
|
||||
this.register(dataType);
|
||||
});
|
||||
};
|
||||
|
||||
private register = (dataType: DataType) => {
|
||||
const { strapi } = this;
|
||||
|
||||
strapi.db.lifecycles.subscribe({
|
||||
models: [dataType.uid],
|
||||
afterCreate: async (event) => this.onEvent(event, dataType),
|
||||
afterUpdate: async (event) => this.onEvent(event, dataType),
|
||||
afterDelete: async (event) => this.onEvent(event, dataType),
|
||||
beforeUpdate: async (event) => this.onEvent(event, dataType),
|
||||
beforeUpdateMany: async (event) => {
|
||||
const { strapi } = this;
|
||||
|
||||
const records = await strapi.query(dataType.uid).findMany({
|
||||
where: event.params.where,
|
||||
populate: true,
|
||||
});
|
||||
|
||||
event.state = {
|
||||
...event.state,
|
||||
prev: records,
|
||||
};
|
||||
},
|
||||
afterUpdateMany: async (event) =>
|
||||
void (await Promise.all(
|
||||
(event.params.where?.id?.["$in"] || [])
|
||||
.filter((id) => !!id)
|
||||
.map((id) =>
|
||||
this.onEvent(
|
||||
{
|
||||
...event,
|
||||
params: { ...event.params, where: { id: id } },
|
||||
action: "afterUpdate",
|
||||
state: {
|
||||
...event.state,
|
||||
prev: ((event.state?.prev || []) as any[]).find(
|
||||
(record: any) => record.id === id
|
||||
),
|
||||
},
|
||||
},
|
||||
dataType
|
||||
)
|
||||
)
|
||||
)),
|
||||
});
|
||||
};
|
||||
|
||||
onEvent = async (event: Event, dataType: DataType) => {
|
||||
const [_r, err] = await settle(() => this.handleEvent(event, dataType));
|
||||
if (err) {
|
||||
this.strapi.log.error(err);
|
||||
this.strapi.log.warn(
|
||||
`Failed to send Discord notification for ${event.model.uid} ${event.action} event`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
handleEvent = async (event: Event, dataType: DataType) => {
|
||||
const { strapi, config } = this;
|
||||
|
||||
if (
|
||||
!["afterCreate", "afterUpdate", "afterDelete", "beforeUpdate"].includes(
|
||||
event.action
|
||||
)
|
||||
)
|
||||
return;
|
||||
|
||||
const postId =
|
||||
event.action === "afterCreate"
|
||||
? (event as any).result.id
|
||||
: event.params.where.id;
|
||||
|
||||
if (event.model.uid !== dataType.uid) return;
|
||||
|
||||
if (event.action === "beforeUpdate") {
|
||||
const record = await this.getRecord(dataType.uid, postId);
|
||||
|
||||
event.state = {
|
||||
...event.state,
|
||||
prev: record,
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const record = await this.getRecord(dataType.uid, postId);
|
||||
|
||||
const isPublished = record?.publishedAt !== null;
|
||||
let action: "created" | "updated" | "deleted" | "published" | "unpublished";
|
||||
|
||||
if (event.action === "afterCreate") {
|
||||
action = "created";
|
||||
} else if (event.action === "afterUpdate") {
|
||||
action = "updated";
|
||||
|
||||
if (!isPublished && !!(event.state.prev as any)?.publishedAt) {
|
||||
action = "unpublished";
|
||||
} else if (isPublished && !(event.state.prev as any)?.publishedAt) {
|
||||
action = "published";
|
||||
}
|
||||
} else if (event.action === "afterDelete") {
|
||||
action = "deleted";
|
||||
}
|
||||
|
||||
const url =
|
||||
action === "deleted"
|
||||
? null
|
||||
: isPublished
|
||||
? await dataType.getUrl?.(record)
|
||||
: await dataType.getPreviewUrl?.(record);
|
||||
|
||||
const changes =
|
||||
event.action === "afterUpdate"
|
||||
? this.findChanges(
|
||||
dataType,
|
||||
event.model,
|
||||
event.state?.prev || {},
|
||||
record || {}
|
||||
)
|
||||
: [];
|
||||
|
||||
const title =
|
||||
event.params.data?.[dataType.titleField] ??
|
||||
(record?.title || "") ??
|
||||
(event as any).result.title;
|
||||
|
||||
const singularName =
|
||||
event.model.singularName.charAt(0).toUpperCase() +
|
||||
event.model.singularName.slice(1);
|
||||
|
||||
const msg = template({
|
||||
title,
|
||||
singularName,
|
||||
isPublished,
|
||||
changes: this.changesToString(changes),
|
||||
url,
|
||||
action,
|
||||
});
|
||||
|
||||
this.client.send({
|
||||
content: msg,
|
||||
avatarURL: this.config.avatarUrl,
|
||||
username: this.config.username || "Discord",
|
||||
});
|
||||
};
|
||||
|
||||
changesToString = (
|
||||
changes: {
|
||||
attribute: string;
|
||||
previous: any;
|
||||
current: any;
|
||||
include?: boolean;
|
||||
}[]
|
||||
) => {
|
||||
let str = changes
|
||||
.filter((change) => change.include)
|
||||
.map((change) => {
|
||||
let name = change.attribute.replace("_", " ");
|
||||
name = name.charAt(0).toUpperCase() + name.slice(1);
|
||||
|
||||
let res = `*${name}:* `;
|
||||
|
||||
if (Array.isArray(change.previous) && Array.isArray(change.current)) {
|
||||
const removed = change.previous.filter(
|
||||
(item) => !change.current.includes(item)
|
||||
);
|
||||
|
||||
removed.forEach((item, index) => {
|
||||
res += `\n- ~~${item}~~`;
|
||||
});
|
||||
|
||||
change.current.forEach((item) => {
|
||||
res += `\n- ${item}`;
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
if (change.previous && change.previous.length > 0)
|
||||
res += `~~${change.previous}~~ -> `;
|
||||
|
||||
if (change.current && change.current.length > 0)
|
||||
res += `\`${change.current}\``;
|
||||
else res += `\`[empty]\``;
|
||||
|
||||
return res;
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
const excluded = changes.filter((change) => !change.include);
|
||||
if (excluded.length > 0)
|
||||
str += `\n\nother fields changed: ${excluded
|
||||
.map((change) => `\`${change.attribute}\``)
|
||||
.join(", ")}`;
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
findChanges = (
|
||||
dataType: DataType,
|
||||
model: Event["model"],
|
||||
previous: any,
|
||||
current: any
|
||||
) => {
|
||||
const changes: {
|
||||
attribute: string;
|
||||
previous: any;
|
||||
current: any;
|
||||
include?: boolean;
|
||||
}[] = [];
|
||||
|
||||
const updated = { ...current };
|
||||
|
||||
const getChangedField = (val: any, key?: string) => {
|
||||
if (Array.isArray(val)) {
|
||||
return val.filter((v) => !!v).map((v) => getChangedField(v, key));
|
||||
}
|
||||
|
||||
if (val === null) return "";
|
||||
if (typeof val === "undefined") return "";
|
||||
|
||||
if (typeof val === "object") {
|
||||
return (key && val[key]) || val[Object.keys(val)[0]] || "";
|
||||
}
|
||||
|
||||
return `${val}`;
|
||||
};
|
||||
|
||||
Object.keys(updated).forEach((key) => {
|
||||
const attr = model.attributes[key];
|
||||
|
||||
if (!attr) return;
|
||||
|
||||
if (isEqual(updated[key], previous[key])) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isRelation = attr.type === "relation";
|
||||
const target = isRelation && (attr as any).target;
|
||||
const conf = this.getConfigByUid(target);
|
||||
|
||||
const oldValue = getChangedField(previous[key], conf?.titleField);
|
||||
const newValue = getChangedField(updated[key], conf?.titleField);
|
||||
|
||||
changes.push({
|
||||
attribute: key,
|
||||
previous: oldValue,
|
||||
current: newValue,
|
||||
include: !(dataType.ignoreFields || []).includes(key),
|
||||
});
|
||||
});
|
||||
|
||||
return changes;
|
||||
};
|
||||
|
||||
getRecord = async (uid: Common.UID.ContentType, id: string) => {
|
||||
const relations = this.getRelations(uid);
|
||||
return this.strapi.query(uid).findOne({
|
||||
where: { id },
|
||||
populate: Object.fromEntries(
|
||||
(await relations).map((rel) => [rel.key, true])
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
getRelations = async (uid: Common.UID.ContentType) => {
|
||||
const model = this.strapi.contentTypes[uid];
|
||||
|
||||
const relations = Object.entries(model.attributes)
|
||||
.filter(
|
||||
([key, attr]) => attr.type === "relation" || attr.type === "media"
|
||||
)
|
||||
.map(([key, attr]) => {
|
||||
const target =
|
||||
attr.type === "media" ? "plugin::upload.file" : (attr as any).target;
|
||||
|
||||
return {
|
||||
key,
|
||||
target,
|
||||
field: this.getConfigByUid(target)?.titleField || "id",
|
||||
};
|
||||
});
|
||||
|
||||
return relations;
|
||||
};
|
||||
|
||||
getConfigByUid = (uid: Common.UID.ContentType) => {
|
||||
return this.config.dataTypes.find((dataType) => dataType.uid === uid);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import { Strapi } from "@strapi/strapi";
|
||||
import { settleSync } from "../../utils/async.utils";
|
||||
import { discordNotificationConfig } from "./config";
|
||||
import { DiscordNotification } from "./discord-notification";
|
||||
|
||||
export * from "./discord-notification";
|
||||
|
||||
const register = async ({ strapi }: { strapi: Strapi }) => {};
|
||||
|
||||
const bootstrap = async ({ strapi }: { strapi: Strapi }) => {
|
||||
const discordNotification = new DiscordNotification(
|
||||
strapi,
|
||||
discordNotificationConfig
|
||||
);
|
||||
|
||||
const [_r, err] = settleSync(() => discordNotification.init());
|
||||
if (err) {
|
||||
strapi.log.error(err);
|
||||
strapi.log.warn("Failed to initialize Discord notification extension.");
|
||||
}
|
||||
};
|
||||
|
||||
export const discordNotificationExtension = {
|
||||
register,
|
||||
bootstrap,
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
import { Attribute, Common } from "@strapi/strapi";
|
||||
|
||||
export type DataType<
|
||||
U extends Common.UID.CollectionType = Common.UID.CollectionType
|
||||
> = {
|
||||
uid: U;
|
||||
enabled: boolean;
|
||||
titleField: string;
|
||||
ignoreFields?: string[];
|
||||
|
||||
getUrl?: (
|
||||
data: Attribute.GetValues<U>
|
||||
) => string | null | Promise<string | null>;
|
||||
|
||||
getPreviewUrl?: (
|
||||
data: Attribute.GetValues<U>
|
||||
) => string | null | Promise<string | null>;
|
||||
};
|
||||
|
||||
export type DiscordNotificationConfig = {
|
||||
webhookUrl: string;
|
||||
username: string;
|
||||
avatarUrl?: string;
|
||||
|
||||
dataTypes: DataType[];
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
import { Strapi } from "@strapi/strapi";
|
||||
import { discordNotificationExtension } from "./extensions/discord-notification";
|
||||
import { searchExtension } from "./extensions/search";
|
||||
|
||||
export default {
|
||||
|
@ -10,6 +11,7 @@ export default {
|
|||
*/
|
||||
async register({ strapi }) {
|
||||
await searchExtension.register({ strapi });
|
||||
await discordNotificationExtension.register({ strapi });
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -21,5 +23,6 @@ export default {
|
|||
*/
|
||||
async bootstrap({ strapi }: { strapi: Strapi }) {
|
||||
await searchExtension.bootstrap({ strapi });
|
||||
await discordNotificationExtension.bootstrap({ strapi });
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
export const settle = async <R, E = Error>(
|
||||
promise: Promise<R> | (() => R | Promise<R>),
|
||||
): Promise<[R, undefined] | [undefined, E]> => {
|
||||
try {
|
||||
const result: R =
|
||||
typeof promise === 'function' ? await promise() : await promise
|
||||
return [result, undefined]
|
||||
} catch (error) {
|
||||
return [undefined, error as E]
|
||||
}
|
||||
}
|
||||
|
||||
export const settleSync = <R, E = Error>(
|
||||
func: () => R,
|
||||
): [R, undefined] | [undefined, E] => {
|
||||
try {
|
||||
return [func(), undefined]
|
||||
} catch (error) {
|
||||
return [undefined, error as E]
|
||||
}
|
||||
}
|
||||
|
||||
export type CreatePromiseResult<T = any, E = Error> = {
|
||||
promise: Promise<T>
|
||||
reject: (err: E) => void
|
||||
resolve: (result: T) => void
|
||||
callback: (data: T, error?: E) => void
|
||||
}
|
||||
|
||||
export const createPromise = <T = any, E = Error>(): CreatePromiseResult<
|
||||
T,
|
||||
E
|
||||
> => {
|
||||
let resolve: any, reject: any
|
||||
|
||||
const promise = new Promise<T>((res, rej) => {
|
||||
resolve = res
|
||||
reject = rej
|
||||
})
|
||||
|
||||
const callback = (data: T, error?: E) => {
|
||||
if (error) return void reject(error)
|
||||
resolve(data)
|
||||
}
|
||||
|
||||
return {
|
||||
reject,
|
||||
resolve,
|
||||
promise,
|
||||
|
||||
callback,
|
||||
}
|
||||
}
|
||||
|
||||
export const sleep = (ms: number) =>
|
||||
new Promise(() => setTimeout(Promise.resolve, ms))
|
212
yarn.lock
212
yarn.lock
|
@ -840,6 +840,71 @@
|
|||
enabled "2.0.x"
|
||||
kuler "^2.0.0"
|
||||
|
||||
"@discordjs/builders@^1.7.0":
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-1.7.0.tgz#e2478c7e55b0f4c40837edb8f102bce977323a37"
|
||||
integrity sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==
|
||||
dependencies:
|
||||
"@discordjs/formatters" "^0.3.3"
|
||||
"@discordjs/util" "^1.0.2"
|
||||
"@sapphire/shapeshift" "^3.9.3"
|
||||
discord-api-types "0.37.61"
|
||||
fast-deep-equal "^3.1.3"
|
||||
ts-mixer "^6.0.3"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@discordjs/collection@1.5.3":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-1.5.3.tgz#5a1250159ebfff9efa4f963cfa7e97f1b291be18"
|
||||
integrity sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==
|
||||
|
||||
"@discordjs/collection@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-2.0.0.tgz#409b80c74eb8486cc4ee6a9b83426aaff1380f8c"
|
||||
integrity sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==
|
||||
|
||||
"@discordjs/formatters@^0.3.3":
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/formatters/-/formatters-0.3.3.tgz#b16fdd79bb819680ab7e519193004e9dc124a749"
|
||||
integrity sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==
|
||||
dependencies:
|
||||
discord-api-types "0.37.61"
|
||||
|
||||
"@discordjs/rest@^2.1.0":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-2.2.0.tgz#f4ec00d3faff965c00a879b7e87bb4b6f4446966"
|
||||
integrity sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^2.0.0"
|
||||
"@discordjs/util" "^1.0.2"
|
||||
"@sapphire/async-queue" "^1.5.0"
|
||||
"@sapphire/snowflake" "^3.5.1"
|
||||
"@vladfrangu/async_event_emitter" "^2.2.2"
|
||||
discord-api-types "0.37.61"
|
||||
magic-bytes.js "^1.5.0"
|
||||
tslib "^2.6.2"
|
||||
undici "5.27.2"
|
||||
|
||||
"@discordjs/util@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/util/-/util-1.0.2.tgz#dc1896d764452b1bd9707eb9aa99ccfbb30bd1c0"
|
||||
integrity sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==
|
||||
|
||||
"@discordjs/ws@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/ws/-/ws-1.0.2.tgz#3933b12d4686aabf6a95dfe5fb6e744342a661d1"
|
||||
integrity sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^2.0.0"
|
||||
"@discordjs/rest" "^2.1.0"
|
||||
"@discordjs/util" "^1.0.2"
|
||||
"@sapphire/async-queue" "^1.5.0"
|
||||
"@types/ws" "^8.5.9"
|
||||
"@vladfrangu/async_event_emitter" "^2.2.2"
|
||||
discord-api-types "0.37.61"
|
||||
tslib "^2.6.2"
|
||||
ws "^8.14.2"
|
||||
|
||||
"@discoveryjs/json-ext@0.5.7":
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||
|
@ -1285,6 +1350,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.2.tgz#1205014625790c7ff0e471644a878a65d1e34ab0"
|
||||
integrity sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw==
|
||||
|
||||
"@fastify/busboy@^2.0.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff"
|
||||
integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==
|
||||
|
||||
"@floating-ui/core@^1.5.3":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.3.tgz#b6aa0827708d70971c8679a16cf680a515b8a52a"
|
||||
|
@ -2044,6 +2114,29 @@
|
|||
colors "~1.2.1"
|
||||
string-argv "~0.3.1"
|
||||
|
||||
"@sapphire/async-queue@^1.5.0":
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.2.tgz#2982dce16e5b8b1ea792604d20c23c0585877b97"
|
||||
integrity sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==
|
||||
|
||||
"@sapphire/shapeshift@^3.9.3":
|
||||
version "3.9.6"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.9.6.tgz#bd9629c08641f5b94ae094e23f092187a3ed9a7d"
|
||||
integrity sha512-4+Na/fxu2SEepZRb9z0dbsVh59QtwPuBg/UVaDib3av7ZY14b14+z09z6QVn0P6Dv6eOU2NDTsjIi0mbtgP56g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
lodash "^4.17.21"
|
||||
|
||||
"@sapphire/snowflake@3.5.1":
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.5.1.tgz#254521c188b49e8b2d4cc048b475fb2b38737fec"
|
||||
integrity sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==
|
||||
|
||||
"@sapphire/snowflake@^3.5.1":
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.5.3.tgz#0c102aa2ec5b34f806e9bc8625fc6a5e1d0a0c6a"
|
||||
integrity sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==
|
||||
|
||||
"@sentry/core@6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.19.7.tgz#156aaa56dd7fad8c89c145be6ad7a4f7209f9785"
|
||||
|
@ -2829,6 +2922,11 @@
|
|||
"@types/keygrip" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/ejs@^3.1.5":
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.5.tgz#49d738257cc73bafe45c13cb8ff240683b4d5117"
|
||||
integrity sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==
|
||||
|
||||
"@types/eslint-scope@^3.7.3":
|
||||
version "3.7.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5"
|
||||
|
@ -3128,6 +3226,20 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
|
||||
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
|
||||
|
||||
"@types/ws@8.5.9":
|
||||
version "8.5.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.9.tgz#384c489f99c83225a53f01ebc3eddf3b8e202a8c"
|
||||
integrity sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/ws@^8.5.9":
|
||||
version "8.5.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787"
|
||||
integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@ucast/core@^1.0.0", "@ucast/core@^1.4.1", "@ucast/core@^1.6.1":
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/@ucast/core/-/core-1.10.2.tgz#30b6b893479823265368e528b61b042f752f2c92"
|
||||
|
@ -3192,6 +3304,11 @@
|
|||
"@types/babel__core" "^7.20.2"
|
||||
react-refresh "^0.14.0"
|
||||
|
||||
"@vladfrangu/async_event_emitter@^2.2.2":
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz#d3537432c6db6444680a596271dff8ea407343b3"
|
||||
integrity sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==
|
||||
|
||||
"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5":
|
||||
version "1.11.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24"
|
||||
|
@ -4060,7 +4177,7 @@ caniuse-lite@^1.0.30001565:
|
|||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz#893be772cf8ee6056d6c1e2d07df365b9ec0a5c4"
|
||||
integrity sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==
|
||||
|
||||
chalk@4.1.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
|
||||
chalk@4.1.2, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
|
@ -4931,6 +5048,31 @@ direction@^1.0.3:
|
|||
resolved "https://registry.yarnpkg.com/direction/-/direction-1.0.4.tgz#2b86fb686967e987088caf8b89059370d4837442"
|
||||
integrity sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==
|
||||
|
||||
discord-api-types@0.37.61:
|
||||
version "0.37.61"
|
||||
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.61.tgz#9dd8e58c624237e6f1b23be2d29579af268b8c5b"
|
||||
integrity sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==
|
||||
|
||||
discord.js@^14.14.1:
|
||||
version "14.14.1"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.14.1.tgz#9a2bea23bba13819705ab87612837610abce9ee3"
|
||||
integrity sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==
|
||||
dependencies:
|
||||
"@discordjs/builders" "^1.7.0"
|
||||
"@discordjs/collection" "1.5.3"
|
||||
"@discordjs/formatters" "^0.3.3"
|
||||
"@discordjs/rest" "^2.1.0"
|
||||
"@discordjs/util" "^1.0.2"
|
||||
"@discordjs/ws" "^1.0.2"
|
||||
"@sapphire/snowflake" "3.5.1"
|
||||
"@types/ws" "8.5.9"
|
||||
discord-api-types "0.37.61"
|
||||
fast-deep-equal "3.1.3"
|
||||
lodash.snakecase "4.1.1"
|
||||
tslib "2.6.2"
|
||||
undici "5.27.2"
|
||||
ws "8.14.2"
|
||||
|
||||
dkim-signer@0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/dkim-signer/-/dkim-signer-0.2.2.tgz#aa81ec071eeed3622781baa922044d7800e5f308"
|
||||
|
@ -5068,6 +5210,13 @@ ee-first@1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
|
||||
|
||||
ejs@^3.1.9:
|
||||
version "3.1.9"
|
||||
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361"
|
||||
integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==
|
||||
dependencies:
|
||||
jake "^10.8.5"
|
||||
|
||||
electron-to-chromium@^1.4.601:
|
||||
version "1.4.626"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.626.tgz#c20e1706354a31721b65e81496800534dd04b222"
|
||||
|
@ -5487,6 +5636,13 @@ figures@^3.0.0:
|
|||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
filelist@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
|
||||
integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==
|
||||
dependencies:
|
||||
minimatch "^5.0.1"
|
||||
|
||||
fill-range@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
|
||||
|
@ -6845,6 +7001,16 @@ iterall@^1.3.0:
|
|||
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea"
|
||||
integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==
|
||||
|
||||
jake@^10.8.5:
|
||||
version "10.8.7"
|
||||
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f"
|
||||
integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==
|
||||
dependencies:
|
||||
async "^3.2.3"
|
||||
chalk "^4.0.2"
|
||||
filelist "^1.0.4"
|
||||
minimatch "^3.1.2"
|
||||
|
||||
jest-worker@^27.4.5:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0"
|
||||
|
@ -7339,6 +7505,11 @@ lodash.isplainobject@4.0.6:
|
|||
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
||||
integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
|
||||
|
||||
lodash.snakecase@4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d"
|
||||
integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==
|
||||
|
||||
lodash.sortby@^4.7.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||
|
@ -7451,6 +7622,11 @@ luxon@^1.26.0:
|
|||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.1.tgz#528cdf3624a54506d710290a2341aa8e6e6c61b0"
|
||||
integrity sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==
|
||||
|
||||
magic-bytes.js@^1.5.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/magic-bytes.js/-/magic-bytes.js-1.8.0.tgz#8362793c60cd77c2dd77db6420be727192df68e2"
|
||||
integrity sha512-lyWpfvNGVb5lu8YUAbER0+UMBTdR63w2mcSUlhhBTyVbxJvjgqwyAf3AZD6MprgK0uHuBoWXSDAMWLupX83o3Q==
|
||||
|
||||
mailcomposer@3.12.0:
|
||||
version "3.12.0"
|
||||
resolved "https://registry.yarnpkg.com/mailcomposer/-/mailcomposer-3.12.0.tgz#9c5e1188aa8e1c62ec8b86bd43468102b639e8f9"
|
||||
|
@ -7682,7 +7858,7 @@ minimalistic-crypto-utils@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
||||
integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
|
||||
|
||||
minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1:
|
||||
minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
|
@ -10277,16 +10453,21 @@ triple-beam@^1.3.0:
|
|||
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984"
|
||||
integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==
|
||||
|
||||
ts-mixer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.3.tgz#69bd50f406ff39daa369885b16c77a6194c7cae6"
|
||||
integrity sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==
|
||||
|
||||
tslib@2.6.2, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.0, tslib@^2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
|
||||
tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.0:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
|
||||
tsscmp@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
|
||||
|
@ -10388,6 +10569,13 @@ undici-types@~5.26.4:
|
|||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||
|
||||
undici@5.27.2:
|
||||
version "5.27.2"
|
||||
resolved "https://registry.yarnpkg.com/undici/-/undici-5.27.2.tgz#a270c563aea5b46cc0df2550523638c95c5d4411"
|
||||
integrity sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==
|
||||
dependencies:
|
||||
"@fastify/busboy" "^2.0.0"
|
||||
|
||||
union-value@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
|
||||
|
@ -10843,11 +11031,21 @@ ws@8.13.0:
|
|||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
|
||||
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
|
||||
|
||||
ws@8.14.2:
|
||||
version "8.14.2"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f"
|
||||
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
|
||||
|
||||
ws@^7.3.1, ws@^7.4.6:
|
||||
version "7.5.9"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
|
||||
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
|
||||
|
||||
ws@^8.14.2:
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4"
|
||||
integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==
|
||||
|
||||
xdg-basedir@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
|
||||
|
|
Loading…
Reference in New Issue