Compare commits

...

6 commits

Author SHA1 Message Date
RenovateBot f2e3102887 Update dependency eslint to v9
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2024-04-14 23:02:58 +00:00
Ethan Lane f7667fe3b7 Fix tests
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-12 18:13:04 +01:00
Ethan Lane 5d0af43b6f Merge branch 'master' into develop 2024-04-12 18:05:00 +01:00
Ethan Lane 8a726b386e v2.1.6
All checks were successful
continuous-integration/drone/push Build is passing
2024-04-12 17:57:13 +01:00
Ethan Lane 9e25e5a0e0 Update tests 2024-04-12 17:54:12 +01:00
Ethan Lane 00b51584b6 Add image helper class to handle reddit galleries 2024-04-07 11:03:20 +01:00
7 changed files with 319 additions and 85 deletions

View file

@ -1,6 +1,6 @@
{
"name": "random-bunny",
"version": "2.1.5",
"version": "2.1.6",
"description": "Get a random subreddit image url",
"license": "MIT",
"author": "Vylpes",
@ -21,6 +21,7 @@
"commander": "^12.0.0",
"glob-parent": "^6.0.0",
"got-cjs": "^12.5.4",
"htmlparser2": "^9.1.0",
"linqts": "^1.14.4"
},
"scripts": {
@ -43,7 +44,7 @@
"@types/node": "^20.0.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^5.54.0",
"eslint": "^8.49.0",
"eslint": "^9.0.0",
"jest": "^29.7.0",
"jest-mock-extended": "^3.0.3",
"np": "^9.0.0",

19
src/imageHelper.ts Normal file
View file

@ -0,0 +1,19 @@
import fetch from "got-cjs";
import * as htmlparser from "htmlparser2";
export default class ImageHelper {
public static async FetchImageFromRedditGallery(url: string): Promise<string | undefined> {
const fetched = await fetch(url);
if (!fetched || fetched.errored || fetched.statusCode != 200) {
return undefined;
}
const dom = htmlparser.parseDocument(fetched.body);
const img = htmlparser.DomUtils.findOne((x => x.tagName == "img" && x.attributes.find(y => y.value.includes("https://preview.redd.it")) != null), dom.children, true);
const imgSrc = img?.attributes.find(x => x.name == "src")?.value;
return imgSrc;
}
}

View file

@ -5,6 +5,7 @@ import { List } from 'linqts';
import IFetchResult from "./contracts/IFetchResult";
import { ErrorCode } from "./constants/ErrorCode";
import ErrorMessages from "./constants/ErrorMessages";
import ImageHelper from "./imageHelper";
const sortable = [
'new',
@ -56,7 +57,7 @@ export default async function randomBunny(subreddit: string, sortBy: string = 'h
const data: IFetchResult[] = json.data.children;
const dataWithImages = new List<IFetchResult>(data)
.Where(x => x!.data.url.includes('.jpg') || x!.data.url.includes('.png'))
.Where(x => x!.data.url.includes('.jpg') || x!.data.url.includes('.png') || x!.data.url.includes("/gallery/"))
.ToArray();
let random = 0;
@ -81,6 +82,30 @@ export default async function randomBunny(subreddit: string, sortBy: string = 'h
const randomData = randomSelect.data;
let url: string;
if (randomData.url.includes("/gallery")) {
const galleryImage = await ImageHelper.FetchImageFromRedditGallery(randomData.url);
if (!galleryImage) {
return {
IsSuccess: false,
Query: {
subreddit: subreddit,
sortBy: sortBy,
},
Error: {
Code: ErrorCode.NoImageResultsFound,
Message: ErrorMessages.NoImageResultsFound,
},
}
}
url = galleryImage;
} else {
url = randomData.url;
}
const redditResult: IRedditResult = {
Archived: randomData['archived'],
Downs: randomData['downs'],
@ -90,7 +115,7 @@ export default async function randomBunny(subreddit: string, sortBy: string = 'h
SubredditSubscribers: randomData['subreddit_subscribers'],
Title: randomData['title'],
Ups: randomData['ups'],
Url: randomData['url']
Url: url,
};
return {

View file

@ -147,7 +147,7 @@ describe('query-metadata', () => {
expect(query).toBeUndefined();
}, 5000);
test('GIVEN --query-metadata is not supplied, EXPECT no query metadata returned', async () => {
test('GIVEN --query-metadata is supplied, EXPECT query metadata returned', async () => {
const result = await cli(['--query-metadata'], '.');
const query = result.stdout.split('\n')
@ -156,7 +156,7 @@ describe('query-metadata', () => {
expect(query).toBeDefined();
}, 5000);
test('GIVEN -q is not supplied, EXPECT no query metadata returned', async () => {
test('GIVEN -q is supplied, EXPECT query metadata returned', async () => {
const result = await cli(['-q'], '.');
const query = result.stdout.split('\n')

90
tests/imageHelper.test.ts Normal file
View file

@ -0,0 +1,90 @@
import ImageHelper from "../src/imageHelper";
import fetch from "got-cjs";
jest.mock('got-cjs');
const fetchMock = jest.mocked(fetch);
describe("FetchImageFromRedditGallery", () => {
test("EXPECT image url to be returned", async () => {
fetchMock.mockResolvedValue({
body: "<html><body><img src='https://preview.redd.it/image.png' /></body></html>",
errored: undefined,
statusCode: 200,
});
const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image");
expect(fetchMock).toHaveBeenCalledTimes(1);
expect(fetchMock).toHaveBeenCalledWith("https://redd.it/gallery/image");
expect(result).toBe("https://preview.redd.it/image.png");
});
test("GIVEN fetch is unable to return data, EXPECT undefined returned", async () => {
fetchMock.mockResolvedValue(null);
const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image");
expect(result).toBeUndefined();
});
test("GIVEN fetch is an error, EXPECT undefined returned", async () => {
fetchMock.mockResolvedValue({
body: "<html><body><img src='https://preview.redd.it/image.png' /></body></html>",
errored: "Error",
statusCode: 200,
});
const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image");
expect(result).toBeUndefined();
});
test("GIVEN fetch is not status code of 200, EXPECT undefined returned", async () => {
fetchMock.mockResolvedValue({
body: "<html><body><img src='https://preview.redd.it/image.png' /></body></html>",
errored: undefined,
statusCode: 500,
});
const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image");
expect(result).toBeUndefined();
});
test("GIVEN image tag is not found, EXPECT undefined returned", async () => {
fetchMock.mockResolvedValue({
body: "<html><body></body></html>",
errored: undefined,
statusCode: 200,
});
const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image");
expect(result).toBeUndefined();
});
test("GIVEN image source attribute is not found, EXPECT undefined returned", async () => {
fetchMock.mockResolvedValue({
body: "<html><body><img /></body></html>",
errored: undefined,
statusCode: 200,
});
const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image");
expect(result).toBeUndefined();
});
test("GIVEN image source attribute is not found that is a preview.redd.it url, EXPECT undefined returned", async () => {
fetchMock.mockResolvedValue({
body: "<html><body><img src='main.png' /></body></html>",
errored: undefined,
statusCode: 200,
});
const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image");
expect(result).toBeUndefined();
});
});

View file

@ -1,5 +1,6 @@
import { ErrorCode } from "../src/constants/ErrorCode";
import ErrorMessages from "../src/constants/ErrorMessages";
import ImageHelper from "../src/imageHelper";
import randomBunny from "../src/index";
import fetch from "got-cjs";
@ -189,5 +190,77 @@ describe('randomBunny', () => {
expect(result.Error!.Message).toBe(ErrorMessages.NoImageResultsFound);
expect(fetchMock).toBeCalledWith('https://reddit.com/r/rabbits/new.json?limit=100');
expect(fetchMock).toBeCalledWith('https://reddit.com/r/rabbits/new.json?limit=100');
});
test("GIVEN data fetched is a gallery AND an image is returned from the helper, EXPECT this to be used", async () => {
fetchMock.mockResolvedValue({
body: JSON.stringify({
data: {
children: [
{
data: {
archived: false,
downs: 0,
hidden: false,
permalink: '/r/Rabbits/comments/12pa5te/someone_told_pickles_its_monday_internal_fury/',
subreddit: 'Rabbits',
subreddit_subscribers: 298713,
title: 'Someone told pickles its Monday… *internal fury*',
ups: 1208,
url: 'https://i.redd.it/gallery/cr8xudsnkgua1',
},
},
],
}
}),
});
ImageHelper.FetchImageFromRedditGallery = jest.fn().mockResolvedValue("https://i.redd.it/cr8xudsnkgua1.jpg")
const result = await randomBunny('rabbits', 'new');
expect(result.IsSuccess).toBeTruthy();
expect(result.Result).toBeDefined();
expect(fetchMock).toBeCalledWith('https://reddit.com/r/rabbits/new.json?limit=100');
expect(ImageHelper.FetchImageFromRedditGallery).toHaveBeenCalledTimes(1);
expect(ImageHelper.FetchImageFromRedditGallery).toHaveBeenCalledWith("https://i.redd.it/gallery/cr8xudsnkgua1");
});
test("GIVEN data fetched is a gallery AND an image is not returned from the helper, EXPECT error", async () => {
fetchMock.mockResolvedValue({
body: JSON.stringify({
data: {
children: [
{
data: {
archived: false,
downs: 0,
hidden: false,
permalink: '/r/Rabbits/comments/12pa5te/someone_told_pickles_its_monday_internal_fury/',
subreddit: 'Rabbits',
subreddit_subscribers: 298713,
title: 'Someone told pickles its Monday… *internal fury*',
ups: 1208,
url: 'https://i.redd.it/gallery/cr8xudsnkgua1',
},
},
],
}
}),
});
ImageHelper.FetchImageFromRedditGallery = jest.fn().mockResolvedValue(undefined)
const result = await randomBunny('rabbits', 'new');
expect(ImageHelper.FetchImageFromRedditGallery).toHaveBeenCalledTimes(1);
expect(result.IsSuccess).toBe(false);
expect(result.Error).toBeDefined();
expect(result.Error?.Code).toBe(ErrorCode.NoImageResultsFound);
expect(result.Error?.Message).toBe(ErrorMessages.NoImageResultsFound);
});
});

184
yarn.lock
View file

@ -392,32 +392,32 @@
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63"
integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==
"@eslint/eslintrc@^2.1.4":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad"
integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==
"@eslint/eslintrc@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.0.2.tgz#36180f8e85bf34d2fe3ccc2261e8e204a411ab4e"
integrity sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^9.6.0"
globals "^13.19.0"
espree "^10.0.1"
globals "^14.0.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@8.57.0":
version "8.57.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f"
integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==
"@eslint/js@9.0.0":
version "9.0.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.0.0.tgz#1a9e4b4c96d8c7886e0110ed310a0135144a1691"
integrity sha512-RThY/MnKrhubF6+s1JflwUjPEsnCEmYCWwqa/aRISKWNXGZ9epUwft4bUMM35SdKF9xvBrLydAM1RDHd1Z//ZQ==
"@humanwhocodes/config-array@^0.11.14":
version "0.11.14"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b"
integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==
"@humanwhocodes/config-array@^0.12.3":
version "0.12.3"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.12.3.tgz#a6216d90f81a30bedd1d4b5d799b47241f318072"
integrity sha512-jsNnTBlMWuTpDkeE3on7+dWJi0D6fdDfeANj/w7MpS8ztROCoLvIO2nG0CcFj+E4k8j4QrSTh4Oryi3i2G669g==
dependencies:
"@humanwhocodes/object-schema" "^2.0.2"
"@humanwhocodes/object-schema" "^2.0.3"
debug "^4.3.1"
minimatch "^3.0.5"
@ -426,10 +426,10 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
"@humanwhocodes/object-schema@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917"
integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==
"@humanwhocodes/object-schema@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3"
integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
@ -1056,17 +1056,12 @@
"@typescript-eslint/types" "7.0.2"
eslint-visitor-keys "^3.4.1"
"@ungap/structured-clone@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn@^8.9.0:
acorn@^8.11.3:
version "8.11.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
@ -1876,12 +1871,35 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
esutils "^2.0.2"
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"
domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"
domutils@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
dot-prop@^6.0.1:
version "6.0.1"
@ -1934,6 +1952,11 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1:
dependencies:
once "^1.4.0"
entities@^4.2.0, entities@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
error-ex@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
@ -1971,54 +1994,55 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-scope@^7.2.2:
version "7.2.2"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f"
integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==
eslint-scope@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.0.1.tgz#a9601e4b81a0b9171657c343fb13111688963cfc"
integrity sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1:
version "3.4.3"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
eslint@^8.49.0:
version "8.57.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668"
integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==
eslint-visitor-keys@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz#e3adc021aa038a2a8e0b2f8b0ce8f66b9483b1fb"
integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==
eslint@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.0.0.tgz#6270548758e390343f78c8afd030566d86927d40"
integrity sha512-IMryZ5SudxzQvuod6rUdIUz29qFItWx281VhtFVc2Psy/ZhlCeD/5DT6lBIJ4H3G+iamGJoTln1v+QSuPw0p7Q==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.6.1"
"@eslint/eslintrc" "^2.1.4"
"@eslint/js" "8.57.0"
"@humanwhocodes/config-array" "^0.11.14"
"@eslint/eslintrc" "^3.0.2"
"@eslint/js" "9.0.0"
"@humanwhocodes/config-array" "^0.12.3"
"@humanwhocodes/module-importer" "^1.0.1"
"@nodelib/fs.walk" "^1.2.8"
"@ungap/structured-clone" "^1.2.0"
ajv "^6.12.4"
chalk "^4.0.0"
cross-spawn "^7.0.2"
debug "^4.3.2"
doctrine "^3.0.0"
escape-string-regexp "^4.0.0"
eslint-scope "^7.2.2"
eslint-visitor-keys "^3.4.3"
espree "^9.6.1"
eslint-scope "^8.0.1"
eslint-visitor-keys "^4.0.0"
espree "^10.0.1"
esquery "^1.4.2"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
file-entry-cache "^6.0.1"
file-entry-cache "^8.0.0"
find-up "^5.0.0"
glob-parent "^6.0.2"
globals "^13.19.0"
graphemer "^1.4.0"
ignore "^5.2.0"
imurmurhash "^0.1.4"
is-glob "^4.0.0"
is-path-inside "^3.0.3"
js-yaml "^4.1.0"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.4.1"
lodash.merge "^4.6.2"
@ -2028,14 +2052,14 @@ eslint@^8.49.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
espree@^9.6.0, espree@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==
espree@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-10.0.1.tgz#600e60404157412751ba4a6f3a2ee1a42433139f"
integrity sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==
dependencies:
acorn "^8.9.0"
acorn "^8.11.3"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^3.4.1"
eslint-visitor-keys "^4.0.0"
esprima@^4.0.0:
version "4.0.1"
@ -2227,12 +2251,12 @@ figures@^5.0.0:
escape-string-regexp "^5.0.0"
is-unicode-supported "^1.2.0"
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
file-entry-cache@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f"
integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==
dependencies:
flat-cache "^3.0.4"
flat-cache "^4.0.0"
fill-range@^7.0.1:
version "7.0.1"
@ -2262,14 +2286,13 @@ find-up@^5.0.0:
locate-path "^6.0.0"
path-exists "^4.0.0"
flat-cache@^3.0.4:
version "3.2.0"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee"
integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==
flat-cache@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c"
integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==
dependencies:
flatted "^3.2.9"
keyv "^4.5.3"
rimraf "^3.0.2"
keyv "^4.5.4"
flatted@^3.2.9:
version "3.3.1"
@ -2426,12 +2449,10 @@ globals@^11.1.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
globals@^13.19.0:
version "13.24.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171"
integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==
dependencies:
type-fest "^0.20.2"
globals@^14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
globby@^11.1.0:
version "11.1.0"
@ -2578,6 +2599,16 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
htmlparser2@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23"
integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.1.0"
entities "^4.5.0"
http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
@ -3498,7 +3529,7 @@ keyv@^4.0.0:
dependencies:
json-buffer "3.0.1"
keyv@^4.5.3:
keyv@^4.5.3, keyv@^4.5.4:
version "4.5.4"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
@ -5082,11 +5113,6 @@ type-detect@4.0.8:
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
type-fest@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
type-fest@^0.21.3:
version "0.21.3"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"