diff --git a/.vscode/settings.json b/.vscode/settings.json index c1cb0065b..9889e55cf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, } \ No newline at end of file diff --git a/package.json b/package.json index 51d4390b2..5fdf6dc90 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@feathersjs/express": "^4.5.15", "@feathersjs/feathers": "^4.5.15", "@feathersjs/socketio": "^4.5.18", - "@line/bot-sdk": "^7.5.2", + "@line/bot-sdk": "^9.2.2", "argon2": "^0.40.3", "azure-cognitiveservices-websearch": "^2.0.0", "cls-hooked": "^4.2.2", diff --git a/src/hooks/bot-line-respond.ts b/src/hooks/bot-line-respond.ts index b5af6c8af..7c47c6e00 100644 --- a/src/hooks/bot-line-respond.ts +++ b/src/hooks/bot-line-respond.ts @@ -4,7 +4,7 @@ import { Hook, HookContext } from "@feathersjs/feathers"; import { CognitiveServicesCredentials } from "ms-rest-azure"; import { WebSearchClient } from "azure-cognitiveservices-websearch"; import logger from "../logger"; -import { Client } from "@line/bot-sdk"; +import { messagingApi } from "@line/bot-sdk"; import { MemberJoinEvent, MessageEvent, @@ -15,118 +15,137 @@ import { Group, JoinEvent, FollowEvent, - FlexBubble, } from "@line/bot-sdk"; +import { FlexBubble } from "@line/bot-sdk/dist/messaging-api/api"; async function handleBye( sourceType: "room" | "group" | "user", messageEvent: MessageEvent, - client: Client, + client: messagingApi.MessagingApiClient, ) { if (sourceType === "room") { await client.leaveRoom((messageEvent.source as Room).roomId); } else if (sourceType === "group") { await client.leaveGroup((messageEvent.source as Group).groupId); } else { - await client.replyMessage(messageEvent.replyToken, { - type: "text", - text: "Maaf, kak. Kita lagi saling chat. Kita gak bisa ninggalin kakak di chat ini. :'(", + await client.replyMessage({ + replyToken: messageEvent.replyToken, + messages: [ + { + type: "text", + text: "Maaf, kak. Kita lagi saling chat. Kita gak bisa ninggalin kakak di chat ini. :'(", + }, + ], }); } } -async function handleHi(messageEvent: MessageEvent, client: Client) { +async function handleHi( + messageEvent: MessageEvent, + client: messagingApi.MessagingApiClient, +) { const userId = messageEvent.source.userId; let name = ""; if (userId != undefined) { const profile = await client.getProfile(userId); name = profile.displayName; } - await client.replyMessage(messageEvent.replyToken, { - type: "text", - text: - name !== "" - ? `Halo, kak ${name}! Semoga hari-harinya menyenangkan!` - : "Halo! Semoga hari-harinya menyenangkan!", + await client.replyMessage({ + replyToken: messageEvent.replyToken, + messages: [ + { + type: "text", + text: + name !== "" + ? `Halo, kak ${name}! Semoga hari-harinya menyenangkan!` + : "Halo! Semoga hari-harinya menyenangkan!", + }, + ], }); } -async function handleHelp(messageEvent: MessageEvent, client: Client) { - await client.replyMessage(messageEvent.replyToken, [ - { - type: "text", - text: "Halo kak! Jadi kita cuman bisa perintah ini loh,", - }, - { - type: "flex", - altText: "bye, hi, search", - contents: { - type: "carousel", - contents: [ - { - type: "bubble", - body: { - type: "box", - layout: "horizontal", - contents: [ - { - type: "text", - text: "Hi", - action: { - label: "Hi", - type: "message", +async function handleHelp( + messageEvent: MessageEvent, + client: messagingApi.MessagingApiClient, +) { + await client.replyMessage({ + replyToken: messageEvent.replyToken, + messages: [ + { + type: "text", + text: "Halo kak! Jadi kita cuman bisa perintah ini loh,", + }, + { + type: "flex", + altText: "bye, hi, search", + contents: { + type: "carousel", + contents: [ + { + type: "bubble", + body: { + type: "box", + layout: "horizontal", + contents: [ + { + type: "text", text: "Hi", + action: { + label: "Hi", + type: "message", + text: "Hi", + }, }, - }, - ], + ], + }, }, - }, - { - type: "bubble", - body: { - type: "box", - layout: "horizontal", - contents: [ - { - type: "text", - text: "Bye", - action: { - label: "Bye", - type: "message", + { + type: "bubble", + body: { + type: "box", + layout: "horizontal", + contents: [ + { + type: "text", text: "Bye", + action: { + label: "Bye", + type: "message", + text: "Bye", + }, }, - }, - ], + ], + }, }, - }, - { - type: "bubble", - body: { - type: "box", - layout: "horizontal", - contents: [ - { - type: "text", - text: "Search", - action: { - label: "Search", - type: "message", + { + type: "bubble", + body: { + type: "box", + layout: "horizontal", + contents: [ + { + type: "text", text: "Search", + action: { + label: "Search", + type: "message", + text: "Search", + }, }, - }, - ], + ], + }, }, - }, - ], + ], + }, }, - }, - ]); + ], + }); } async function handleSearch( messageText: string, messageEvent: MessageEvent, - client: Client, + client: messagingApi.MessagingApiClient, ) { const splitText = messageText.split(" ", 2); if (splitText.length > 1) { @@ -176,40 +195,60 @@ async function handleSearch( } } if (output.length == 0) { - await client.replyMessage(messageEvent.replyToken, { - type: "text", - text: "Sepertinya pencarian kakak tidak ditemukan. :(", + await client.replyMessage({ + replyToken: messageEvent.replyToken, + messages: [ + { + type: "text", + text: "Sepertinya pencarian kakak tidak ditemukan. :(", + }, + ], }); } else if (output.length > 10) { - await client.replyMessage(messageEvent.replyToken, { - type: "flex", - altText: "Web Result", - contents: { - type: "carousel", - contents: output.slice(0, 10), - }, + await client.replyMessage({ + replyToken: messageEvent.replyToken, + messages: [ + { + type: "flex", + altText: "Web Result", + contents: { + type: "carousel", + contents: output.slice(0, 10), + }, + }, + ], }); } else { - await client.replyMessage(messageEvent.replyToken, { - type: "flex", - altText: "Web Result", - contents: { - type: "carousel", - contents: output, - }, + await client.replyMessage({ + replyToken: messageEvent.replyToken, + messages: [ + { + type: "flex", + altText: "Web Result", + contents: { + type: "carousel", + contents: output, + }, + }, + ], }); } } else { - await client.replyMessage(messageEvent.replyToken, { - type: "text", - text: "Masukan kata kunci yang ingin anda cari. Misalkan, search ayam", + await client.replyMessage({ + replyToken: messageEvent.replyToken, + messages: [ + { + type: "text", + text: "Masukan kata kunci yang ingin anda cari. Misalkan, search ayam", + }, + ], }); } } async function proccessMessageEvent( messageEvent: MessageEvent, - client: Client, + client: messagingApi.MessagingApiClient, ) { const message = messageEvent.message; const sourceType = messageEvent.source.type; @@ -231,9 +270,14 @@ async function proccessMessageEvent( if (messageText.startsWith("search")) { await handleSearch(messageText, messageEvent, client); } else { - await client.replyMessage(messageEvent.replyToken, { - type: "text", - text: "Maaf saat ini perintah yang anda berikan tidak tersedia. Mohon masukan 'bantuan' untuk info lebih lanjut.", + await client.replyMessage({ + replyToken: messageEvent.replyToken, + messages: [ + { + type: "text", + text: "Maaf saat ini perintah yang anda berikan tidak tersedia. Mohon masukan 'bantuan' untuk info lebih lanjut.", + }, + ], }); } break; @@ -241,44 +285,61 @@ async function proccessMessageEvent( } } -async function proccessMemberJoin(joinEvent: MemberJoinEvent, client: Client) { +async function proccessMemberJoin( + joinEvent: MemberJoinEvent, + client: messagingApi.MessagingApiClient, +) { const joinedMembers = joinEvent.joined.members; for (const member of joinedMembers) { logger.info(`Welcome to ${member.userId}`); const profile = await client.getProfile(member.userId); - await client.replyMessage(joinEvent.replyToken, { - type: "text", - text: `Halo kak, ${profile.displayName}! Selamat datang di grup!`, + await client.replyMessage({ + replyToken: joinEvent.replyToken, + messages: [ + { + type: "text", + text: `Halo kak, ${profile.displayName}! Selamat datang di grup!`, + }, + ], }); } } -async function proccessFollowEvent(followEvent: FollowEvent, client: Client) { +async function proccessFollowEvent( + followEvent: FollowEvent, + client: messagingApi.MessagingApiClient, +) { const sourceType = followEvent.source.type.toLowerCase(); if (sourceType === "user") { const userId = followEvent.source.userId; logger.info(`Welcoming to ${userId}`); if (userId != undefined) { const profile = await client.getProfile(userId); - await client.replyMessage(followEvent.replyToken, [ - { - type: "text", - text: `Halo kak ${profile.displayName}, terima kasih sudah menambahkan saya!`, - }, - { - type: "text", - text: "Ketik 'bantuan' untuk perintah lebih lanjut ya, kak.", - }, - { - type: "text", - text: "Kami bisa membantu kakak mencari banyak hal di web.", - }, - ]); + await client.replyMessage({ + replyToken: followEvent.replyToken, + messages: [ + { + type: "text", + text: `Halo kak ${profile.displayName}, terima kasih sudah menambahkan saya!`, + }, + { + type: "text", + text: "Ketik 'bantuan' untuk perintah lebih lanjut ya, kak.", + }, + { + type: "text", + text: "Kami bisa membantu kakak mencari banyak hal di web.", + }, + ], + }); } } } -async function handleEvent(event: WebhookEvent, client: Client) { +async function handleEvent( + event: WebhookEvent, + client: messagingApi.MessagingApiClient, +) { try { logger.info(JSON.stringify(event)); const eventType = event.type; @@ -294,16 +355,19 @@ async function handleEvent(event: WebhookEvent, client: Client) { break; case "join": const joinEvent = event as JoinEvent; - await client.replyMessage(joinEvent.replyToken, [ - { - type: "text", - text: "Halo semuanya! Terima kasih telah mengundang kami di grup ini! Ketik 'bantuan' tanpa tanda petik untuk melihat fungsi dari bot ini.", - }, - { - type: "text", - text: "Bot ini berfungsi memberikan sugesti halaman web yang dapat dituju berdasarkan kata kunci dari kakak.", - }, - ]); + await client.replyMessage({ + replyToken: joinEvent.replyToken, + messages: [ + { + type: "text", + text: "Halo semuanya! Terima kasih telah mengundang kami di grup ini! Ketik 'bantuan' tanpa tanda petik untuk melihat fungsi dari bot ini.", + }, + { + type: "text", + text: "Bot ini berfungsi memberikan sugesti halaman web yang dapat dituju berdasarkan kata kunci dari kakak.", + }, + ], + }); break; case "follow": const followEvent = event as FollowEvent; @@ -325,7 +389,7 @@ export default (options = {}): Hook => { const hookBody = data as WebhookRequestBody; logger.info(`Event sending to ${hookBody.destination}`); const events = hookBody.events; - const client: Client = app.get("lineClient"); + const client: messagingApi.MessagingApiClient = app.get("lineClient"); for (const event of events) { await handleEvent(event, client); } diff --git a/src/line-client.ts b/src/line-client.ts index 3504d0b60..d670a10a9 100644 --- a/src/line-client.ts +++ b/src/line-client.ts @@ -1,4 +1,5 @@ -import { Client } from "@line/bot-sdk"; +import { messagingApi } from "@line/bot-sdk"; +const { MessagingApiClient } = messagingApi; import { Application } from "./declarations"; export default function (app: Application): void { @@ -6,6 +7,6 @@ export default function (app: Application): void { channelAccessToken: app.get("lineAccessToken"), channelSecret: app.get("lineSecret"), }; - const client = new Client(lineConfig); + const client = new MessagingApiClient(lineConfig); app.set("lineClient", client); } diff --git a/test/hooks/bot-error-handling.test.ts b/test/hooks/bot-error-handling.test.ts index b497039d5..2d4940dd7 100644 --- a/test/hooks/bot-error-handling.test.ts +++ b/test/hooks/bot-error-handling.test.ts @@ -16,9 +16,13 @@ describe("Hook test 'bot-error-handling ", () => { return {}; } if (data.isSignatureError) { - throw new SignatureValidationFailed("Dummy Error", "Something Error"); + throw new SignatureValidationFailed("Dummy Error", { + signature: "Something Error", + }); } else if (data.isJsonParseError) { - throw new JSONParseError("Json Error", "Can't read the json"); + throw new JSONParseError("Json Error", { + raw: "Can't read the json", + }); } return {}; }, diff --git a/test/hooks/bot-line-respond.test.ts b/test/hooks/bot-line-respond.test.ts index 81d2a41f6..b98467968 100644 --- a/test/hooks/bot-line-respond.test.ts +++ b/test/hooks/bot-line-respond.test.ts @@ -55,6 +55,8 @@ describe("Hook test 'bot-error-handling ", () => { source: { type: "group", groupId: "anon" }, mode: "active", replyToken: "mock", + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -72,6 +74,8 @@ describe("Hook test 'bot-error-handling ", () => { source: { type: "group", groupId: "anon" }, mode: "active", replyToken: "mock", + webhookEventId: "anyid-1", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -89,6 +93,8 @@ describe("Hook test 'bot-error-handling ", () => { source: { type: "user", userId: "anon" }, mode: "active", replyToken: "mock", + webhookEventId: "anyid-1", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -104,9 +110,16 @@ describe("Hook test 'bot-error-handling ", () => { type: "message", timestamp: 0, source: { type: "user", userId: "ok" }, - message: { type: "text", text: "hi", id: "randomly" }, + message: { + type: "text", + text: "hi", + id: "randomly", + quoteToken: "any-quote-token", + }, mode: "active", replyToken: "mock", + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -122,9 +135,16 @@ describe("Hook test 'bot-error-handling ", () => { type: "message", timestamp: 0, source: { type: "group", groupId: "ok" }, - message: { type: "text", text: "bantuan", id: "randomly" }, + message: { + type: "text", + text: "bantuan", + id: "randomly", + quoteToken: "any-quote-token", + }, mode: "active", replyToken: "mock", + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -140,9 +160,16 @@ describe("Hook test 'bot-error-handling ", () => { type: "message", timestamp: 0, source: { type: "group", groupId: "ok" }, - message: { type: "text", text: "bye", id: "randomly" }, + message: { + type: "text", + text: "bye", + id: "randomly", + quoteToken: "any-quote-token", + }, mode: "active", replyToken: "mock", + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -158,9 +185,16 @@ describe("Hook test 'bot-error-handling ", () => { type: "message", timestamp: 0, source: { type: "room", roomId: "ok" }, - message: { type: "text", text: "bye", id: "randomly" }, + message: { + type: "text", + text: "bye", + id: "randomly", + quoteToken: "any-quote-token", + }, mode: "active", replyToken: "mock", + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -176,9 +210,16 @@ describe("Hook test 'bot-error-handling ", () => { type: "message", timestamp: 0, source: { type: "user", userId: "ok" }, - message: { type: "text", text: "bye", id: "randomly" }, + message: { + type: "text", + text: "bye", + id: "randomly", + quoteToken: "any-quote-token", + }, mode: "active", replyToken: "mock", + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -194,9 +235,16 @@ describe("Hook test 'bot-error-handling ", () => { type: "message", timestamp: 0, source: { type: "user", userId: "ok" }, - message: { type: "text", text: "search", id: "randomly" }, + message: { + type: "text", + text: "search", + id: "randomly", + quoteToken: "any-quote-token", + }, mode: "active", replyToken: "mock", + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -212,9 +260,16 @@ describe("Hook test 'bot-error-handling ", () => { type: "message", timestamp: 0, source: { type: "user", userId: "ok" }, - message: { type: "text", text: "randomly", id: "randomly" }, + message: { + type: "text", + text: "randomly", + id: "randomly", + quoteToken: "any-quote-token", + }, mode: "active", replyToken: "mock", + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", @@ -233,6 +288,8 @@ describe("Hook test 'bot-error-handling ", () => { mode: "active", replyToken: "mock", link: { result: "ok", nonce: "" }, + webhookEventId: "xxxx", + deliveryContext: { isRedelivery: false }, }; const request: WebhookRequestBody = { destination: "here", diff --git a/yarn.lock b/yarn.lock index b0b16db35..b78289961 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1582,17 +1582,14 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@line/bot-sdk@^7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@line/bot-sdk/-/bot-sdk-7.5.2.tgz#ecf5410e2ceda0ed491aa178c587be8f2b691ddd" - integrity sha512-mMaDnr+mOqQDLYJcUp+fQwZklg/LoOZzNILlWdsj2IFD2nXF+HhAm3KEy5tyUx629Y2bCx6nv9Jl0UlMwBiAiw== - dependencies: - "@types/body-parser" "^1.19.2" - "@types/node" "^16.0.0" - axios "^0.27.0" - body-parser "^1.20.0" - file-type "^16.5.4" - form-data "^4.0.0" +"@line/bot-sdk@^9.2.2": + version "9.2.2" + resolved "https://registry.yarnpkg.com/@line/bot-sdk/-/bot-sdk-9.2.2.tgz#80656140038c136a4a0ee693bd1c43a3835891e2" + integrity sha512-s2lzDpKZJ1Xjn3aL6wD2bGO/J9ZK19bUu6mSlplaQi17fYNKZTu7nMv99lsaY37XOYq7nyvfS5UUjKJk58m/vQ== + dependencies: + "@types/node" "^20.0.0" + optionalDependencies: + axios "^1.0.0" "@mongodb-js/saslprep@^1.1.5": version "1.1.5" @@ -2057,11 +2054,6 @@ "@smithy/types" "^3.3.0" tslib "^2.6.2" -"@tokenizer/token@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" - integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== - "@tootallnate/once@1": version "1.1.2" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -2130,7 +2122,7 @@ resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.42.tgz#7ec05f1ce9986d920313c1377a5662b1b563d366" integrity sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A== -"@types/body-parser@*", "@types/body-parser@^1.19.2": +"@types/body-parser@*": version "1.19.2" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== @@ -2293,18 +2285,13 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== -"@types/node@*", "@types/node@^20.12.12": - version "20.12.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.12.tgz#7cbecdf902085cec634fdb362172dfe12b8f2050" - integrity sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw== +"@types/node@*", "@types/node@^20.0.0", "@types/node@^20.12.12": + version "20.13.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.13.0.tgz#011a76bc1e71ae9a026dddcfd7039084f752c4b6" + integrity sha512-FM6AOb3khNkNIXPnHFDYaHerSv8uN22C91z098AnGccVu+Pcdhi+pNUFDi0iLmPIsVE0JBD0KVS7mzUYt4nRzQ== dependencies: undici-types "~5.26.4" -"@types/node@^16.0.0": - version "16.11.58" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.58.tgz#0a3698dee3492617a8d5fe7998d18d7520b63026" - integrity sha512-uMVxJ111wpHzkx/vshZFb6Qni3BOMnlWLq7q9jrwej7Yw/KvjsEbpxCCxw+hLKxexFMc8YmpG8J9tnEe/rKsIg== - "@types/nodemailer@^6.4.15": version "6.4.15" resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.15.tgz#494be695e11c438f7f5df738fb4ab740312a6ed2" @@ -2769,15 +2756,7 @@ axios@^0.21.1: dependencies: follow-redirects "^1.14.0" -axios@^0.27.0: - version "0.27.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" - integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== - dependencies: - follow-redirects "^1.14.9" - form-data "^4.0.0" - -axios@^1.7.2: +axios@^1.0.0, axios@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.2.tgz#b625db8a7051fbea61c35a3cbb3a1daa7b9c7621" integrity sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw== @@ -2928,24 +2907,6 @@ body-parser@1.20.2: type-is "~1.6.18" unpipe "1.0.0" -body-parser@^1.20.0: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - bowser@^2.11.0: version "2.11.0" resolved "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" @@ -4088,15 +4049,6 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-type@^16.5.4: - version "16.5.4" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.4.tgz#474fb4f704bee427681f98dd390058a172a6c2fd" - integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw== - dependencies: - readable-web-to-node-stream "^3.0.0" - strtok3 "^6.2.4" - token-types "^4.1.1" - filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" @@ -4163,7 +4115,7 @@ fn.name@1.x.x: resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== -follow-redirects@^1.14.0, follow-redirects@^1.14.9, follow-redirects@^1.15.6: +follow-redirects@^1.14.0, follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== @@ -4521,11 +4473,6 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -5953,11 +5900,6 @@ path-type@^4.0.0: resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -peek-readable@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" - integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== - performance-now@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -6184,16 +6126,6 @@ range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - raw-body@2.5.2: version "2.5.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" @@ -6218,13 +6150,6 @@ readable-stream@^3.0.0, readable-stream@^3.1.1, readable-stream@^3.4.0, readable string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-web-to-node-stream@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" - integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== - dependencies: - readable-stream "^3.6.0" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -6811,14 +6736,6 @@ strnum@^1.0.5: resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== -strtok3@^6.2.4: - version "6.3.0" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" - integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== - dependencies: - "@tokenizer/token" "^0.3.0" - peek-readable "^4.1.0" - stubs@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" @@ -6920,14 +6837,6 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -token-types@^4.1.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753" - integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ== - dependencies: - "@tokenizer/token" "^0.3.0" - ieee754 "^1.2.1" - toposort-class@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988"