diff --git a/app/migrations/20241101084749_add_substitution_column_to_customer_order.js b/app/migrations/20241101084749_add_substitution_column_to_customer_order.js new file mode 100644 index 0000000..6ca1f3e --- /dev/null +++ b/app/migrations/20241101084749_add_substitution_column_to_customer_order.js @@ -0,0 +1,19 @@ +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = function (knex) { + return knex.schema.table("CustomerOrder", table => { + table.json("Substitution").nullable().defaultTo(null).after("Reply"); + }); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = function (knex) { + return knex.schema.table("CustomerOrder", table => { + table.dropColumn("substitution"); + }); +}; diff --git a/app/package.json b/app/package.json index d279fb1..62761b6 100644 --- a/app/package.json +++ b/app/package.json @@ -12,7 +12,7 @@ "migrate": "knex migrate:latest" }, "dependencies": { - "@sentry/node": "^8.35.0", + "@sentry/node": "^8.36.0", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "axios": "1.7.7", @@ -20,7 +20,7 @@ "brotli": "^1.3.3", "cheerio": "^1.0.0", "config": "^3.3.12", - "cron": "^3.1.7", + "cron": "^3.1.8", "date-format": "^4.0.14", "express": "^4.21.1", "express-rate-limit": "^7.4.1", @@ -36,7 +36,7 @@ "moment": "^2.30.1", "mysql2": "^3.11.3", "redis": "^4.7.0", - "socket.io": "^4.8.0", + "socket.io": "^4.8.1", "sqlite3": "^5.1.7", "table": "^6.8.2", "uuid-random": "^1.3.2" diff --git a/app/src/app.js b/app/src/app.js index 7384f0a..3c73cff 100644 --- a/app/src/app.js +++ b/app/src/app.js @@ -286,12 +286,8 @@ function CustomerOrder(context) { return [ text(/^[#.]?(指令列表|orderlist)$/, showOrderManager), - text(/^[#.]?新增指令/, (context, props) => - customerOrder.insertCustomerOrder(context, props, 1) - ), - text(/^[#.]?新增關鍵字指令/, (context, props) => - customerOrder.insertCustomerOrder(context, props, 2) - ), + text(/^[#.]?新增指令/, withProps(customerOrder.insertCustomerOrder, { touchType: 1 })), + text(/^[#.]?新增關鍵字指令/, withProps(customerOrder.insertCustomerOrder, { touchType: 2 })), text( /^[#.]?[移刪]除指令(\s*(?\S+))?(\s*(?\S+))?$/, customerOrder.deleteCustomerOrder diff --git a/app/src/controller/application/CustomerOrder.js b/app/src/controller/application/CustomerOrder.js index 9157860..a39448a 100644 --- a/app/src/controller/application/CustomerOrder.js +++ b/app/src/controller/application/CustomerOrder.js @@ -5,6 +5,7 @@ const random = require("math-random"); const CustomerOrderTemplate = require("../../templates/application/CustomerOrder"); const { send } = require("../../templates/application/Order"); const { recordSign } = require("../../util/traffic"); +const { get } = require("lodash"); function CusOrderException(message, code = 0) { this.message = message; @@ -18,7 +19,7 @@ function CusOrderException(message, code = 0) { * @return {Object} */ function initialReply(strReply) { - var replyDatas = strReply + let replyDatas = strReply .split(/\|/) .filter(reply => reply.trim() !== "") .map(reply => { @@ -80,16 +81,17 @@ function handleSender(param) { * 新增自訂指令 * @param {Context} context * @param {Object} props - * @param {Number} touchType 觸發類型,1:完全符合,2:部分符合 + * @param {Number} props.touchType 觸發類型,1:完全符合,2:部分符合 */ -exports.insertCustomerOrder = async (context, props, touchType = 1) => { +exports.insertCustomerOrder = async (context, props) => { try { recordSign("insertCustomerOrder"); const param = minimist(context.event.message.text.split(/\s+/)); + const { touchType } = props; - var [prefix, order] = param._; - var reply = context.event.message.text.replace(prefix, "").replace(order, "").trim(); - var [sourceId, userId] = getSourceId(context); + let [prefix, order] = param._; + let reply = context.event.message.text.replace(prefix, "").replace(order, "").trim(); + let [sourceId, userId] = getSourceId(context); if (order === undefined || reply === undefined) { CustomerOrderTemplate[context.platform].showInsertManual(context); @@ -98,8 +100,30 @@ exports.insertCustomerOrder = async (context, props, touchType = 1) => { reply = reply.toString(); - var replyDatas = initialReply(reply); - var { name, iconUrl } = handleSender(param); + const mentionees = get(context, "event.message.mention.mentionees", []); + let substitution = {}; + // 如果 reply 內容有 mention,需轉換為替代字元 + mentionees.forEach((mentionee, idx) => { + const name = get(context, "event.message.text", "").substring( + mentionee.index, + mentionee.index + mentionee.length + ); + + // @all 不處理 + if (mentionee.type === "all") return; + + substitution[`user${idx}`] = { + type: "mention", + mentionee: { + type: "user", + userId: mentionee.userId, + }, + }; + reply = reply.replace(name, `{user${idx}}`); + }); + + let replyDatas = initialReply(reply); + let { name, iconUrl } = handleSender(param); let orderKey = uuid(); let params = replyDatas.map((data, index) => ({ @@ -110,6 +134,7 @@ exports.insertCustomerOrder = async (context, props, touchType = 1) => { touchType, MessageType: data.type, Reply: data.data, + Substitution: substitution, CreateDTM: new Date(), CreateUser: userId, ModifyUser: userId, @@ -155,13 +180,13 @@ function getSourceId(context) { * @param {Context} context */ exports.CustomerOrderDetect = async context => { - var [sourceId] = getSourceId(context); - var orderDatas = await CustomerOrderModel.queryOrderBySourceId(sourceId, 1); + let [sourceId] = getSourceId(context); + let orderDatas = await CustomerOrderModel.queryOrderBySourceId(sourceId, 1); // 尚未建立任何指令 if (orderDatas.length === 0) return false; - var chosenOrderKey = chooseOrder(orderDatas); + let chosenOrderKey = chooseOrder(orderDatas); if (chosenOrderKey === false) return false; recordSign("CustomerOrderDetect"); @@ -245,12 +270,12 @@ exports.deleteCustomerOrder = async (context, { match }) => { return; } - var [sourceId, userId] = getSourceId(context); + let [sourceId, userId] = getSourceId(context); - var deleteOrders = await CustomerOrderModel.queryOrderToDelete(order, sourceId); + let deleteOrders = await CustomerOrderModel.queryOrderToDelete(order, sourceId); if (deleteOrders.length === 0) throw new CusOrderException(`未搜尋到"${order}"的指令`); - var { orderKey: key } = autoComplete(orderKey, deleteOrders); + let { orderKey: key } = autoComplete(orderKey, deleteOrders); // 剛好只有一筆符合刪除條件 if (deleteOrders.length === 1 || key !== undefined) { await CustomerOrderModel.setStatus( @@ -289,7 +314,7 @@ exports.api = {}; exports.api.fetchCustomerOrders = async (req, res) => { const { sourceId } = req.params; - var orderDatas = await CustomerOrderModel.queryOrderBySourceId(sourceId); + let orderDatas = await CustomerOrderModel.queryOrderBySourceId(sourceId); let userIds = []; orderDatas.forEach(data => { @@ -311,7 +336,7 @@ exports.api.updateOrder = async (req, res) => { const { userId } = req.profile; try { - var updateResult = await CustomerOrderModel.updateOrder(sourceId, req.body, userId); + let updateResult = await CustomerOrderModel.updateOrder(sourceId, req.body, userId); if (updateResult === false) throw new CusOrderException("Update Failed", 2); res.json({}); @@ -331,8 +356,8 @@ exports.api.insertOrder = async (req, res) => { const { body: orderDatas, profile } = req; try { - var { order, senderName, senderIcon, touchType } = orderDatas; - var orderKey = uuid(); + let { order, senderName, senderIcon, touchType } = orderDatas; + let orderKey = uuid(); if ([order, touchType].includes("")) throw new CusOrderException("Bad Request."); if ([order, touchType].includes(null)) throw new CusOrderException("Bad Request."); @@ -346,7 +371,7 @@ exports.api.insertOrder = async (req, res) => { throw new CusOrderException("Bad Request."); }); - var params = orderDatas.replyDatas.map((data, index) => ({ + let params = orderDatas.replyDatas.map((data, index) => ({ No: index, sourceId, orderKey, diff --git a/app/src/templates/application/Order.js b/app/src/templates/application/Order.js index 2aadfb3..45ecda7 100644 --- a/app/src/templates/application/Order.js +++ b/app/src/templates/application/Order.js @@ -4,7 +4,7 @@ const CharacterModel = require("../../model/princess/character"); /** * 發送訊息整合,整合多平台發送方式 - * @param {Context} context + * @param {import("bottender").LineContext} context * @param {Array.} replyData * @param {String|Number} replyData.no * @param {String} replyData.messageType @@ -21,13 +21,25 @@ exports.send = (context, replyDatas, sender = { name: null, iconUrl: null }) => replyDatas .sort((a, b) => a.no - b.no) .forEach(data => { - let content = handleText(data.reply, context); - switch (data.messageType) { + const { reply, messageType, substitution } = data; + let content = handleText(reply, context); + switch (messageType) { case "image": _sendImage(context, content, sender); return; case "text": - context.replyText(content, { sender }); + if (substitution !== null) { + context.reply([ + { + type: "textV2", + text: content, + sender, + substitution, + }, + ]); + } else { + context.replyText(content, { sender }); + } return; } }); diff --git a/app/yarn.lock b/app/yarn.lock index d1e06da..b9889d9 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -949,7 +949,14 @@ dependencies: "@opentelemetry/api" "^1.0.0" -"@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.8", "@opentelemetry/api@^1.9.0": +"@opentelemetry/api-logs@0.54.0": + version "0.54.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.54.0.tgz#a8e09ae22f6d318b6202765dbc2cc0b05e3377be" + integrity sha512-9HhEh5GqFrassUndqJsyW7a0PzfyWr2eV2xwzHLIS+wX3125+9HE9FMRAKmJRwxZhgZGwH3HNQQjoMGZqmOeVA== + dependencies: + "@opentelemetry/api" "^1.3.0" + +"@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.3.0", "@opentelemetry/api@^1.8", "@opentelemetry/api@^1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== @@ -982,13 +989,13 @@ "@opentelemetry/instrumentation" "^0.53.0" "@opentelemetry/semantic-conventions" "^1.27.0" -"@opentelemetry/instrumentation-connect@0.39.0": - version "0.39.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.39.0.tgz#32bdbaac464cba061c95df6c850ee81efdd86f8b" - integrity sha512-pGBiKevLq7NNglMgqzmeKczF4XQMTOUOTkK8afRHMZMnrK3fcETyTH7lVaSozwiOM3Ws+SuEmXZT7DYrrhxGlg== +"@opentelemetry/instrumentation-connect@0.40.0": + version "0.40.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.40.0.tgz#cb151b860ad8a711ebce4d7e025dcde95e4ba2c5" + integrity sha512-3aR/3YBQ160siitwwRLjwqrv2KBT16897+bo6yz8wIfel6nWOxTZBJudcbsK3p42pTC7qrbotJ9t/1wRLpv79Q== dependencies: "@opentelemetry/core" "^1.8.0" - "@opentelemetry/instrumentation" "^0.53.0" + "@opentelemetry/instrumentation" "^0.54.0" "@opentelemetry/semantic-conventions" "^1.27.0" "@types/connect" "3.4.36" @@ -999,13 +1006,13 @@ dependencies: "@opentelemetry/instrumentation" "^0.53.0" -"@opentelemetry/instrumentation-express@0.43.0": - version "0.43.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-express/-/instrumentation-express-0.43.0.tgz#35ff5bcf40b816d9a9159d5f7814ed7e5d83f69b" - integrity sha512-bxTIlzn9qPXJgrhz8/Do5Q3jIlqfpoJrSUtVGqH+90eM1v2PkPHc+SdE+zSqe4q9Y1UQJosmZ4N4bm7Zj/++MA== +"@opentelemetry/instrumentation-express@0.44.0": + version "0.44.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-express/-/instrumentation-express-0.44.0.tgz#51dc11e3152ffbee1c4e389298aac30231c8270a" + integrity sha512-GWgibp6Q0wxyFaaU8ERIgMMYgzcHmGrw3ILUtGchLtLncHNOKk0SNoWGqiylXWWT4HTn5XdV8MGawUgpZh80cA== dependencies: "@opentelemetry/core" "^1.8.0" - "@opentelemetry/instrumentation" "^0.53.0" + "@opentelemetry/instrumentation" "^0.54.0" "@opentelemetry/semantic-conventions" "^1.27.0" "@opentelemetry/instrumentation-fastify@0.40.0": @@ -1017,13 +1024,13 @@ "@opentelemetry/instrumentation" "^0.53.0" "@opentelemetry/semantic-conventions" "^1.27.0" -"@opentelemetry/instrumentation-fs@0.15.0": - version "0.15.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.15.0.tgz#41658507860f39fee5209bca961cea8d24ca2a83" - integrity sha512-JWVKdNLpu1skqZQA//jKOcKdJC66TWKqa2FUFq70rKohvaSq47pmXlnabNO+B/BvLfmidfiaN35XakT5RyMl2Q== +"@opentelemetry/instrumentation-fs@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.16.0.tgz#aa1cc3aa81011ad9843a0156b200f06f31ffa03e" + integrity sha512-hMDRUxV38ln1R3lNz6osj3YjlO32ykbHqVrzG7gEhGXFQfu7LJUx8t9tEwE4r2h3CD4D0Rw4YGDU4yF4mP3ilg== dependencies: "@opentelemetry/core" "^1.8.0" - "@opentelemetry/instrumentation" "^0.53.0" + "@opentelemetry/instrumentation" "^0.54.0" "@opentelemetry/instrumentation-generic-pool@0.39.0": version "0.39.0" @@ -1067,12 +1074,12 @@ "@opentelemetry/redis-common" "^0.36.2" "@opentelemetry/semantic-conventions" "^1.27.0" -"@opentelemetry/instrumentation-kafkajs@0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.3.0.tgz#6687bce4dac8b90ef8ccbf1b662d5d1e95a34414" - integrity sha512-UnkZueYK1ise8FXQeKlpBd7YYUtC7mM8J0wzUSccEfc/G8UqHQqAzIyYCUOUPUKp8GsjLnWOOK/3hJc4owb7Jg== +"@opentelemetry/instrumentation-kafkajs@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.4.0.tgz#c1fe0de45a65a66581be0d7422f6828cc806b3bb" + integrity sha512-I9VwDG314g7SDL4t8kD/7+1ytaDBRbZQjhVaQaVIDR8K+mlsoBhLsWH79yHxhHQKvwCSZwqXF+TiTOhoQVUt7A== dependencies: - "@opentelemetry/instrumentation" "^0.53.0" + "@opentelemetry/instrumentation" "^0.54.0" "@opentelemetry/semantic-conventions" "^1.27.0" "@opentelemetry/instrumentation-koa@0.43.0": @@ -1187,6 +1194,18 @@ semver "^7.5.2" shimmer "^1.2.1" +"@opentelemetry/instrumentation@^0.54.0": + version "0.54.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.54.0.tgz#3fa9df964d3b157ea7ef2270168d343331d6448e" + integrity sha512-B0Ydo9g9ehgNHwtpc97XivEzjz0XBKR6iQ83NTENIxEEf5NHE0otZQuZLgDdey1XNk+bP1cfRpIkSFWM5YlSyg== + dependencies: + "@opentelemetry/api-logs" "0.54.0" + "@types/shimmer" "^1.2.0" + import-in-the-middle "^1.8.1" + require-in-the-middle "^7.1.1" + semver "^7.5.2" + shimmer "^1.2.1" + "@opentelemetry/redis-common@^0.36.2": version "0.36.2" resolved "https://registry.yarnpkg.com/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz#906ac8e4d804d4109f3ebd5c224ac988276fdc47" @@ -1300,35 +1319,35 @@ resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.1.0.tgz#cba454c05ec201bd5547aaf55286d44682ac8eb5" integrity sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g== -"@sentry/core@8.35.0": - version "8.35.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-8.35.0.tgz#17090f4d2d3bb983d9d99ecd2d27f4e9e107e0b0" - integrity sha512-Ci0Nmtw5ETWLqQJGY4dyF+iWh7PWKy6k303fCEoEmqj2czDrKJCp7yHBNV0XYbo00prj2ZTbCr6I7albYiyONA== +"@sentry/core@8.36.0": + version "8.36.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-8.36.0.tgz#34276354f0cd2298803c2f8d86ba571473435ff1" + integrity sha512-cbq1WQyRqc/+YpPhjwQxfniUM3ZxmO3Pm1oisTB8dw6mlbgQfGD6aznEIjXWWJY6k6acewJlMUx09N7DnprtBw== dependencies: - "@sentry/types" "8.35.0" - "@sentry/utils" "8.35.0" + "@sentry/types" "8.36.0" + "@sentry/utils" "8.36.0" -"@sentry/node@^8.35.0": - version "8.35.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-8.35.0.tgz#14ab7d77d5bcce649e571fa05b4efacb71811395" - integrity sha512-B0FLOcZEfYe3CJ2t0l1N0HJcHXcIrLlGENQ2kf5HqR2zcOcOzRxyITJTSV5brCnmzVNgkz9PG8VWo3w0HXZQpA== +"@sentry/node@^8.36.0": + version "8.36.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-8.36.0.tgz#6b4b6714c6c925e353e7c7eff0e45f8675bb530e" + integrity sha512-2RRbSck90TGpVz8F3OaNbq5Q9RXgeRlq5leGWHU7NfQOl3LmkG+vkzTbOqPDPZLtiYcw5KQ3G5G+vybrDS6AGg== dependencies: "@opentelemetry/api" "^1.9.0" "@opentelemetry/context-async-hooks" "^1.25.1" "@opentelemetry/core" "^1.25.1" "@opentelemetry/instrumentation" "^0.53.0" "@opentelemetry/instrumentation-amqplib" "^0.42.0" - "@opentelemetry/instrumentation-connect" "0.39.0" + "@opentelemetry/instrumentation-connect" "0.40.0" "@opentelemetry/instrumentation-dataloader" "0.12.0" - "@opentelemetry/instrumentation-express" "0.43.0" + "@opentelemetry/instrumentation-express" "0.44.0" "@opentelemetry/instrumentation-fastify" "0.40.0" - "@opentelemetry/instrumentation-fs" "0.15.0" + "@opentelemetry/instrumentation-fs" "0.16.0" "@opentelemetry/instrumentation-generic-pool" "0.39.0" "@opentelemetry/instrumentation-graphql" "0.43.0" "@opentelemetry/instrumentation-hapi" "0.41.0" "@opentelemetry/instrumentation-http" "0.53.0" "@opentelemetry/instrumentation-ioredis" "0.43.0" - "@opentelemetry/instrumentation-kafkajs" "0.3.0" + "@opentelemetry/instrumentation-kafkajs" "0.4.0" "@opentelemetry/instrumentation-koa" "0.43.0" "@opentelemetry/instrumentation-lru-memoizer" "0.40.0" "@opentelemetry/instrumentation-mongodb" "0.47.0" @@ -1343,32 +1362,32 @@ "@opentelemetry/sdk-trace-base" "^1.26.0" "@opentelemetry/semantic-conventions" "^1.27.0" "@prisma/instrumentation" "5.19.1" - "@sentry/core" "8.35.0" - "@sentry/opentelemetry" "8.35.0" - "@sentry/types" "8.35.0" - "@sentry/utils" "8.35.0" + "@sentry/core" "8.36.0" + "@sentry/opentelemetry" "8.36.0" + "@sentry/types" "8.36.0" + "@sentry/utils" "8.36.0" import-in-the-middle "^1.11.2" -"@sentry/opentelemetry@8.35.0": - version "8.35.0" - resolved "https://registry.yarnpkg.com/@sentry/opentelemetry/-/opentelemetry-8.35.0.tgz#8cf88deb50813ea84c355bddeb49ec0bbebb1b49" - integrity sha512-2mWMpEiIFop/omia9BqTJa+0Khe+tSsiZSUrxbnSpxM0zgw8DFIzJMHbiqw/I7Qaluz9pnO2HZXqgUTwNPsU8A== +"@sentry/opentelemetry@8.36.0": + version "8.36.0" + resolved "https://registry.yarnpkg.com/@sentry/opentelemetry/-/opentelemetry-8.36.0.tgz#4e4330fa67cfeb7f2e23d4e078659ac61806b3b0" + integrity sha512-pMKMphH0j1Mh8zknLWEEUaaaxeYn76rniGOxKLoQVk1pCUhhzkFEJdxKC41aR8yin/uN8X3CGWQb9vp/przwSg== dependencies: - "@sentry/core" "8.35.0" - "@sentry/types" "8.35.0" - "@sentry/utils" "8.35.0" + "@sentry/core" "8.36.0" + "@sentry/types" "8.36.0" + "@sentry/utils" "8.36.0" -"@sentry/types@8.35.0": - version "8.35.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-8.35.0.tgz#535c807800f7e378f61416f30177c0ef81b95012" - integrity sha512-AVEZjb16MlYPifiDDvJ19dPQyDn0jlrtC1PHs6ZKO+Rzyz+2EX2BRdszvanqArldexPoU1p5Bn2w81XZNXThBA== +"@sentry/types@8.36.0": + version "8.36.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-8.36.0.tgz#b58397eb672d896b65b06103feb59dba74da9d39" + integrity sha512-K1pVFfdGHw115RzGHpwSOqoEPeayn4N1F9IfM0kxrYpQSbFT1X29eak88GBfC8gPiLEF0iFGlSaQ4ERmF7oRcA== -"@sentry/utils@8.35.0": - version "8.35.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-8.35.0.tgz#1e099fcbc60040091c79f028a83226c145d588ee" - integrity sha512-MdMb6+uXjqND7qIPWhulubpSeHzia6HtxeJa8jYI09OCvIcmNGPydv/Gx/LZBwosfMHrLdTWcFH7Y7aCxrq7cg== +"@sentry/utils@8.36.0": + version "8.36.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-8.36.0.tgz#e733042ae231fdeeafe6970e49283dcd9ac9700f" + integrity sha512-oJ3EDPj0I00z+AwC3EWBpSidXYUoKW0Id8MfMQP5Hflniz3gif7UEReblT+FJgPEVo6+6uNzAncY0MuNMxmDKQ== dependencies: - "@sentry/types" "8.35.0" + "@sentry/types" "8.36.0" "@sinclair/typebox@^0.27.8": version "0.27.8" @@ -2879,13 +2898,13 @@ create-jest@^29.7.0: jest-util "^29.7.0" prompts "^2.0.1" -cron@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/cron/-/cron-3.1.7.tgz#3423d618ba625e78458fff8cb67001672d49ba0d" - integrity sha512-tlBg7ARsAMQLzgwqVxy8AZl/qlTc5nibqYwtNGoCrd+cV+ugI+tvZC1oT/8dFH8W455YrywGykx/KMmAqOr7Jw== +cron@^3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cron/-/cron-3.1.8.tgz#0def028942596ee528879a1251e1c612b9afc22b" + integrity sha512-45bqmAOSd/XB5JJWfV1W59fFEzqgNNWmOYQZVcw0sfyQqU35HFdVfTsr2xzlqWoTAfspRrvK0lSSLj8Pj9YmpQ== dependencies: "@types/luxon" "~3.4.0" - luxon "~3.4.0" + luxon "~3.5.0" cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" @@ -5241,10 +5260,10 @@ lru.min@^1.0.0: resolved "https://registry.yarnpkg.com/lru.min/-/lru.min-1.1.0.tgz#fd222364c440a389d2c4e5f637cc0521a114bfca" integrity sha512-86xXMB6DiuKrTqkE/lRL0drlNh568awttBPJ7D66fzDHpy6NC5r3N+Ly/lKCS2zjmeGyvFDx670z0cD0PVBwGA== -luxon@~3.4.0: - version "3.4.3" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.3.tgz#8ddf0358a9492267ffec6a13675fbaab5551315d" - integrity sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg== +luxon@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.5.0.tgz#6b6f65c5cd1d61d1fd19dbf07ee87a50bf4b8e20" + integrity sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ== make-dir@^3.0.0: version "3.1.0" @@ -6902,10 +6921,10 @@ socket.io-parser@~4.2.4: "@socket.io/component-emitter" "~3.1.0" debug "~4.3.1" -socket.io@^4.8.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.8.0.tgz#33d05ae0915fad1670bd0c4efcc07ccfabebe3b1" - integrity sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA== +socket.io@^4.8.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.8.1.tgz#fa0eaff965cc97fdf4245e8d4794618459f7558a" + integrity sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg== dependencies: accepts "~1.3.4" base64id "~2.0.0"