mirror of
https://github.com/muerwre/vk-tg-bot.git
synced 2025-04-24 22:46:41 +07:00
commit
f3a746efe8
11 changed files with 330 additions and 16 deletions
|
@ -14,6 +14,7 @@ vk:
|
|||
groups: []
|
||||
templates:
|
||||
message_new: templates/message_new.md
|
||||
wall_post_new: templates/post_new.md
|
||||
# groups:
|
||||
# - id: 0
|
||||
# name: 'Group name'
|
||||
|
|
|
@ -22,10 +22,12 @@
|
|||
"remark-extract-frontmatter": "^3.1.0",
|
||||
"remark-frontmatter": "^3.0.0",
|
||||
"remark-parse-frontmatter": "^1.0.3",
|
||||
"retext": "^7.0.1",
|
||||
"socks-proxy-agent": "^5.0.0",
|
||||
"telegraf": "^4.3.0",
|
||||
"to-vfile": "^6.1.0",
|
||||
"typescript": "^4.2.3",
|
||||
"unist-util-filter": "^3.0.0",
|
||||
"url": "^0.11.0",
|
||||
"vk-io": "^4.2.0",
|
||||
"winston": "^3.3.3",
|
||||
|
|
|
@ -84,6 +84,7 @@ export class TelegramService {
|
|||
message: string,
|
||||
extra?: ExtraReplyMessage
|
||||
) => {
|
||||
logger.debug(`sending message "${message}" to chan "${channel}"`);
|
||||
await this.bot.telegram.sendMessage(channel, message, extra);
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import extract from "remark-extract-frontmatter";
|
||||
import frontmatter from "remark-frontmatter";
|
||||
import compiler from "remark-stringify";
|
||||
import compiler from "retext-stringify";
|
||||
import parser from "remark-parse";
|
||||
import unified from "unified";
|
||||
import { parse } from "yaml";
|
||||
|
@ -8,6 +8,10 @@ import toVFile from "to-vfile";
|
|||
import path from "path";
|
||||
import hb from "handlebars";
|
||||
|
||||
const removeFrontmatter = () => (tree) => {
|
||||
tree.children = tree.children.filter((item) => item.type !== "yaml");
|
||||
};
|
||||
|
||||
export class Template<
|
||||
F extends Record<string, any>,
|
||||
V extends Record<string, any>
|
||||
|
@ -22,19 +26,17 @@ export class Template<
|
|||
}
|
||||
|
||||
const processor = unified()
|
||||
.use(parser)
|
||||
.use(compiler)
|
||||
.use(frontmatter)
|
||||
.use(extract, { yaml: parse });
|
||||
.use(extract, { yaml: parse })
|
||||
.use(removeFrontmatter)
|
||||
.use(parser);
|
||||
|
||||
const file = toVFile.readSync(path.join(__dirname, "../../", filename));
|
||||
const result = processor.processSync(file);
|
||||
|
||||
this.fields = result.data as F;
|
||||
this.template = result
|
||||
.toString()
|
||||
.replace(/^---\n(.*)---\n?$/gms, "")
|
||||
.trim();
|
||||
this.template = result.contents.toString().trim();
|
||||
} catch (e) {
|
||||
throw new Error(`Template: ${e.toString()}`);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { ConfigGroup } from "../types";
|
|||
import { ExtraReplyMessage } from "telegraf/typings/telegram-types";
|
||||
|
||||
interface Fields {
|
||||
buttons?: string[];
|
||||
buttons?: "link"[];
|
||||
link_text?: string;
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,7 @@ export class MessageNewHandler extends VkEventHandler<Fields, Values> {
|
|||
|
||||
this.appendButtons(extras, user.id);
|
||||
|
||||
await this.telegram
|
||||
.sendMessageToChan(this.channel, parsed, extras)
|
||||
.catch(next);
|
||||
await this.telegram.sendMessageToChan(this.channel, parsed, extras);
|
||||
|
||||
await next();
|
||||
};
|
||||
|
|
186
src/service/vk/handlers/PostNewHandler.ts
Normal file
186
src/service/vk/handlers/PostNewHandler.ts
Normal 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}`
|
||||
);
|
||||
};
|
||||
}
|
|
@ -5,6 +5,7 @@ import { StubHandler } from "./StubHandler";
|
|||
import { VkService } from "../index";
|
||||
import { TelegramService } from "../../telegram";
|
||||
import { Template } from "../../template";
|
||||
import { PostNewHandler } from "./PostNewHandler";
|
||||
|
||||
interface Handler {
|
||||
new (
|
||||
|
@ -22,6 +23,5 @@ export const vkEventToHandler: Record<VkEvent, Handler> = {
|
|||
[VkEvent.GroupJoin]: StubHandler,
|
||||
[VkEvent.GroupLeave]: StubHandler,
|
||||
[VkEvent.MessageNew]: MessageNewHandler,
|
||||
[VkEvent.PostSuggestion]: StubHandler,
|
||||
[VkEvent.WallPostNew]: StubHandler,
|
||||
[VkEvent.WallPostNew]: PostNewHandler,
|
||||
};
|
||||
|
|
|
@ -21,7 +21,6 @@ interface GroupChannel {
|
|||
|
||||
export enum VkEvent {
|
||||
WallPostNew = "wall_post_new",
|
||||
PostSuggestion = "post_suggestion",
|
||||
GroupJoin = "group_join",
|
||||
GroupLeave = "group_leave",
|
||||
MessageNew = "message_new",
|
||||
|
|
17
src/utils/extract.ts
Normal file
17
src/utils/extract.ts
Normal 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
21
templates/post_new.md
Normal 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}}
|
91
yarn.lock
91
yarn.lock
|
@ -191,6 +191,11 @@ array-flatten@1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
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:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
|
||||
|
@ -661,7 +666,7 @@ inflight@^1.0.4:
|
|||
once "^1.3.0"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
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"
|
||||
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:
|
||||
version "2.6.1"
|
||||
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-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:
|
||||
version "1.3.3"
|
||||
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"
|
||||
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:
|
||||
version "0.3.1"
|
||||
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"
|
||||
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:
|
||||
version "9.2.1"
|
||||
resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.1.tgz#ae18d5674c114021bfdbdf73865ca60f410215a3"
|
||||
|
@ -1451,6 +1513,14 @@ unified@^9.1.0:
|
|||
trough "^1.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:
|
||||
version "1.0.2"
|
||||
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"
|
||||
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:
|
||||
version "2.0.3"
|
||||
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:
|
||||
"@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:
|
||||
version "2.1.2"
|
||||
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"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
xtend@~4.0.1:
|
||||
xtend@^4.0.0, xtend@~4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue