mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
test(test): migrate from Mocha to Vitest (#62085)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@@ -199,6 +199,7 @@ curriculum/curricula.json
|
|||||||
### Additional Folders ###
|
### Additional Folders ###
|
||||||
curriculum/dist
|
curriculum/dist
|
||||||
curriculum/build
|
curriculum/build
|
||||||
|
curriculum/test/blocks-generated
|
||||||
|
|
||||||
### Playwright ###
|
### Playwright ###
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ const {
|
|||||||
getCurriculumStructure,
|
getCurriculumStructure,
|
||||||
getBlockStructure,
|
getBlockStructure,
|
||||||
getSuperblockStructure,
|
getSuperblockStructure,
|
||||||
getBlockStructurePath
|
getBlockStructurePath,
|
||||||
|
getBlockStructureDir
|
||||||
} = require('./file-handler');
|
} = require('./file-handler');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -294,14 +295,9 @@ function validateBlocks(superblocks, blockStructureDir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildCurriculum(lang, filters) {
|
async function parseCurriculumStructure(filters) {
|
||||||
const contentDir = getContentDir(lang);
|
|
||||||
const blockStructureDir = getLanguageConfig(lang).blockStructureDir;
|
|
||||||
const builder = new SuperblockCreator({
|
|
||||||
blockCreator: getBlockCreator(lang, !isEmpty(filters))
|
|
||||||
});
|
|
||||||
|
|
||||||
const curriculum = getCurriculumStructure();
|
const curriculum = getCurriculumStructure();
|
||||||
|
const blockStructureDir = getBlockStructureDir();
|
||||||
if (isEmpty(curriculum.superblocks))
|
if (isEmpty(curriculum.superblocks))
|
||||||
throw Error('No superblocks found in curriculum.json');
|
throw Error('No superblocks found in curriculum.json');
|
||||||
if (isEmpty(curriculum.certifications))
|
if (isEmpty(curriculum.certifications))
|
||||||
@@ -314,8 +310,22 @@ async function buildCurriculum(lang, filters) {
|
|||||||
const superblockList = addBlockStructure(
|
const superblockList = addBlockStructure(
|
||||||
addSuperblockStructure(curriculum.superblocks)
|
addSuperblockStructure(curriculum.superblocks)
|
||||||
);
|
);
|
||||||
|
return {
|
||||||
|
fullSuperblockList: applyFilters(superblockList, filters),
|
||||||
|
certifications: curriculum.certifications
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function buildCurriculum(lang, filters) {
|
||||||
|
const contentDir = getContentDir(lang);
|
||||||
|
|
||||||
|
const builder = new SuperblockCreator({
|
||||||
|
blockCreator: getBlockCreator(lang, !isEmpty(filters))
|
||||||
|
});
|
||||||
|
|
||||||
|
const { fullSuperblockList, certifications } =
|
||||||
|
await parseCurriculumStructure(filters);
|
||||||
|
|
||||||
const fullSuperblockList = applyFilters(superblockList, filters);
|
|
||||||
const fullCurriculum = { certifications: { blocks: {} } };
|
const fullCurriculum = { certifications: { blocks: {} } };
|
||||||
|
|
||||||
for (const superblock of fullSuperblockList) {
|
for (const superblock of fullSuperblockList) {
|
||||||
@@ -323,7 +333,7 @@ async function buildCurriculum(lang, filters) {
|
|||||||
await builder.processSuperblock(superblock);
|
await builder.processSuperblock(superblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const cert of curriculum.certifications) {
|
for (const cert of certifications) {
|
||||||
const certPath = path.resolve(contentDir, 'certifications', `${cert}.yml`);
|
const certPath = path.resolve(contentDir, 'certifications', `${cert}.yml`);
|
||||||
if (!fs.existsSync(certPath)) {
|
if (!fs.existsSync(certPath)) {
|
||||||
throw Error(`Certification file not found: ${certPath}`);
|
throw Error(`Certification file not found: ${certPath}`);
|
||||||
@@ -344,5 +354,7 @@ module.exports = {
|
|||||||
getSuperblockStructure,
|
getSuperblockStructure,
|
||||||
createCommentMap,
|
createCommentMap,
|
||||||
superBlockToFilename,
|
superBlockToFilename,
|
||||||
getSuperblocks
|
getSuperblocks,
|
||||||
|
addSuperblockStructure,
|
||||||
|
parseCurriculumStructure
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ function getBlockStructurePath(block) {
|
|||||||
return path.resolve(BLOCK_STRUCTURE_DIR, `${block}.json`);
|
return path.resolve(BLOCK_STRUCTURE_DIR, `${block}.json`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBlockStructureDir() {
|
||||||
|
return BLOCK_STRUCTURE_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
function getBlockStructure(block) {
|
function getBlockStructure(block) {
|
||||||
return JSON.parse(fs.readFileSync(getBlockStructurePath(block), 'utf8'));
|
return JSON.parse(fs.readFileSync(getBlockStructurePath(block), 'utf8'));
|
||||||
}
|
}
|
||||||
@@ -148,17 +152,15 @@ function getSuperblockStructurePath(superblockFilename) {
|
|||||||
*/
|
*/
|
||||||
function getLanguageConfig(
|
function getLanguageConfig(
|
||||||
lang,
|
lang,
|
||||||
{ baseDir, i18nBaseDir, structureDir } = {
|
{ baseDir, i18nBaseDir } = {
|
||||||
baseDir: CURRICULUM_DIR,
|
baseDir: CURRICULUM_DIR,
|
||||||
i18nBaseDir: I18N_CURRICULUM_DIR,
|
i18nBaseDir: I18N_CURRICULUM_DIR
|
||||||
structureDir: STRUCTURE_DIR
|
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
const contentDir = path.resolve(baseDir, 'challenges', 'english');
|
const contentDir = path.resolve(baseDir, 'challenges', 'english');
|
||||||
const i18nContentDir = path.resolve(i18nBaseDir, 'challenges', lang);
|
const i18nContentDir = path.resolve(i18nBaseDir, 'challenges', lang);
|
||||||
const blockContentDir = path.resolve(contentDir, 'blocks');
|
const blockContentDir = path.resolve(contentDir, 'blocks');
|
||||||
const i18nBlockContentDir = path.resolve(i18nContentDir, 'blocks');
|
const i18nBlockContentDir = path.resolve(i18nContentDir, 'blocks');
|
||||||
const blockStructureDir = path.resolve(structureDir, 'blocks');
|
|
||||||
const dictionariesDir = path.resolve(baseDir, 'dictionaries');
|
const dictionariesDir = path.resolve(baseDir, 'dictionaries');
|
||||||
const i18nDictionariesDir = path.resolve(i18nBaseDir, 'dictionaries');
|
const i18nDictionariesDir = path.resolve(i18nBaseDir, 'dictionaries');
|
||||||
|
|
||||||
@@ -179,7 +181,6 @@ function getLanguageConfig(
|
|||||||
|
|
||||||
debug(`Using content directory: ${contentDir}`);
|
debug(`Using content directory: ${contentDir}`);
|
||||||
debug(`Using i18n content directory: ${i18nContentDir}`);
|
debug(`Using i18n content directory: ${i18nContentDir}`);
|
||||||
debug(`Using block content directory: ${blockContentDir}`);
|
|
||||||
debug(`Using i18n block content directory: ${i18nBlockContentDir}`);
|
debug(`Using i18n block content directory: ${i18nBlockContentDir}`);
|
||||||
debug(`Using dictionaries directory: ${dictionariesDir}`);
|
debug(`Using dictionaries directory: ${dictionariesDir}`);
|
||||||
debug(`Using i18n dictionaries directory: ${i18nDictionariesDir}`);
|
debug(`Using i18n dictionaries directory: ${i18nDictionariesDir}`);
|
||||||
@@ -189,7 +190,6 @@ function getLanguageConfig(
|
|||||||
i18nContentDir,
|
i18nContentDir,
|
||||||
blockContentDir,
|
blockContentDir,
|
||||||
i18nBlockContentDir,
|
i18nBlockContentDir,
|
||||||
blockStructureDir,
|
|
||||||
dictionariesDir,
|
dictionariesDir,
|
||||||
i18nDictionariesDir
|
i18nDictionariesDir
|
||||||
};
|
};
|
||||||
@@ -197,6 +197,7 @@ function getLanguageConfig(
|
|||||||
|
|
||||||
exports.getContentConfig = getContentConfig;
|
exports.getContentConfig = getContentConfig;
|
||||||
exports.getContentDir = getContentDir;
|
exports.getContentDir = getContentDir;
|
||||||
|
exports.getBlockStructureDir = getBlockStructureDir;
|
||||||
exports.getBlockStructure = getBlockStructure;
|
exports.getBlockStructure = getBlockStructure;
|
||||||
exports.getBlockStructurePath = getBlockStructurePath;
|
exports.getBlockStructurePath = getBlockStructurePath;
|
||||||
exports.getSuperblockStructure = getSuperblockStructure;
|
exports.getSuperblockStructure = getSuperblockStructure;
|
||||||
|
|||||||
@@ -35,13 +35,14 @@
|
|||||||
"reorder-tasks": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/reorder-tasks",
|
"reorder-tasks": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/reorder-tasks",
|
||||||
"update-challenge-order": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/update-challenge-order",
|
"update-challenge-order": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/update-challenge-order",
|
||||||
"update-step-titles": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/update-step-titles",
|
"update-step-titles": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/update-step-titles",
|
||||||
"test": "NODE_OPTIONS='--max-old-space-size=7168' tsx ./node_modules/mocha/bin/mocha.js --delay --exit --reporter progress --bail",
|
"test-gen": "node ./test/utils/generate-block-tests.mjs",
|
||||||
"test:full-output": "NODE_OPTIONS='--max-old-space-size=7168' FULL_OUTPUT=true tsx ./node_modules/mocha/bin/mocha.js --delay --reporter progress"
|
"test": "NODE_OPTIONS='--max-old-space-size=7168' pnpm -s test-gen && vitest -c test/vitest.config.mjs",
|
||||||
|
"test:full-output": "NODE_OPTIONS='--max-old-space-size=7168' pnpm -s test-gen && FULL_OUTPUT=true vitest -c test/vitest.config.mjs --reporter=default"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.23.7",
|
"@babel/core": "7.23.7",
|
||||||
"@babel/register": "7.23.7",
|
"@babel/register": "7.23.7",
|
||||||
"@compodoc/live-server": "^1.2.3",
|
"@types/polka": "^0.5.7",
|
||||||
"@vitest/ui": "^3.2.4",
|
"@vitest/ui": "^3.2.4",
|
||||||
"chai": "4.4.1",
|
"chai": "4.4.1",
|
||||||
"glob": "8.1.0",
|
"glob": "8.1.0",
|
||||||
@@ -54,8 +55,10 @@
|
|||||||
"mocha": "10.3.0",
|
"mocha": "10.3.0",
|
||||||
"mock-require": "3.0.3",
|
"mock-require": "3.0.3",
|
||||||
"ora": "5.4.1",
|
"ora": "5.4.1",
|
||||||
|
"polka": "^0.5.2",
|
||||||
"puppeteer": "22.12.1",
|
"puppeteer": "22.12.1",
|
||||||
"readdirp": "3.6.0",
|
"readdirp": "3.6.0",
|
||||||
|
"sirv": "^3.0.2",
|
||||||
"string-similarity": "4.0.4",
|
"string-similarity": "4.0.4",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^3.2.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { assert, describe, it } from 'vitest';
|
||||||
|
import { testedLang } from '../utils';
|
||||||
|
import { getChallenges } from './test-challenges';
|
||||||
|
|
||||||
|
// Daily coding challenges are upcoming changes, so this test does nothing
|
||||||
|
// unless SHOW_UPCOMING_CHANGES is true.
|
||||||
|
describe('Daily Coding Challenges', async () => {
|
||||||
|
const lang = testedLang();
|
||||||
|
const challenges = await getChallenges(lang, {
|
||||||
|
superBlock: 'dev-playground'
|
||||||
|
});
|
||||||
|
|
||||||
|
const jsDailyChallenges = challenges.filter(
|
||||||
|
c => c.block === 'daily-coding-challenges-javascript'
|
||||||
|
);
|
||||||
|
|
||||||
|
const pyDailyChallenges = challenges.filter(
|
||||||
|
c => c.block === 'daily-coding-challenges-python'
|
||||||
|
);
|
||||||
|
|
||||||
|
it('should have matching number of JavaScript and Python challenges', function () {
|
||||||
|
assert.equal(
|
||||||
|
jsDailyChallenges.length,
|
||||||
|
pyDailyChallenges.length,
|
||||||
|
`JavaScript challenges: ${jsDailyChallenges.length}, Python challenges: ${pyDailyChallenges.length}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i = 0; i < jsDailyChallenges.length; i++) {
|
||||||
|
describe(`Challenge ${i + 1} Parity`, function () {
|
||||||
|
const jsChallenge = jsDailyChallenges[i];
|
||||||
|
const pyChallenge = pyDailyChallenges[i];
|
||||||
|
|
||||||
|
it("should have matching ID's", function () {
|
||||||
|
assert.equal(
|
||||||
|
jsChallenge.id,
|
||||||
|
pyChallenge.id,
|
||||||
|
`Challenge ${i + 1} ID mismatch - JS: ${jsChallenge.id}, Python: ${pyChallenge.id}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should have matching titles`, function () {
|
||||||
|
assert.equal(
|
||||||
|
jsChallenge.title,
|
||||||
|
pyChallenge.title,
|
||||||
|
`Challenge ${i + 1} title mismatch - JS: ${jsChallenge.title}, Python: ${pyChallenge.title}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have matching descriptions', function () {
|
||||||
|
assert.equal(
|
||||||
|
jsChallenge.description,
|
||||||
|
pyChallenge.description,
|
||||||
|
`Challenge ${i + 1} description mismatch`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have the same number of tests', function () {
|
||||||
|
const jsTestCount = jsChallenge.tests.length;
|
||||||
|
const pyTestCount = pyChallenge.tests.length;
|
||||||
|
assert.equal(
|
||||||
|
jsTestCount,
|
||||||
|
pyTestCount,
|
||||||
|
`Challenge ${i + 1} test count mismatch - JS: ${jsTestCount}, Python: ${pyTestCount}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
+251
-407
@@ -1,42 +1,26 @@
|
|||||||
const path = require('path');
|
import { createRequire } from 'node:module';
|
||||||
const { assert, AssertionError } = require('chai');
|
|
||||||
const jsdom = require('jsdom');
|
|
||||||
const liveServer = require('@compodoc/live-server');
|
|
||||||
const lodash = require('lodash');
|
|
||||||
const Mocha = require('mocha');
|
|
||||||
const mockRequire = require('mock-require');
|
|
||||||
const spinner = require('ora')();
|
|
||||||
const puppeteer = require('puppeteer');
|
|
||||||
|
|
||||||
// lodash-es can't easily be used in node environments, so we just mock it out
|
import { describe, it, beforeAll } from 'vitest';
|
||||||
// for the original lodash in testing.
|
import { assert, AssertionError } from 'chai';
|
||||||
mockRequire('lodash-es', lodash);
|
import jsdom from 'jsdom';
|
||||||
|
import lodash from 'lodash';
|
||||||
|
|
||||||
const clientPath = path.resolve(__dirname, '../../client');
|
import {
|
||||||
require('@babel/register')({
|
|
||||||
root: clientPath,
|
|
||||||
babelrc: false,
|
|
||||||
presets: ['@babel/preset-env', '@babel/typescript'],
|
|
||||||
plugins: ['dynamic-import-node'],
|
|
||||||
ignore: [/node_modules/],
|
|
||||||
only: [clientPath]
|
|
||||||
});
|
|
||||||
const {
|
|
||||||
buildChallenge,
|
buildChallenge,
|
||||||
runnerTypes
|
runnerTypes
|
||||||
} = require('../../client/src/templates/Challenges/utils/build');
|
} from '../../client/src/templates/Challenges/utils/build';
|
||||||
const {
|
import {
|
||||||
challengeTypes,
|
challengeTypes,
|
||||||
hasNoSolution
|
hasNoSolution
|
||||||
} = require('../../shared/config/challenge-types');
|
} from '../../shared/config/challenge-types';
|
||||||
const { getLines } = require('../../shared/utils/get-lines');
|
import { getLines } from '../../shared/utils/get-lines';
|
||||||
|
import { prefixDoctype } from '../../client/src/templates/Challenges/utils/frame';
|
||||||
|
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
const { getChallengesForLang } = require('../get-challenges');
|
const { getChallengesForLang } = require('../get-challenges');
|
||||||
const { challengeSchemaValidator } = require('../schema/challenge-schema');
|
const { challengeSchemaValidator } = require('../schema/challenge-schema');
|
||||||
const { testedLang } = require('../utils');
|
const { testedLang } = require('../utils');
|
||||||
const {
|
|
||||||
prefixDoctype,
|
|
||||||
helperVersion
|
|
||||||
} = require('../../client/src/templates/Challenges/utils/frame');
|
|
||||||
|
|
||||||
const { curriculumSchemaValidator } = require('../schema/curriculum-schema');
|
const { curriculumSchemaValidator } = require('../schema/curriculum-schema');
|
||||||
const { validateMetaSchema } = require('../schema/meta-schema');
|
const { validateMetaSchema } = require('../schema/meta-schema');
|
||||||
@@ -49,183 +33,79 @@ const { sortChallenges } = require('./utils/sort-challenges');
|
|||||||
|
|
||||||
const { flatten, isEmpty, cloneDeep } = lodash;
|
const { flatten, isEmpty, cloneDeep } = lodash;
|
||||||
|
|
||||||
const testFilter = {
|
|
||||||
block: process.env.FCC_BLOCK ? process.env.FCC_BLOCK.trim() : undefined,
|
|
||||||
challengeId: process.env.FCC_CHALLENGE_ID
|
|
||||||
? process.env.FCC_CHALLENGE_ID.trim()
|
|
||||||
: undefined,
|
|
||||||
superBlock: process.env.FCC_SUPERBLOCK
|
|
||||||
? process.env.FCC_SUPERBLOCK.trim()
|
|
||||||
: undefined
|
|
||||||
};
|
|
||||||
|
|
||||||
// rethrow unhandled rejections to make sure the tests exit with non-zero code
|
|
||||||
process.on('unhandledRejection', err => handleRejection(err));
|
|
||||||
// If an uncaught exception gets here, then mocha is in an unexpected state. All
|
|
||||||
// we can do is log the exception and exit with a non-zero code.
|
|
||||||
process.on('uncaughtException', err => {
|
|
||||||
console.error('Uncaught exception:');
|
|
||||||
console.error(err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// some errors *may* not be reported, since cleanup is triggered by the first
|
|
||||||
// error and that starts shutting down the browser and the server.
|
|
||||||
const handleRejection = err => {
|
|
||||||
console.error('Unhandled rejection:');
|
|
||||||
// setting the error code because node does not (yet) exit with a non-zero
|
|
||||||
// code on unhandled exceptions.
|
|
||||||
process.exitCode = 1;
|
|
||||||
cleanup();
|
|
||||||
console.error(err);
|
|
||||||
if (process.env.FULL_OUTPUT !== 'true') process.exit();
|
|
||||||
};
|
|
||||||
|
|
||||||
const dom = new jsdom.JSDOM('');
|
const dom = new jsdom.JSDOM('');
|
||||||
global.document = dom.window.document;
|
global.document = dom.window.document;
|
||||||
global.DOMParser = dom.window.DOMParser;
|
global.DOMParser = dom.window.DOMParser;
|
||||||
|
|
||||||
const oldRunnerFail = Mocha.Runner.prototype.fail;
|
// The puppeteer page is global so that we can recreate it during tests, if
|
||||||
Mocha.Runner.prototype.fail = function (test, err) {
|
// needed.
|
||||||
if (err instanceof AssertionError) {
|
let page;
|
||||||
const errMessage = String(err.message || '');
|
|
||||||
const assertIndex = errMessage.indexOf(': expected');
|
|
||||||
if (assertIndex !== -1) {
|
|
||||||
err.message = errMessage.slice(0, assertIndex);
|
|
||||||
}
|
|
||||||
// Don't show stacktrace for assertion errors.
|
|
||||||
if (err.stack) {
|
|
||||||
delete err.stack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return oldRunnerFail.call(this, test, err);
|
|
||||||
};
|
|
||||||
|
|
||||||
async function newPageContext(browser) {
|
const poolId = process.env.VITEST_POOL_ID;
|
||||||
const page = await browser.newPage();
|
|
||||||
// it's needed for workers as context.
|
async function createAndVisitNewPage() {
|
||||||
await page.goto('http://127.0.0.1:8080/index.html');
|
const page = await globalThis.puppeteerBrowserContext[poolId].newPage();
|
||||||
|
await page.goto(`http://127.0.0.1:8080/index.html`);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
spinner.start();
|
async function newPageContext() {
|
||||||
spinner.text = 'Populate tests.';
|
// Reuse a single page per worker/pool to avoid the overhead of creating a
|
||||||
|
// new page for every block file.
|
||||||
|
globalThis.__fccPuppeteerPages ??= {};
|
||||||
|
globalThis.__fccPuppeteerPages[poolId] ??= globalThis.__fccPuppeteerPages[
|
||||||
|
poolId
|
||||||
|
] = createAndVisitNewPage();
|
||||||
|
|
||||||
let browser;
|
return globalThis.__fccPuppeteerPages[poolId];
|
||||||
let page;
|
}
|
||||||
|
|
||||||
setup()
|
|
||||||
.then(runTests)
|
|
||||||
.catch(err => handleRejection(err));
|
|
||||||
|
|
||||||
async function setup() {
|
|
||||||
// liveServer starts synchronously
|
|
||||||
liveServer.start({
|
|
||||||
host: '127.0.0.1',
|
|
||||||
port: '8080',
|
|
||||||
root: path.resolve(__dirname, 'stubs'),
|
|
||||||
mount: [
|
|
||||||
[
|
|
||||||
'/dist',
|
|
||||||
path.join(clientPath, `static/js/test-runner/${helperVersion}`)
|
|
||||||
],
|
|
||||||
['/js', path.join(clientPath, 'static/js')]
|
|
||||||
],
|
|
||||||
open: false,
|
|
||||||
logLevel: 0
|
|
||||||
});
|
|
||||||
browser = await puppeteer.launch({
|
|
||||||
args: [
|
|
||||||
// Required for Docker version of Puppeteer
|
|
||||||
'--no-sandbox',
|
|
||||||
'--disable-setuid-sandbox',
|
|
||||||
// This will write shared memory files into /tmp instead of /dev/shm,
|
|
||||||
// because Docker’s default for /dev/shm is 64MB
|
|
||||||
'--disable-dev-shm-usage'
|
|
||||||
// dumpio: true
|
|
||||||
],
|
|
||||||
headless: 'new'
|
|
||||||
});
|
|
||||||
global.Worker = createPseudoWorker(await newPageContext(browser));
|
|
||||||
|
|
||||||
page = await newPageContext(browser);
|
|
||||||
await page.setViewport({ width: 300, height: 150 });
|
|
||||||
|
|
||||||
|
export async function defineTestsForBlock({ block }) {
|
||||||
const lang = testedLang();
|
const lang = testedLang();
|
||||||
const challenges = await getChallenges(lang, testFilter);
|
const challenges = await getChallenges(lang, { block });
|
||||||
const nonCertificationChallenges = challenges.filter(
|
const nonCertificationChallenges = challenges.filter(
|
||||||
({ challengeType }) => challengeType !== 7
|
({ challengeType }) => challengeType !== 7
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isEmpty(nonCertificationChallenges)) {
|
if (isEmpty(nonCertificationChallenges)) {
|
||||||
throw Error(
|
console.warn(`No non-certification challenges to test for block ${block}.`);
|
||||||
`No challenges to test when using filter ${JSON.stringify(testFilter)}
|
describe('Check challenges', () => {
|
||||||
If the challenge file exists, try running 'build:curriculum' for more information.
|
it('No non-certification challenges to test', () => {});
|
||||||
`
|
});
|
||||||
);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the next few statements create a list of all blocks and superblocks
|
|
||||||
// as they appear in the list of challenges
|
|
||||||
const superBlocks = challenges.map(({ superBlock }) => superBlock);
|
|
||||||
const targetSuperBlockStrings = [
|
|
||||||
...new Set(superBlocks.filter(el => Boolean(el)))
|
|
||||||
];
|
|
||||||
|
|
||||||
const meta = {};
|
const meta = {};
|
||||||
for (const challenge of challenges) {
|
for (const challenge of challenges) {
|
||||||
const dashedBlockName = challenge.block;
|
const dashedBlockName = challenge.block;
|
||||||
// certifications do not have dashedBlockName's and don't have metas so
|
|
||||||
// we can skip them.
|
|
||||||
// TODO: omit certifications from the list of challenges
|
|
||||||
if (dashedBlockName && !meta[dashedBlockName]) {
|
if (dashedBlockName && !meta[dashedBlockName]) {
|
||||||
meta[dashedBlockName] = getBlockStructure(dashedBlockName);
|
meta[dashedBlockName] = getBlockStructure(dashedBlockName);
|
||||||
const result = validateMetaSchema(meta[dashedBlockName]);
|
const result = validateMetaSchema(meta[dashedBlockName]);
|
||||||
|
if (result.error) throw new AssertionError(result.error);
|
||||||
if (result.error) {
|
|
||||||
throw new AssertionError(result.error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
meta,
|
|
||||||
challenges,
|
|
||||||
lang,
|
|
||||||
superBlocks: targetSuperBlockStrings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup calls some async functions, but it's the last thing that happens, so
|
const challengeData = { meta, challenges, lang };
|
||||||
// no need to await anything.
|
|
||||||
function cleanup() {
|
|
||||||
if (browser) {
|
|
||||||
browser.close();
|
|
||||||
}
|
|
||||||
liveServer.shutdown();
|
|
||||||
spinner.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
function runTests(challengeData) {
|
describe('Check challenges', () => {
|
||||||
describe('Check challenges', function () {
|
beforeAll(async () => {
|
||||||
after(function () {
|
page = await newPageContext();
|
||||||
cleanup();
|
global.Worker = createPseudoWorker(page);
|
||||||
});
|
});
|
||||||
populateTestsForLang(challengeData);
|
|
||||||
|
populateTestsForLang(challengeData, () => page);
|
||||||
});
|
});
|
||||||
spinner.text = 'Testing';
|
|
||||||
run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getChallenges(lang, filters) {
|
export async function getChallenges(lang, filters) {
|
||||||
const challenges = await getChallengesForLang(lang, filters).then(
|
const challenges = await getChallengesForLang(lang, filters).then(
|
||||||
curriculum => {
|
curriculum => {
|
||||||
const result = curriculumSchemaValidator(curriculum);
|
|
||||||
// If there are filters, we're testing a single challenge or block, so we
|
// If there are filters, we're testing a single challenge or block, so we
|
||||||
// can skip the validation.
|
// can skip the validation.
|
||||||
if (result.error && isEmpty(filters)) {
|
if (isEmpty(filters)) {
|
||||||
throw new Error(
|
const result = curriculumSchemaValidator(curriculum);
|
||||||
`Curriculum validation failed: ${result.error.message}`
|
if (result.error)
|
||||||
);
|
throw new Error(
|
||||||
|
`Curriculum validation failed: ${result.error.message}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return Object.keys(curriculum)
|
return Object.keys(curriculum)
|
||||||
.map(key => curriculum[key].blocks)
|
.map(key => curriculum[key].blocks)
|
||||||
@@ -242,213 +122,143 @@ async function getChallenges(lang, filters) {
|
|||||||
return sortChallenges(challenges);
|
return sortChallenges(challenges);
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateTestsForLang({ lang, challenges, meta, superBlocks }) {
|
function populateTestsForLang({ lang, challenges, meta }) {
|
||||||
const validateChallenge = challengeSchemaValidator();
|
const validateChallenge = challengeSchemaValidator();
|
||||||
|
|
||||||
superBlocks.forEach(superBlock => {
|
describe(`Language: ${lang}`, function () {
|
||||||
describe(`Language: ${lang}`, function () {
|
const challengeTitles = new ChallengeTitles();
|
||||||
describe(`SuperBlock: ${superBlock}`, function () {
|
const mongoIds = new MongoIds();
|
||||||
this.timeout(5000);
|
|
||||||
const superBlockChallenges = challenges.filter(
|
|
||||||
c => c.superBlock === superBlock
|
|
||||||
);
|
|
||||||
|
|
||||||
// daily challenge tests
|
challenges.forEach((challenge, id) => {
|
||||||
if (superBlock === 'dev-playground') {
|
// When testing single challenge, in project based curriculum,
|
||||||
describe('Daily Coding Challenges', function () {
|
// challenge to test (current challenge) might not have solution.
|
||||||
const jsDailyChallenges = superBlockChallenges.filter(
|
// Instead seed from next challenge is tested against tests from
|
||||||
c => c.block === 'daily-coding-challenges-javascript'
|
// current challenge. Next challenge is skipped from testing.
|
||||||
);
|
if (process.env.FCC_CHALLENGE_ID && id > 0) return;
|
||||||
|
|
||||||
const pyDailyChallenges = superBlockChallenges.filter(
|
const dashedBlockName = challenge.block;
|
||||||
c => c.block === 'daily-coding-challenges-python'
|
// TODO: once certifications are not included in the list of challenges,
|
||||||
);
|
// stop returning early here.
|
||||||
|
if (typeof dashedBlockName === 'undefined') return;
|
||||||
|
describe(`Block: ${challenge.block}`, function () {
|
||||||
|
describe(`Title: ${challenge.title}`, function () {
|
||||||
|
describe(`ID: ${challenge.id}`, function () {
|
||||||
|
// Note: the title in meta.json are purely for human readability and
|
||||||
|
// do not include translations, so we do not validate against them.
|
||||||
|
it('Matches an ID in meta.json', function () {
|
||||||
|
const index = meta[dashedBlockName]?.challengeOrder?.findIndex(
|
||||||
|
({ id }) => id === challenge.id
|
||||||
|
);
|
||||||
|
|
||||||
it('should have matching number of JavaScript and Python challenges', function () {
|
if (index < 0) {
|
||||||
assert.equal(
|
throw new AssertionError(
|
||||||
jsDailyChallenges.length,
|
`Cannot find ID "${challenge.id}" in meta.json file for block "${dashedBlockName}"`
|
||||||
pyDailyChallenges.length,
|
);
|
||||||
`JavaScript challenges: ${jsDailyChallenges.length}, Python challenges: ${pyDailyChallenges.length}`
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Common checks', function () {
|
||||||
|
const result = validateChallenge(challenge);
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
throw new AssertionError(result.error);
|
||||||
|
}
|
||||||
|
const { id, block, dashedName } = challenge;
|
||||||
|
assert.exists(
|
||||||
|
dashedName,
|
||||||
|
`Missing dashedName for challenge ${id} in ${block}.`
|
||||||
|
);
|
||||||
|
const pathAndTitle = `${block}/${dashedName}`;
|
||||||
|
const idVerificationMessage = mongoIds.check(id, block);
|
||||||
|
assert.isNull(idVerificationMessage, idVerificationMessage);
|
||||||
|
const dupeTitleCheck = challengeTitles.check(dashedName, block);
|
||||||
|
assert.isTrue(
|
||||||
|
dupeTitleCheck,
|
||||||
|
`All challenges within a block must have a unique dashed name. ${dashedName} (at ${pathAndTitle}) is already assigned`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let i = 0; i < jsDailyChallenges.length; i++) {
|
const { challengeType } = challenge;
|
||||||
describe(`Challenge ${i + 1} Parity`, function () {
|
|
||||||
const jsChallenge = jsDailyChallenges[i];
|
|
||||||
const pyChallenge = pyDailyChallenges[i];
|
|
||||||
|
|
||||||
it("should have matching ID's", function () {
|
if (hasNoSolution(challengeType)) return;
|
||||||
assert.equal(
|
|
||||||
jsChallenge.id,
|
|
||||||
pyChallenge.id,
|
|
||||||
`Challenge ${i + 1} ID mismatch - JS: ${jsChallenge.id}, Python: ${pyChallenge.id}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should have matching titles`, function () {
|
let { tests = [] } = challenge;
|
||||||
assert.equal(
|
tests = tests.filter(test => !!test.testString);
|
||||||
jsChallenge.title,
|
if (tests.length === 0) {
|
||||||
pyChallenge.title,
|
it('Check tests. No tests.', () => {});
|
||||||
`Challenge ${i + 1} title mismatch - JS: ${jsChallenge.title}, Python: ${pyChallenge.title}`
|
return;
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have matching descriptions', function () {
|
|
||||||
assert.equal(
|
|
||||||
jsChallenge.description,
|
|
||||||
pyChallenge.description,
|
|
||||||
`Challenge ${i + 1} description mismatch`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have the same number of tests', function () {
|
|
||||||
const jsTestCount = jsChallenge.tests.length;
|
|
||||||
const pyTestCount = pyChallenge.tests.length;
|
|
||||||
assert.equal(
|
|
||||||
jsTestCount,
|
|
||||||
pyTestCount,
|
|
||||||
`Challenge ${i + 1} test count mismatch - JS: ${jsTestCount}, Python: ${pyTestCount}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const challengeTitles = new ChallengeTitles();
|
if (challengeType === challengeTypes.backend) {
|
||||||
const mongoIds = new MongoIds();
|
it('Check tests is not implemented.', () => {});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
superBlockChallenges.forEach((challenge, id) => {
|
// The python tests are (currently) slow, so we give them more time.
|
||||||
// When testing single challenge, in project based curriculum,
|
const timePerTest =
|
||||||
// challenge to test (current challenge) might not have solution.
|
challengeType === challengeTypes.python ? 10000 : 5000;
|
||||||
// Instead seed from next challenge is tested against tests from
|
it(
|
||||||
// current challenge. Next challenge is skipped from testing.
|
'Test suite must fail on the initial contents',
|
||||||
if (process.env.FCC_CHALLENGE_ID && id > 0) return;
|
async function () {
|
||||||
|
// suppress errors in the console.
|
||||||
const dashedBlockName = challenge.block;
|
const oldConsoleError = console.error;
|
||||||
// TODO: once certifications are not included in the list of challenges,
|
console.error = () => {};
|
||||||
// stop returning early here.
|
let fails = false;
|
||||||
if (typeof dashedBlockName === 'undefined') return;
|
let testRunner;
|
||||||
describe(`Block: ${challenge.block}`, function () {
|
// TODO: if this times out, try wrapping this whole test in a
|
||||||
describe(`Title: ${challenge.title}`, function () {
|
// new describe block and create the runner in a beforeAll (i.e.
|
||||||
describe(`ID: ${challenge.id}`, function () {
|
// same as "Check tests against solutions")
|
||||||
// Note: the title in meta.json are purely for human readability and
|
try {
|
||||||
// do not include translations, so we do not validate against them.
|
testRunner = await createTestRunner(
|
||||||
it('Matches an ID in meta.json', function () {
|
challenge,
|
||||||
const index = meta[
|
challenge.challengeFiles,
|
||||||
dashedBlockName
|
buildChallenge
|
||||||
]?.challengeOrder?.findIndex(({ id }) => id === challenge.id);
|
|
||||||
|
|
||||||
if (index < 0) {
|
|
||||||
throw new AssertionError(
|
|
||||||
`Cannot find ID "${challenge.id}" in meta.json file for block "${dashedBlockName}"`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Common checks', function () {
|
|
||||||
const result = validateChallenge(challenge);
|
|
||||||
|
|
||||||
if (result.error) {
|
|
||||||
throw new AssertionError(result.error);
|
|
||||||
}
|
|
||||||
const { id, block, dashedName } = challenge;
|
|
||||||
assert.exists(
|
|
||||||
dashedName,
|
|
||||||
`Missing dashedName for challenge ${id} in ${block}.`
|
|
||||||
);
|
);
|
||||||
const pathAndTitle = `${block}/${dashedName}`;
|
} catch (e) {
|
||||||
const idVerificationMessage = mongoIds.check(id, block);
|
console.error(
|
||||||
assert.isNull(idVerificationMessage, idVerificationMessage);
|
`Error creating test runner for initial contents`
|
||||||
const dupeTitleCheck = challengeTitles.check(
|
|
||||||
dashedName,
|
|
||||||
block
|
|
||||||
);
|
);
|
||||||
assert.isTrue(
|
console.error(e);
|
||||||
dupeTitleCheck,
|
fails = true;
|
||||||
`All challenges within a block must have a unique dashed name. ${dashedName} (at ${pathAndTitle}) is already assigned`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const { challengeType } = challenge;
|
|
||||||
|
|
||||||
if (hasNoSolution(challengeType)) return;
|
|
||||||
|
|
||||||
let { tests = [] } = challenge;
|
|
||||||
tests = tests.filter(test => !!test.testString);
|
|
||||||
if (tests.length === 0) {
|
|
||||||
it('Check tests. No tests.');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (!fails) {
|
||||||
if (challengeType === challengeTypes.backend) {
|
|
||||||
it('Check tests is not implemented.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The python tests are (currently) slow, so we give them more time.
|
|
||||||
const timePerTest =
|
|
||||||
challengeType === challengeTypes.python ? 10000 : 5000;
|
|
||||||
it('Test suite must fail on the initial contents', async function () {
|
|
||||||
// TODO: some tests take a surprisingly long time to setup the
|
|
||||||
// test runner, so this timeout is large while we investigate.
|
|
||||||
this.timeout(timePerTest * tests.length + 20000);
|
|
||||||
// suppress errors in the console.
|
|
||||||
const oldConsoleError = console.error;
|
|
||||||
console.error = () => {};
|
|
||||||
let fails = false;
|
|
||||||
let testRunner;
|
|
||||||
try {
|
try {
|
||||||
testRunner = await createTestRunner(
|
await testRunner(tests);
|
||||||
challenge,
|
} catch {
|
||||||
challenge.challengeFiles,
|
|
||||||
buildChallenge
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(
|
|
||||||
`Error creating test runner for initial contents`
|
|
||||||
);
|
|
||||||
console.error(e);
|
|
||||||
fails = true;
|
fails = true;
|
||||||
}
|
}
|
||||||
if (!fails) {
|
}
|
||||||
try {
|
console.error = oldConsoleError;
|
||||||
await testRunner(tests);
|
assert(
|
||||||
} catch {
|
fails,
|
||||||
fails = true;
|
'Test suite does not fail on the initial contents'
|
||||||
}
|
);
|
||||||
}
|
},
|
||||||
console.error = oldConsoleError;
|
timePerTest * tests.length + 20000
|
||||||
assert(
|
);
|
||||||
fails,
|
|
||||||
'Test suite does not fail on the initial contents'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
let { solutions = [] } = challenge;
|
let { solutions = [] } = challenge;
|
||||||
|
|
||||||
// if there's an empty string as solution, this is likely a mistake
|
// if there's an empty string as solution, this is likely a mistake
|
||||||
// TODO: what does this look like now? (this being detection of empty
|
// TODO: what does this look like now? (this being detection of empty
|
||||||
// lines in solutions - rather than entirely missing solutions)
|
// lines in solutions - rather than entirely missing solutions)
|
||||||
|
|
||||||
// We need to track where the solution came from to give better
|
// We need to track where the solution came from to give better
|
||||||
// feedback if the solution is failing.
|
// feedback if the solution is failing.
|
||||||
let solutionFromNext = false;
|
let solutionFromNext = false;
|
||||||
|
|
||||||
if (isEmpty(solutions)) {
|
if (isEmpty(solutions)) {
|
||||||
// if there are no solutions in the challenge, it's assumed the next
|
// if there are no solutions in the challenge, it's assumed the next
|
||||||
// challenge's seed will be a solution to the current challenge.
|
// challenge's seed will be a solution to the current challenge.
|
||||||
// This is expected to happen in the project based curriculum.
|
// This is expected to happen in the project based curriculum.
|
||||||
|
|
||||||
const nextChallenge = superBlockChallenges[id + 1];
|
const nextChallenge = challenges[id + 1];
|
||||||
|
|
||||||
if (nextChallenge) {
|
if (nextChallenge) {
|
||||||
const solutionFiles = cloneDeep(
|
const solutionFiles = cloneDeep(nextChallenge.challengeFiles);
|
||||||
nextChallenge.challengeFiles
|
if (!solutionFiles) {
|
||||||
);
|
throw Error(
|
||||||
if (!solutionFiles) {
|
`No solution found.
|
||||||
throw Error(
|
|
||||||
`No solution found.
|
|
||||||
Check the next challenge (${nextChallenge.title}): it should have a seed which solves the current challenge.
|
Check the next challenge (${nextChallenge.title}): it should have a seed which solves the current challenge.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
@@ -460,61 +270,65 @@ For example:
|
|||||||
seed goes here
|
seed goes here
|
||||||
\`\`\`
|
\`\`\`
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
}
|
|
||||||
const solutionFilesWithEditableContents = solutionFiles.map(
|
|
||||||
file => ({
|
|
||||||
...file,
|
|
||||||
editableContents: getLines(
|
|
||||||
file.contents,
|
|
||||||
file.editableRegionBoundaries
|
|
||||||
)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// Since there is only one seed, there can only be one solution,
|
|
||||||
// but the tests assume solutions is an array.
|
|
||||||
solutions = [solutionFilesWithEditableContents];
|
|
||||||
solutionFromNext = true;
|
|
||||||
} else {
|
|
||||||
throw Error(
|
|
||||||
`solution omitted for ${challenge.superBlock} ${challenge.block} ${challenge.title}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const solutionFilesWithEditableContents = solutionFiles.map(
|
||||||
// TODO: the no-solution filtering is a little convoluted:
|
file => ({
|
||||||
const noSolution = new RegExp('// solution required');
|
...file,
|
||||||
|
editableContents: getLines(
|
||||||
const filteredSolutions = solutions.filter(solution => {
|
file.contents,
|
||||||
return !isEmpty(
|
file.editableRegionBoundaries
|
||||||
solution.filter(
|
|
||||||
challengeFile => !noSolution.test(challengeFile.contents)
|
|
||||||
)
|
)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// Since there is only one seed, there can only be one solution,
|
||||||
|
// but the tests assume solutions is an array.
|
||||||
|
solutions = [solutionFilesWithEditableContents];
|
||||||
|
solutionFromNext = true;
|
||||||
|
} else {
|
||||||
|
throw Error(
|
||||||
|
`solution omitted for ${challenge.superBlock} ${challenge.block} ${challenge.title}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: the no-solution filtering is a little convoluted:
|
||||||
|
const noSolution = new RegExp('// solution required');
|
||||||
|
|
||||||
|
const filteredSolutions = solutions.filter(solution => {
|
||||||
|
return !isEmpty(
|
||||||
|
solution.filter(
|
||||||
|
challengeFile => !noSolution.test(challengeFile.contents)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isEmpty(filteredSolutions)) {
|
||||||
|
it('Check tests. No solutions', () => {});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Check tests against solutions', function () {
|
||||||
|
solutions.forEach((solution, index) => {
|
||||||
|
let testRunner;
|
||||||
|
// Creating the test runner can be slow, so we do it in
|
||||||
|
// beforeAll rather than the test itself.
|
||||||
|
beforeAll(async () => {
|
||||||
|
testRunner = await createTestRunner(
|
||||||
|
challenge,
|
||||||
|
solution,
|
||||||
|
buildChallenge,
|
||||||
|
solutionFromNext
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isEmpty(filteredSolutions)) {
|
it(
|
||||||
it('Check tests. No solutions');
|
`Solution ${index + 1} must pass the tests`,
|
||||||
return;
|
async function () {
|
||||||
}
|
await testRunner(tests);
|
||||||
|
},
|
||||||
describe('Check tests against solutions', function () {
|
timePerTest * tests.length + 2000
|
||||||
solutions.forEach((solution, index) => {
|
);
|
||||||
it(`Solution ${
|
|
||||||
index + 1
|
|
||||||
} must pass the tests`, async function () {
|
|
||||||
this.timeout(timePerTest * tests.length + 2000);
|
|
||||||
const testRunner = await createTestRunner(
|
|
||||||
challenge,
|
|
||||||
solution,
|
|
||||||
buildChallenge,
|
|
||||||
solutionFromNext
|
|
||||||
);
|
|
||||||
|
|
||||||
await testRunner(tests);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -543,6 +357,8 @@ async function createTestRunner(
|
|||||||
{ usesTestRunner: true }
|
{ usesTestRunner: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!page) throw new Error('Browser page is not ready yet');
|
||||||
|
|
||||||
const evaluator = await getContextEvaluator({
|
const evaluator = await getContextEvaluator({
|
||||||
// passing in challengeId so it's easier to debug timeouts
|
// passing in challengeId so it's easier to debug timeouts
|
||||||
challengeId: challenge.id,
|
challengeId: challenge.id,
|
||||||
@@ -617,7 +433,7 @@ async function getContextEvaluator(config) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initializeTestRunner({
|
async function _initializeTestRunner({
|
||||||
build,
|
build,
|
||||||
sources,
|
sources,
|
||||||
type,
|
type,
|
||||||
@@ -625,7 +441,6 @@ async function initializeTestRunner({
|
|||||||
loadEnzyme
|
loadEnzyme
|
||||||
}) {
|
}) {
|
||||||
const source = type === 'dom' ? prefixDoctype({ build, sources }) : build;
|
const source = type === 'dom' ? prefixDoctype({ build, sources }) : build;
|
||||||
|
|
||||||
await page.evaluate(
|
await page.evaluate(
|
||||||
async (sources, source, type, hooks, loadEnzyme) => {
|
async (sources, source, type, hooks, loadEnzyme) => {
|
||||||
await window.FCCTestRunner.createTestRunner({
|
await window.FCCTestRunner.createTestRunner({
|
||||||
@@ -643,3 +458,32 @@ async function initializeTestRunner({
|
|||||||
loadEnzyme
|
loadEnzyme
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function initializeTestRunner({
|
||||||
|
build,
|
||||||
|
sources,
|
||||||
|
type,
|
||||||
|
hooks,
|
||||||
|
loadEnzyme
|
||||||
|
}) {
|
||||||
|
// Ensure FCCTestRunner is available before creating it
|
||||||
|
await page.waitForFunction(
|
||||||
|
'window.FCCTestRunner && window.FCCTestRunner.createTestRunner',
|
||||||
|
{ timeout: 5000 }
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await _initializeTestRunner({ build, sources, type, hooks, loadEnzyme });
|
||||||
|
} catch (e) {
|
||||||
|
// It's not clear why, but sometimes the iframe load times out. It seems to
|
||||||
|
// be an issue with Puppeteer, so we give it one more try to reduce test
|
||||||
|
// flakiness.
|
||||||
|
if (e.message.includes('Timed out waiting for the test frame to load')) {
|
||||||
|
console.warn('Test frame load timed out. Retrying...');
|
||||||
|
page = await createAndVisitNewPage();
|
||||||
|
await _initializeTestRunner({ build, sources, type, hooks, loadEnzyme });
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
import { parseCurriculumStructure } from '../../build-curriculum.js';
|
||||||
|
|
||||||
|
const __dirname = import.meta.dirname;
|
||||||
|
|
||||||
|
const testFilter = {
|
||||||
|
block: process.env.FCC_BLOCK ? process.env.FCC_BLOCK.trim() : undefined,
|
||||||
|
challengeId: process.env.FCC_CHALLENGE_ID
|
||||||
|
? process.env.FCC_CHALLENGE_ID.trim()
|
||||||
|
: undefined,
|
||||||
|
superBlock: process.env.FCC_SUPERBLOCK
|
||||||
|
? process.env.FCC_SUPERBLOCK.trim()
|
||||||
|
: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const GENERATED_DIR = path.resolve(__dirname, '../blocks-generated');
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// clean and recreate directory
|
||||||
|
await fs.promises.rm(GENERATED_DIR, { force: true, recursive: true });
|
||||||
|
await fs.promises.mkdir(GENERATED_DIR, { recursive: true });
|
||||||
|
|
||||||
|
const { fullSuperblockList } = await parseCurriculumStructure(testFilter);
|
||||||
|
|
||||||
|
const blocks = _.uniq(
|
||||||
|
fullSuperblockList.flatMap(({ blocks }) => blocks).map(b => b.dashedName)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const block of blocks) {
|
||||||
|
const filePath = path.join(GENERATED_DIR, `${block}.test.js`);
|
||||||
|
const contents = generateSingleBlockFile({ block });
|
||||||
|
await fs.promises.writeFile(filePath, contents, 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Generated ${blocks.length} block test file(s).`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateSingleBlockFile({ block }) {
|
||||||
|
return `import { defineTestsForBlock } from '../test-challenges.js';
|
||||||
|
|
||||||
|
await defineTestsForBlock({ block: ${JSON.stringify(block)} });
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import sirv from 'sirv';
|
||||||
|
import polka from 'polka';
|
||||||
|
import puppeteer from 'puppeteer';
|
||||||
|
|
||||||
|
import { helperVersion } from '../../client/src/templates/Challenges/utils/frame';
|
||||||
|
|
||||||
|
const clientPath = path.resolve(__dirname, '../../client');
|
||||||
|
|
||||||
|
async function createBrowser() {
|
||||||
|
return puppeteer.launch({
|
||||||
|
args: [
|
||||||
|
'--no-sandbox',
|
||||||
|
'--disable-setuid-sandbox',
|
||||||
|
'--disable-dev-shm-usage'
|
||||||
|
],
|
||||||
|
headless: 'new'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let browser, server;
|
||||||
|
|
||||||
|
async function startServer() {
|
||||||
|
const host = '127.0.0.1';
|
||||||
|
const port = 8080;
|
||||||
|
|
||||||
|
const app = polka();
|
||||||
|
|
||||||
|
// Mount static files used by the tests
|
||||||
|
app.use(
|
||||||
|
'/dist',
|
||||||
|
sirv(path.join(clientPath, `static/js/test-runner/${helperVersion}`))
|
||||||
|
);
|
||||||
|
app.use('/js', sirv(path.join(clientPath, 'static/js')));
|
||||||
|
app.use('/', sirv(path.resolve(__dirname, 'stubs')));
|
||||||
|
app.listen(port, host);
|
||||||
|
return app.server;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setup() {
|
||||||
|
server = await startServer();
|
||||||
|
browser = await createBrowser();
|
||||||
|
// Sharing the Websocket endpoint so that setup files can connect. This allows
|
||||||
|
// us to do as much work as possible once in the global setup while allowing
|
||||||
|
// each test pool to maintain its own connection.
|
||||||
|
process.env.PUPPETEER_WS_ENDPOINT = browser.wsEndpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function teardown() {
|
||||||
|
await browser.close();
|
||||||
|
await server.close();
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// connect to the puppeteer browser instance and create a new page context
|
||||||
|
// each VITEST_POOL_ID will have its own context
|
||||||
|
|
||||||
|
import puppeteer from 'puppeteer';
|
||||||
|
|
||||||
|
if (!globalThis.puppeteerBrowserContext?.[process.env.VITEST_POOL_ID]) {
|
||||||
|
globalThis.puppeteerBrowserContext ??= {};
|
||||||
|
const browser = await puppeteer.connect({
|
||||||
|
browserWSEndpoint: process.env.PUPPETEER_WS_ENDPOINT
|
||||||
|
});
|
||||||
|
globalThis.puppeteerBrowserContext[process.env.VITEST_POOL_ID] =
|
||||||
|
await browser.createBrowserContext();
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
include: ['test/blocks-generated/**/*.test.js'],
|
||||||
|
environment: 'node',
|
||||||
|
hookTimeout: 60000,
|
||||||
|
testTimeout: 30000,
|
||||||
|
isolate: false,
|
||||||
|
globalSetup: 'test/vitest-global-setup.mjs',
|
||||||
|
setupFiles: 'test/vitest-setup.mjs'
|
||||||
|
}
|
||||||
|
});
|
||||||
+6
-4
@@ -58,23 +58,25 @@ function getSuperOrder(superblock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the superblocks array to only include blocks with the specified dashedName (block).
|
* Filters the superblocks array to include, at most, a single superblock with the specified block.
|
||||||
* If no block is provided, returns the original superblocks array.
|
* If no block is provided, returns the original superblocks array.
|
||||||
*
|
*
|
||||||
* @param {Array<Object>} superblocks - Array of superblock objects, each containing a blocks array.
|
* @param {Array<Object>} superblocks - Array of superblock objects, each containing a blocks array.
|
||||||
* @param {Object} [options] - Options object
|
* @param {Object} [options] - Options object
|
||||||
* @param {string} [options.block] - The dashedName of the block to filter for (in kebab case).
|
* @param {string} [options.block] - The dashedName of the block to filter for (in kebab case).
|
||||||
* @returns {Array<Object>} Filtered array of superblocks containing only the specified block, or the original array if block is not provided.
|
* @returns {Array<Object>} Array with one superblock containing the specified block, or the original array if block is not provided.
|
||||||
*/
|
*/
|
||||||
function filterByBlock(superblocks, { block } = {}) {
|
function filterByBlock(superblocks, { block } = {}) {
|
||||||
if (!block) return superblocks;
|
if (!block) return superblocks;
|
||||||
|
|
||||||
return superblocks
|
const superblock = superblocks
|
||||||
.map(superblock => ({
|
.map(superblock => ({
|
||||||
...superblock,
|
...superblock,
|
||||||
blocks: superblock.blocks.filter(({ dashedName }) => dashedName === block)
|
blocks: superblock.blocks.filter(({ dashedName }) => dashedName === block)
|
||||||
}))
|
}))
|
||||||
.filter(superblock => superblock.blocks.length > 0);
|
.find(superblock => superblock.blocks.length > 0);
|
||||||
|
|
||||||
|
return superblock ? [superblock] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
exclude: ['test/blocks-generated/**/*.test.js']
|
||||||
|
}
|
||||||
|
});
|
||||||
+2
-1
@@ -67,7 +67,8 @@ export default tseslint.config(
|
|||||||
$: true,
|
$: true,
|
||||||
ga: true,
|
ga: true,
|
||||||
jQuery: true,
|
jQuery: true,
|
||||||
router: true
|
router: true,
|
||||||
|
globalThis: true
|
||||||
},
|
},
|
||||||
|
|
||||||
parser: babelParser,
|
parser: babelParser,
|
||||||
|
|||||||
+2
-2
@@ -75,9 +75,9 @@
|
|||||||
"test:tools:challenge-helper-scripts": "cd ./tools/challenge-helper-scripts && pnpm test run",
|
"test:tools:challenge-helper-scripts": "cd ./tools/challenge-helper-scripts && pnpm test run",
|
||||||
"test:tools:scripts-build": "cd ./tools/scripts/build && pnpm test run",
|
"test:tools:scripts-build": "cd ./tools/scripts/build && pnpm test run",
|
||||||
"test:tools:challenge-parser": "cd ./tools/challenge-parser && pnpm test run",
|
"test:tools:challenge-parser": "cd ./tools/challenge-parser && pnpm test run",
|
||||||
"test:curriculum:content": "cd ./curriculum && pnpm test",
|
"test:curriculum:content": "cd ./curriculum && pnpm test run",
|
||||||
"test:curriculum:tooling": "cd ./curriculum && pnpm vitest run",
|
"test:curriculum:tooling": "cd ./curriculum && pnpm vitest run",
|
||||||
"test-curriculum-full-output": "cd ./curriculum && pnpm run test:full-output",
|
"test-curriculum-full-output": "cd ./curriculum && pnpm run test:full-output run",
|
||||||
"test:client": "cd ./client && pnpm test run",
|
"test:client": "cd ./client && pnpm test run",
|
||||||
"test-config": "jest config",
|
"test-config": "jest config",
|
||||||
"test-tools": "jest tools",
|
"test-tools": "jest tools",
|
||||||
|
|||||||
Generated
+63
-307
@@ -715,9 +715,9 @@ importers:
|
|||||||
'@babel/register':
|
'@babel/register':
|
||||||
specifier: 7.23.7
|
specifier: 7.23.7
|
||||||
version: 7.23.7(@babel/core@7.23.7)
|
version: 7.23.7(@babel/core@7.23.7)
|
||||||
'@compodoc/live-server':
|
'@types/polka':
|
||||||
specifier: ^1.2.3
|
specifier: ^0.5.7
|
||||||
version: 1.2.3
|
version: 0.5.7
|
||||||
'@vitest/ui':
|
'@vitest/ui':
|
||||||
specifier: ^3.2.4
|
specifier: ^3.2.4
|
||||||
version: 3.2.4(vitest@3.2.4)
|
version: 3.2.4(vitest@3.2.4)
|
||||||
@@ -754,12 +754,18 @@ importers:
|
|||||||
ora:
|
ora:
|
||||||
specifier: 5.4.1
|
specifier: 5.4.1
|
||||||
version: 5.4.1
|
version: 5.4.1
|
||||||
|
polka:
|
||||||
|
specifier: ^0.5.2
|
||||||
|
version: 0.5.2
|
||||||
puppeteer:
|
puppeteer:
|
||||||
specifier: 22.12.1
|
specifier: 22.12.1
|
||||||
version: 22.12.1(typescript@5.8.2)
|
version: 22.12.1(typescript@5.8.2)
|
||||||
readdirp:
|
readdirp:
|
||||||
specifier: 3.6.0
|
specifier: 3.6.0
|
||||||
version: 3.6.0
|
version: 3.6.0
|
||||||
|
sirv:
|
||||||
|
specifier: ^3.0.2
|
||||||
|
version: 3.0.2
|
||||||
string-similarity:
|
string-similarity:
|
||||||
specifier: 4.0.4
|
specifier: 4.0.4
|
||||||
version: 4.0.4
|
version: 4.0.4
|
||||||
@@ -1171,6 +1177,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-vyrkEHG1jrukmzTPtyWB4NLPauUw5bQeg4uhn8f+1SSynmrOcyvlb1GKQjjgoBzElLdfXCRYX8UnBlhklOHYRQ==}
|
resolution: {integrity: sha512-vyrkEHG1jrukmzTPtyWB4NLPauUw5bQeg4uhn8f+1SSynmrOcyvlb1GKQjjgoBzElLdfXCRYX8UnBlhklOHYRQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
'@arr/every@1.0.1':
|
||||||
|
resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
'@asamuzakjp/css-color@3.2.0':
|
'@asamuzakjp/css-color@3.2.0':
|
||||||
resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==}
|
resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==}
|
||||||
|
|
||||||
@@ -2280,11 +2290,6 @@ packages:
|
|||||||
'@bundled-es-modules/tough-cookie@0.1.6':
|
'@bundled-es-modules/tough-cookie@0.1.6':
|
||||||
resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==}
|
resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==}
|
||||||
|
|
||||||
'@compodoc/live-server@1.2.3':
|
|
||||||
resolution: {integrity: sha512-hDmntVCyjjaxuJzPzBx68orNZ7TW4BtHWMnXlIVn5dqhK7vuFF/11hspO1cMmc+2QTYgqde1TBcb3127S7Zrow==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
'@cspotcode/source-map-support@0.8.1':
|
'@cspotcode/source-map-support@0.8.1':
|
||||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -3640,8 +3645,8 @@ packages:
|
|||||||
webpack-plugin-serve:
|
webpack-plugin-serve:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@polka/url@1.0.0-next.23':
|
'@polka/url@0.5.0':
|
||||||
resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==}
|
resolution: {integrity: sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==}
|
||||||
|
|
||||||
'@polka/url@1.0.0-next.29':
|
'@polka/url@1.0.0-next.29':
|
||||||
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||||
@@ -4705,6 +4710,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==}
|
resolution: {integrity: sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==}
|
||||||
deprecated: This is a stub types definition. pino provides its own type definitions, so you do not need this installed.
|
deprecated: This is a stub types definition. pino provides its own type definitions, so you do not need this installed.
|
||||||
|
|
||||||
|
'@types/polka@0.5.7':
|
||||||
|
resolution: {integrity: sha512-TH8CDXM8zoskPCNmWabtK7ziGv9Q21s4hMZLVYK5HFEfqmGXBqq/Wgi7jNELWXftZK/1J/9CezYa06x1RKeQ+g==}
|
||||||
|
|
||||||
'@types/prismjs@1.26.5':
|
'@types/prismjs@1.26.5':
|
||||||
resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==}
|
resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==}
|
||||||
|
|
||||||
@@ -4824,6 +4832,9 @@ packages:
|
|||||||
'@types/tough-cookie@4.0.5':
|
'@types/tough-cookie@4.0.5':
|
||||||
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
|
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
|
||||||
|
|
||||||
|
'@types/trouter@3.1.4':
|
||||||
|
resolution: {integrity: sha512-4YIL/2AvvZqKBWenjvEpxpblT2KGO6793ipr5QS7/6DpQ3O3SwZGgNGWezxf3pzeYZc24a2pJIrR/+Jxh/wYNQ==}
|
||||||
|
|
||||||
'@types/unist@2.0.8':
|
'@types/unist@2.0.8':
|
||||||
resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==}
|
resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==}
|
||||||
|
|
||||||
@@ -5495,14 +5506,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
apache-crypt@1.2.6:
|
|
||||||
resolution: {integrity: sha512-072WetlM4blL8PREJVeY+WHiUh1R5VNt2HfceGS8aKqttPHcmqE5pkKuXPz/ULmJOFkc8Hw3kfKl6vy7Qka6DA==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
|
|
||||||
apache-md5@1.1.8:
|
|
||||||
resolution: {integrity: sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
|
|
||||||
append-field@1.0.0:
|
append-field@1.0.0:
|
||||||
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
|
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
|
||||||
|
|
||||||
@@ -5917,12 +5920,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==}
|
resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
|
|
||||||
batch@0.6.1:
|
|
||||||
resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==}
|
|
||||||
|
|
||||||
bcryptjs@2.4.3:
|
|
||||||
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
|
|
||||||
|
|
||||||
better-opn@2.1.1:
|
better-opn@2.1.1:
|
||||||
resolution: {integrity: sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==}
|
resolution: {integrity: sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==}
|
||||||
engines: {node: '>8.0.0'}
|
engines: {node: '>8.0.0'}
|
||||||
@@ -6406,10 +6403,6 @@ packages:
|
|||||||
colorette@2.0.20:
|
colorette@2.0.20:
|
||||||
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
||||||
|
|
||||||
colors@1.4.0:
|
|
||||||
resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==}
|
|
||||||
engines: {node: '>=0.1.90'}
|
|
||||||
|
|
||||||
combine-source-map@0.8.0:
|
combine-source-map@0.8.0:
|
||||||
resolution: {integrity: sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==}
|
resolution: {integrity: sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==}
|
||||||
|
|
||||||
@@ -6478,10 +6471,6 @@ packages:
|
|||||||
confusing-browser-globals@1.0.11:
|
confusing-browser-globals@1.0.11:
|
||||||
resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
|
resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
|
||||||
|
|
||||||
connect@3.7.0:
|
|
||||||
resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==}
|
|
||||||
engines: {node: '>= 0.10.0'}
|
|
||||||
|
|
||||||
console-browserify@1.2.0:
|
console-browserify@1.2.0:
|
||||||
resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==}
|
resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==}
|
||||||
|
|
||||||
@@ -6916,10 +6905,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
define-lazy-prop@2.0.0:
|
|
||||||
resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
|
|
||||||
define-properties@1.2.1:
|
define-properties@1.2.1:
|
||||||
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -7190,10 +7175,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
|
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
encodeurl@2.0.0:
|
|
||||||
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
|
|
||||||
engines: {node: '>= 0.8'}
|
|
||||||
|
|
||||||
end-of-stream@1.4.4:
|
end-of-stream@1.4.4:
|
||||||
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
|
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
|
||||||
|
|
||||||
@@ -7668,9 +7649,6 @@ packages:
|
|||||||
event-source-polyfill@1.0.31:
|
event-source-polyfill@1.0.31:
|
||||||
resolution: {integrity: sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==}
|
resolution: {integrity: sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==}
|
||||||
|
|
||||||
event-stream@4.0.1:
|
|
||||||
resolution: {integrity: sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==}
|
|
||||||
|
|
||||||
event-target-shim@5.0.1:
|
event-target-shim@5.0.1:
|
||||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -7851,10 +7829,6 @@ packages:
|
|||||||
fault@1.0.4:
|
fault@1.0.4:
|
||||||
resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==}
|
resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==}
|
||||||
|
|
||||||
faye-websocket@0.11.4:
|
|
||||||
resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==}
|
|
||||||
engines: {node: '>=0.8.0'}
|
|
||||||
|
|
||||||
fb-watchman@2.0.2:
|
fb-watchman@2.0.2:
|
||||||
resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
|
resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
|
||||||
|
|
||||||
@@ -7921,10 +7895,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-TL48Pi1oNHeMOHrKv1bCJUrWZDcD3DIG6AGYVNOnyZPr7Bd/pStN0pL+lfzF5BNoj/FclaoiaLenk4XUIFVYng==}
|
resolution: {integrity: sha512-TL48Pi1oNHeMOHrKv1bCJUrWZDcD3DIG6AGYVNOnyZPr7Bd/pStN0pL+lfzF5BNoj/FclaoiaLenk4XUIFVYng==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
finalhandler@1.1.2:
|
|
||||||
resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
|
|
||||||
engines: {node: '>= 0.8'}
|
|
||||||
|
|
||||||
finalhandler@1.2.0:
|
finalhandler@1.2.0:
|
||||||
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
|
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
@@ -8068,13 +8038,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
|
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
fresh@2.0.0:
|
|
||||||
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
|
|
||||||
engines: {node: '>= 0.8'}
|
|
||||||
|
|
||||||
from@0.1.7:
|
|
||||||
resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==}
|
|
||||||
|
|
||||||
fs-constants@1.0.0:
|
fs-constants@1.0.0:
|
||||||
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
||||||
|
|
||||||
@@ -8715,21 +8678,9 @@ packages:
|
|||||||
htmlparser2@8.0.2:
|
htmlparser2@8.0.2:
|
||||||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||||
|
|
||||||
http-auth-connect@1.0.6:
|
|
||||||
resolution: {integrity: sha512-yaO0QSCPqGCjPrl3qEEHjJP+lwZ6gMpXLuCBE06eWwcXomkI5TARtu0kxf9teFuBj6iaV3Ybr15jaWUvbzNzHw==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
|
|
||||||
http-auth@4.1.9:
|
|
||||||
resolution: {integrity: sha512-kvPYxNGc9EKGTXvOMnTBQw2RZfuiSihK/mLw/a4pbtRueTE45S55Lw/3k5CktIf7Ak0veMKEIteDj4YkNmCzmQ==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
|
|
||||||
http-cache-semantics@4.1.1:
|
http-cache-semantics@4.1.1:
|
||||||
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
|
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
|
||||||
|
|
||||||
http-errors@1.6.3:
|
|
||||||
resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==}
|
|
||||||
engines: {node: '>= 0.6'}
|
|
||||||
|
|
||||||
http-errors@1.8.0:
|
http-errors@1.8.0:
|
||||||
resolution: {integrity: sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==}
|
resolution: {integrity: sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -8738,9 +8689,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
|
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
http-parser-js@0.5.8:
|
|
||||||
resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==}
|
|
||||||
|
|
||||||
http-proxy-agent@4.0.1:
|
http-proxy-agent@4.0.1:
|
||||||
resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
|
resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@@ -10076,9 +10024,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
|
resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
map-stream@0.0.7:
|
|
||||||
resolution: {integrity: sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==}
|
|
||||||
|
|
||||||
map-visit@1.0.0:
|
map-visit@1.0.0:
|
||||||
resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
|
resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -10101,6 +10046,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==}
|
resolution: {integrity: sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
matchit@1.1.0:
|
||||||
|
resolution: {integrity: sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
matchmediaquery@0.3.1:
|
matchmediaquery@0.3.1:
|
||||||
resolution: {integrity: sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==}
|
resolution: {integrity: sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==}
|
||||||
|
|
||||||
@@ -10483,10 +10432,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
mime-types@3.0.1:
|
|
||||||
resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==}
|
|
||||||
engines: {node: '>= 0.6'}
|
|
||||||
|
|
||||||
mime@1.6.0:
|
mime@1.6.0:
|
||||||
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
|
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -10647,10 +10592,6 @@ packages:
|
|||||||
socks:
|
socks:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
morgan@1.10.0:
|
|
||||||
resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==}
|
|
||||||
engines: {node: '>= 0.8.0'}
|
|
||||||
|
|
||||||
mri@1.2.0:
|
mri@1.2.0:
|
||||||
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -10951,10 +10892,6 @@ packages:
|
|||||||
on-exit-leak-free@2.1.0:
|
on-exit-leak-free@2.1.0:
|
||||||
resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==}
|
resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==}
|
||||||
|
|
||||||
on-finished@2.3.0:
|
|
||||||
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
|
|
||||||
engines: {node: '>= 0.8'}
|
|
||||||
|
|
||||||
on-finished@2.4.1:
|
on-finished@2.4.1:
|
||||||
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
|
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
@@ -10978,10 +10915,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
|
resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
open@8.4.0:
|
|
||||||
resolution: {integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
openapi-types@12.1.3:
|
openapi-types@12.1.3:
|
||||||
resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==}
|
resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==}
|
||||||
|
|
||||||
@@ -11231,9 +11164,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
|
resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
|
||||||
engines: {node: '>= 14.16'}
|
engines: {node: '>= 14.16'}
|
||||||
|
|
||||||
pause-stream@0.0.11:
|
|
||||||
resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==}
|
|
||||||
|
|
||||||
pbkdf2@3.1.2:
|
pbkdf2@3.1.2:
|
||||||
resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==}
|
resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==}
|
||||||
engines: {node: '>=0.12'}
|
engines: {node: '>=0.12'}
|
||||||
@@ -11340,6 +11270,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
polka@0.5.2:
|
||||||
|
resolution: {integrity: sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==}
|
||||||
|
|
||||||
portfinder@1.0.37:
|
portfinder@1.0.37:
|
||||||
resolution: {integrity: sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==}
|
resolution: {integrity: sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==}
|
||||||
engines: {node: '>= 10.12'}
|
engines: {node: '>= 10.12'}
|
||||||
@@ -11725,10 +11658,6 @@ packages:
|
|||||||
proxy-from-env@1.1.0:
|
proxy-from-env@1.1.0:
|
||||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||||
|
|
||||||
proxy-middleware@0.15.0:
|
|
||||||
resolution: {integrity: sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==}
|
|
||||||
engines: {node: '>=0.8.0'}
|
|
||||||
|
|
||||||
pseudomap@1.0.2:
|
pseudomap@1.0.2:
|
||||||
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
|
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
|
||||||
|
|
||||||
@@ -12552,10 +12481,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
|
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
send@1.2.0:
|
|
||||||
resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==}
|
|
||||||
engines: {node: '>= 18'}
|
|
||||||
|
|
||||||
serialize-javascript@5.0.1:
|
serialize-javascript@5.0.1:
|
||||||
resolution: {integrity: sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==}
|
resolution: {integrity: sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==}
|
||||||
|
|
||||||
@@ -12568,10 +12493,6 @@ packages:
|
|||||||
serve-handler@6.1.3:
|
serve-handler@6.1.3:
|
||||||
resolution: {integrity: sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==}
|
resolution: {integrity: sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==}
|
||||||
|
|
||||||
serve-index@1.9.1:
|
|
||||||
resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==}
|
|
||||||
engines: {node: '>= 0.8.0'}
|
|
||||||
|
|
||||||
serve-static@1.15.0:
|
serve-static@1.15.0:
|
||||||
resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
|
resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@@ -12610,9 +12531,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
|
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
setprototypeof@1.1.0:
|
|
||||||
resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==}
|
|
||||||
|
|
||||||
setprototypeof@1.2.0:
|
setprototypeof@1.2.0:
|
||||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||||
|
|
||||||
@@ -12720,8 +12638,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==}
|
resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
sirv@3.0.1:
|
sirv@3.0.2:
|
||||||
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
|
resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
sister@3.0.2:
|
sister@3.0.2:
|
||||||
@@ -12873,9 +12791,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||||
engines: {node: '>= 10.x'}
|
engines: {node: '>= 10.x'}
|
||||||
|
|
||||||
split@1.0.1:
|
|
||||||
resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==}
|
|
||||||
|
|
||||||
sprintf-js@1.0.3:
|
sprintf-js@1.0.3:
|
||||||
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
||||||
|
|
||||||
@@ -12940,9 +12855,6 @@ packages:
|
|||||||
stream-combiner2@1.1.1:
|
stream-combiner2@1.1.1:
|
||||||
resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==}
|
resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==}
|
||||||
|
|
||||||
stream-combiner@0.2.2:
|
|
||||||
resolution: {integrity: sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==}
|
|
||||||
|
|
||||||
stream-http@3.2.0:
|
stream-http@3.2.0:
|
||||||
resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==}
|
resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==}
|
||||||
|
|
||||||
@@ -13449,6 +13361,10 @@ packages:
|
|||||||
trough@1.0.5:
|
trough@1.0.5:
|
||||||
resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==}
|
resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==}
|
||||||
|
|
||||||
|
trouter@2.0.1:
|
||||||
|
resolution: {integrity: sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
true-case-path@2.2.1:
|
true-case-path@2.2.1:
|
||||||
resolution: {integrity: sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==}
|
resolution: {integrity: sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==}
|
||||||
|
|
||||||
@@ -13813,9 +13729,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
|
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
|
|
||||||
unix-crypt-td-js@1.1.4:
|
|
||||||
resolution: {integrity: sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==}
|
|
||||||
|
|
||||||
unixify@1.0.0:
|
unixify@1.0.0:
|
||||||
resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==}
|
resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -14202,14 +14115,6 @@ packages:
|
|||||||
webpack-cli:
|
webpack-cli:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
websocket-driver@0.7.4:
|
|
||||||
resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}
|
|
||||||
engines: {node: '>=0.8.0'}
|
|
||||||
|
|
||||||
websocket-extensions@0.1.4:
|
|
||||||
resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==}
|
|
||||||
engines: {node: '>=0.8.0'}
|
|
||||||
|
|
||||||
whatwg-encoding@1.0.5:
|
whatwg-encoding@1.0.5:
|
||||||
resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==}
|
resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==}
|
||||||
|
|
||||||
@@ -14642,6 +14547,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.0.3
|
tslib: 2.0.3
|
||||||
|
|
||||||
|
'@arr/every@1.0.1': {}
|
||||||
|
|
||||||
'@asamuzakjp/css-color@3.2.0':
|
'@asamuzakjp/css-color@3.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)
|
'@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)
|
||||||
@@ -17029,25 +16936,6 @@ snapshots:
|
|||||||
'@types/tough-cookie': 4.0.5
|
'@types/tough-cookie': 4.0.5
|
||||||
tough-cookie: 4.1.4
|
tough-cookie: 4.1.4
|
||||||
|
|
||||||
'@compodoc/live-server@1.2.3':
|
|
||||||
dependencies:
|
|
||||||
chokidar: 3.6.0
|
|
||||||
colors: 1.4.0
|
|
||||||
connect: 3.7.0
|
|
||||||
cors: 2.8.5
|
|
||||||
event-stream: 4.0.1
|
|
||||||
faye-websocket: 0.11.4
|
|
||||||
http-auth: 4.1.9
|
|
||||||
http-auth-connect: 1.0.6
|
|
||||||
morgan: 1.10.0
|
|
||||||
object-assign: 4.1.1
|
|
||||||
open: 8.4.0
|
|
||||||
proxy-middleware: 0.15.0
|
|
||||||
send: 1.2.0
|
|
||||||
serve-index: 1.9.1
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
'@cspotcode/source-map-support@0.8.1':
|
'@cspotcode/source-map-support@0.8.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/trace-mapping': 0.3.9
|
'@jridgewell/trace-mapping': 0.3.9
|
||||||
@@ -18492,7 +18380,7 @@ snapshots:
|
|||||||
source-map: 0.7.4
|
source-map: 0.7.4
|
||||||
webpack: 5.90.3(webpack-cli@4.10.0)
|
webpack: 5.90.3(webpack-cli@4.10.0)
|
||||||
|
|
||||||
'@polka/url@1.0.0-next.23': {}
|
'@polka/url@0.5.0': {}
|
||||||
|
|
||||||
'@polka/url@1.0.0-next.29': {}
|
'@polka/url@1.0.0-next.29': {}
|
||||||
|
|
||||||
@@ -19832,6 +19720,13 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
pino: 9.7.0
|
pino: 9.7.0
|
||||||
|
|
||||||
|
'@types/polka@0.5.7':
|
||||||
|
dependencies:
|
||||||
|
'@types/express': 4.17.21
|
||||||
|
'@types/express-serve-static-core': 4.17.37
|
||||||
|
'@types/node': 20.12.8
|
||||||
|
'@types/trouter': 3.1.4
|
||||||
|
|
||||||
'@types/prismjs@1.26.5': {}
|
'@types/prismjs@1.26.5': {}
|
||||||
|
|
||||||
'@types/prop-types@15.7.8': {}
|
'@types/prop-types@15.7.8': {}
|
||||||
@@ -19970,6 +19865,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/tough-cookie@4.0.5': {}
|
'@types/tough-cookie@4.0.5': {}
|
||||||
|
|
||||||
|
'@types/trouter@3.1.4': {}
|
||||||
|
|
||||||
'@types/unist@2.0.8': {}
|
'@types/unist@2.0.8': {}
|
||||||
|
|
||||||
'@types/unist@3.0.0': {}
|
'@types/unist@3.0.0': {}
|
||||||
@@ -20493,7 +20390,7 @@ snapshots:
|
|||||||
fflate: 0.8.2
|
fflate: 0.8.2
|
||||||
flatted: 3.3.3
|
flatted: 3.3.3
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
sirv: 3.0.1
|
sirv: 3.0.2
|
||||||
tinyglobby: 0.2.14
|
tinyglobby: 0.2.14
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vitest: 3.2.4(@types/node@20.12.8)(@vitest/ui@3.2.4)(jsdom@26.1.0)(msw@2.8.7(@types/node@20.12.8)(typescript@5.8.2))(terser@5.28.1)(tsx@4.19.1)(yaml@2.8.0)
|
vitest: 3.2.4(@types/node@20.12.8)(@vitest/ui@3.2.4)(jsdom@26.1.0)(msw@2.8.7(@types/node@20.12.8)(typescript@5.8.2))(terser@5.28.1)(tsx@4.19.1)(yaml@2.8.0)
|
||||||
@@ -20783,12 +20680,6 @@ snapshots:
|
|||||||
normalize-path: 3.0.0
|
normalize-path: 3.0.0
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
apache-crypt@1.2.6:
|
|
||||||
dependencies:
|
|
||||||
unix-crypt-td-js: 1.1.4
|
|
||||||
|
|
||||||
apache-md5@1.1.8: {}
|
|
||||||
|
|
||||||
append-field@1.0.0: {}
|
append-field@1.0.0: {}
|
||||||
|
|
||||||
application-config-path@0.1.1: {}
|
application-config-path@0.1.1: {}
|
||||||
@@ -21369,10 +21260,6 @@ snapshots:
|
|||||||
|
|
||||||
basic-ftp@5.0.5: {}
|
basic-ftp@5.0.5: {}
|
||||||
|
|
||||||
batch@0.6.1: {}
|
|
||||||
|
|
||||||
bcryptjs@2.4.3: {}
|
|
||||||
|
|
||||||
better-opn@2.1.1:
|
better-opn@2.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
open: 7.4.2
|
open: 7.4.2
|
||||||
@@ -22017,8 +21904,6 @@ snapshots:
|
|||||||
|
|
||||||
colorette@2.0.20: {}
|
colorette@2.0.20: {}
|
||||||
|
|
||||||
colors@1.4.0: {}
|
|
||||||
|
|
||||||
combine-source-map@0.8.0:
|
combine-source-map@0.8.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
convert-source-map: 1.1.3
|
convert-source-map: 1.1.3
|
||||||
@@ -22098,15 +21983,6 @@ snapshots:
|
|||||||
|
|
||||||
confusing-browser-globals@1.0.11: {}
|
confusing-browser-globals@1.0.11: {}
|
||||||
|
|
||||||
connect@3.7.0:
|
|
||||||
dependencies:
|
|
||||||
debug: 2.6.9
|
|
||||||
finalhandler: 1.1.2
|
|
||||||
parseurl: 1.3.3
|
|
||||||
utils-merge: 1.0.1
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
console-browserify@1.2.0: {}
|
console-browserify@1.2.0: {}
|
||||||
|
|
||||||
constants-browserify@1.0.0: {}
|
constants-browserify@1.0.0: {}
|
||||||
@@ -22620,8 +22496,6 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
gopd: 1.0.1
|
gopd: 1.0.1
|
||||||
|
|
||||||
define-lazy-prop@2.0.0: {}
|
|
||||||
|
|
||||||
define-properties@1.2.1:
|
define-properties@1.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
define-data-property: 1.1.4
|
define-data-property: 1.1.4
|
||||||
@@ -22915,8 +22789,6 @@ snapshots:
|
|||||||
|
|
||||||
encodeurl@1.0.2: {}
|
encodeurl@1.0.2: {}
|
||||||
|
|
||||||
encodeurl@2.0.0: {}
|
|
||||||
|
|
||||||
end-of-stream@1.4.4:
|
end-of-stream@1.4.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
@@ -23756,16 +23628,6 @@ snapshots:
|
|||||||
|
|
||||||
event-source-polyfill@1.0.31: {}
|
event-source-polyfill@1.0.31: {}
|
||||||
|
|
||||||
event-stream@4.0.1:
|
|
||||||
dependencies:
|
|
||||||
duplexer: 0.1.2
|
|
||||||
from: 0.1.7
|
|
||||||
map-stream: 0.0.7
|
|
||||||
pause-stream: 0.0.11
|
|
||||||
split: 1.0.1
|
|
||||||
stream-combiner: 0.2.2
|
|
||||||
through: 2.3.8
|
|
||||||
|
|
||||||
event-target-shim@5.0.1: {}
|
event-target-shim@5.0.1: {}
|
||||||
|
|
||||||
eventemitter3@3.1.2: {}
|
eventemitter3@3.1.2: {}
|
||||||
@@ -24038,10 +23900,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
format: 0.2.2
|
format: 0.2.2
|
||||||
|
|
||||||
faye-websocket@0.11.4:
|
|
||||||
dependencies:
|
|
||||||
websocket-driver: 0.7.4
|
|
||||||
|
|
||||||
fb-watchman@2.0.2:
|
fb-watchman@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
bser: 2.1.1
|
bser: 2.1.1
|
||||||
@@ -24105,18 +23963,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.23.9
|
'@babel/runtime': 7.23.9
|
||||||
|
|
||||||
finalhandler@1.1.2:
|
|
||||||
dependencies:
|
|
||||||
debug: 2.6.9
|
|
||||||
encodeurl: 1.0.2
|
|
||||||
escape-html: 1.0.3
|
|
||||||
on-finished: 2.3.0
|
|
||||||
parseurl: 1.3.3
|
|
||||||
statuses: 1.5.0
|
|
||||||
unpipe: 1.0.0
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
finalhandler@1.2.0:
|
finalhandler@1.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 2.6.9
|
debug: 2.6.9
|
||||||
@@ -24280,10 +24126,6 @@ snapshots:
|
|||||||
|
|
||||||
fresh@0.5.2: {}
|
fresh@0.5.2: {}
|
||||||
|
|
||||||
fresh@2.0.0: {}
|
|
||||||
|
|
||||||
from@0.1.7: {}
|
|
||||||
|
|
||||||
fs-constants@1.0.0: {}
|
fs-constants@1.0.0: {}
|
||||||
|
|
||||||
fs-exists-cached@1.0.0: {}
|
fs-exists-cached@1.0.0: {}
|
||||||
@@ -25431,24 +25273,8 @@ snapshots:
|
|||||||
domutils: 3.1.0
|
domutils: 3.1.0
|
||||||
entities: 4.5.0
|
entities: 4.5.0
|
||||||
|
|
||||||
http-auth-connect@1.0.6: {}
|
|
||||||
|
|
||||||
http-auth@4.1.9:
|
|
||||||
dependencies:
|
|
||||||
apache-crypt: 1.2.6
|
|
||||||
apache-md5: 1.1.8
|
|
||||||
bcryptjs: 2.4.3
|
|
||||||
uuid: 8.3.2
|
|
||||||
|
|
||||||
http-cache-semantics@4.1.1: {}
|
http-cache-semantics@4.1.1: {}
|
||||||
|
|
||||||
http-errors@1.6.3:
|
|
||||||
dependencies:
|
|
||||||
depd: 1.1.2
|
|
||||||
inherits: 2.0.3
|
|
||||||
setprototypeof: 1.1.0
|
|
||||||
statuses: 1.5.0
|
|
||||||
|
|
||||||
http-errors@1.8.0:
|
http-errors@1.8.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
depd: 1.1.2
|
depd: 1.1.2
|
||||||
@@ -25465,8 +25291,6 @@ snapshots:
|
|||||||
statuses: 2.0.1
|
statuses: 2.0.1
|
||||||
toidentifier: 1.0.1
|
toidentifier: 1.0.1
|
||||||
|
|
||||||
http-parser-js@0.5.8: {}
|
|
||||||
|
|
||||||
http-proxy-agent@4.0.1:
|
http-proxy-agent@4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tootallnate/once': 1.1.2
|
'@tootallnate/once': 1.1.2
|
||||||
@@ -27148,8 +26972,6 @@ snapshots:
|
|||||||
|
|
||||||
map-cache@0.2.2: {}
|
map-cache@0.2.2: {}
|
||||||
|
|
||||||
map-stream@0.0.7: {}
|
|
||||||
|
|
||||||
map-visit@1.0.0:
|
map-visit@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
object-visit: 1.0.1
|
object-visit: 1.0.1
|
||||||
@@ -27176,6 +26998,10 @@ snapshots:
|
|||||||
markdown-it: 14.0.0
|
markdown-it: 14.0.0
|
||||||
markdownlint-micromark: 0.1.8
|
markdownlint-micromark: 0.1.8
|
||||||
|
|
||||||
|
matchit@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
'@arr/every': 1.0.1
|
||||||
|
|
||||||
matchmediaquery@0.3.1:
|
matchmediaquery@0.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
css-mediaquery: 0.1.2
|
css-mediaquery: 0.1.2
|
||||||
@@ -27902,10 +27728,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
mime-db: 1.52.0
|
mime-db: 1.52.0
|
||||||
|
|
||||||
mime-types@3.0.1:
|
|
||||||
dependencies:
|
|
||||||
mime-db: 1.54.0
|
|
||||||
|
|
||||||
mime@1.6.0: {}
|
mime@1.6.0: {}
|
||||||
|
|
||||||
mime@2.6.0: {}
|
mime@2.6.0: {}
|
||||||
@@ -28052,16 +27874,6 @@ snapshots:
|
|||||||
'@aws-sdk/credential-providers': 3.521.0
|
'@aws-sdk/credential-providers': 3.521.0
|
||||||
socks: 2.8.3
|
socks: 2.8.3
|
||||||
|
|
||||||
morgan@1.10.0:
|
|
||||||
dependencies:
|
|
||||||
basic-auth: 2.0.1
|
|
||||||
debug: 2.6.9
|
|
||||||
depd: 2.0.0
|
|
||||||
on-finished: 2.3.0
|
|
||||||
on-headers: 1.0.2
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
mri@1.2.0: {}
|
mri@1.2.0: {}
|
||||||
|
|
||||||
mrmime@1.0.1: {}
|
mrmime@1.0.1: {}
|
||||||
@@ -28426,10 +28238,6 @@ snapshots:
|
|||||||
|
|
||||||
on-exit-leak-free@2.1.0: {}
|
on-exit-leak-free@2.1.0: {}
|
||||||
|
|
||||||
on-finished@2.3.0:
|
|
||||||
dependencies:
|
|
||||||
ee-first: 1.1.1
|
|
||||||
|
|
||||||
on-finished@2.4.1:
|
on-finished@2.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
ee-first: 1.1.1
|
ee-first: 1.1.1
|
||||||
@@ -28453,12 +28261,6 @@ snapshots:
|
|||||||
is-docker: 2.2.1
|
is-docker: 2.2.1
|
||||||
is-wsl: 2.2.0
|
is-wsl: 2.2.0
|
||||||
|
|
||||||
open@8.4.0:
|
|
||||||
dependencies:
|
|
||||||
define-lazy-prop: 2.0.0
|
|
||||||
is-docker: 2.2.1
|
|
||||||
is-wsl: 2.2.0
|
|
||||||
|
|
||||||
openapi-types@12.1.3: {}
|
openapi-types@12.1.3: {}
|
||||||
|
|
||||||
opener@1.5.2: {}
|
opener@1.5.2: {}
|
||||||
@@ -28732,10 +28534,6 @@ snapshots:
|
|||||||
|
|
||||||
pathval@2.0.1: {}
|
pathval@2.0.1: {}
|
||||||
|
|
||||||
pause-stream@0.0.11:
|
|
||||||
dependencies:
|
|
||||||
through: 2.3.8
|
|
||||||
|
|
||||||
pbkdf2@3.1.2:
|
pbkdf2@3.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
create-hash: 1.2.0
|
create-hash: 1.2.0
|
||||||
@@ -28846,6 +28644,11 @@ snapshots:
|
|||||||
|
|
||||||
pluralize@8.0.0: {}
|
pluralize@8.0.0: {}
|
||||||
|
|
||||||
|
polka@0.5.2:
|
||||||
|
dependencies:
|
||||||
|
'@polka/url': 0.5.0
|
||||||
|
trouter: 2.0.1
|
||||||
|
|
||||||
portfinder@1.0.37:
|
portfinder@1.0.37:
|
||||||
dependencies:
|
dependencies:
|
||||||
async: 3.2.6
|
async: 3.2.6
|
||||||
@@ -29238,8 +29041,6 @@ snapshots:
|
|||||||
|
|
||||||
proxy-from-env@1.1.0: {}
|
proxy-from-env@1.1.0: {}
|
||||||
|
|
||||||
proxy-middleware@0.15.0: {}
|
|
||||||
|
|
||||||
pseudomap@1.0.2: {}
|
pseudomap@1.0.2: {}
|
||||||
|
|
||||||
psl@1.9.0: {}
|
psl@1.9.0: {}
|
||||||
@@ -30299,22 +30100,6 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
send@1.2.0:
|
|
||||||
dependencies:
|
|
||||||
debug: 4.4.1
|
|
||||||
encodeurl: 2.0.0
|
|
||||||
escape-html: 1.0.3
|
|
||||||
etag: 1.8.1
|
|
||||||
fresh: 2.0.0
|
|
||||||
http-errors: 2.0.0
|
|
||||||
mime-types: 3.0.1
|
|
||||||
ms: 2.1.3
|
|
||||||
on-finished: 2.4.1
|
|
||||||
range-parser: 1.2.1
|
|
||||||
statuses: 2.0.1
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
serialize-javascript@5.0.1:
|
serialize-javascript@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
randombytes: 2.1.0
|
randombytes: 2.1.0
|
||||||
@@ -30338,18 +30123,6 @@ snapshots:
|
|||||||
path-to-regexp: 2.2.1
|
path-to-regexp: 2.2.1
|
||||||
range-parser: 1.2.0
|
range-parser: 1.2.0
|
||||||
|
|
||||||
serve-index@1.9.1:
|
|
||||||
dependencies:
|
|
||||||
accepts: 1.3.8
|
|
||||||
batch: 0.6.1
|
|
||||||
debug: 2.6.9
|
|
||||||
escape-html: 1.0.3
|
|
||||||
http-errors: 1.6.3
|
|
||||||
mime-types: 2.1.35
|
|
||||||
parseurl: 1.3.3
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
serve-static@1.15.0:
|
serve-static@1.15.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
encodeurl: 1.0.2
|
encodeurl: 1.0.2
|
||||||
@@ -30421,8 +30194,6 @@ snapshots:
|
|||||||
is-plain-object: 2.0.4
|
is-plain-object: 2.0.4
|
||||||
split-string: 3.1.0
|
split-string: 3.1.0
|
||||||
|
|
||||||
setprototypeof@1.1.0: {}
|
|
||||||
|
|
||||||
setprototypeof@1.2.0: {}
|
setprototypeof@1.2.0: {}
|
||||||
|
|
||||||
sha.js@2.4.11:
|
sha.js@2.4.11:
|
||||||
@@ -30549,11 +30320,11 @@ snapshots:
|
|||||||
|
|
||||||
sirv@2.0.3:
|
sirv@2.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@polka/url': 1.0.0-next.23
|
'@polka/url': 1.0.0-next.29
|
||||||
mrmime: 1.0.1
|
mrmime: 1.0.1
|
||||||
totalist: 3.0.1
|
totalist: 3.0.1
|
||||||
|
|
||||||
sirv@3.0.1:
|
sirv@3.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@polka/url': 1.0.0-next.29
|
'@polka/url': 1.0.0-next.29
|
||||||
mrmime: 2.0.1
|
mrmime: 2.0.1
|
||||||
@@ -30744,10 +30515,6 @@ snapshots:
|
|||||||
|
|
||||||
split2@4.2.0: {}
|
split2@4.2.0: {}
|
||||||
|
|
||||||
split@1.0.1:
|
|
||||||
dependencies:
|
|
||||||
through: 2.3.8
|
|
||||||
|
|
||||||
sprintf-js@1.0.3: {}
|
sprintf-js@1.0.3: {}
|
||||||
|
|
||||||
sprintf-js@1.1.3: {}
|
sprintf-js@1.1.3: {}
|
||||||
@@ -30811,11 +30578,6 @@ snapshots:
|
|||||||
duplexer2: 0.1.4
|
duplexer2: 0.1.4
|
||||||
readable-stream: 2.3.8
|
readable-stream: 2.3.8
|
||||||
|
|
||||||
stream-combiner@0.2.2:
|
|
||||||
dependencies:
|
|
||||||
duplexer: 0.1.2
|
|
||||||
through: 2.3.8
|
|
||||||
|
|
||||||
stream-http@3.2.0:
|
stream-http@3.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
builtin-status-codes: 3.0.0
|
builtin-status-codes: 3.0.0
|
||||||
@@ -31409,7 +31171,7 @@ snapshots:
|
|||||||
tough-cookie@4.1.4:
|
tough-cookie@4.1.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
psl: 1.9.0
|
psl: 1.9.0
|
||||||
punycode: 2.3.0
|
punycode: 2.3.1
|
||||||
universalify: 0.2.0
|
universalify: 0.2.0
|
||||||
url-parse: 1.5.10
|
url-parse: 1.5.10
|
||||||
|
|
||||||
@@ -31443,6 +31205,10 @@ snapshots:
|
|||||||
|
|
||||||
trough@1.0.5: {}
|
trough@1.0.5: {}
|
||||||
|
|
||||||
|
trouter@2.0.1:
|
||||||
|
dependencies:
|
||||||
|
matchit: 1.1.0
|
||||||
|
|
||||||
true-case-path@2.2.1: {}
|
true-case-path@2.2.1: {}
|
||||||
|
|
||||||
ts-api-utils@2.0.1(typescript@5.7.3):
|
ts-api-utils@2.0.1(typescript@5.7.3):
|
||||||
@@ -31890,8 +31656,6 @@ snapshots:
|
|||||||
|
|
||||||
universalify@2.0.0: {}
|
universalify@2.0.0: {}
|
||||||
|
|
||||||
unix-crypt-td-js@1.1.4: {}
|
|
||||||
|
|
||||||
unixify@1.0.0:
|
unixify@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
normalize-path: 2.1.1
|
normalize-path: 2.1.1
|
||||||
@@ -32493,14 +32257,6 @@ snapshots:
|
|||||||
- esbuild
|
- esbuild
|
||||||
- uglify-js
|
- uglify-js
|
||||||
|
|
||||||
websocket-driver@0.7.4:
|
|
||||||
dependencies:
|
|
||||||
http-parser-js: 0.5.8
|
|
||||||
safe-buffer: 5.2.1
|
|
||||||
websocket-extensions: 0.1.4
|
|
||||||
|
|
||||||
websocket-extensions@0.1.4: {}
|
|
||||||
|
|
||||||
whatwg-encoding@1.0.5:
|
whatwg-encoding@1.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
iconv-lite: 0.4.24
|
iconv-lite: 0.4.24
|
||||||
|
|||||||
Reference in New Issue
Block a user