Resolve npm audit vulnerabilities

This commit is contained in:
Matt Isenhower
2026-08-30 16:40:14 -07:00
parent ac6e374e97
commit 5dd2bbf172
8 changed files with 156 additions and 41 deletions

26
app/common/jsonpath.mjs Normal file
View File

@@ -0,0 +1,26 @@
import { JSONPath } from 'jsonpath-plus';
function query(data, expression) {
return JSONPath({
json: data,
path: expression,
eval: false,
});
}
function apply(data, expression, transform) {
const matches = JSONPath({
json: data,
path: expression,
resultType: 'all',
eval: false,
});
for (const { parent, parentProperty, value } of matches) {
parent[parentProperty] = transform(value);
}
return data;
}
export default { apply, query };

View File

@@ -1,7 +1,7 @@
import fs from 'fs/promises';
import path from 'path';
import { mkdirp } from '../common/fs.mjs';
import jsonpath from 'jsonpath';
import jsonpath from '../common/jsonpath.mjs';
import get from 'lodash/get.js';
import set from 'lodash/set.js';
import pLimit from 'p-limit';

View File

@@ -83,6 +83,24 @@ describe('LocalizationProcessor', () => {
});
describe('dataIterations', () => {
it('finds matching nodes at any depth', () => {
const processor = makeProcessor([
{ key: 'stages', nodes: '$..stages.*', id: 'id', values: 'name' },
]);
const data = {
schedules: [
{ stages: [{ id: 'stage-1', name: 'Scorch Gorge' }] },
{ nested: { stages: [{ id: 'stage-2', name: 'Eeltail Alley' }] } },
],
};
expect([...processor.dataIterations(data)].map(({ id, value }) => ({ id, value }))).toEqual([
{ id: 'stage-1', value: 'Scorch Gorge' },
{ id: 'stage-2', value: 'Eeltail Alley' },
]);
});
it('yields entries with correct id, value, and path', () => {
const processor = makeProcessor([
{ key: 'stages', nodes: '$.stages[*]', id: 'id', values: 'name' },

View File

@@ -10,7 +10,7 @@ import ImageProcessor from '../ImageProcessor.mjs';
import NsoClient from '../../splatnet/NsoClient.mjs';
import { locales, regionalLocales, defaultLocale } from '../../../src/common/i18n.mjs';
import { LocalizationProcessor } from '../LocalizationProcessor.mjs';
import jsonpath from 'jsonpath';
import jsonpath from '../../common/jsonpath.mjs';
import { deriveId, getDateParts, getTopOfCurrentHour } from '../../common/util.mjs';
export default class DataUpdater
{

View File

@@ -0,0 +1,42 @@
import { describe, expect, it } from 'vitest';
import DataUpdater from './DataUpdater.mjs';
describe('DataUpdater', () => {
describe('deriveIds', () => {
it('replaces every recursively matched node while preserving its data', () => {
const updater = Object.create(DataUpdater.prototype);
updater.derivedIds = ['$..weapons.*'];
const splattershot = {
name: 'Splattershot',
image: { url: 'https://example.com/assets/weapon-a.png' },
};
const splatRoller = {
name: 'Splat Roller',
image: { url: 'https://example.com/assets/weapon-b.png' },
};
const scheduleWeapons = [splattershot];
const nestedWeapons = [splatRoller];
const data = {
schedules: [
{
weapons: scheduleWeapons,
},
{
nested: {
weapons: nestedWeapons,
},
},
],
};
updater.deriveIds(data);
const weapons = [...scheduleWeapons, ...nestedWeapons];
expect(weapons.map(({ name }) => name)).toEqual(['Splattershot', 'Splat Roller']);
expect(weapons.map(({ __splatoon3ink_id: id }) => id)).toEqual([
'1bfe00916f1f6b9a',
'027798dcfb87596b',
]);
});
});
});

View File

@@ -1,6 +1,6 @@
import fs from 'fs/promises';
import pLimit from 'p-limit';
import jsonpath from 'jsonpath';
import jsonpath from '../../common/jsonpath.mjs';
import { getFestId } from '../../common/util.mjs';
import ValueCache from '../../common/ValueCache.mjs';
import { regionTokens } from '../../splatnet/NsoClient.mjs';

95
package-lock.json generated
View File

@@ -17,7 +17,7 @@
"cron": "^4.4.0",
"dotenv": "^17.3.1",
"ical-generator": "^11.1.1",
"jsonpath": "^1.2.1",
"jsonpath-plus": "^10.4.0",
"lodash": "^4.17.21",
"masto": "^8.0.0",
"nxapi": "^1.6.1-next.248",
@@ -3136,6 +3136,30 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@jsep-plugin/assignment": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz",
"integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==",
"license": "MIT",
"engines": {
"node": ">= 10.16.0"
},
"peerDependencies": {
"jsep": "^0.4.0||^1.0.0"
}
},
"node_modules/@jsep-plugin/regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz",
"integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==",
"license": "MIT",
"engines": {
"node": ">= 10.16.0"
},
"peerDependencies": {
"jsep": "^0.4.0||^1.0.0"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -5800,6 +5824,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
"integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"esprima": "^4.0.1",
@@ -6043,6 +6068,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
@@ -6082,6 +6108,7 @@
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -6097,6 +6124,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
@@ -6994,6 +7022,15 @@
"node": ">=20.0.0"
}
},
"node_modules/jsep": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz",
"integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==",
"license": "MIT",
"engines": {
"node": ">= 10.16.0"
}
},
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -7091,27 +7128,22 @@
"node": ">=10"
}
},
"node_modules/jsonpath": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.3.0.tgz",
"integrity": "sha512-0kjkYHJBkAy50Z5QzArZ7udmvxrJzkpKYW27fiF//BrMY7TQibYLl+FYIXN2BiYmwMIVzSfD8aDRj6IzgBX2/w==",
"node_modules/jsonpath-plus": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.4.0.tgz",
"integrity": "sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA==",
"license": "MIT",
"dependencies": {
"esprima": "1.2.5",
"static-eval": "2.1.1",
"underscore": "1.13.6"
}
},
"node_modules/jsonpath/node_modules/esprima": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.5.tgz",
"integrity": "sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==",
"@jsep-plugin/assignment": "^1.3.0",
"@jsep-plugin/regex": "^1.0.4",
"jsep": "^1.4.0"
},
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
"jsonpath": "bin/jsonpath-cli.js",
"jsonpath-plus": "bin/jsonpath-cli.js"
},
"engines": {
"node": ">=0.4.0"
"node": ">=18.0.0"
}
},
"node_modules/keyv": {
@@ -8995,6 +9027,7 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"optional": true,
"engines": {
@@ -9047,15 +9080,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/static-eval": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.1.tgz",
"integrity": "sha512-MgWpQ/ZjGieSVB3eOJVs4OA2LT/q1vx98KPCTTQPzq/aLr0YUXTsgryTXr4SLfR0ZfUUCiedM9n/ABeDIyy4mA==",
"license": "MIT",
"dependencies": {
"escodegen": "^2.1.0"
}
},
"node_modules/statuses": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
@@ -9406,12 +9430,6 @@
"integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==",
"license": "MIT"
},
"node_modules/underscore": {
"version": "1.13.6",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
@@ -9526,13 +9544,16 @@
}
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz",
"integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/vary": {

View File

@@ -44,7 +44,7 @@
"cron": "^4.4.0",
"dotenv": "^17.3.1",
"ical-generator": "^11.1.1",
"jsonpath": "^1.2.1",
"jsonpath-plus": "^10.4.0",
"lodash": "^4.17.21",
"masto": "^8.0.0",
"nxapi": "^1.6.1-next.248",
@@ -77,5 +77,13 @@
"vite": "^8.2.2",
"vitest": "^4.1.11",
"vue-eslint-parser": "^10.4.0"
},
"overrides": {
"nxapi": {
"uuid": "^11.1.1",
"node-notifier": {
"uuid": "^11.1.1"
}
}
}
}