1
0
Fork 0
mirror of https://github.com/muerwre/vk-tg-bot.git synced 2025-04-24 22:46:41 +07:00

Merge pull request #7 from muerwre/task/#2

Task/#2
This commit is contained in:
muerwre 2021-05-04 11:12:19 +07:00 committed by GitHub
commit f3a746efe8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 330 additions and 16 deletions

View file

@ -14,6 +14,7 @@ vk:
groups: [] groups: []
templates: templates:
message_new: templates/message_new.md message_new: templates/message_new.md
wall_post_new: templates/post_new.md
# groups: # groups:
# - id: 0 # - id: 0
# name: 'Group name' # name: 'Group name'

View file

@ -22,10 +22,12 @@
"remark-extract-frontmatter": "^3.1.0", "remark-extract-frontmatter": "^3.1.0",
"remark-frontmatter": "^3.0.0", "remark-frontmatter": "^3.0.0",
"remark-parse-frontmatter": "^1.0.3", "remark-parse-frontmatter": "^1.0.3",
"retext": "^7.0.1",
"socks-proxy-agent": "^5.0.0", "socks-proxy-agent": "^5.0.0",
"telegraf": "^4.3.0", "telegraf": "^4.3.0",
"to-vfile": "^6.1.0", "to-vfile": "^6.1.0",
"typescript": "^4.2.3", "typescript": "^4.2.3",
"unist-util-filter": "^3.0.0",
"url": "^0.11.0", "url": "^0.11.0",
"vk-io": "^4.2.0", "vk-io": "^4.2.0",
"winston": "^3.3.3", "winston": "^3.3.3",

View file

@ -84,6 +84,7 @@ export class TelegramService {
message: string, message: string,
extra?: ExtraReplyMessage extra?: ExtraReplyMessage
) => { ) => {
logger.debug(`sending message "${message}" to chan "${channel}"`);
await this.bot.telegram.sendMessage(channel, message, extra); await this.bot.telegram.sendMessage(channel, message, extra);
return; return;
}; };

View file

@ -1,6 +1,6 @@
import extract from "remark-extract-frontmatter"; import extract from "remark-extract-frontmatter";
import frontmatter from "remark-frontmatter"; import frontmatter from "remark-frontmatter";
import compiler from "remark-stringify"; import compiler from "retext-stringify";
import parser from "remark-parse"; import parser from "remark-parse";
import unified from "unified"; import unified from "unified";
import { parse } from "yaml"; import { parse } from "yaml";
@ -8,6 +8,10 @@ import toVFile from "to-vfile";
import path from "path"; import path from "path";
import hb from "handlebars"; import hb from "handlebars";
const removeFrontmatter = () => (tree) => {
tree.children = tree.children.filter((item) => item.type !== "yaml");
};
export class Template< export class Template<
F extends Record<string, any>, F extends Record<string, any>,
V extends Record<string, any> V extends Record<string, any>
@ -22,19 +26,17 @@ export class Template<
} }
const processor = unified() const processor = unified()
.use(parser)
.use(compiler) .use(compiler)
.use(frontmatter) .use(frontmatter)
.use(extract, { yaml: parse }); .use(extract, { yaml: parse })
.use(removeFrontmatter)
.use(parser);
const file = toVFile.readSync(path.join(__dirname, "../../", filename)); const file = toVFile.readSync(path.join(__dirname, "../../", filename));
const result = processor.processSync(file); const result = processor.processSync(file);
this.fields = result.data as F; this.fields = result.data as F;
this.template = result this.template = result.contents.toString().trim();
.toString()
.replace(/^---\n(.*)---\n?$/gms, "")
.trim();
} catch (e) { } catch (e) {
throw new Error(`Template: ${e.toString()}`); throw new Error(`Template: ${e.toString()}`);
} }

View file

@ -8,7 +8,7 @@ import { ConfigGroup } from "../types";
import { ExtraReplyMessage } from "telegraf/typings/telegram-types"; import { ExtraReplyMessage } from "telegraf/typings/telegram-types";
interface Fields { interface Fields {
buttons?: string[]; buttons?: "link"[];
link_text?: string; link_text?: string;
} }
@ -46,9 +46,7 @@ export class MessageNewHandler extends VkEventHandler<Fields, Values> {
this.appendButtons(extras, user.id); this.appendButtons(extras, user.id);
await this.telegram await this.telegram.sendMessageToChan(this.channel, parsed, extras);
.sendMessageToChan(this.channel, parsed, extras)
.catch(next);
await next(); await next();
}; };

View file

@ -0,0 +1,186 @@
import { VkEventHandler } from "./VkEventHandler";
import { WallPostContext } from "vk-io";
import { NextMiddleware } from "middleware-io";
import { UsersUserFull } from "vk-io/lib/api/schemas/objects";
import { ConfigGroup } from "../types";
import { ExtraReplyMessage } from "telegraf/typings/telegram-types";
import { InlineKeyboardButton, Update } from "typegram";
import { keys } from "ramda";
import { extractURLs } from "../../../utils/extract";
import logger from "../../logger";
import Composer from "telegraf";
import CallbackQueryUpdate = Update.CallbackQueryUpdate;
type Button = "links" | "likes";
type UrlPrefix = string;
type ExtraGenerator = (text: string) => InlineKeyboardButton[];
interface Fields {
image?: boolean;
buttons?: Button[];
link_text?: string;
links: Record<UrlPrefix, string>;
likes?: string[];
}
interface Values {
user?: UsersUserFull;
group: ConfigGroup;
text: string;
}
type LikeCtx = Composer.Context<CallbackQueryUpdate> & { match: string[] };
export class PostNewHandler extends VkEventHandler<Fields, Values> {
constructor(...props: any) {
// @ts-ignore
super(...props);
this.onInit();
}
private likes: string[] = ["👎", "👍"];
public execute = async (context: WallPostContext, next: NextMiddleware) => {
if (
context.isRepost ||
!PostNewHandler.isValidPostType(context?.wall?.postType)
) {
await next();
return;
}
const user = context.wall.signerId
? await this.getUserByID(String(context.wall.signerId))
: undefined;
const text = context.wall.text.trim();
const parsed = this.template.theme({
user,
group: this.group,
text,
});
const extras: ExtraReplyMessage = {
disable_web_page_preview: true,
};
this.appendExtras(extras, text);
await this.telegram.sendMessageToChan(this.channel, parsed, extras);
await next();
};
/**
* Checks if event of type we can handle
*/
public static isValidPostType(type: string): boolean {
return type === "post";
}
/**
* Creates extras
*/
private appendExtras = (extras: ExtraReplyMessage, text: string) => {
const { buttons } = this.template.fields;
if (!buttons?.length) {
return;
}
const keyboard = buttons
.map((button) => this.extrasGenerators[button](text))
.filter((el) => el && el.length);
if (!keyboard.length) {
return;
}
extras.reply_markup = {
inline_keyboard: keyboard,
};
};
/**
* Generates link buttons for post
*/
private generateLinks: ExtraGenerator = (text) => {
const links = this.template.fields.links;
if (!links) {
return [];
}
const urls = extractURLs(text);
if (!urls) {
return [];
}
return urls
.map((url) => {
const label = keys(links).find((link) =>
url.toString().startsWith(link)
);
return label ? { text: links[label], url: url.toString() } : undefined;
})
.filter((el) => el);
};
/**
* Generates like button
*/
private generateLikes: ExtraGenerator = () => {
return this.likes.map((like, i) => ({
text: like,
callback_data: `/like ${this.channel} ${like}`,
}));
};
/**
* Button generators dictionary
*/
private extrasGenerators: Record<Button, ExtraGenerator> = {
links: this.generateLinks,
likes: this.generateLikes,
};
/**
* Adds needed listeners
*/
protected onInit = () => {
if (this.template.fields.likes) {
this.likes = this.template.fields.likes;
}
if (!this.template.fields.buttons?.includes("likes")) {
return;
}
this.telegram.bot.action(/like (.*) (.*)/, this.onLikeAction);
};
/**
* Reacts to like button press
*/
onLikeAction = async (ctx: LikeCtx, next) => {
const id = ctx.update.callback_query.message.message_id;
const [_, channel, emo] = ctx.match;
if (
!channel ||
!emo ||
!id ||
channel != this.channel ||
!this.likes.includes(emo)
) {
await next();
return;
}
logger.warn(
`someone reacted with ${emo} to message ${id} on channel ${channel}`
);
};
}

View file

@ -5,6 +5,7 @@ import { StubHandler } from "./StubHandler";
import { VkService } from "../index"; import { VkService } from "../index";
import { TelegramService } from "../../telegram"; import { TelegramService } from "../../telegram";
import { Template } from "../../template"; import { Template } from "../../template";
import { PostNewHandler } from "./PostNewHandler";
interface Handler { interface Handler {
new ( new (
@ -22,6 +23,5 @@ export const vkEventToHandler: Record<VkEvent, Handler> = {
[VkEvent.GroupJoin]: StubHandler, [VkEvent.GroupJoin]: StubHandler,
[VkEvent.GroupLeave]: StubHandler, [VkEvent.GroupLeave]: StubHandler,
[VkEvent.MessageNew]: MessageNewHandler, [VkEvent.MessageNew]: MessageNewHandler,
[VkEvent.PostSuggestion]: StubHandler, [VkEvent.WallPostNew]: PostNewHandler,
[VkEvent.WallPostNew]: StubHandler,
}; };

View file

@ -21,7 +21,6 @@ interface GroupChannel {
export enum VkEvent { export enum VkEvent {
WallPostNew = "wall_post_new", WallPostNew = "wall_post_new",
PostSuggestion = "post_suggestion",
GroupJoin = "group_join", GroupJoin = "group_join",
GroupLeave = "group_leave", GroupLeave = "group_leave",
MessageNew = "message_new", MessageNew = "message_new",

17
src/utils/extract.ts Normal file
View file

@ -0,0 +1,17 @@
import { URL } from "url";
const urlRe = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gim;
export const extractURLs = (text: string): URL[] => {
const matches = text.match(urlRe) || [];
return matches
.map((m) => {
try {
return new URL(m);
} catch (e) {
return;
}
})
.filter((el) => el);
};

21
templates/post_new.md Normal file
View file

@ -0,0 +1,21 @@
---
image: true
buttons: [likes,links]
link_text: Пост полностью
links:
https://map.vault48.org/: Посмотреть карту
http://map.vault48.org/: Посмотреть карту
https://vk.com/album-: Альбом поката
http://vk.com/album-: Альбом поката
likes: ['😱','🤔','😃']
---
{{!--
use handlebars template here
available variables are: text, user, group
(see PostNewHandler)
--}}
{{text}}
{{#if user}}
[{{user.first_name}} {{user.last_name}}](https://vk.com/id{{user.id}})
{{/if}}

View file

@ -191,6 +191,11 @@ array-flatten@1.1.1:
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
array-iterate@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/array-iterate/-/array-iterate-1.1.4.tgz#add1522e9dd9749bb41152d08b845bd08d6af8b7"
integrity sha512-sNRaPGh9nnmdC8Zf+pT3UqP8rnWj5Hf9wiFGsX3wUQ2yVSIhO2ShFwCoceIPpB41QF6i2OEmrHmCo36xronCVA==
async@^3.1.0: async@^3.1.0:
version "3.2.0" version "3.2.0"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
@ -661,7 +666,7 @@ inflight@^1.0.4:
once "^1.3.0" once "^1.3.0"
wrappy "1" wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -955,6 +960,11 @@ neo-async@^2.6.0:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
nlcst-to-string@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/nlcst-to-string/-/nlcst-to-string-2.0.4.tgz#9315dfab80882bbfd86ddf1b706f53622dc400cc"
integrity sha512-3x3jwTd6UPG7vi5k4GEzvxJ5rDA7hVUIRNHPblKuMVP9Z3xmlsd9cgLcpAMkc5uPOBna82EeshROFhsPkbnTZg==
node-fetch@^2.6.1: node-fetch@^2.6.1:
version "2.6.1" version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
@ -1027,6 +1037,15 @@ parse-entities@^2.0.0:
is-decimal "^1.0.0" is-decimal "^1.0.0"
is-hexadecimal "^1.0.0" is-hexadecimal "^1.0.0"
parse-latin@^4.0.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/parse-latin/-/parse-latin-4.3.0.tgz#1a70fc5601743baa06c5f12253c334fc94b4a917"
integrity sha512-TYKL+K98dcAWoCw/Ac1yrPviU8Trk+/gmjQVaoWEFDZmVD4KRg6c/80xKqNNFQObo2mTONgF8trzAf2UTwKafw==
dependencies:
nlcst-to-string "^2.0.0"
unist-util-modify-children "^2.0.0"
unist-util-visit-children "^1.0.0"
parseurl@~1.3.3: parseurl@~1.3.3:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@ -1205,6 +1224,30 @@ require-directory@^2.1.1:
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
retext-latin@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/retext-latin/-/retext-latin-2.0.4.tgz#ef5d34ae7641ae56b0675ea391095e8ee762b251"
integrity sha512-fOoSSoQgDZ+l/uS81oxI3alBghDUPja0JEl0TpQxI6MN+dhM6fLFumPJwMZ4PJTyL5FFAgjlsdv8IX+6IRuwMw==
dependencies:
parse-latin "^4.0.0"
unherit "^1.0.4"
retext-stringify@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/retext-stringify/-/retext-stringify-2.0.4.tgz#496d6c532f7dc6d15e4b262de0266e828f72efa9"
integrity sha512-xOtx5mFJBoT3j7PBtiY2I+mEGERNniofWktI1cKXvjMEJPOuqve0dghLHO1+gz/gScLn4zqspDGv4kk2wS5kSA==
dependencies:
nlcst-to-string "^2.0.0"
retext@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/retext/-/retext-7.0.1.tgz#04b7965ab78fe6e5e3a489304545b460d41bf5aa"
integrity sha512-N0IaEDkvUjqyfn3/gwxVfI51IxfGzOiVXqPLWnKeCDbiQdxSg0zebzHPxXWnL7TeplAJ+RE4uqrXyYN//s9HjQ==
dependencies:
retext-latin "^2.0.0"
retext-stringify "^2.0.0"
unified "^8.0.0"
revalidator@^0.3.1: revalidator@^0.3.1:
version "0.3.1" version "0.3.1"
resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.3.1.tgz#ff2cc4cf7cc7c6385ac710178276e6dbcd03762f" resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.3.1.tgz#ff2cc4cf7cc7c6385ac710178276e6dbcd03762f"
@ -1439,6 +1482,25 @@ uglify-js@^3.1.4:
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.4.tgz#592588bb9f47ae03b24916e2471218d914955574" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.4.tgz#592588bb9f47ae03b24916e2471218d914955574"
integrity sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw== integrity sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw==
unherit@^1.0.4:
version "1.1.3"
resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22"
integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==
dependencies:
inherits "^2.0.0"
xtend "^4.0.0"
unified@^8.0.0:
version "8.4.2"
resolved "https://registry.yarnpkg.com/unified/-/unified-8.4.2.tgz#13ad58b4a437faa2751a4a4c6a16f680c500fff1"
integrity sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==
dependencies:
bail "^1.0.0"
extend "^3.0.0"
is-plain-obj "^2.0.0"
trough "^1.0.0"
vfile "^4.0.0"
unified@^9.1.0: unified@^9.1.0:
version "9.2.1" version "9.2.1"
resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.1.tgz#ae18d5674c114021bfdbdf73865ca60f410215a3" resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.1.tgz#ae18d5674c114021bfdbdf73865ca60f410215a3"
@ -1451,6 +1513,14 @@ unified@^9.1.0:
trough "^1.0.0" trough "^1.0.0"
vfile "^4.0.0" vfile "^4.0.0"
unist-util-filter@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/unist-util-filter/-/unist-util-filter-3.0.0.tgz#aae33b1dff78875dfe37351ad3363478ac0f110e"
integrity sha512-Vxzp2Z2LJuJLEkXYdfuW+fwWzC5xz1sjDFL3+xyGaDMxsn0pB457oQ8gdDbuhQdUSdxtuJ/WF7gDQVHOh7kyCg==
dependencies:
"@types/unist" "^2.0.0"
unist-util-is "^5.0.0"
unist-util-find@^1.0.2: unist-util-find@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/unist-util-find/-/unist-util-find-1.0.2.tgz#4d5b01a69fca2a382ad4f55f9865e402129ecf56" resolved "https://registry.yarnpkg.com/unist-util-find/-/unist-util-find-1.0.2.tgz#4d5b01a69fca2a382ad4f55f9865e402129ecf56"
@ -1464,6 +1534,18 @@ unist-util-is@^3.0.0:
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd" resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd"
integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==
unist-util-is@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.0.0.tgz#c71eddea34aa7009d54f671a6fafb3779b8035d3"
integrity sha512-G4p13DhfdUNmlnJxd0uy5Skx1FG58LSDhX8h1xgpeSq0omOQ4ZN5BO54ToFlNX55NDTbRHMdwTOJXqAieInSEA==
unist-util-modify-children@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-2.0.0.tgz#9c9c30d4e32502aabb3fde10d7872a17c86801e2"
integrity sha512-HGrj7JQo9DwZt8XFsX8UD4gGqOsIlCih9opG6Y+N11XqkBGKzHo8cvDi+MfQQgiZ7zXRUiQREYHhjOBHERTMdg==
dependencies:
array-iterate "^1.0.0"
unist-util-stringify-position@^2.0.0: unist-util-stringify-position@^2.0.0:
version "2.0.3" version "2.0.3"
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da"
@ -1471,6 +1553,11 @@ unist-util-stringify-position@^2.0.0:
dependencies: dependencies:
"@types/unist" "^2.0.2" "@types/unist" "^2.0.2"
unist-util-visit-children@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/unist-util-visit-children/-/unist-util-visit-children-1.1.4.tgz#e8a087e58a33a2815f76ea1901c15dec2cb4b432"
integrity sha512-sA/nXwYRCQVRwZU2/tQWUqJ9JSFM1X3x7JIOsIgSzrFHcfVt6NkzDtKzyxg2cZWkCwGF9CO8x4QNZRJRMK8FeQ==
unist-util-visit-parents@^2.0.0: unist-util-visit-parents@^2.0.0:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9" resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9"
@ -1597,7 +1684,7 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
xtend@~4.0.1: xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==