mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
chore: refactor progressCB to one place, fix sydney, and sanitize html
This commit is contained in:
parent
9a17e94f8f
commit
2e20b28c4d
12 changed files with 351 additions and 69 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const { KeyvFile } = require('keyv-file');
|
const { KeyvFile } = require('keyv-file');
|
||||||
|
|
||||||
const askBing = async ({ text, progressCallback, convo }) => {
|
const askBing = async ({ text, onProgress, convo }) => {
|
||||||
const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api'));
|
const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api'));
|
||||||
|
|
||||||
const bingAIClient = new BingAIClient({
|
const bingAIClient = new BingAIClient({
|
||||||
|
|
@ -14,10 +14,7 @@ const askBing = async ({ text, progressCallback, convo }) => {
|
||||||
proxy: process.env.PROXY || null,
|
proxy: process.env.PROXY || null,
|
||||||
});
|
});
|
||||||
|
|
||||||
let options = {
|
let options = { onProgress };
|
||||||
onProgress: async (partialRes) => await progressCallback(partialRes),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (convo) {
|
if (convo) {
|
||||||
options = { ...options, ...convo };
|
options = { ...options, ...convo };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const clientOptions = {
|
||||||
proxy: process.env.PROXY || null,
|
proxy: process.env.PROXY || null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const browserClient = async ({ text, progressCallback, convo }) => {
|
const browserClient = async ({ text, onProgress, convo }) => {
|
||||||
const { ChatGPTBrowserClient } = await import('@waylaidwanderer/chatgpt-api');
|
const { ChatGPTBrowserClient } = await import('@waylaidwanderer/chatgpt-api');
|
||||||
|
|
||||||
const store = {
|
const store = {
|
||||||
|
|
@ -18,10 +18,7 @@ const browserClient = async ({ text, progressCallback, convo }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const client = new ChatGPTBrowserClient(clientOptions, store);
|
const client = new ChatGPTBrowserClient(clientOptions, store);
|
||||||
|
let options = { onProgress };
|
||||||
let options = {
|
|
||||||
onProgress: async (partialRes) => await progressCallback(partialRes)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!!convo.parentMessageId && !!convo.conversationId) {
|
if (!!convo.parentMessageId && !!convo.conversationId) {
|
||||||
options = { ...options, ...convo };
|
options = { ...options, ...convo };
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,14 @@ const clientOptions = {
|
||||||
debug: false
|
debug: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const askClient = async ({ text, progressCallback, convo }) => {
|
const askClient = async ({ text, onProgress, convo }) => {
|
||||||
const ChatGPTClient = (await import('@waylaidwanderer/chatgpt-api')).default;
|
const ChatGPTClient = (await import('@waylaidwanderer/chatgpt-api')).default;
|
||||||
const store = {
|
const store = {
|
||||||
store: new KeyvFile({ filename: './data/cache.json' })
|
store: new KeyvFile({ filename: './data/cache.json' })
|
||||||
};
|
};
|
||||||
|
|
||||||
const client = new ChatGPTClient(process.env.OPENAI_KEY, clientOptions, store);
|
const client = new ChatGPTClient(process.env.OPENAI_KEY, clientOptions, store);
|
||||||
|
let options = { onProgress };
|
||||||
let options = {
|
|
||||||
onProgress: async (partialRes) => await progressCallback(partialRes)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!!convo.parentMessageId && !!convo.conversationId) {
|
if (!!convo.parentMessageId && !!convo.conversationId) {
|
||||||
options = { ...options, ...convo };
|
options = { ...options, ...convo };
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const { KeyvFile } = require('keyv-file');
|
const { KeyvFile } = require('keyv-file');
|
||||||
|
|
||||||
const askSydney = async ({ text, progressCallback, convo }) => {
|
const askSydney = async ({ text, onProgress, convo }) => {
|
||||||
const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api'));
|
const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api'));
|
||||||
|
|
||||||
const sydneyClient = new BingAIClient({
|
const sydneyClient = new BingAIClient({
|
||||||
|
|
@ -15,10 +15,10 @@ const askSydney = async ({ text, progressCallback, convo }) => {
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
jailbreakConversationId: true,
|
jailbreakConversationId: true,
|
||||||
onProgress: async (partialRes) => await progressCallback(partialRes),
|
onProgress,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (convo.parentMessageId) {
|
if (convo.jailbreakConversationId) {
|
||||||
options = { ...options, jailbreakConversationId: convo.jailbreakConversationId, parentMessageId: convo.parentMessageId };
|
options = { ...options, jailbreakConversationId: convo.jailbreakConversationId, parentMessageId: convo.parentMessageId };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1
api/package-lock.json
generated
1
api/package-lock.json
generated
|
|
@ -17,6 +17,7 @@
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"keyv": "^4.5.2",
|
"keyv": "^4.5.2",
|
||||||
"keyv-file": "^0.2.0",
|
"keyv-file": "^0.2.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"mongoose": "^6.9.0",
|
"mongoose": "^6.9.0",
|
||||||
"openai": "^3.1.0"
|
"openai": "^3.1.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"keyv": "^4.5.2",
|
"keyv": "^4.5.2",
|
||||||
"keyv-file": "^0.2.0",
|
"keyv-file": "^0.2.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"mongoose": "^6.9.0",
|
"mongoose": "^6.9.0",
|
||||||
"openai": "^3.1.0"
|
"openai": "^3.1.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const {
|
||||||
detectCode
|
detectCode
|
||||||
} = require('../../app/');
|
} = require('../../app/');
|
||||||
const { getConvo, saveMessage, getConvoTitle, saveConvo } = require('../../models');
|
const { getConvo, saveMessage, getConvoTitle, saveConvo } = require('../../models');
|
||||||
const { handleError, sendMessage } = require('./handlers');
|
const { handleError, sendMessage, createOnProgress } = require('./handlers');
|
||||||
const { getMessages } = require('../../models/Message');
|
const { getMessages } = require('../../models/Message');
|
||||||
|
|
||||||
router.use('/bing', askBing);
|
router.use('/bing', askBing);
|
||||||
|
|
@ -138,37 +138,10 @@ const ask = async ({
|
||||||
sendMessage(res, { message: userMessage, created: true });
|
sendMessage(res, { message: userMessage, created: true });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let i = 0;
|
const progressCallback = createOnProgress();
|
||||||
let tokens = '';
|
|
||||||
const progressCallback = async (partial) => {
|
|
||||||
if (i === 0 && typeof partial === 'object') {
|
|
||||||
userMessage.conversationId = conversationId ? conversationId : partial.conversationId;
|
|
||||||
await saveMessage(userMessage);
|
|
||||||
sendMessage(res, { ...partial, parentMessageId: overrideParentMessageId || userMessageId, initial: true });
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof partial === 'object') {
|
|
||||||
sendMessage(res, { ...partial, parentMessageId: overrideParentMessageId || userMessageId, message: true });
|
|
||||||
} else {
|
|
||||||
tokens += partial === text ? '' : partial;
|
|
||||||
if (tokens.match(/^\n/)) {
|
|
||||||
tokens = tokens.replace(/^\n/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tokens.includes('[DONE]')) {
|
|
||||||
tokens = tokens.replace('[DONE]', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
// tokens = await detectCode(tokens);
|
|
||||||
sendMessage(res, { text: tokens, message: true, initial: i === 0 ? true : false });
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let gptResponse = await client({
|
let gptResponse = await client({
|
||||||
text,
|
text,
|
||||||
progressCallback,
|
onProgress: progressCallback.call(null, model, {res, text }),
|
||||||
convo: {
|
convo: {
|
||||||
parentMessageId: userParentMessageId,
|
parentMessageId: userParentMessageId,
|
||||||
conversationId,
|
conversationId,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ const crypto = require('crypto');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const { titleConvo, getCitations, citeText, askBing } = require('../../app/');
|
const { titleConvo, getCitations, citeText, askBing } = require('../../app/');
|
||||||
const { saveMessage, getConvoTitle, saveConvo } = require('../../models');
|
const { saveMessage, getConvoTitle, saveConvo } = require('../../models');
|
||||||
const { handleError, sendMessage } = require('./handlers');
|
const { handleError, sendMessage, createOnProgress } = require('./handlers');
|
||||||
const citationRegex = /\[\^\d+?\^]/g;
|
const citationRegex = /\[\^\d+?\^]/g;
|
||||||
|
|
||||||
router.post('/', async (req, res) => {
|
router.post('/', async (req, res) => {
|
||||||
|
|
@ -68,17 +68,10 @@ const ask = async ({
|
||||||
sendMessage(res, { message: userMessage, created: true });
|
sendMessage(res, { message: userMessage, created: true });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let tokens = '';
|
const progressCallback = createOnProgress();
|
||||||
const progressCallback = async (partial) => {
|
|
||||||
tokens += partial === text ? '' : partial;
|
|
||||||
// tokens = appendCode(tokens);
|
|
||||||
tokens = citeText(tokens, true);
|
|
||||||
sendMessage(res, { text: tokens, message: true, parentMessageId: overrideParentMessageId || userMessageId });
|
|
||||||
};
|
|
||||||
|
|
||||||
let response = await askBing({
|
let response = await askBing({
|
||||||
text,
|
text,
|
||||||
progressCallback,
|
onProgress: progressCallback.call(null, model, {res, text, parentMessageId: overrideParentMessageId || userMessageId }),
|
||||||
convo: {
|
convo: {
|
||||||
...convo,
|
...convo,
|
||||||
parentMessageId: userParentMessageId,
|
parentMessageId: userParentMessageId,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ const crypto = require('crypto');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const { titleConvo, getCitations, citeText, askSydney } = require('../../app/');
|
const { titleConvo, getCitations, citeText, askSydney } = require('../../app/');
|
||||||
const { saveMessage, saveConvo, getConvoTitle } = require('../../models');
|
const { saveMessage, saveConvo, getConvoTitle } = require('../../models');
|
||||||
const { handleError, sendMessage } = require('./handlers');
|
const { handleError, sendMessage, createOnProgress } = require('./handlers');
|
||||||
const citationRegex = /\[\^\d+?\^]/g;
|
const citationRegex = /\[\^\d+?\^]/g;
|
||||||
|
|
||||||
router.post('/', async (req, res) => {
|
router.post('/', async (req, res) => {
|
||||||
|
|
@ -68,17 +68,10 @@ const ask = async ({
|
||||||
sendMessage(res, { message: userMessage, created: true });
|
sendMessage(res, { message: userMessage, created: true });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let tokens = '';
|
const progressCallback = createOnProgress();
|
||||||
const progressCallback = async (partial) => {
|
|
||||||
tokens += partial === text ? '' : partial;
|
|
||||||
// tokens = appendCode(tokens);
|
|
||||||
tokens = citeText(tokens, true);
|
|
||||||
sendMessage(res, { text: tokens, message: true, parentMessageId: overrideParentMessageId || userMessageId });
|
|
||||||
};
|
|
||||||
|
|
||||||
let response = await askSydney({
|
let response = await askSydney({
|
||||||
text,
|
text,
|
||||||
progressCallback,
|
onProgress: progressCallback.call(null, model, {res, text, parentMessageId: overrideParentMessageId || userMessageId }),
|
||||||
convo: {
|
convo: {
|
||||||
parentMessageId: userParentMessageId,
|
parentMessageId: userParentMessageId,
|
||||||
conversationId,
|
conversationId,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
const { citeText } = require('../../app/');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const sanitizeHtml = require('sanitize-html');
|
||||||
|
|
||||||
const handleError = (res, message) => {
|
const handleError = (res, message) => {
|
||||||
res.write(`event: error\ndata: ${JSON.stringify(message)}\n\n`);
|
res.write(`event: error\ndata: ${JSON.stringify(message)}\n\n`);
|
||||||
res.end();
|
res.end();
|
||||||
|
|
@ -10,4 +14,32 @@ const sendMessage = (res, message) => {
|
||||||
res.write(`event: message\ndata: ${JSON.stringify(message)}\n\n`);
|
res.write(`event: message\ndata: ${JSON.stringify(message)}\n\n`);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = { handleError, sendMessage };
|
const createOnProgress = () => {
|
||||||
|
let i = 0;
|
||||||
|
let tokens = '';
|
||||||
|
|
||||||
|
const progressCallback = async (partial, { res, text, bing = false, ...rest }) => {
|
||||||
|
tokens += partial === text ? '' : partial;
|
||||||
|
tokens = tokens.trim();
|
||||||
|
tokens = tokens.replaceAll('[DONE]', '');
|
||||||
|
if (tokens.includes('```')) {
|
||||||
|
tokens = sanitizeHtml(tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bing) {
|
||||||
|
tokens = citeText(tokens, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage(res, { text: tokens, message: true, initial: i === 0, ...rest });
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onProgress = (model, opts) => {
|
||||||
|
const bingModels = new Set(['bingai', 'sydney']);
|
||||||
|
return _.partialRight(progressCallback, { ...opts, bing: bingModels.has(model) });
|
||||||
|
};
|
||||||
|
|
||||||
|
return onProgress;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { handleError, sendMessage, createOnProgress };
|
||||||
293
package-lock.json
generated
Normal file
293
package-lock.json
generated
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
{
|
||||||
|
"name": "chatgpt-clone",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"sanitize-html": "^2.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/deepmerge": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dom-serializer": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||||
|
"dependencies": {
|
||||||
|
"domelementtype": "^2.3.0",
|
||||||
|
"domhandler": "^5.0.2",
|
||||||
|
"entities": "^4.2.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/domelementtype": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/fb55"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/domhandler": {
|
||||||
|
"version": "5.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||||
|
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||||
|
"dependencies": {
|
||||||
|
"domelementtype": "^2.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/domutils": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"dom-serializer": "^2.0.0",
|
||||||
|
"domelementtype": "^2.3.0",
|
||||||
|
"domhandler": "^5.0.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/entities": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/escape-string-regexp": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/htmlparser2": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/fb55"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"domelementtype": "^2.3.0",
|
||||||
|
"domhandler": "^5.0.2",
|
||||||
|
"domutils": "^3.0.1",
|
||||||
|
"entities": "^4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-plain-object": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "3.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
||||||
|
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/parse-srcset": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
|
||||||
|
},
|
||||||
|
"node_modules/picocolors": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
||||||
|
},
|
||||||
|
"node_modules/postcss": {
|
||||||
|
"version": "8.4.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
|
||||||
|
"integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.3.4",
|
||||||
|
"picocolors": "^1.0.0",
|
||||||
|
"source-map-js": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || >=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/sanitize-html": {
|
||||||
|
"version": "2.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.10.0.tgz",
|
||||||
|
"integrity": "sha512-JqdovUd81dG4k87vZt6uA6YhDfWkUGruUu/aPmXLxXi45gZExnt9Bnw/qeQU8oGf82vPyaE0vO4aH0PbobB9JQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"htmlparser2": "^8.0.0",
|
||||||
|
"is-plain-object": "^5.0.0",
|
||||||
|
"parse-srcset": "^1.0.2",
|
||||||
|
"postcss": "^8.3.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/source-map-js": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"deepmerge": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og=="
|
||||||
|
},
|
||||||
|
"dom-serializer": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "^2.3.0",
|
||||||
|
"domhandler": "^5.0.2",
|
||||||
|
"entities": "^4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domelementtype": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
|
||||||
|
},
|
||||||
|
"domhandler": {
|
||||||
|
"version": "5.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||||
|
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "^2.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domutils": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
|
||||||
|
"requires": {
|
||||||
|
"dom-serializer": "^2.0.0",
|
||||||
|
"domelementtype": "^2.3.0",
|
||||||
|
"domhandler": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entities": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
|
||||||
|
},
|
||||||
|
"escape-string-regexp": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||||
|
},
|
||||||
|
"htmlparser2": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "^2.3.0",
|
||||||
|
"domhandler": "^5.0.2",
|
||||||
|
"domutils": "^3.0.1",
|
||||||
|
"entities": "^4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"is-plain-object": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||||
|
},
|
||||||
|
"nanoid": {
|
||||||
|
"version": "3.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
||||||
|
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
|
||||||
|
},
|
||||||
|
"parse-srcset": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
|
||||||
|
},
|
||||||
|
"picocolors": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
||||||
|
},
|
||||||
|
"postcss": {
|
||||||
|
"version": "8.4.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
|
||||||
|
"integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
|
||||||
|
"requires": {
|
||||||
|
"nanoid": "^3.3.4",
|
||||||
|
"picocolors": "^1.0.0",
|
||||||
|
"source-map-js": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sanitize-html": {
|
||||||
|
"version": "2.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.10.0.tgz",
|
||||||
|
"integrity": "sha512-JqdovUd81dG4k87vZt6uA6YhDfWkUGruUu/aPmXLxXi45gZExnt9Bnw/qeQU8oGf82vPyaE0vO4aH0PbobB9JQ==",
|
||||||
|
"requires": {
|
||||||
|
"deepmerge": "^4.2.2",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"htmlparser2": "^8.0.0",
|
||||||
|
"is-plain-object": "^5.0.0",
|
||||||
|
"parse-srcset": "^1.0.2",
|
||||||
|
"postcss": "^8.3.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source-map-js": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
package.json
Normal file
5
package.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"sanitize-html": "^2.10.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue