Add Splatfest calendar feeds

This commit is contained in:
Samuel Elliott 2022-11-07 18:43:13 +00:00
parent 0e4812079f
commit 110314ee17
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
6 changed files with 253 additions and 63 deletions

View File

@ -22,7 +22,7 @@ export default class ImageProcessor
await this.maybeDownload(url, destination);
// Return the new public URL
return this.publicUrl(destination);
return [destination, this.publicUrl(destination)];
}
normalize(url) {

View File

@ -2,6 +2,7 @@ import fs from 'fs/promises';
import path from 'path';
import mkdirp from 'mkdirp';
import jsonpath from 'jsonpath';
import ical from 'ical-generator';
import prefixedConsole from "../../common/prefixedConsole.mjs";
import SplatNet3Client from "../../splatnet/SplatNet3Client.mjs";
import ImageProcessor from '../ImageProcessor.mjs';
@ -14,6 +15,8 @@ export default class DataUpdater
{
name = null;
filename = null;
calendarName = null;
calendarFilename = null;
outputDirectory = 'dist/data';
archiveOutputDirectory = 'storage/archive';
@ -64,11 +67,14 @@ export default class DataUpdater
await this.updateLocalizations(this.defaultLocale, data);
// Download any new images
await this.downloadImages(data);
const images = await this.downloadImages(data);
// Write the data to disk
await this.saveData(data);
// Update iCal data
await this.updateCalendarEvents(data, images);
this.console.info('Done');
}
@ -116,18 +122,24 @@ export default class DataUpdater
}
async downloadImages(data) {
// Return a map of image URLs to their local path
const images = {};
for (let expression of this.imagePaths) {
// This JSONPath library is completely synchronous, so we have to
// build a mapping here after transforming all URLs.
let mapping = {};
for (let url of jsonpath.query(data, expression)) {
let publicUrl = await this.imageProcessor.process(url);
let [path, publicUrl] = await this.imageProcessor.process(url);
mapping[url] = publicUrl;
images[publicUrl] = path;
}
// Now apply the URL transformations
jsonpath.apply(data, expression, url => mapping[url]);
}
return images;
}
// File handling
@ -162,4 +174,75 @@ export default class DataUpdater
await mkdirp(path.dirname(file))
await fs.writeFile(file, data);
}
// Calendar output
async updateCalendarEvents(data, images) {
const events = this.getCalendarEntries(data);
if (!events) return;
const ical = await this.getiCalData(events, images);
this.writeFile(this.getCalendarPath(this.calendarFilename ?? this.filename), ical);
}
getCalendarPath(filename) {
return `${this.outputDirectory}/${filename}.ics`;
}
getCalendarEntries(data) {
//
}
async getiCalData(events, images) {
// Create a calendar object
const calendar = new ical({
name: this.calendarName ?? this.name,
url: 'https://splatoon3.ink',
prodId: {
company: 'splatoon3.ink',
product: 'splatoon3.ink',
language: 'EN',
},
timezone: 'UTC',
});
// Create a map of image URLs to image data
const imageData = {};
// Add event entries
for (let event of events) {
calendar.createEvent(({
id: event.id,
summary: event.title,
start: event.start,
end: event.end,
url: event.url,
attachments: [event.imageUrl],
}));
const filename = images[event.imageUrl];
if (filename) {
const data = await fs.readFile(this.imageProcessor.localPath(filename));
imageData[event.imageUrl] = data;
}
}
// Convert the calendar to an ICS string
let ics = calendar.toString();
// Embed image attachments
ics = ics.replaceAll(/^ATTACH:((.|\r\n )*)$/gm, (match, url) => {
url = url.replaceAll('\r\n ', '');
const filename = images[url];
const data = imageData[url];
if (!filename || !data) return match;
const ical = `ATTACH;ENCODING=BASE64;VALUE=BINARY;X-APPLE-FILENAME=${path.basename(filename)}:${data.toString('base64')}`;
return ical.replace(/(.{72})/g, '$1\r\n ').trim();
});
return ics;
}
}

View File

@ -1,10 +1,25 @@
import fs from 'fs/promises';
import DataUpdater from "./DataUpdater.mjs";
function generateFestUrl(id) {
return process.env.DEBUG ?
`https://s.nintendo.com/av5ja-lp1/znca/game/4834290508791808?p=/fest_record/${id}` :
`${process.env.SITE_URL ?? ''}/nso/f/${id}`;
}
export default class FestivalUpdater extends DataUpdater
{
name = 'Festivals';
filename = 'festivals';
calendarName = 'Splatoon 3 Splatfests';
calendarFilename = 'festivals';
constructor(region = null) {
super(region);
this.calendarName += ` (${region})`;
this.calendarFilename += `.${region}`;
}
imagePaths = [
'$..image.url',
@ -39,4 +54,17 @@ export default class FestivalUpdater extends DataUpdater
return super.formatDataForWrite(result);
}
*getCalendarEntries(data) {
for (const fest of data.data.festRecords.nodes) {
yield {
id: getFestId(fest.id),
title: `Splatfest (${this.region}): ${fest.teams.map(t => t.teamName).join(' vs. ')}`,
url: generateFestUrl(fest.id),
imageUrl: fest.image.url,
start: fest.startTime,
end: fest.endTime,
};
}
}
}

View File

@ -12,4 +12,9 @@ server {
location ~ /nso/g/(.*) {
return 302 https://s.nintendo.com/av5ja-lp1/znca/game/4834290508791808?p=/gesotown/$1;
}
# Festival redirect
location ~ /nso/f/(.*) {
return 302 https://s.nintendo.com/av5ja-lp1/znca/game/4834290508791808?p=/fest_record/$1;
}
}

193
package-lock.json generated
View File

@ -15,6 +15,7 @@
"cron": "^2.1.0",
"dotenv": "^16.0.2",
"ecstatic": "^4.1.4",
"ical-generator": "^3.6.0",
"jsonpath": "^1.1.1",
"lodash": "^4.17.21",
"mkdirp": "^1.0.4",
@ -695,9 +696,9 @@
}
},
"node_modules/body-parser": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
"integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.4",
@ -707,7 +708,7 @@
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.10.3",
"qs": "6.11.0",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
@ -948,13 +949,16 @@
}
},
"node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/color-convert": {
@ -2059,13 +2063,13 @@
}
},
"node_modules/express": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
"integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.0",
"body-parser": "1.20.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.5.0",
@ -2084,7 +2088,7 @@
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.7",
"qs": "6.10.3",
"qs": "6.11.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.18.0",
@ -2595,6 +2599,57 @@
"node": ">= 6"
}
},
"node_modules/ical-generator": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/ical-generator/-/ical-generator-3.6.0.tgz",
"integrity": "sha512-QDVRLdiVHNzQYjsi6fSJVVSIUqQcHfgmHr/xBuTE+/YNyO6Duj64TCbtV8Gy/wwWEYhp9dB95hRSNOgtwxtBWg==",
"dependencies": {
"uuid-random": "^1.3.2"
},
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"@touch4it/ical-timezones": ">=1.6.0",
"@types/luxon": ">= 1.26.0",
"@types/mocha": ">= 8.2.1",
"@types/node": ">= 15.0.0",
"dayjs": ">= 1.10.0",
"luxon": ">= 1.26.0",
"moment": ">= 2.29.0",
"moment-timezone": ">= 0.5.33",
"rrule": ">= 2.6.8"
},
"peerDependenciesMeta": {
"@touch4it/ical-timezones": {
"optional": true
},
"@types/luxon": {
"optional": true
},
"@types/mocha": {
"optional": true
},
"@types/node": {
"optional": true
},
"dayjs": {
"optional": true
},
"luxon": {
"optional": true
},
"moment": {
"optional": true
},
"moment-timezone": {
"optional": true
},
"rrule": {
"optional": true
}
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -3086,9 +3141,9 @@
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"node_modules/nan": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
"integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==",
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
"optional": true
},
"node_modules/nanoid": {
@ -3123,9 +3178,9 @@
}
},
"node_modules/node-abi": {
"version": "3.24.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.24.0.tgz",
"integrity": "sha512-YPG3Co0luSu6GwOBsmIdGW6Wx0NyNDLg/hriIyDllVsNwnI6UeqaWShxC3lbH4LtEQUgoLP3XR1ndXiDAWvmRw==",
"version": "3.28.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.28.0.tgz",
"integrity": "sha512-fRlDb4I0eLcQeUvGq7IY3xHrSb0c9ummdvDSYWfT9+LKP+3jCKw/tKoqaM7r1BAoiAC6GtwyjaGnOz6B3OtF+A==",
"optional": true,
"dependencies": {
"semver": "^7.3.5"
@ -3752,9 +3807,9 @@
}
},
"node_modules/qs": {
"version": "6.10.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
"integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"dependencies": {
"side-channel": "^1.0.4"
},
@ -4412,9 +4467,9 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
"integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
@ -4552,6 +4607,11 @@
"uuid": "dist/bin/uuid"
}
},
"node_modules/uuid-random": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/uuid-random/-/uuid-random-1.3.2.tgz",
"integrity": "sha512-UOzej0Le/UgkbWEO8flm+0y+G+ljUon1QWTEZOq1rnMAsxo2+SckbiZdKzAHHlVh6gJqI1TjC/xwgR50MuCrBQ=="
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@ -4811,17 +4871,17 @@
}
},
"node_modules/yargs": {
"version": "17.5.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
"integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
"version": "17.6.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
"integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
"dependencies": {
"cliui": "^7.0.2",
"cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.0.0"
"yargs-parser": "^21.1.1"
},
"engines": {
"node": ">=12"
@ -5324,9 +5384,9 @@
}
},
"body-parser": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
"integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"requires": {
"bytes": "3.1.2",
"content-type": "~1.0.4",
@ -5336,7 +5396,7 @@
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.10.3",
"qs": "6.11.0",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
@ -5493,12 +5553,12 @@
}
},
"cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
}
},
@ -6200,13 +6260,13 @@
"optional": true
},
"express": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
"integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
"requires": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.0",
"body-parser": "1.20.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.5.0",
@ -6225,7 +6285,7 @@
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.7",
"qs": "6.10.3",
"qs": "6.11.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.18.0",
@ -6612,6 +6672,14 @@
"debug": "4"
}
},
"ical-generator": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/ical-generator/-/ical-generator-3.6.0.tgz",
"integrity": "sha512-QDVRLdiVHNzQYjsi6fSJVVSIUqQcHfgmHr/xBuTE+/YNyO6Duj64TCbtV8Gy/wwWEYhp9dB95hRSNOgtwxtBWg==",
"requires": {
"uuid-random": "^1.3.2"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -6959,9 +7027,9 @@
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"nan": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
"integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==",
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
"optional": true
},
"nanoid": {
@ -6987,9 +7055,9 @@
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
},
"node-abi": {
"version": "3.24.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.24.0.tgz",
"integrity": "sha512-YPG3Co0luSu6GwOBsmIdGW6Wx0NyNDLg/hriIyDllVsNwnI6UeqaWShxC3lbH4LtEQUgoLP3XR1ndXiDAWvmRw==",
"version": "3.28.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.28.0.tgz",
"integrity": "sha512-fRlDb4I0eLcQeUvGq7IY3xHrSb0c9ummdvDSYWfT9+LKP+3jCKw/tKoqaM7r1BAoiAC6GtwyjaGnOz6B3OtF+A==",
"optional": true,
"requires": {
"semver": "^7.3.5"
@ -7393,9 +7461,9 @@
}
},
"qs": {
"version": "6.10.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
"integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"requires": {
"side-channel": "^1.0.4"
}
@ -7841,9 +7909,9 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
"integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
},
"tunnel-agent": {
"version": "0.6.0",
@ -7941,6 +8009,11 @@
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"uuid-random": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/uuid-random/-/uuid-random-1.3.2.tgz",
"integrity": "sha512-UOzej0Le/UgkbWEO8flm+0y+G+ljUon1QWTEZOq1rnMAsxo2+SckbiZdKzAHHlVh6gJqI1TjC/xwgR50MuCrBQ=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@ -8103,17 +8176,17 @@
}
},
"yargs": {
"version": "17.5.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
"integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
"version": "17.6.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
"integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
"requires": {
"cliui": "^7.0.2",
"cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.0.0"
"yargs-parser": "^21.1.1"
}
},
"yargs-parser": {

View File

@ -20,6 +20,7 @@
"cron": "^2.1.0",
"dotenv": "^16.0.2",
"ecstatic": "^4.1.4",
"ical-generator": "^3.6.0",
"jsonpath": "^1.1.1",
"lodash": "^4.17.21",
"mkdirp": "^1.0.4",