28 changed files with 912 additions and 341 deletions
@ -0,0 +1,67 @@ |
|||||
|
// admin/newsletter.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const DTP_COMPONENT_NAME = 'admin:newsletter'; |
||||
|
const express = require('express'); |
||||
|
|
||||
|
const { SiteController } = require('../../../lib/site-lib'); |
||||
|
|
||||
|
class NewsletterController extends SiteController { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, DTP_COMPONENT_NAME); |
||||
|
} |
||||
|
|
||||
|
async start ( ) { |
||||
|
const router = express.Router(); |
||||
|
router.use(async (req, res, next) => { |
||||
|
res.locals.currentView = 'admin'; |
||||
|
res.locals.adminView = 'newsletter'; |
||||
|
return next(); |
||||
|
}); |
||||
|
|
||||
|
router.param('newsletterId', this.populateNewsletterId.bind(this)); |
||||
|
|
||||
|
router.get('/compose', this.getComposer.bind(this)); |
||||
|
|
||||
|
router.get('/:newsletterId', this.getComposer.bind(this)); |
||||
|
|
||||
|
router.get('/', this.getIndex.bind(this)); |
||||
|
|
||||
|
return router; |
||||
|
} |
||||
|
|
||||
|
async populateNewsletterId (req, res, next, newsletterId) { |
||||
|
const { newsletter: newsletterService } = this.dtp.services; |
||||
|
try { |
||||
|
res.locals.newsletter = await newsletterService.getById(newsletterId); |
||||
|
return next(); |
||||
|
} catch (error) { |
||||
|
this.log.error('failed to populate newsletterId', { newsletterId, error }); |
||||
|
return next(error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async getComposer (req, res) { |
||||
|
res.render('admin/newsletter/editor'); |
||||
|
} |
||||
|
|
||||
|
async getIndex (req, res, next) { |
||||
|
const { newsletter: newsletterService } = this.dtp.services; |
||||
|
try { |
||||
|
res.locals.pagination = this.getPaginationParameters(req, 20); |
||||
|
res.locals.newsletters = await newsletterService.getNewsletters(res.locals.pagination); |
||||
|
res.render('admin/newsletter/index'); |
||||
|
} catch (error) { |
||||
|
return next(error); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = async (dtp) => { |
||||
|
let controller = new NewsletterController(dtp); |
||||
|
return controller; |
||||
|
}; |
@ -0,0 +1,45 @@ |
|||||
|
// admin/page.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const DTP_COMPONENT_NAME = 'admin:page'; |
||||
|
const express = require('express'); |
||||
|
|
||||
|
const { SiteController } = require('../../../lib/site-lib'); |
||||
|
|
||||
|
class PageController extends SiteController { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, DTP_COMPONENT_NAME); |
||||
|
} |
||||
|
|
||||
|
async start ( ) { |
||||
|
const router = express.Router(); |
||||
|
router.use(async (req, res, next) => { |
||||
|
res.locals.currentView = 'admin'; |
||||
|
res.locals.adminView = 'page'; |
||||
|
return next(); |
||||
|
}); |
||||
|
|
||||
|
router.param('pageId', this.populatePageId.bind(this)); |
||||
|
|
||||
|
router.get('/', this.getIndex.bind(this)); |
||||
|
|
||||
|
return router; |
||||
|
} |
||||
|
|
||||
|
async populatePageId (req, res, next/*, pageId*/) { |
||||
|
return next(); |
||||
|
} |
||||
|
|
||||
|
async getIndex (req, res) { |
||||
|
res.render('admin/page/index'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = async (dtp) => { |
||||
|
let controller = new PageController(dtp); |
||||
|
return controller; |
||||
|
}; |
@ -0,0 +1,45 @@ |
|||||
|
// admin/post.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const DTP_COMPONENT_NAME = 'admin:post'; |
||||
|
const express = require('express'); |
||||
|
|
||||
|
const { SiteController } = require('../../../lib/site-lib'); |
||||
|
|
||||
|
class PostController extends SiteController { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, DTP_COMPONENT_NAME); |
||||
|
} |
||||
|
|
||||
|
async start ( ) { |
||||
|
const router = express.Router(); |
||||
|
router.use(async (req, res, next) => { |
||||
|
res.locals.currentView = 'admin'; |
||||
|
res.locals.adminView = 'post'; |
||||
|
return next(); |
||||
|
}); |
||||
|
|
||||
|
router.param('postId', this.populatePostId.bind(this)); |
||||
|
|
||||
|
router.get('/', this.getIndex.bind(this)); |
||||
|
|
||||
|
return router; |
||||
|
} |
||||
|
|
||||
|
async populatePostId (req, res, next/*, postId*/) { |
||||
|
return next(); |
||||
|
} |
||||
|
|
||||
|
async getIndex (req, res) { |
||||
|
res.render('admin/post/index'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = async (dtp) => { |
||||
|
let controller = new PostController(dtp); |
||||
|
return controller; |
||||
|
}; |
@ -0,0 +1,100 @@ |
|||||
|
// newsletter.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const DTP_COMPONENT_NAME = 'newsletter'; |
||||
|
|
||||
|
const express = require('express'); |
||||
|
const multer = require('multer'); |
||||
|
|
||||
|
const { SiteController } = require('../../lib/site-lib'); |
||||
|
|
||||
|
class NewsletterController extends SiteController { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, DTP_COMPONENT_NAME); |
||||
|
} |
||||
|
|
||||
|
async start ( ) { |
||||
|
const { dtp } = this; |
||||
|
const { limiter: limiterService } = dtp.services; |
||||
|
|
||||
|
const upload = multer({ dest: '/tmp' }); |
||||
|
|
||||
|
const router = express.Router(); |
||||
|
dtp.app.use('/newsletter', router); |
||||
|
|
||||
|
router.use(async (req, res, next) => { |
||||
|
res.locals.currentView = DTP_COMPONENT_NAME; |
||||
|
return next(); |
||||
|
}); |
||||
|
|
||||
|
router.param('newsletterId', this.populateNewsletterId.bind(this)); |
||||
|
|
||||
|
router.post('/', upload.none(), this.postAddRecipient.bind(this)); |
||||
|
|
||||
|
router.get('/:newsletterId', |
||||
|
limiterService.create(limiterService.config.newsletter.getView), |
||||
|
this.getView.bind(this), |
||||
|
); |
||||
|
|
||||
|
router.get('/', |
||||
|
limiterService.create(limiterService.config.newsletter.getIndex), |
||||
|
this.getIndex.bind(this), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
async populateNewsletterId (req, res, next, newsletterId) { |
||||
|
const { newsletter: newsletterService } = this.dtp.services; |
||||
|
try { |
||||
|
res.locals.newsletter = await newsletterService.getById(newsletterId); |
||||
|
return next(); |
||||
|
} catch (error) { |
||||
|
this.log.error('failed to populate newsletterId', { newsletterId, error }); |
||||
|
return next(error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async postAddRecipient (req, res) { |
||||
|
const { newsletter: newsletterService, displayEngine: displayEngineService } = this.dtp.services; |
||||
|
try { |
||||
|
const displayList = displayEngineService.createDisplayList('add-recipient'); |
||||
|
await newsletterService.addRecipient(req.body.email); |
||||
|
displayList.showNotification( |
||||
|
'You have been added to the newsletter. Please check your email and verify your email address.', |
||||
|
'success', |
||||
|
'bottom-center', |
||||
|
10000, |
||||
|
); |
||||
|
res.status(200).json({ success: true, displayList }); |
||||
|
} catch (error) { |
||||
|
this.log.error('failed to update account settings', { error }); |
||||
|
return res.status(error.statusCode || 500).json({ |
||||
|
success: false, |
||||
|
message: error.message, |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async getView (req, res) { |
||||
|
res.render('newsletter/view'); |
||||
|
} |
||||
|
|
||||
|
async getIndex (req, res, next) { |
||||
|
const { newsletter: newsletterService } = this.dtp.services; |
||||
|
try { |
||||
|
res.locals.pagination = this.getPaginationParameters(req, 20); |
||||
|
res.locals.newsletters = await newsletterService.getNewsletters(res.locals.pagination); |
||||
|
res.render('newsletter/index'); |
||||
|
} catch (error) { |
||||
|
return next(error); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = async (dtp) => { |
||||
|
let controller = new NewsletterController(dtp); |
||||
|
return controller; |
||||
|
}; |
@ -0,0 +1,15 @@ |
|||||
|
// email-body.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const mongoose = require('mongoose'); |
||||
|
const Schema = mongoose.Schema; |
||||
|
|
||||
|
const EmailBodySchema = new Schema({ |
||||
|
subject: { type: String, required: true }, |
||||
|
body: { type: String, required: true }, |
||||
|
}); |
||||
|
|
||||
|
module.exports = mongoose.model('EmailBody', EmailBodySchema); |
@ -0,0 +1,20 @@ |
|||||
|
// email.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const mongoose = require('mongoose'); |
||||
|
const Schema = mongoose.Schema; |
||||
|
|
||||
|
const EmailSchema = new Schema({ |
||||
|
created: { type: Date, default: Date.now, required: true, index: -1 }, |
||||
|
token: { type: String, required: true, index: 1 }, |
||||
|
from: { type: String, required: true, }, |
||||
|
to: { type: String, required: true }, |
||||
|
to_lc: { type: String, required: true, lowercase: true, index: 1 }, |
||||
|
contentType: { type: String, enum: ['Newsletter'], required: true }, |
||||
|
content: { type: Schema.ObjectId, required: true, index: true, refPath: 'contentType' }, |
||||
|
}); |
||||
|
|
||||
|
module.exports = mongoose.model('Email', EmailSchema); |
@ -0,0 +1,21 @@ |
|||||
|
// newsletter-recipient.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const mongoose = require('mongoose'); |
||||
|
const Schema = mongoose.Schema; |
||||
|
|
||||
|
const NewsletterRecipientSchema = new Schema({ |
||||
|
created: { type: Date, default: Date.now, required: true, index: 1 }, |
||||
|
address: { type: String, required: true }, |
||||
|
address_lc: { type: String, required: true, lowercase: true, unique: true, index: 1 }, |
||||
|
flags: { |
||||
|
isVerified: { type: Boolean, default: false, required: true, index: 1 }, |
||||
|
isOptIn: { type: Boolean, default: false, required: true, index: 1 }, |
||||
|
isRejected: { type: Boolean, default: false, required: true, index: 1 }, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
module.exports = mongoose.model('NewsletterRecipient', NewsletterRecipientSchema); |
@ -0,0 +1,31 @@ |
|||||
|
// newsletter.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const mongoose = require('mongoose'); |
||||
|
|
||||
|
const Schema = mongoose.Schema; |
||||
|
|
||||
|
const NEWSLETTER_STATUS_LIST = ['draft', 'published', 'archived']; |
||||
|
|
||||
|
const NewsletterSchema = new Schema({ |
||||
|
created: { type: Date, default: Date.now, required: true, index: -1 }, |
||||
|
author: { type: Schema.ObjectId, required: true, index: 1, ref: 'User' }, |
||||
|
title: { type: String, required: true }, |
||||
|
summary: { type: String }, |
||||
|
content: { |
||||
|
html: { type: String, required: true, select: false, }, |
||||
|
text: { type: String, required: true, select: false, }, |
||||
|
}, |
||||
|
status: { |
||||
|
type: String, |
||||
|
enum: NEWSLETTER_STATUS_LIST, |
||||
|
default: 'draft', |
||||
|
required: true, |
||||
|
index: true, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
module.exports = mongoose.model('Newsletter', NewsletterSchema); |
@ -0,0 +1,37 @@ |
|||||
|
// markdown.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const fs = require('fs'); |
||||
|
|
||||
|
const { SiteService } = require('../../lib/site-lib'); |
||||
|
|
||||
|
const marked = require('marked'); |
||||
|
|
||||
|
class MarkdownService extends SiteService { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, module.exports); |
||||
|
} |
||||
|
|
||||
|
async start ( ) { |
||||
|
this.markedRenderer = new marked.Renderer(); |
||||
|
} |
||||
|
|
||||
|
async renderMarkdownFile (documentFile) { |
||||
|
const markdown = await fs.promises.readFile(documentFile, 'utf8'); |
||||
|
return this.renderMarkdown(markdown); |
||||
|
} |
||||
|
|
||||
|
async renderMarkdown (markdown) { |
||||
|
return marked(markdown, { renderer: this.markedRenderer }); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
slug: 'markdown', |
||||
|
name: 'markdown', |
||||
|
create: (dtp) => { return new MarkdownService(dtp); }, |
||||
|
}; |
@ -0,0 +1,114 @@ |
|||||
|
// newsletter.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const striptags = require('striptags'); |
||||
|
|
||||
|
const { SiteService } = require('../../lib/site-lib'); |
||||
|
|
||||
|
const mongoose = require('mongoose'); |
||||
|
|
||||
|
const Newsletter = mongoose.model('Newsletter'); |
||||
|
const NewsletterRecipient = mongoose.model('NewsletterRecipient'); |
||||
|
|
||||
|
class NewsletterService extends SiteService { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, module.exports); |
||||
|
|
||||
|
this.populateNewsletter = [ |
||||
|
{ |
||||
|
path: 'author', |
||||
|
select: '_id username username_lc displayName picture', |
||||
|
}, |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
async create (author, newsletterDefinition) { |
||||
|
const NOW = new Date(); |
||||
|
|
||||
|
const newsletter = new Newsletter(); |
||||
|
newsletter.created = NOW; |
||||
|
newsletter.author = author._id; |
||||
|
newsletter.title = striptags(newsletterDefinition.title.trim()); |
||||
|
newsletter.summary = striptags(newsletterDefinition.summary.trim()); |
||||
|
newsletter.content = newsletterDefinition.content.trim(); |
||||
|
newsletter.status = striptags(newsletterDefinition.status.trim().toLowerCase()); |
||||
|
|
||||
|
await newsletter.save(); |
||||
|
|
||||
|
return newsletter.toObject(); |
||||
|
} |
||||
|
|
||||
|
async update (newsletter, newsletterDefinition) { |
||||
|
const updateOp = { $set: { } }; |
||||
|
|
||||
|
if (newsletterDefinition.title) { |
||||
|
updateOp.$set.title = striptags(newsletterDefinition.title.trim()); |
||||
|
} |
||||
|
if (newsletterDefinition.summary) { |
||||
|
updateOp.$set.summary = striptags(newsletterDefinition.summary.trim()); |
||||
|
} |
||||
|
if (newsletterDefinition.content) { |
||||
|
updateOp.$set.content = newsletterDefinition.title.trim(); |
||||
|
} |
||||
|
if (newsletterDefinition.status) { |
||||
|
updateOp.$set.status = striptags(newsletterDefinition.status.trim()); |
||||
|
} |
||||
|
|
||||
|
if (Object.keys(updateOp.$set).length === 0) { |
||||
|
return; // no update to perform
|
||||
|
} |
||||
|
|
||||
|
await Newsletter.updateOne( |
||||
|
{ _id: newsletter._id }, |
||||
|
updateOp, |
||||
|
{ upsert: true }, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
async getNewsletters (pagination, status = ['published']) { |
||||
|
if (!Array.isArray(status)) { |
||||
|
status = [status]; |
||||
|
} |
||||
|
const newsletters = await Newsletter |
||||
|
.find({ status: { $in: status } }) |
||||
|
.sort({ created: -1 }) |
||||
|
.skip(pagination.skip) |
||||
|
.limit(pagination.cpp) |
||||
|
.lean(); |
||||
|
return newsletters; |
||||
|
} |
||||
|
|
||||
|
async getById (newsletterId) { |
||||
|
const newsletter = await Newsletter |
||||
|
.findById(newsletterId) |
||||
|
.select('+content') |
||||
|
.populate(this.populateNewsletter) |
||||
|
.lean(); |
||||
|
return newsletter; |
||||
|
} |
||||
|
|
||||
|
async addRecipient (emailAddress) { |
||||
|
const { email: emailService } = this.dtp.services; |
||||
|
const NOW = new Date(); |
||||
|
|
||||
|
await emailService.checkEmailAddress(emailAddress); |
||||
|
|
||||
|
const recipient = new NewsletterRecipient(); |
||||
|
recipient.created = NOW; |
||||
|
recipient.address = striptags(emailAddress.trim()); |
||||
|
recipient.address_lc = recipient.address.toLowerCase(); |
||||
|
await recipient.save(); |
||||
|
|
||||
|
return recipient.toObject(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
slug: 'newsletter', |
||||
|
name: 'newsletter', |
||||
|
create: (dtp) => { return new NewsletterService(dtp); }, |
||||
|
}; |
@ -0,0 +1,59 @@ |
|||||
|
extends ../layouts/main |
||||
|
block content |
||||
|
|
||||
|
- var actionUrl = newsletter ? `/admin/newsletter/${newsletter._id}` : `/admin/newsletter`; |
||||
|
|
||||
|
form(method="POST", action= actionUrl).uk-form |
||||
|
.uk-margin |
||||
|
label(for="title").uk-form-label.sr-only Newsletter title |
||||
|
input(id="title", name="title", type="text", placeholder= "Enter newsletter title", value= newsletter ? newsletter.title : undefined).uk-input |
||||
|
|
||||
|
.uk-margin |
||||
|
label(for="content-html").uk-form-label.sr-only Newsletter HTML body |
||||
|
textarea(id="content-html", name="content.html", rows="4").uk-textarea= newsletter ? newsletter.content.html : undefined |
||||
|
|
||||
|
.uk-margin |
||||
|
button(type="button", onclick="return dtp.app.copyHtmlToText(event, 'content-text');").uk-button.dtp-button-default Copy HTML to Text |
||||
|
|
||||
|
.uk-margin |
||||
|
label(for="content-text").uk-form-label.sr-only Newsletter text body |
||||
|
textarea(id="content-text", name="content.text", rows="4", placeholder= "Enter text-only version of newsletter.").uk-textarea= newsletter ? newsletter.content.text : undefined |
||||
|
|
||||
|
.uk-margin |
||||
|
label(for="summary").uk-form-label.sr-only Newsletter summary |
||||
|
textarea(id="summary", name="summary", rows="4", placeholder= "Enter newsletter summary (text only, no HTML)").uk-textarea= newsletter ? newsletter.summary : undefined |
||||
|
|
||||
|
button(type="submit").uk-button.dtp-button-primary= newsletter ? 'Update newsletter' : 'Save newsletter' |
||||
|
|
||||
|
block viewjs |
||||
|
script(src="/tinymce/tinymce.min.js") |
||||
|
script. |
||||
|
window.addEventListener('dtp-load', async ( ) => { |
||||
|
const toolbarItems = [ |
||||
|
'undo redo', |
||||
|
'formatselect', |
||||
|
'bold italic backcolor', |
||||
|
'alignleft aligncenter alignright alignjustify', |
||||
|
'bullist numlist outdent indent removeformat', |
||||
|
'link image', |
||||
|
'help' |
||||
|
]; |
||||
|
const pluginItems = [ |
||||
|
'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'print', |
||||
|
'preview', 'anchor', 'searchreplace', 'visualblocks', 'code', |
||||
|
'fullscreen', 'insertdatetime', 'media', 'table', 'paste', 'code', |
||||
|
'help', 'wordcount', |
||||
|
] |
||||
|
|
||||
|
const editors = await tinymce.init({ |
||||
|
selector: 'textarea#content-html', |
||||
|
height: 500, |
||||
|
menubar: false, |
||||
|
plugins: pluginItems.join(' '), |
||||
|
toolbar: toolbarItems.join('|'), |
||||
|
branding: false, |
||||
|
images_upload_url: '/image/tinymce', |
||||
|
}); |
||||
|
|
||||
|
window.dtp.app.editor = editors[0]; |
||||
|
}); |
@ -0,0 +1,21 @@ |
|||||
|
extends ../layouts/main |
||||
|
block content |
||||
|
|
||||
|
.uk-margin |
||||
|
div(uk-grid) |
||||
|
.uk-width-expand |
||||
|
h1 Newsletters |
||||
|
.uk-width-auto |
||||
|
a(href="/admin/newsletter/compose").uk-button.dtp-button-primary |
||||
|
span |
||||
|
i.fas.fa-plus |
||||
|
span.uk-margin-small-left New Newsletter |
||||
|
|
||||
|
.uk-margin |
||||
|
if (Array.isArray(newsletters) && (newsletters.length > 0)) |
||||
|
ul.uk-list |
||||
|
each newsletter in newsletters |
||||
|
li |
||||
|
a(href=`/admin/newsletter/${newsletter._id}`)= newsletter.title |
||||
|
else |
||||
|
div There are no newsletters at this time. |
@ -0,0 +1,15 @@ |
|||||
|
extends ../layouts/main |
||||
|
block content |
||||
|
|
||||
|
section.uk-section.uk-section-default |
||||
|
.uk-container |
||||
|
|
||||
|
h1 #{site.name} Newsletters |
||||
|
|
||||
|
if Array.isArray(newsletters) && (newsletters.length > 0) |
||||
|
ul.uk-list |
||||
|
each newsletter of newsletters |
||||
|
li |
||||
|
a(href=`/newsletter/${newsletter._id}`).uk-link-reset= newsletter.title |
||||
|
else |
||||
|
div There are no newsletters at this time. Please check back later. |
@ -0,0 +1,113 @@ |
|||||
|
// newsletter.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// All Rights Reserved
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const DTP_COMPONENT_NAME = 'newsletter'; |
||||
|
|
||||
|
const path = require('path'); |
||||
|
require('dotenv').config({ path: path.resolve(__dirname, '..', '..', '.env') }); |
||||
|
|
||||
|
const mongoose = require('mongoose'); |
||||
|
|
||||
|
const { SitePlatform, SiteLog } = require(path.join(__dirname, '..', '..', 'lib', 'site-lib')); |
||||
|
|
||||
|
module.pkg = require(path.resolve(__dirname, '..', '..', 'package.json')); |
||||
|
module.config = { |
||||
|
componentName: DTP_COMPONENT_NAME, |
||||
|
root: path.resolve(__dirname, '..', '..'), |
||||
|
}; |
||||
|
|
||||
|
module.log = new SiteLog(module, module.config.componentName); |
||||
|
|
||||
|
module.sendNewsletter = async (job) => { |
||||
|
|
||||
|
module.log.info('newsletter email job received', { data: job.data }); |
||||
|
|
||||
|
const NewsletterRecipient = mongoose.model('NewsletterRecipient'); |
||||
|
|
||||
|
try { |
||||
|
/* |
||||
|
* Create one Bull Queue job per email to be delivered. |
||||
|
*/ |
||||
|
await NewsletterRecipient |
||||
|
.find({ 'flags.isVerified': true, 'flags.isOptIn': true, 'flags.isRejected': false }) |
||||
|
.lean() |
||||
|
.cursor() |
||||
|
.eachAsync(async (recipient) => { |
||||
|
try { |
||||
|
const jobData = { |
||||
|
newsletterId: job.data.newsletterId, |
||||
|
recipient: recipient.address, |
||||
|
}; |
||||
|
const jobOptions = { |
||||
|
attempts: 3, |
||||
|
}; |
||||
|
await module.jobQueue.add('email-send', jobData, jobOptions); |
||||
|
} catch (error) { |
||||
|
module.log.error('failed to create newsletter email job'); |
||||
|
// but continue
|
||||
|
} |
||||
|
}, { parallel: 4 }); |
||||
|
} catch (error) { |
||||
|
module.log('failed to send newsletter', { newsletterId: job.data.newsletterId, error }); |
||||
|
throw error; // throw error to Bull so it can report in job reports
|
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
module.sendNewsletterEmail = async (job) => { |
||||
|
const { newsletter: newsletterService, email: emailService } = module.services; |
||||
|
const { newsletterId, recipient } = job.data; |
||||
|
try { |
||||
|
|
||||
|
let newsletter = module.newsletters[newsletterId]; |
||||
|
|
||||
|
if (!newsletter) { |
||||
|
newsletter = await newsletterService.getById(newsletterId); |
||||
|
module.newsletters[newsletterId] = newsletter; //TODO: clean up memory leak of newsletter (remove when all emails are sent)
|
||||
|
} |
||||
|
|
||||
|
if (!newsletter) { |
||||
|
throw new Error('newsletter not found'); |
||||
|
} |
||||
|
|
||||
|
const response = await emailService.send({ |
||||
|
from: '[email protected]', |
||||
|
to: recipient, |
||||
|
subject: newsletter.title, |
||||
|
html: newsletter.content.html, |
||||
|
text: newsletter.content.text, |
||||
|
}); |
||||
|
|
||||
|
job.log(`newsletter email sent: ${response}`); |
||||
|
} catch (error) { |
||||
|
module.error('failed to send newsletter email', { newsletterId, recipient, error }); |
||||
|
throw error; // throw error to Bull so it can report in job reports
|
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
(async ( ) => { |
||||
|
try { |
||||
|
/* |
||||
|
* Platform startup |
||||
|
*/ |
||||
|
await SitePlatform.startPlatform(module); |
||||
|
|
||||
|
const { jobQueue: jobQueueService } = module.services; |
||||
|
|
||||
|
module.jobQueue = await jobQueueService.getJobQueue('newsletter', { |
||||
|
attempts: 3, |
||||
|
}); |
||||
|
module.jobQueue.process('email', module.sendNewsletter); |
||||
|
module.jobQueue.process('email-send', module.sendNewsletterEmail); |
||||
|
|
||||
|
/* |
||||
|
* Worker startup |
||||
|
*/ |
||||
|
module.log.info(`${module.pkg.name} v${module.pkg.version} Newsletter worker started`); |
||||
|
} catch (error) { |
||||
|
module.log.error('failed to start Newsletter worker', { error }); |
||||
|
process.exit(-1); |
||||
|
} |
||||
|
})(); |
@ -0,0 +1,40 @@ |
|||||
|
# DTP Sites: Services |
||||
|
|
||||
|
Services are common logic implemented in a centralized location made accessible to the rest of the application to perform tasks in a common way. They live in [app/services](app/services), and are scripts that export a specific structure that identifies the service and provides a way to create, start, and stop them. |
||||
|
|
||||
|
Services can't reference each other in their constructors, but they can reference each other in their `start` method with the caveat that the service you are referencing may not have had it's `start` method called, yet. DTP loads services in one loop, then starts them in a separate loop after they are loaded. |
||||
|
|
||||
|
All other service methods implemented can reference all other services with the assumption that they are started and ready to provide full service. |
||||
|
|
||||
|
```js |
||||
|
// myservice.js |
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC |
||||
|
// License: Apache-2.0 |
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const { SiteService } = require('../../lib/site-lib'); |
||||
|
|
||||
|
class MyService extends SiteService { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, module.exports); |
||||
|
} |
||||
|
|
||||
|
async start ( ) { |
||||
|
/* |
||||
|
* perform service initialization here |
||||
|
*/ |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* Implement service methods here |
||||
|
*/ |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
slug: 'my-service', |
||||
|
name: 'myService', |
||||
|
create: (dtp) => { return new MyService(dtp); }, |
||||
|
}; |
||||
|
``` |
@ -1265,13 +1265,6 @@ [email protected]: |
|||||
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" |
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" |
||||
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= |
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= |
||||
|
|
||||
agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: |
|
||||
version "4.3.0" |
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" |
|
||||
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== |
|
||||
dependencies: |
|
||||
es6-promisify "^5.0.0" |
|
||||
|
|
||||
agent-base@6: |
agent-base@6: |
||||
version "6.0.2" |
version "6.0.2" |
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" |
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" |
||||
@ -1279,13 +1272,6 @@ agent-base@6: |
|||||
dependencies: |
dependencies: |
||||
debug "4" |
debug "4" |
||||
|
|
||||
agent-base@~4.2.1: |
|
||||
version "4.2.1" |
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" |
|
||||
integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== |
|
||||
dependencies: |
|
||||
es6-promisify "^5.0.0" |
|
||||
|
|
||||
ajv-keywords@^3.5.2: |
ajv-keywords@^3.5.2: |
||||
version "3.5.2" |
version "3.5.2" |
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" |
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" |
||||
@ -1547,13 +1533,6 @@ assign-symbols@^1.0.0: |
|||||
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" |
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" |
||||
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= |
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= |
||||
|
|
||||
[email protected]: |
|
||||
version "0.14.2" |
|
||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" |
|
||||
integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== |
|
||||
dependencies: |
|
||||
tslib "^2.0.1" |
|
||||
|
|
||||
async-done@^1.2.0, async-done@^1.2.2: |
async-done@^1.2.0, async-done@^1.2.2: |
||||
version "1.3.2" |
version "1.3.2" |
||||
resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" |
resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" |
||||
@ -1591,7 +1570,7 @@ [email protected]: |
|||||
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" |
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" |
||||
integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= |
integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= |
||||
|
|
||||
async@^2.1.1, async@^2.6.1: |
async@^2.1.1: |
||||
version "2.6.3" |
version "2.6.3" |
||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" |
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" |
||||
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== |
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== |
||||
@ -2301,7 +2280,7 @@ colors@^1.1.2, colors@^1.2.1: |
|||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" |
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" |
||||
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== |
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== |
||||
|
|
||||
combined-stream@^1.0.6, combined-stream@^1.0.8: |
combined-stream@^1.0.8: |
||||
version "1.0.8" |
version "1.0.8" |
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" |
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" |
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== |
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== |
||||
@ -2574,11 +2553,6 @@ d@1, d@^1.0.1: |
|||||
es5-ext "^0.10.50" |
es5-ext "^0.10.50" |
||||
type "^1.0.1" |
type "^1.0.1" |
||||
|
|
||||
data-uri-to-buffer@1: |
|
||||
version "1.2.0" |
|
||||
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" |
|
||||
integrity sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ== |
|
||||
|
|
||||
data-urls@^3.0.1: |
data-urls@^3.0.1: |
||||
version "3.0.1" |
version "3.0.1" |
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.1.tgz#597fc2ae30f8bc4dbcf731fcd1b1954353afc6f8" |
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.1.tgz#597fc2ae30f8bc4dbcf731fcd1b1954353afc6f8" |
||||
@ -2593,7 +2567,7 @@ date-now@^0.1.4: |
|||||
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" |
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" |
||||
integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= |
integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= |
||||
|
|
||||
debug@2, [email protected], debug@^2.2.0, debug@^2.3.3, debug@~2.6.4: |
[email protected], debug@^2.2.0, debug@^2.3.3, debug@~2.6.4: |
||||
version "2.6.9" |
version "2.6.9" |
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" |
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" |
||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== |
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== |
||||
@ -2621,7 +2595,7 @@ [email protected]: |
|||||
dependencies: |
dependencies: |
||||
ms "2.1.2" |
ms "2.1.2" |
||||
|
|
||||
debug@^3.1.0, debug@^3.2.6, debug@^3.2.7: |
debug@^3.2.6, debug@^3.2.7: |
||||
version "3.2.7" |
version "3.2.7" |
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" |
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" |
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== |
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== |
||||
@ -2730,15 +2704,6 @@ define-property@^2.0.2: |
|||||
is-descriptor "^1.0.2" |
is-descriptor "^1.0.2" |
||||
isobject "^3.0.1" |
isobject "^3.0.1" |
||||
|
|
||||
degenerator@^1.0.4: |
|
||||
version "1.0.4" |
|
||||
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" |
|
||||
integrity sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU= |
|
||||
dependencies: |
|
||||
ast-types "0.x.x" |
|
||||
escodegen "1.x.x" |
|
||||
esprima "3.x.x" |
|
||||
|
|
||||
delayed-stream@~1.0.0: |
delayed-stream@~1.0.0: |
||||
version "1.0.0" |
version "1.0.0" |
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" |
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" |
||||
@ -3146,18 +3111,6 @@ es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3: |
|||||
es5-ext "^0.10.35" |
es5-ext "^0.10.35" |
||||
es6-symbol "^3.1.1" |
es6-symbol "^3.1.1" |
||||
|
|
||||
es6-promise@^4.0.3: |
|
||||
version "4.2.8" |
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" |
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== |
|
||||
|
|
||||
es6-promisify@^5.0.0: |
|
||||
version "5.0.0" |
|
||||
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" |
|
||||
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= |
|
||||
dependencies: |
|
||||
es6-promise "^4.0.3" |
|
||||
|
|
||||
es6-symbol@^3.1.1, es6-symbol@~3.1.3: |
es6-symbol@^3.1.1, es6-symbol@~3.1.3: |
||||
version "3.1.3" |
version "3.1.3" |
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" |
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" |
||||
@ -3196,18 +3149,6 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: |
|||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" |
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" |
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= |
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= |
||||
|
|
||||
[email protected]: |
|
||||
version "1.14.3" |
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" |
|
||||
integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== |
|
||||
dependencies: |
|
||||
esprima "^4.0.1" |
|
||||
estraverse "^4.2.0" |
|
||||
esutils "^2.0.2" |
|
||||
optionator "^0.8.1" |
|
||||
optionalDependencies: |
|
||||
source-map "~0.6.1" |
|
||||
|
|
||||
escodegen@^2.0.0: |
escodegen@^2.0.0: |
||||
version "2.0.0" |
version "2.0.0" |
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" |
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" |
||||
@ -3228,11 +3169,6 @@ [email protected]: |
|||||
esrecurse "^4.3.0" |
esrecurse "^4.3.0" |
||||
estraverse "^4.1.1" |
estraverse "^4.1.1" |
||||
|
|
||||
[email protected]: |
|
||||
version "3.1.3" |
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" |
|
||||
integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= |
|
||||
|
|
||||
esprima@^4.0.1: |
esprima@^4.0.1: |
||||
version "4.0.1" |
version "4.0.1" |
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" |
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" |
||||
@ -3245,7 +3181,7 @@ esrecurse@^4.3.0: |
|||||
dependencies: |
dependencies: |
||||
estraverse "^5.2.0" |
estraverse "^5.2.0" |
||||
|
|
||||
estraverse@^4.1.1, estraverse@^4.2.0: |
estraverse@^4.1.1: |
||||
version "4.3.0" |
version "4.3.0" |
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" |
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" |
||||
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== |
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== |
||||
@ -3409,7 +3345,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: |
|||||
assign-symbols "^1.0.0" |
assign-symbols "^1.0.0" |
||||
is-extendable "^1.0.1" |
is-extendable "^1.0.1" |
||||
|
|
||||
extend@^3.0.0, extend@~3.0.2: |
extend@^3.0.0: |
||||
version "3.0.2" |
version "3.0.2" |
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" |
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" |
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== |
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== |
||||
@ -3479,7 +3415,7 @@ feed@^4.2.2: |
|||||
dependencies: |
dependencies: |
||||
xml-js "^1.6.11" |
xml-js "^1.6.11" |
||||
|
|
||||
file-uri-to-path@1, [email protected]: |
[email protected]: |
||||
version "1.0.0" |
version "1.0.0" |
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" |
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" |
||||
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== |
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== |
||||
@ -3616,15 +3552,6 @@ foreach@^2.0.5: |
|||||
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" |
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" |
||||
integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= |
integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= |
||||
|
|
||||
form-data@^2.3.3: |
|
||||
version "2.5.1" |
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" |
|
||||
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== |
|
||||
dependencies: |
|
||||
asynckit "^0.4.0" |
|
||||
combined-stream "^1.0.6" |
|
||||
mime-types "^2.1.12" |
|
||||
|
|
||||
form-data@^4.0.0: |
form-data@^4.0.0: |
||||
version "4.0.0" |
version "4.0.0" |
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" |
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" |
||||
@ -3701,14 +3628,6 @@ fsevents@~2.3.2: |
|||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" |
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" |
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== |
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== |
||||
|
|
||||
ftp@~0.3.10: |
|
||||
version "0.3.10" |
|
||||
resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" |
|
||||
integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0= |
|
||||
dependencies: |
|
||||
readable-stream "1.1.x" |
|
||||
xregexp "2.0.0" |
|
||||
|
|
||||
function-bind@^1.1.1: |
function-bind@^1.1.1: |
||||
version "1.1.1" |
version "1.1.1" |
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" |
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" |
||||
@ -3802,18 +3721,6 @@ get-symbol-description@^1.0.0: |
|||||
call-bind "^1.0.2" |
call-bind "^1.0.2" |
||||
get-intrinsic "^1.1.1" |
get-intrinsic "^1.1.1" |
||||
|
|
||||
get-uri@^2.0.0: |
|
||||
version "2.0.4" |
|
||||
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.4.tgz#d4937ab819e218d4cb5ae18e4f5962bef169cc6a" |
|
||||
integrity sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q== |
|
||||
dependencies: |
|
||||
data-uri-to-buffer "1" |
|
||||
debug "2" |
|
||||
extend "~3.0.2" |
|
||||
file-uri-to-path "1" |
|
||||
ftp "~0.3.10" |
|
||||
readable-stream "2" |
|
||||
|
|
||||
get-value@^2.0.3, get-value@^2.0.6: |
get-value@^2.0.3, get-value@^2.0.6: |
||||
version "2.0.6" |
version "2.0.6" |
||||
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" |
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" |
||||
@ -4236,14 +4143,6 @@ http-errors@~1.7.2: |
|||||
statuses ">= 1.5.0 < 2" |
statuses ">= 1.5.0 < 2" |
||||
toidentifier "1.0.0" |
toidentifier "1.0.0" |
||||
|
|
||||
http-proxy-agent@^2.1.0: |
|
||||
version "2.1.0" |
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" |
|
||||
integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== |
|
||||
dependencies: |
|
||||
agent-base "4" |
|
||||
debug "3.1.0" |
|
||||
|
|
||||
http-proxy-agent@^5.0.0: |
http-proxy-agent@^5.0.0: |
||||
version "5.0.0" |
version "5.0.0" |
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" |
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" |
||||
@ -4262,14 +4161,6 @@ http-proxy@^1.18.1: |
|||||
follow-redirects "^1.0.0" |
follow-redirects "^1.0.0" |
||||
requires-port "^1.0.0" |
requires-port "^1.0.0" |
||||
|
|
||||
https-proxy-agent@^3.0.0: |
|
||||
version "3.0.1" |
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz#b8c286433e87602311b01c8ea34413d856a4af81" |
|
||||
integrity sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg== |
|
||||
dependencies: |
|
||||
agent-base "^4.3.0" |
|
||||
debug "^3.1.0" |
|
||||
|
|
||||
https-proxy-agent@^5.0.0: |
https-proxy-agent@^5.0.0: |
||||
version "5.0.0" |
version "5.0.0" |
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" |
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" |
||||
@ -4337,16 +4228,6 @@ [email protected]: |
|||||
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" |
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" |
||||
integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= |
integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= |
||||
|
|
||||
inflection@~1.12.0: |
|
||||
version "1.12.0" |
|
||||
resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" |
|
||||
integrity sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= |
|
||||
|
|
||||
inflection@~1.3.0: |
|
||||
version "1.3.8" |
|
||||
resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.3.8.tgz#cbd160da9f75b14c3cc63578d4f396784bf3014e" |
|
||||
integrity sha1-y9Fg2p91sUw8xjV41POWeEvzAU4= |
|
||||
|
|
||||
inflight@^1.0.4: |
inflight@^1.0.4: |
||||
version "1.0.6" |
version "1.0.6" |
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" |
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" |
||||
@ -4420,11 +4301,6 @@ ip-address@^5.8.9: |
|||||
lodash "^4.17.15" |
lodash "^4.17.15" |
||||
sprintf-js "1.1.2" |
sprintf-js "1.1.2" |
||||
|
|
||||
[email protected], ip@^1.1.5: |
|
||||
version "1.1.5" |
|
||||
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" |
|
||||
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= |
|
||||
|
|
||||
[email protected]: |
[email protected]: |
||||
version "1.9.1" |
version "1.9.1" |
||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" |
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" |
||||
@ -4754,11 +4630,6 @@ is-shared-array-buffer@^1.0.1: |
|||||
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" |
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" |
||||
integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== |
integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== |
||||
|
|
||||
is-stream@^1.1.0: |
|
||||
version "1.1.0" |
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" |
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= |
|
||||
|
|
||||
is-stream@^2.0.0: |
is-stream@^2.0.0: |
||||
version "2.0.1" |
version "2.0.1" |
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" |
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" |
||||
@ -5295,13 +5166,6 @@ lowercase-keys@^2.0.0: |
|||||
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" |
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" |
||||
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== |
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== |
||||
|
|
||||
lru-cache@^5.1.1: |
|
||||
version "5.1.1" |
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" |
|
||||
integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== |
|
||||
dependencies: |
|
||||
yallist "^3.0.2" |
|
||||
|
|
||||
lru-cache@^6.0.0: |
lru-cache@^6.0.0: |
||||
version "6.0.0" |
version "6.0.0" |
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" |
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" |
||||
@ -5316,21 +5180,6 @@ magic-string@^0.25.0, magic-string@^0.25.7: |
|||||
dependencies: |
dependencies: |
||||
sourcemap-codec "^1.4.4" |
sourcemap-codec "^1.4.4" |
||||
|
|
||||
mailgun-js@^0.22.0: |
|
||||
version "0.22.0" |
|
||||
resolved "https://registry.yarnpkg.com/mailgun-js/-/mailgun-js-0.22.0.tgz#128942b5e47a364a470791608852bf68c96b3a05" |
|
||||
integrity sha512-a2alg5nuTZA9Psa1pSEIEsbxr1Zrmqx4VkgGCQ30xVh0kIH7Bu57AYILo+0v8QLSdXtCyLaS+KVmdCrQo0uWFA== |
|
||||
dependencies: |
|
||||
async "^2.6.1" |
|
||||
debug "^4.1.0" |
|
||||
form-data "^2.3.3" |
|
||||
inflection "~1.12.0" |
|
||||
is-stream "^1.1.0" |
|
||||
path-proxy "~1.0.0" |
|
||||
promisify-call "^2.0.2" |
|
||||
proxy-agent "^3.0.3" |
|
||||
tsscmp "^1.0.6" |
|
||||
|
|
||||
make-dir@^2.1.0: |
make-dir@^2.1.0: |
||||
version "2.1.0" |
version "2.1.0" |
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" |
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" |
||||
@ -5700,11 +5549,6 @@ neo-async@^2.6.2: |
|||||
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== |
||||
|
|
||||
netmask@^1.0.6: |
|
||||
version "1.0.6" |
|
||||
resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" |
|
||||
integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU= |
|
||||
|
|
||||
next-tick@~1.0.0: |
next-tick@~1.0.0: |
||||
version "1.0.0" |
version "1.0.0" |
||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" |
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" |
||||
@ -5734,6 +5578,11 @@ node-releases@^2.0.1: |
|||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" |
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" |
||||
integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== |
integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== |
||||
|
|
||||
|
nodemailer@^6.7.2: |
||||
|
version "6.7.2" |
||||
|
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.2.tgz#44b2ad5f7ed71b7067f7a21c4fedabaec62b85e0" |
||||
|
integrity sha512-Dz7zVwlef4k5R71fdmxwR8Q39fiboGbu3xgswkzGwczUfjp873rVxt1O46+Fh0j1ORnAC6L9+heI8uUpO6DT7Q== |
||||
|
|
||||
nodemon@^2.0.2: |
nodemon@^2.0.2: |
||||
version "2.0.15" |
version "2.0.15" |
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e" |
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e" |
||||
@ -6026,31 +5875,6 @@ p-try@^2.0.0: |
|||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" |
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" |
||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== |
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== |
||||
|
|
||||
pac-proxy-agent@^3.0.1: |
|
||||
version "3.0.1" |
|
||||
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz#115b1e58f92576cac2eba718593ca7b0e37de2ad" |
|
||||
integrity sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ== |
|
||||
dependencies: |
|
||||
agent-base "^4.2.0" |
|
||||
debug "^4.1.1" |
|
||||
get-uri "^2.0.0" |
|
||||
http-proxy-agent "^2.1.0" |
|
||||
https-proxy-agent "^3.0.0" |
|
||||
pac-resolver "^3.0.0" |
|
||||
raw-body "^2.2.0" |
|
||||
socks-proxy-agent "^4.0.1" |
|
||||
|
|
||||
pac-resolver@^3.0.0: |
|
||||
version "3.0.0" |
|
||||
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-3.0.0.tgz#6aea30787db0a891704deb7800a722a7615a6f26" |
|
||||
integrity sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA== |
|
||||
dependencies: |
|
||||
co "^4.6.0" |
|
||||
degenerator "^1.0.4" |
|
||||
ip "^1.1.5" |
|
||||
netmask "^1.0.6" |
|
||||
thunkify "^2.1.2" |
|
||||
|
|
||||
package-json@^6.3.0: |
package-json@^6.3.0: |
||||
version "6.5.0" |
version "6.5.0" |
||||
resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" |
resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" |
||||
@ -6169,13 +5993,6 @@ path-parse@^1.0.6: |
|||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" |
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" |
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== |
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== |
||||
|
|
||||
path-proxy@~1.0.0: |
|
||||
version "1.0.0" |
|
||||
resolved "https://registry.yarnpkg.com/path-proxy/-/path-proxy-1.0.0.tgz#18e8a36859fc9d2f1a53b48dee138543c020de5e" |
|
||||
integrity sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4= |
|
||||
dependencies: |
|
||||
inflection "~1.3.0" |
|
||||
|
|
||||
path-root-regex@^0.1.0: |
path-root-regex@^0.1.0: |
||||
version "0.1.2" |
version "0.1.2" |
||||
resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" |
resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" |
||||
@ -6334,13 +6151,6 @@ promise@^7.0.1: |
|||||
dependencies: |
dependencies: |
||||
asap "~2.0.3" |
asap "~2.0.3" |
||||
|
|
||||
promisify-call@^2.0.2: |
|
||||
version "2.0.4" |
|
||||
resolved "https://registry.yarnpkg.com/promisify-call/-/promisify-call-2.0.4.tgz#d48c2d45652ccccd52801ddecbd533a6d4bd5fba" |
|
||||
integrity sha1-1IwtRWUszM1SgB3ey9UzptS9X7o= |
|
||||
dependencies: |
|
||||
with-callback "^1.0.2" |
|
||||
|
|
||||
proxy-addr@~2.0.5: |
proxy-addr@~2.0.5: |
||||
version "2.0.7" |
version "2.0.7" |
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" |
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" |
||||
@ -6349,25 +6159,6 @@ proxy-addr@~2.0.5: |
|||||
forwarded "0.2.0" |
forwarded "0.2.0" |
||||
ipaddr.js "1.9.1" |
ipaddr.js "1.9.1" |
||||
|
|
||||
proxy-agent@^3.0.3: |
|
||||
version "3.1.1" |
|
||||
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-3.1.1.tgz#7e04e06bf36afa624a1540be247b47c970bd3014" |
|
||||
integrity sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw== |
|
||||
dependencies: |
|
||||
agent-base "^4.2.0" |
|
||||
debug "4" |
|
||||
http-proxy-agent "^2.1.0" |
|
||||
https-proxy-agent "^3.0.0" |
|
||||
lru-cache "^5.1.1" |
|
||||
pac-proxy-agent "^3.0.1" |
|
||||
proxy-from-env "^1.0.0" |
|
||||
socks-proxy-agent "^4.0.1" |
|
||||
|
|
||||
proxy-from-env@^1.0.0: |
|
||||
version "1.1.0" |
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" |
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== |
|
||||
|
|
||||
prr@~1.0.1: |
prr@~1.0.1: |
||||
version "1.0.1" |
version "1.0.1" |
||||
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" |
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" |
||||
@ -6580,7 +6371,7 @@ [email protected]: |
|||||
iconv-lite "0.4.24" |
iconv-lite "0.4.24" |
||||
unpipe "1.0.0" |
unpipe "1.0.0" |
||||
|
|
||||
raw-body@^2.2.0, raw-body@^2.3.2: |
raw-body@^2.3.2: |
||||
version "2.4.2" |
version "2.4.2" |
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" |
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" |
||||
integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== |
integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== |
||||
@ -6654,7 +6445,16 @@ [email protected]: |
|||||
isarray "0.0.1" |
isarray "0.0.1" |
||||
string_decoder "~0.10.x" |
string_decoder "~0.10.x" |
||||
|
|
||||
readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: |
"readable-stream@2 || 3", readable-stream@3, readable-stream@^3.1.1, readable-stream@^3.4.0: |
||||
|
version "3.6.0" |
||||
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" |
||||
|
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== |
||||
|
dependencies: |
||||
|
inherits "^2.0.3" |
||||
|
string_decoder "^1.1.1" |
||||
|
util-deprecate "^1.0.1" |
||||
|
|
||||
|
readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: |
||||
version "2.3.7" |
version "2.3.7" |
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" |
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" |
||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== |
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== |
||||
@ -6667,15 +6467,6 @@ readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stre |
|||||
string_decoder "~1.1.1" |
string_decoder "~1.1.1" |
||||
util-deprecate "~1.0.1" |
util-deprecate "~1.0.1" |
||||
|
|
||||
"readable-stream@2 || 3", readable-stream@3, readable-stream@^3.1.1, readable-stream@^3.4.0: |
|
||||
version "3.6.0" |
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" |
|
||||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== |
|
||||
dependencies: |
|
||||
inherits "^2.0.3" |
|
||||
string_decoder "^1.1.1" |
|
||||
util-deprecate "^1.0.1" |
|
||||
|
|
||||
readdirp@^2.2.1: |
readdirp@^2.2.1: |
||||
version "2.2.1" |
version "2.2.1" |
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" |
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" |
||||
@ -7281,11 +7072,6 @@ slug@^5.1.0: |
|||||
resolved "https://registry.yarnpkg.com/slug/-/slug-5.1.0.tgz#8a7e30ca1c3a6dc40cf74e269750913a865edb0b" |
resolved "https://registry.yarnpkg.com/slug/-/slug-5.1.0.tgz#8a7e30ca1c3a6dc40cf74e269750913a865edb0b" |
||||
integrity sha512-IS39jKR6m+puU8zWgH6ruwx1sfzFNJ6Ai5PKIlUqd0X8C3ca7PB49Cvm0uayqgEt1jgaojO2wWEsQJngnh7fDA== |
integrity sha512-IS39jKR6m+puU8zWgH6ruwx1sfzFNJ6Ai5PKIlUqd0X8C3ca7PB49Cvm0uayqgEt1jgaojO2wWEsQJngnh7fDA== |
||||
|
|
||||
smart-buffer@^4.1.0: |
|
||||
version "4.2.0" |
|
||||
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" |
|
||||
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== |
|
||||
|
|
||||
snapdragon-node@^2.0.1: |
snapdragon-node@^2.0.1: |
||||
version "2.1.1" |
version "2.1.1" |
||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" |
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" |
||||
@ -7414,22 +7200,6 @@ socket.io@^4.4.0: |
|||||
socket.io-adapter "~2.3.3" |
socket.io-adapter "~2.3.3" |
||||
socket.io-parser "~4.0.4" |
socket.io-parser "~4.0.4" |
||||
|
|
||||
socks-proxy-agent@^4.0.1: |
|
||||
version "4.0.2" |
|
||||
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" |
|
||||
integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== |
|
||||
dependencies: |
|
||||
agent-base "~4.2.1" |
|
||||
socks "~2.3.2" |
|
||||
|
|
||||
socks@~2.3.2: |
|
||||
version "2.3.3" |
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" |
|
||||
integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== |
|
||||
dependencies: |
|
||||
ip "1.1.5" |
|
||||
smart-buffer "^4.1.0" |
|
||||
|
|
||||
source-list-map@^2.0.0: |
source-list-map@^2.0.0: |
||||
version "2.0.1" |
version "2.0.1" |
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" |
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" |
||||
@ -7878,11 +7648,6 @@ through@^2.3.8: |
|||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" |
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" |
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= |
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= |
||||
|
|
||||
thunkify@^2.1.2: |
|
||||
version "2.1.2" |
|
||||
resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" |
|
||||
integrity sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0= |
|
||||
|
|
||||
time-stamp@^1.0.0: |
time-stamp@^1.0.0: |
||||
version "1.1.0" |
version "1.1.0" |
||||
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" |
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" |
||||
@ -8005,16 +7770,11 @@ tr46@~0.0.3: |
|||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" |
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" |
||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= |
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= |
||||
|
|
||||
tslib@^2.0.1, tslib@^2.3.0: |
tslib@^2.3.0: |
||||
version "2.3.1" |
version "2.3.1" |
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" |
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" |
||||
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== |
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== |
||||
|
|
||||
tsscmp@^1.0.6: |
|
||||
version "1.0.6" |
|
||||
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" |
|
||||
integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== |
|
||||
|
|
||||
tunnel-agent@^0.6.0: |
tunnel-agent@^0.6.0: |
||||
version "0.6.0" |
version "0.6.0" |
||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" |
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" |
||||
@ -8578,11 +8338,6 @@ widest-line@^3.1.0: |
|||||
dependencies: |
dependencies: |
||||
string-width "^4.0.0" |
string-width "^4.0.0" |
||||
|
|
||||
with-callback@^1.0.2: |
|
||||
version "1.0.2" |
|
||||
resolved "https://registry.yarnpkg.com/with-callback/-/with-callback-1.0.2.tgz#a09629b9a920028d721404fb435bdcff5c91bc21" |
|
||||
integrity sha1-oJYpuakgAo1yFAT7Q1vc/1yRvCE= |
|
||||
|
|
||||
with@^7.0.0: |
with@^7.0.0: |
||||
version "7.0.2" |
version "7.0.2" |
||||
resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" |
resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" |
||||
@ -8870,11 +8625,6 @@ xmlhttprequest-ssl@~1.6.2: |
|||||
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz#03b713873b01659dfa2c1c5d056065b27ddc2de6" |
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz#03b713873b01659dfa2c1c5d056065b27ddc2de6" |
||||
integrity sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q== |
integrity sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q== |
||||
|
|
||||
[email protected]: |
|
||||
version "2.0.0" |
|
||||
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" |
|
||||
integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM= |
|
||||
|
|
||||
xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: |
xtend@^4.0.0, 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" |
||||
@ -8895,11 +8645,6 @@ y18n@^5.0.5: |
|||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" |
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" |
||||
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== |
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== |
||||
|
|
||||
yallist@^3.0.2: |
|
||||
version "3.1.1" |
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" |
|
||||
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== |
|
||||
|
|
||||
yallist@^4.0.0: |
yallist@^4.0.0: |
||||
version "4.0.0" |
version "4.0.0" |
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" |
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" |
||||
|
Loading…
Reference in new issue