mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-24 11:29:12 +00:00
port bot to rust, upgrade response, and cut away some of the tf cruft
This commit is contained in:
parent
0a37eff047
commit
f5fb729ce7
17 changed files with 1440 additions and 205 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -118,7 +118,7 @@ jobs:
|
|||
id: docker
|
||||
with:
|
||||
context: .
|
||||
file: ./hack/dockerfiles/${{matrix.dockerfile}}.Dockerfile
|
||||
file: ./packages/${{ matrix.dockerfile }}/Dockerfile
|
||||
push: true
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
FROM node:16 AS builder
|
||||
|
||||
# Create the user and group files that will be used in the running container to
|
||||
# run the process as an unprivileged user.
|
||||
RUN mkdir /user \
|
||||
&& echo 'nobody:x:65534:65534:nobody:/:' > /user/passwd \
|
||||
&& echo 'nobody:x:65534:' > /user/group
|
||||
|
||||
# Set the working directory outside $GOPATH to enable the support for modules.
|
||||
WORKDIR /src
|
||||
|
||||
# Fetch dependencies first; they are less susceptible to change on every build
|
||||
# and will therefore be cached for speeding up the next build
|
||||
COPY ./package.json ./yarn.lock /src/
|
||||
COPY ./packages/bot/package.json /src/packages/bot/
|
||||
RUN yarn workspace @roleypoly/bot install --focus
|
||||
|
||||
FROM node:16-slim AS final
|
||||
WORKDIR /src
|
||||
|
||||
COPY --from=builder /user/group /user/passwd /etc/
|
||||
USER nobody:nobody
|
||||
|
||||
# Import the code from the context.
|
||||
COPY --from=builder /src/node_modules /src/node_modules
|
||||
COPY ./packages/bot /src/packages/bot
|
||||
|
||||
ENTRYPOINT [ "node", "/src/packages/bot/index.js" ]
|
|
@ -57,5 +57,5 @@ export const embedResponse = (
|
|||
export const embedPalette = {
|
||||
success: 0x1d8227,
|
||||
error: 0xf14343,
|
||||
neutral: 0x2c2f33,
|
||||
neutral: 0x453e3d,
|
||||
};
|
||||
|
|
1
packages/bot/.gitignore
vendored
Normal file
1
packages/bot/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
target
|
1283
packages/bot/Cargo.lock
generated
Normal file
1283
packages/bot/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
12
packages/bot/Cargo.toml
Normal file
12
packages/bot/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "bot"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serenity = { version = "0.10.10", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "unstable_discord_api", "collector"] }
|
||||
dotenv = "0.15.0"
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
||||
url = "2.2.2"
|
22
packages/bot/Dockerfile
Normal file
22
packages/bot/Dockerfile
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Leveraging the pre-built Docker images with
|
||||
# cargo-chef and the Rust toolchain
|
||||
FROM lukemathwalker/cargo-chef:latest-rust-1.58.1 AS chef
|
||||
WORKDIR /app
|
||||
|
||||
FROM chef AS planner
|
||||
COPY . .
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
FROM chef AS builder
|
||||
COPY --from=planner /app/recipe.json recipe.json
|
||||
# Build dependencies - this is the caching Docker layer!
|
||||
RUN cargo chef cook --release --recipe-path recipe.json
|
||||
# Build application
|
||||
COPY . .
|
||||
RUN cargo build --release --bin app
|
||||
|
||||
# We do not need the Rust toolchain to run the binary!
|
||||
FROM gcr.io/distroless/base AS runtime
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/target/release/app /usr/local/bin
|
||||
ENTRYPOINT ["/usr/local/bin/app"]
|
19
packages/bot/README.md
Normal file
19
packages/bot/README.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Roleypoly Mention Responder
|
||||
|
||||
This is written in Rust.
|
||||
|
||||
You'll need:
|
||||
|
||||
- The rust toolchain (cargo, rust, etc)
|
||||
|
||||
...and nothing else.
|
||||
|
||||
## Premise of why Rust
|
||||
|
||||
Node.js is slow. It's fast enough for 90% of what we want to do, but due to the slowness and memory constraints we'd like to utilize, something else, particularly one designed for extreme multiprocessing (like Rust or Go) is infinitely better. More threads, more memory control (e.g. we can GC the majority of incoming info before we care about it), just better.
|
||||
|
||||
This was a very simple Node.js app, but it just couldn't be used with the production workload.
|
||||
|
||||
Roleypoly Legacy was running a Go-based bot that worked extremely well, and this iteration's de-evolution back to JS didn't end up working.
|
||||
|
||||
**tl;dr:** this piece of shit only responds to mentions. it has no real logic. it shouldn't take a $45/m cloud server to run it.
|
|
@ -1,34 +0,0 @@
|
|||
const { Client, Message } = require('discord.js');
|
||||
|
||||
const botToken = process.env['BOT_TOKEN'];
|
||||
const allowedBots = process.env['ALLOWED_BOTS']?.split(',') ?? [];
|
||||
const appUrl = process.env['UI_PUBLIC_URI'] ?? '';
|
||||
|
||||
function messageEventListener(message) {
|
||||
const { author, channel, client, guild, mentions } = message;
|
||||
|
||||
if (!guild) {
|
||||
return;
|
||||
} // Ignore DMs
|
||||
|
||||
if (
|
||||
client.user &&
|
||||
!mentions.has(client.user.id, { ignoreRoles: true, ignoreEveryone: true })
|
||||
) {
|
||||
return;
|
||||
} // Ignore non bot mentions
|
||||
|
||||
if (author.bot && !allowedBots.includes(author.id)) {
|
||||
return;
|
||||
} // Only respond to allowed bots
|
||||
|
||||
const guildId = guild.id;
|
||||
channel.send({ content: `:beginner: Assign your roles here! ${appUrl}/s/${guildId}` });
|
||||
}
|
||||
|
||||
const client = new Client({
|
||||
intents: ['GUILDS', 'GUILD_MESSAGES'],
|
||||
});
|
||||
|
||||
client.on('messageCreate', (message) => messageEventListener(message));
|
||||
client.login(botToken);
|
|
@ -1,12 +0,0 @@
|
|||
const path = require('path');
|
||||
require('dotenv').config({ path: path.resolve(__dirname, '../../.env') });
|
||||
|
||||
const { ShardingManager } = require('discord.js');
|
||||
|
||||
const botToken = process.env['BOT_TOKEN'];
|
||||
|
||||
const manager = new ShardingManager(path.resolve(__dirname, 'bot.js'), {
|
||||
token: botToken,
|
||||
});
|
||||
|
||||
manager.spawn();
|
|
@ -1,11 +1,7 @@
|
|||
{
|
||||
"name": "@roleypoly/bot",
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"discord.js": "^13.6.0",
|
||||
"dotenv": "^14.3.2"
|
||||
"start": "cargo run"
|
||||
}
|
||||
}
|
||||
|
|
89
packages/bot/src/main.rs
Normal file
89
packages/bot/src/main.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
extern crate dotenv;
|
||||
extern crate tokio;
|
||||
|
||||
use dotenv::dotenv;
|
||||
use std::env;
|
||||
use serenity::{
|
||||
async_trait,
|
||||
model::{
|
||||
channel::Message,
|
||||
gateway::Ready,
|
||||
interactions::{
|
||||
message_component::ButtonStyle,
|
||||
},
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
|
||||
struct Handler {
|
||||
ui_public_uri : String,
|
||||
ui_hostname : String,
|
||||
}
|
||||
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn message(&self, ctx: Context, msg: Message) {
|
||||
// No DMs, bots, or self.
|
||||
if msg.is_private() || msg.author.bot {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore messages that don't mention the bot
|
||||
if !msg.mentions_me(&ctx).await.unwrap_or(false) {
|
||||
return;
|
||||
}
|
||||
|
||||
msg.channel_id.send_message(&ctx, |m| {
|
||||
m.reference_message(&msg).allowed_mentions(|f| {
|
||||
f.replied_user(false)
|
||||
});
|
||||
|
||||
m.embed(|e| {
|
||||
e.title(":beginner: Howdy, pick your roles here!");
|
||||
e.description("Roleypoly will open in your browser.\n\nIf that's not cool with you, try the `/roleypoly` command!");
|
||||
e.url(&self.ui_public_uri);
|
||||
e.color(0x453e3d);
|
||||
e
|
||||
});
|
||||
|
||||
m.components(|c| {
|
||||
c.create_action_row(|r| {
|
||||
r.create_button(|b| {
|
||||
b.style(ButtonStyle::Link);
|
||||
b.url(&self.ui_public_uri);
|
||||
b.label(format!("Pick your roles on {}", self.ui_hostname));
|
||||
b
|
||||
});
|
||||
r
|
||||
});
|
||||
c
|
||||
});
|
||||
m
|
||||
}).await.unwrap();
|
||||
}
|
||||
|
||||
async fn ready(&self, _: Context, ready: Ready) {
|
||||
println!("{} is connected! (shard: {:?})", ready.user.name, ready.shard.unwrap_or_default());
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
dotenv().ok();
|
||||
let token = env::var("BOT_TOKEN").expect("BOT_TOKEN not set");
|
||||
let client_id: u64 = env::var("BOT_CLIENT_ID").expect("BOT_CLIENT_ID not set").parse().unwrap();
|
||||
let ui_public_uri = env::var("UI_PUBLIC_URI").expect("UI_PUBLIC_URI not set");
|
||||
let ui_hostname = url::Url::parse(&ui_public_uri).unwrap().host_str().unwrap().to_string();
|
||||
|
||||
let mut client =
|
||||
Client::builder(&token).application_id(client_id).event_handler(Handler {
|
||||
ui_public_uri,
|
||||
ui_hostname,
|
||||
}).await.expect("Err creating client");
|
||||
|
||||
if let Err(why) = client.start_autosharded().await {
|
||||
println!("Client error: {:?}", why);
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
locals {
|
||||
artifactBaseMap = {
|
||||
us-east4 = "us-docker.pkg.dev/roleypoly/roleypoly"
|
||||
us-central1 = "us-docker.pkg.dev/roleypoly/roleypoly"
|
||||
us-west1 = "us-docker.pkg.dev/roleypoly/roleypoly"
|
||||
europe-west2 = "europe-docker.pkg.dev/roleypoly/roleypoly"
|
||||
europe-west3 = "europe-docker.pkg.dev/roleypoly/roleypoly"
|
||||
australia-southeast1 = "asia-docker.pkg.dev/roleypoly/roleypoly"
|
||||
asia-northeast1 = "asia-docker.pkg.dev/roleypoly/roleypoly"
|
||||
asia-southeast1 = "asia-docker.pkg.dev/roleypoly/roleypoly"
|
||||
}
|
||||
}
|
|
@ -8,11 +8,6 @@ variable "environment_tag" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "ui_regions" {
|
||||
type = list(string)
|
||||
description = "Cloud Run regions to deploy UI to"
|
||||
}
|
||||
|
||||
variable "ui_tag" {
|
||||
type = string
|
||||
description = ":tag or @sha265: of *-docker.pkg.dev/roleypoly/roleypoly/ui"
|
||||
|
@ -47,11 +42,6 @@ variable "ui_public_uri" {
|
|||
description = "UI Public Base Path"
|
||||
}
|
||||
|
||||
variable "ui_hostnames" {
|
||||
type = list(string)
|
||||
description = "Hostnames to allow web UI requests from, e.g. roleypoly.com, web-prod.roleypoly.com"
|
||||
}
|
||||
|
||||
variable "api_public_uri" {
|
||||
type = string
|
||||
description = "API Public Base Path"
|
||||
|
|
|
@ -1,20 +1,6 @@
|
|||
environment_tag = "prod"
|
||||
ui_regions = [
|
||||
"us-east4",
|
||||
"us-central1",
|
||||
"us-west1",
|
||||
"europe-west2",
|
||||
"europe-west3",
|
||||
"australia-southeast1",
|
||||
"asia-northeast1",
|
||||
"asia-southeast1"
|
||||
]
|
||||
deploy_bot = true
|
||||
bot_instance_size = "e2-medium"
|
||||
ui_hostnames = [
|
||||
"next.roleypoly.com",
|
||||
"web-prod.roleypoly.com"
|
||||
]
|
||||
bot_instance_size = "e2-small"
|
||||
ui_public_uri = "https://roleypoly.com"
|
||||
api_public_uri = "https://api-prod.roleypoly.com"
|
||||
allowed_callback_hosts = "https://roleypoly.com,https://next.roleypoly.com"
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
environment_tag = "stage"
|
||||
ui_regions = [
|
||||
"us-east4"
|
||||
]
|
||||
deploy_bot = true
|
||||
bot_instance_size = "f1-micro"
|
||||
ui_hostnames = [
|
||||
"stage.roleypoly.com",
|
||||
"web-stage.roleypoly.com"
|
||||
]
|
||||
ui_public_uri = "https://stage.roleypoly.com"
|
||||
api_public_uri = "https://api-stage.roleypoly.com"
|
||||
allowed_callback_hosts = "https://roleypoly.com,https://stage.roleypoly.com,https://*.roleypoly.pages.dev"
|
76
yarn.lock
76
yarn.lock
|
@ -1198,22 +1198,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4"
|
||||
integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==
|
||||
|
||||
"@discordjs/builders@^0.11.0":
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-0.11.0.tgz#4102abe3e0cd093501f3f71931df43eb92f5b0cc"
|
||||
integrity sha512-ZTB8yJdJKrKlq44dpWkNUrAtEJEq0gqpb7ASdv4vmq6/mZal5kOv312hQ56I/vxwMre+VIkoHquNUAfnTbiYtg==
|
||||
dependencies:
|
||||
"@sindresorhus/is" "^4.2.0"
|
||||
discord-api-types "^0.26.0"
|
||||
ts-mixer "^6.0.0"
|
||||
tslib "^2.3.1"
|
||||
zod "^3.11.6"
|
||||
|
||||
"@discordjs/collection@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.4.0.tgz#b6488286a1cc7b41b644d7e6086f25a1c1e6f837"
|
||||
integrity sha512-zmjq+l/rV35kE6zRrwe8BHqV78JvIh2ybJeZavBi5NySjWXqN3hmmAKg7kYMMXSeiWtSsMoZ/+MQi0DiQWy2lw==
|
||||
|
||||
"@discoveryjs/json-ext@^0.5.3":
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
|
||||
|
@ -1872,16 +1856,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz#7f698254aadf921e48dda8c0a6b304026b8a9323"
|
||||
integrity sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==
|
||||
|
||||
"@sapphire/async-queue@^1.1.9":
|
||||
version "1.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.1.9.tgz#ce69611c8753c4affd905a7ef43061c7eb95c01b"
|
||||
integrity sha512-CbXaGwwlEMq+l1TRu01FJCvySJ1CEFKFclHT48nIfNeZXaAAmmwwy7scUKmYHPUa3GhoMp6Qr1B3eAJux6XgOQ==
|
||||
|
||||
"@sindresorhus/is@^4.2.0":
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.3.0.tgz#344fd9bf808a84567ba563d00cc54b2f428dbab1"
|
||||
integrity sha512-wwOvh0eO3PiTEivGJWiZ+b946SlMSb4pe+y+Ur/4S87cwo09pYi+FWHHnbrM3W9W7cBYKDqQXcrFYjYUCOJUEQ==
|
||||
|
||||
"@sinonjs/commons@^1.7.0":
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217"
|
||||
|
@ -3204,7 +3178,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
|
||||
integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
|
||||
|
||||
"@types/node-fetch@^2.5.12", "@types/node-fetch@^2.5.7":
|
||||
"@types/node-fetch@^2.5.7":
|
||||
version "2.5.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66"
|
||||
integrity sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==
|
||||
|
@ -6398,26 +6372,6 @@ discontinuous-range@1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
|
||||
integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=
|
||||
|
||||
discord-api-types@^0.26.0:
|
||||
version "0.26.1"
|
||||
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.26.1.tgz#726f766ddc37d60da95740991d22cb6ef2ed787b"
|
||||
integrity sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ==
|
||||
|
||||
discord.js@^13.6.0:
|
||||
version "13.6.0"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.6.0.tgz#d8a8a591dbf25cbcf9c783d5ddf22c4694860475"
|
||||
integrity sha512-tXNR8zgsEPxPBvGk3AQjJ9ljIIC6/LOPjzKwpwz8Y1Q2X66Vi3ZqFgRHYwnHKC0jC0F+l4LzxlhmOJsBZDNg9g==
|
||||
dependencies:
|
||||
"@discordjs/builders" "^0.11.0"
|
||||
"@discordjs/collection" "^0.4.0"
|
||||
"@sapphire/async-queue" "^1.1.9"
|
||||
"@types/node-fetch" "^2.5.12"
|
||||
"@types/ws" "^8.2.2"
|
||||
discord-api-types "^0.26.0"
|
||||
form-data "^4.0.0"
|
||||
node-fetch "^2.6.1"
|
||||
ws "^8.4.0"
|
||||
|
||||
dlv@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
|
||||
|
@ -6579,11 +6533,6 @@ dotenv@^10.0.0:
|
|||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
|
||||
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
|
||||
|
||||
dotenv@^14.3.2:
|
||||
version "14.3.2"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-14.3.2.tgz#7c30b3a5f777c79a3429cb2db358eef6751e8369"
|
||||
integrity sha512-vwEppIphpFdvaMCaHfCEv9IgwcxMljMw2TnAQBB4VWPvzXQLTb82jwmdOKzlEVUL3gNFT4l4TPKO+Bn+sqcrVQ==
|
||||
|
||||
dotenv@^8.0.0:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
|
||||
|
@ -7733,15 +7682,6 @@ form-data@^3.0.0:
|
|||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
format@^0.2.0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
|
||||
|
@ -14754,11 +14694,6 @@ ts-loader@^9.2.6:
|
|||
micromatch "^4.0.0"
|
||||
semver "^7.3.4"
|
||||
|
||||
ts-mixer@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.0.tgz#4e631d3a36e3fa9521b973b132e8353bc7267f9f"
|
||||
integrity sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==
|
||||
|
||||
ts-node@^10.4.0:
|
||||
version "10.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"
|
||||
|
@ -14797,7 +14732,7 @@ tslib@^1.8.1, tslib@^1.9.0:
|
|||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1:
|
||||
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||
|
@ -15912,7 +15847,7 @@ ws@^7.4.6:
|
|||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b"
|
||||
integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==
|
||||
|
||||
ws@^8.1.0, ws@^8.2.2, ws@^8.2.3, ws@^8.4.0:
|
||||
ws@^8.1.0, ws@^8.2.2, ws@^8.2.3:
|
||||
version "8.4.2"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b"
|
||||
integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==
|
||||
|
@ -15995,11 +15930,6 @@ youch@^2.2.2:
|
|||
mustache "^4.2.0"
|
||||
stack-trace "0.0.10"
|
||||
|
||||
zod@^3.11.6:
|
||||
version "3.11.6"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.11.6.tgz#e43a5e0c213ae2e02aefe7cb2b1a6fa3d7f1f483"
|
||||
integrity sha512-daZ80A81I3/9lIydI44motWe6n59kRBfNzTuS2bfzVh1nAXi667TOTWWtatxyG+fwgNUiagSj/CWZwRRbevJIg==
|
||||
|
||||
zwitch@^1.0.0:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
|
||||
|
|
Loading…
Add table
Reference in a new issue