mirror of
https://github.com/misenhower/splatoon3.ink.git
synced 2026-04-26 15:57:06 -05:00
Replace deprecated and unmaintained packages
- Removed mkdirp in favor of native fs.mkdir({ recursive: true })
- Replaced ecstatic (unmaintained since 2021) with sirv
- Replaced jsonpath (security vulnerability) with jsonpath-plus
- Added jsonpathQuery/jsonpathApply helpers in app/common/util.mjs
- Updated sharp: 0.32.6 → 0.34.5
- Updated puppeteer-core: 23.8.0 → 24.37.3
Vulnerabilities reduced from 40 to 1 (only remaining: axios in
threads-api transitive dependency).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e6004154b9
commit
8780463c66
|
|
@ -1,6 +1,5 @@
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import mkdirp from 'mkdirp';
|
|
||||||
export default class ValueCache
|
export default class ValueCache
|
||||||
{
|
{
|
||||||
constructor(key) {
|
constructor(key) {
|
||||||
|
|
@ -48,7 +47,7 @@ export default class ValueCache
|
||||||
let cachedAt = new Date;
|
let cachedAt = new Date;
|
||||||
let serialized = JSON.stringify({ expires, data, cachedAt }, undefined, 2);
|
let serialized = JSON.stringify({ expires, data, cachedAt }, undefined, 2);
|
||||||
|
|
||||||
await mkdirp(path.dirname(this.path));
|
await fs.mkdir(path.dirname(this.path), { recursive: true });
|
||||||
await fs.writeFile(this.path, serialized);
|
await fs.writeFile(this.path, serialized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
import { JSONPath } from 'jsonpath-plus';
|
||||||
|
|
||||||
export function getTopOfCurrentHour(date = null) {
|
export function getTopOfCurrentHour(date = null) {
|
||||||
date ??= new Date;
|
date ??= new Date;
|
||||||
|
|
@ -88,6 +89,16 @@ export function getXRankSeasonId(id) {
|
||||||
* @param {number} expiresIn - Seconds until expiry
|
* @param {number} expiresIn - Seconds until expiry
|
||||||
* @returns {number} Timestamp to expire the cache (5 minutes early)
|
* @returns {number} Timestamp to expire the cache (5 minutes early)
|
||||||
*/
|
*/
|
||||||
|
export function jsonpathQuery(data, path) {
|
||||||
|
return JSONPath({ path, json: data });
|
||||||
|
}
|
||||||
|
|
||||||
|
export function jsonpathApply(data, path, fn) {
|
||||||
|
JSONPath({ path, json: data, resultType: 'all', callback: (result) => {
|
||||||
|
result.parent[result.parentProperty] = fn(result.value);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
export function calculateCacheExpiry(expiresIn) {
|
export function calculateCacheExpiry(expiresIn) {
|
||||||
let expires = Date.now() + expiresIn * 1000;
|
let expires = Date.now() + expiresIn * 1000;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import mkdirp from 'mkdirp';
|
|
||||||
import PQueue from 'p-queue';
|
import PQueue from 'p-queue';
|
||||||
import prefixedConsole from '../common/prefixedConsole.mjs';
|
import prefixedConsole from '../common/prefixedConsole.mjs';
|
||||||
import { normalizeSplatnetResourcePath } from '../common/util.mjs';
|
import { normalizeSplatnetResourcePath } from '../common/util.mjs';
|
||||||
|
|
@ -70,7 +69,7 @@ export default class ImageProcessor
|
||||||
throw new Error(`Invalid image response code: ${result.status}`);
|
throw new Error(`Invalid image response code: ${result.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await mkdirp(path.dirname(this.localPath(destination)));
|
await fs.mkdir(path.dirname(this.localPath(destination)), { recursive: true });
|
||||||
await fs.writeFile(this.localPath(destination), result.body);
|
await fs.writeFile(this.localPath(destination), result.body);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.console.error(`Image download failed for ${destination}`, e);
|
this.console.error(`Image download failed for ${destination}`, e);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import mkdirp from 'mkdirp';
|
import { jsonpathQuery } from '../common/util.mjs';
|
||||||
import jsonpath from 'jsonpath';
|
|
||||||
import get from 'lodash/get.js';
|
import get from 'lodash/get.js';
|
||||||
import set from 'lodash/set.js';
|
import set from 'lodash/set.js';
|
||||||
import pLimit from 'p-limit';
|
import pLimit from 'p-limit';
|
||||||
|
|
@ -41,7 +40,7 @@ export class LocalizationProcessor {
|
||||||
|
|
||||||
*dataIterations(data) {
|
*dataIterations(data) {
|
||||||
for (let ruleset of this.rulesetIterations()) {
|
for (let ruleset of this.rulesetIterations()) {
|
||||||
for (let node of jsonpath.query(data, ruleset.node)) {
|
for (let node of jsonpathQuery(data, ruleset.node)) {
|
||||||
if (!node) continue;
|
if (!node) continue;
|
||||||
|
|
||||||
let id = get(node, ruleset.id);
|
let id = get(node, ruleset.id);
|
||||||
|
|
@ -92,7 +91,7 @@ export class LocalizationProcessor {
|
||||||
|
|
||||||
data = JSON.stringify(data, undefined, space);
|
data = JSON.stringify(data, undefined, space);
|
||||||
|
|
||||||
await mkdirp(path.dirname(this.filename));
|
await fs.mkdir(path.dirname(this.filename), { recursive: true });
|
||||||
await fs.writeFile(this.filename, data);
|
await fs.writeFile(this.filename, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { Console } from 'node:console';
|
import { Console } from 'node:console';
|
||||||
import mkdirp from 'mkdirp';
|
|
||||||
import jsonpath from 'jsonpath';
|
|
||||||
import ical from 'ical-generator';
|
import ical from 'ical-generator';
|
||||||
import pFilter from 'p-filter';
|
import pFilter from 'p-filter';
|
||||||
import prefixedConsole from '../../common/prefixedConsole.mjs';
|
import prefixedConsole from '../../common/prefixedConsole.mjs';
|
||||||
|
|
@ -11,7 +9,7 @@ import ImageProcessor from '../ImageProcessor.mjs';
|
||||||
import NsoClient from '../../splatnet/NsoClient.mjs';
|
import NsoClient from '../../splatnet/NsoClient.mjs';
|
||||||
import { locales, regionalLocales, defaultLocale } from '../../../src/common/i18n.mjs';
|
import { locales, regionalLocales, defaultLocale } from '../../../src/common/i18n.mjs';
|
||||||
import { LocalizationProcessor } from '../LocalizationProcessor.mjs';
|
import { LocalizationProcessor } from '../LocalizationProcessor.mjs';
|
||||||
import { deriveId, getDateParts, getTopOfCurrentHour } from '../../common/util.mjs';
|
import { deriveId, getDateParts, getTopOfCurrentHour, jsonpathQuery, jsonpathApply } from '../../common/util.mjs';
|
||||||
export default class DataUpdater
|
export default class DataUpdater
|
||||||
{
|
{
|
||||||
name = null;
|
name = null;
|
||||||
|
|
@ -120,7 +118,7 @@ export default class DataUpdater
|
||||||
|
|
||||||
deriveIds(data) {
|
deriveIds(data) {
|
||||||
for (let expression of this.derivedIds) {
|
for (let expression of this.derivedIds) {
|
||||||
jsonpath.apply(data, expression, deriveId);
|
jsonpathApply(data, expression, deriveId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,14 +155,14 @@ export default class DataUpdater
|
||||||
// This JSONPath library is completely synchronous, so we have to
|
// This JSONPath library is completely synchronous, so we have to
|
||||||
// build a mapping here after transforming all URLs.
|
// build a mapping here after transforming all URLs.
|
||||||
let mapping = {};
|
let mapping = {};
|
||||||
for (let url of jsonpath.query(data, expression)) {
|
for (let url of jsonpathQuery(data, expression)) {
|
||||||
let [path, publicUrl] = await this.imageProcessor.process(url);
|
let [path, publicUrl] = await this.imageProcessor.process(url);
|
||||||
mapping[url] = publicUrl;
|
mapping[url] = publicUrl;
|
||||||
images[publicUrl] = path;
|
images[publicUrl] = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now apply the URL transformations
|
// Now apply the URL transformations
|
||||||
jsonpath.apply(data, expression, url => mapping[url]);
|
jsonpathApply(data, expression, url => mapping[url]);
|
||||||
}
|
}
|
||||||
|
|
||||||
await ImageProcessor.onIdle();
|
await ImageProcessor.onIdle();
|
||||||
|
|
@ -217,7 +215,7 @@ export default class DataUpdater
|
||||||
}
|
}
|
||||||
|
|
||||||
async writeFile(file, data) {
|
async writeFile(file, data) {
|
||||||
await mkdirp(path.dirname(file));
|
await fs.mkdir(path.dirname(file), { recursive: true });
|
||||||
await fs.writeFile(file, data);
|
await fs.writeFile(file, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import jsonpath from 'jsonpath';
|
|
||||||
import pLimit from 'p-limit';
|
import pLimit from 'p-limit';
|
||||||
import { getFestId } from '../../common/util.mjs';
|
import { getFestId, jsonpathQuery, jsonpathApply } from '../../common/util.mjs';
|
||||||
import ValueCache from '../../common/ValueCache.mjs';
|
import ValueCache from '../../common/ValueCache.mjs';
|
||||||
import { regionTokens } from '../../splatnet/NsoClient.mjs';
|
import { regionTokens } from '../../splatnet/NsoClient.mjs';
|
||||||
import FestivalRankingUpdater from './FestivalRankingUpdater.mjs';
|
import FestivalRankingUpdater from './FestivalRankingUpdater.mjs';
|
||||||
|
|
@ -70,7 +69,7 @@ export default class FestivalUpdater extends DataUpdater
|
||||||
let data = await this.splatnet(locale).getFestRecordDataPage(cursor);
|
let data = await this.splatnet(locale).getFestRecordDataPage(cursor);
|
||||||
|
|
||||||
// Grab the nodes from the current page
|
// Grab the nodes from the current page
|
||||||
result.data.festRecords.nodes.push(...jsonpath.query(data, '$..festRecords.edges.*.node'));
|
result.data.festRecords.nodes.push(...jsonpathQuery(data, '$..festRecords.edges.*.node'));
|
||||||
|
|
||||||
// Update the cursor and next page indicator
|
// Update the cursor and next page indicator
|
||||||
cursor = data.data.festRecords.pageInfo.endCursor;
|
cursor = data.data.festRecords.pageInfo.endCursor;
|
||||||
|
|
@ -103,7 +102,7 @@ export default class FestivalUpdater extends DataUpdater
|
||||||
}
|
}
|
||||||
|
|
||||||
deriveFestivalIds(data) {
|
deriveFestivalIds(data) {
|
||||||
jsonpath.apply(data, '$..nodes.*', node => ({
|
jsonpathApply(data, '$..nodes.*', node => ({
|
||||||
'__splatoon3ink_id': getFestId(node.id),
|
'__splatoon3ink_id': getFestId(node.id),
|
||||||
...node,
|
...node,
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import ecstatic from 'ecstatic';
|
import sirv from 'sirv';
|
||||||
|
|
||||||
export default class HttpServer
|
export default class HttpServer
|
||||||
{
|
{
|
||||||
|
|
@ -16,7 +16,7 @@ export default class HttpServer
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = ecstatic({ root: './dist' });
|
const handler = sirv('./dist');
|
||||||
this.#server = http.createServer(handler);
|
this.#server = http.createServer(handler);
|
||||||
this.#server.on('listening', () => resolve());
|
this.#server.on('listening', () => resolve());
|
||||||
this.#server.listen();
|
this.#server.listen();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import mkdirp from 'mkdirp';
|
|
||||||
import Client from './Client.mjs';
|
import Client from './Client.mjs';
|
||||||
|
|
||||||
export default class FileWriter extends Client {
|
export default class FileWriter extends Client {
|
||||||
|
|
@ -9,7 +8,7 @@ export default class FileWriter extends Client {
|
||||||
dir = 'temp';
|
dir = 'temp';
|
||||||
|
|
||||||
async send(status, generator) {
|
async send(status, generator) {
|
||||||
await mkdirp(this.dir);
|
await fs.mkdir(this.dir, { recursive: true });
|
||||||
|
|
||||||
if (status.media?.length > 0) {
|
if (status.media?.length > 0) {
|
||||||
let imgFilename = `${this.dir}/${generator.key}.png`;
|
let imgFilename = `${this.dir}/${generator.key}.png`;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import mkdirp from 'mkdirp';
|
|
||||||
import Client from './Client.mjs';
|
import Client from './Client.mjs';
|
||||||
|
|
||||||
export default class ImageWriter extends Client {
|
export default class ImageWriter extends Client {
|
||||||
|
|
@ -13,7 +12,7 @@ export default class ImageWriter extends Client {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await mkdirp(this.dir);
|
await fs.mkdir(this.dir, { recursive: true });
|
||||||
|
|
||||||
let imgFilename = `${this.dir}/${generator.key}.png`;
|
let imgFilename = `${this.dir}/${generator.key}.png`;
|
||||||
await fs.writeFile(imgFilename, status.media[0].file);
|
await fs.writeFile(imgFilename, status.media[0].file);
|
||||||
|
|
|
||||||
1164
package-lock.json
generated
1164
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
|
@ -34,20 +34,19 @@
|
||||||
"console-stamp": "^3.0.6",
|
"console-stamp": "^3.0.6",
|
||||||
"cron": "^2.1.0",
|
"cron": "^2.1.0",
|
||||||
"dotenv": "^16.0.2",
|
"dotenv": "^16.0.2",
|
||||||
"ecstatic": "^4.1.4",
|
|
||||||
"ical-generator": "^3.6.0",
|
"ical-generator": "^3.6.0",
|
||||||
"jsonpath": "^1.1.1",
|
"jsonpath-plus": "^10.3.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"masto": "^7.10.1",
|
"masto": "^7.10.1",
|
||||||
"mkdirp": "^1.0.4",
|
|
||||||
"nxapi": "^1.6.1-next.170",
|
"nxapi": "^1.6.1-next.170",
|
||||||
"p-filter": "^4.1.0",
|
"p-filter": "^4.1.0",
|
||||||
"p-limit": "^6.1.0",
|
"p-limit": "^6.1.0",
|
||||||
"p-queue": "^8.0.1",
|
"p-queue": "^8.0.1",
|
||||||
"pinia": "^2.3.1",
|
"pinia": "^2.3.1",
|
||||||
"puppeteer-core": "^23.8.0",
|
"puppeteer-core": "^24.37.3",
|
||||||
"s3-sync-client": "^4.3.1",
|
"s3-sync-client": "^4.3.1",
|
||||||
"sharp": "^0.32.0",
|
"sharp": "^0.34.5",
|
||||||
|
"sirv": "^3.0.2",
|
||||||
"threads-api": "^1.4.0",
|
"threads-api": "^1.4.0",
|
||||||
"twitter-api-v2": "^1.29.0",
|
"twitter-api-v2": "^1.29.0",
|
||||||
"vue": "^3.5.28",
|
"vue": "^3.5.28",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user