diff --git a/next-env.d.ts b/next-env.d.ts
index 0ad0784..1fab158 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,3 +1,15 @@
///
///
///
+
+declare global {
+ namespace NodeJS {
+ interface ProcessEnv {
+ AWS_REGION?: string;
+ AWS_ACCESS_KEY_ID?: string;
+ AWS_SECRET_ACCESS_KEY?: string;
+ AWS_S3_BUCKET_NAME?: string;
+ LAMBDA_PRESIGN_UPLOAD_ENDPOINT?: string;
+ }
+ }
+}
diff --git a/package.json b/package.json
index d6d3a3f..fa11025 100644
--- a/package.json
+++ b/package.json
@@ -3,10 +3,11 @@
"version": "2.2.1",
"private": true,
"dependencies": {
- "@dotkomonline/design-system": "^0.22.0",
+ "@dotkomonline/design-system": "^0.22.2",
"@reduxjs/toolkit": "^1.4.0",
"@sentry/browser": "^5.0.3",
"@sentry/node": "^5.4.3",
+ "@types/aws-sdk": "^2.7.0",
"@types/file-saver": "^2.0.0",
"@types/get-stream": "^3.0.2",
"@types/jsdom": "^16.2.4",
@@ -19,6 +20,7 @@
"@types/react-dom": "16.9.8",
"@types/react-redux": "^7.1.0",
"@types/styled-components": "^5.1.4",
+ "aws-sdk": "^2.1560.0",
"core-js": "^3.0.1",
"file-saver": "^2.0.1",
"get-stream": "^6.0.1",
diff --git a/src/constants/backend.ts b/src/constants/backend.ts
index 55c9e4c..d360591 100644
--- a/src/constants/backend.ts
+++ b/src/constants/backend.ts
@@ -1,3 +1,4 @@
export const LAMBDA_ENDPOINT = '/api/generate-receipt';
+export const LAMBDA_PRESIGN_UPLOAD_ENDPOINT = '/api/presign-upload-url';
export const OW4_ADDRESS = process.env.NEXT_PUBLIC_OW4_ADDRESS || 'https://online.ntnu.no';
diff --git a/src/form/state.ts b/src/form/state.ts
index e7b8101..141b9be 100644
--- a/src/form/state.ts
+++ b/src/form/state.ts
@@ -2,6 +2,8 @@ import { ApiBodyError } from './../lambda/errors';
import { Group } from 'models/groups';
import { readDataUrlAsFile2 } from 'utils/readDataUrlAsFile';
import { readFileAsDataUrl } from 'utils/readFileAsDataUrl';
+import { uploadFile } from "../utils/uploadFile";
+import { downloadFileFromS3Bucket } from "../utils/downloadFileFromS3Bucket";
export type ReceiptType = 'card' | 'deposit';
export type SendMode = 'download' | 'email' | 'teapot';
@@ -56,7 +58,9 @@ export interface IDeserializedState {
}
export const deserializeReceipt = async (state: IState): Promise => {
- const attachments = await Promise.all(state.attachments.map(async (file) => readFileAsDataUrl(file)));
+ const attachments = await Promise.all(
+ state.attachments.map(async (file) => uploadFile(file))
+ );
const signature = await readFileAsDataUrl(state.signature || new File([], 'newfile'));
return {
...state,
@@ -67,9 +71,11 @@ export const deserializeReceipt = async (state: IState): Promise => {
try {
- const attachments = await Promise.all(
- deserializedState.attachments.map(async (dataUrl) => readDataUrlAsFile2(dataUrl))
- );
+ const illegalAttachment = deserializedState.attachments.find((attachment) => !attachment.startsWith("uploads/"));
+ if (illegalAttachment) {
+ throw new TypeError('Illegal attachment');
+ }
+ const attachments = await Promise.all(deserializedState.attachments.map(downloadFileFromS3Bucket));
const signature = await readDataUrlAsFile2(deserializedState.signature);
return {
...deserializedState,
diff --git a/src/form/validation.ts b/src/form/validation.ts
index 1c97ff9..7fec576 100644
--- a/src/form/validation.ts
+++ b/src/form/validation.ts
@@ -29,8 +29,8 @@ export const ACCOUNT_NUMBER_REGEX = new RegExp(/^\d{4} \d{2} \d{5}$/);
export const COMMITTEE_EMAIL_REGEX = new RegExp(/^.{2,50}@online\.ntnu\.no$/);
export const EMAIL_REGEX = new RegExp(/^[a-zA-Z0-9.!#$%&’*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/);
export const CARD_DETAIL_REGEX = new RegExp(/^.{5,30}$/);
-export const FILE_SIZE_WARN = 7 * 1024 * 1024; // 7 MB
-export const FILE_SIZE_MAX = 9 * 1024 * 1024; // 9 MB
+export const FILE_SIZE_WARN = 20 * 1024 * 1024; // 20 MB
+export const FILE_SIZE_MAX = 25 * 1024 * 1024; // 25 MB
export const STATE_VALIDATION: StateValidators = {
fullname: [
diff --git a/src/lambda/handler.ts b/src/lambda/handler.ts
index df88c4a..2febc8e 100755
--- a/src/lambda/handler.ts
+++ b/src/lambda/handler.ts
@@ -10,6 +10,7 @@ import { readFileAsDataUrl } from 'utils/readFileAsDataUrl';
import { sendEmail } from './sendEmail';
import { ApiBodyError, ApiValidationError } from './errors';
import { pdfGenerator } from './browserlessGenerator';
+import { uploadFileToS3Bucket } from "../utils/uploadFileToS3Bucket";
export interface SuccessBody {
message: string;
@@ -48,12 +49,16 @@ export const generateReceipt = async (data: IDeserializedState | null): Promise<
}
const validState = state as NonNullableState;
const pdf = await pdfGenerator(validState);
- const pdfFile = new File([pdf], 'receipt.pdf', { type: 'application/pdf' });
- const pdfString = await readFileAsDataUrl(pdfFile);
if (state.mode === 'download') {
- return DOWNLOAD_SUCCESS_MESSAGE(pdfString);
+ const dato = `${new Date().toISOString().split('T')[0]}`;
+ const filename = `kvittering-${dato}-${+Date.now()}.pdf`;
+ const downloadUrl = await uploadFileToS3Bucket(pdf, `receipts/${filename}`);
+ return DOWNLOAD_SUCCESS_MESSAGE(downloadUrl);
} else if (state.mode === 'email') {
+ const pdfFile = new File([pdf], 'receipt.pdf', { type: 'application/pdf' });
+ const pdfString = await readFileAsDataUrl(pdfFile);
+
await sendEmail(pdfString, state);
return EMAIL_SUCCESS_MESSAGE;
} else if (state.mode === 'teapot') {
diff --git a/src/pages/api/presign-upload-url.ts b/src/pages/api/presign-upload-url.ts
new file mode 100644
index 0000000..068d141
--- /dev/null
+++ b/src/pages/api/presign-upload-url.ts
@@ -0,0 +1,27 @@
+import { NextApiRequest, NextApiResponse, PageConfig } from 'next';
+
+import { SuccessBody } from 'lambda/handler';
+import { sentryMiddleware } from 'lambda/sentry';
+import { ErrorData } from 'lambda/errors';
+import { getPresignedS3URL } from "../../utils/getPresignedS3URL";
+
+const handler = async (req: NextApiRequest, res: NextApiResponse) => {
+ const { filename, contentType } = req.body;
+
+ try {
+ const data = await getPresignedS3URL(filename, contentType);
+ res.status(200).json({ message: "Presigned URL", data: JSON.stringify(data) });
+ } catch (error) {
+ res.status(500).json({ message: "Failed to get presigned URL", data: error });
+ }
+};
+
+export const config: PageConfig = {
+ api: {
+ bodyParser: {
+ sizeLimit: '25mb',
+ },
+ },
+};
+
+export default sentryMiddleware(handler);
diff --git a/src/redux/actions/authActions.ts b/src/redux/actions/authActions.ts
index d2b52f5..fc2ec5d 100644
--- a/src/redux/actions/authActions.ts
+++ b/src/redux/actions/authActions.ts
@@ -68,7 +68,6 @@ export const loginAction = createAsyncThunk('user/login', async (_, { dispatch,
const user: User | null = await getManager().getUser();
if (user) {
const newForm = await processUser(user, form);
- console.log({ newForm });
updateForm(dispatch, newForm);
} else {
logInRedirect(form);
@@ -96,6 +95,7 @@ export const catchCallbackAction = createAsyncThunk('user/catchCallback', async
window.location.hash = '';
} catch (err) {
/** Do nothing if no user data is present */
+ window.location.hash = '';
return;
}
});
diff --git a/src/redux/actions/submitActions.ts b/src/redux/actions/submitActions.ts
index 8f6c910..eca2014 100644
--- a/src/redux/actions/submitActions.ts
+++ b/src/redux/actions/submitActions.ts
@@ -3,9 +3,7 @@ import { createAsyncThunk } from '@reduxjs/toolkit';
import { NonNullableState } from 'lambda/generatePDF';
import { getFileName } from 'lambda/tools/format';
-import { downloadFile } from 'utils/download';
import { postReceipt } from 'utils/postReceipt';
-import { readDataUrlAsFile } from 'utils/readDataUrlAsFile';
import { downloadFinished, downloadStarted, loadingDone, setResponse } from 'redux/reducers/statusReducer';
import { State } from 'redux/store';
import { SuccessBody } from 'lambda/handler';
@@ -14,10 +12,13 @@ const handleDownload = async (response: SuccessBody, state: NonNullableState) =>
if (response.data) {
/** Use the same filename that would be generated when sending a mail */
const fileName = getFileName(state);
- const pdfFile = await readDataUrlAsFile(response.data, fileName);
- if (pdfFile) {
- downloadFile(pdfFile);
- }
+ // response.data is a URL to the file
+
+ const a = document.createElement('a');
+ document.body.appendChild(a);
+ a.href = response.data;
+ a.download = fileName;
+ a.click();
}
};
diff --git a/src/utils/downloadFileFromS3Bucket.ts b/src/utils/downloadFileFromS3Bucket.ts
new file mode 100644
index 0000000..ef4923e
--- /dev/null
+++ b/src/utils/downloadFileFromS3Bucket.ts
@@ -0,0 +1,32 @@
+import AWS from "aws-sdk";
+
+const credentials = (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ?
+ {
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
+ } :
+ undefined;
+
+AWS.config.update({
+ region: process.env.AWS_REGION,
+ credentials,
+})
+
+export async function downloadFileFromS3Bucket(key: string): Promise {
+ if (!process.env.AWS_S3_BUCKET_NAME) {
+ throw new Error('AWS_S3_BUCKET_NAME is not set');
+ }
+
+ const s3 = new AWS.S3({
+ apiVersion: '2006-03-01',
+ });
+
+ const params = {
+ Bucket: process.env.AWS_S3_BUCKET_NAME,
+ Key: key,
+ };
+
+ const data = await s3.getObject(params).promise();
+
+ return new File([data.Body as Blob], key, { type: data.ContentType });
+}
diff --git a/src/utils/getPresignedS3URL.ts b/src/utils/getPresignedS3URL.ts
new file mode 100644
index 0000000..0f0fa30
--- /dev/null
+++ b/src/utils/getPresignedS3URL.ts
@@ -0,0 +1,41 @@
+import AWS from "aws-sdk";
+
+const credentials = (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ?
+ {
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
+ } :
+ undefined;
+
+AWS.config.update({
+ region: process.env.AWS_REGION,
+ credentials,
+})
+
+const s3 = new AWS.S3({
+ apiVersion: '2006-03-01',
+});
+
+const createPresignedPost = (params: AWS.S3.PresignedPost.Params): Promise => new Promise((resolve, reject) => {
+ s3.createPresignedPost(params, function (err, data) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(data)
+ }
+ });
+});
+
+export const getPresignedS3URL = async (name: string, contentType: string): Promise<{ url: string, fields: {[key: string]: string}}> => {
+ return await createPresignedPost({
+ Bucket: "receipt-form",
+ Fields: {
+ key: `uploads/${+new Date()}-${name}`,
+ "Content-Type": contentType,
+ },
+ Conditions: [
+ ["content-length-range", 0, 1024 * 1024 * 10],
+ ],
+ Expires: 60,
+ })
+}
\ No newline at end of file
diff --git a/src/utils/uploadFile.ts b/src/utils/uploadFile.ts
new file mode 100644
index 0000000..a49d734
--- /dev/null
+++ b/src/utils/uploadFile.ts
@@ -0,0 +1,42 @@
+import { LAMBDA_PRESIGN_UPLOAD_ENDPOINT } from "constants/backend";
+
+export const uploadFile = async (file: File): Promise => {
+ if (!LAMBDA_PRESIGN_UPLOAD_ENDPOINT) {
+ throw new Error('LAMBDA_PRESIGN_UPLOAD_ENDPOINT is not set');
+ }
+
+ // Request to get the presigned POST data
+ const response = await fetch(LAMBDA_PRESIGN_UPLOAD_ENDPOINT, {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ filename: file.name, contentType: file.type }),
+ });
+
+ const body = await response.json();
+ if (!response.ok) {
+ console.error(await response.text());
+ throw new Error('Failed to get presigned post data');
+ }
+
+ const { url, fields }: {url: string, fields: {[key: string]: string}} = JSON.parse(body.data);
+
+ const formData = new FormData();
+ for (const key in fields) {
+ formData.append(key, fields[key]);
+ }
+ formData.append('file', file);
+
+ const uploadResponse = await fetch(url, {
+ method: 'POST',
+ body: formData,
+ });
+
+ if (!uploadResponse.ok) {
+ throw new Error('Failed to upload file');
+ }
+
+ return fields.key
+};
diff --git a/src/utils/uploadFileToS3Bucket.ts b/src/utils/uploadFileToS3Bucket.ts
new file mode 100644
index 0000000..4ddd445
--- /dev/null
+++ b/src/utils/uploadFileToS3Bucket.ts
@@ -0,0 +1,35 @@
+import AWS from "aws-sdk";
+
+const credentials = (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ?
+ {
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
+ } :
+ undefined;
+
+AWS.config.update({
+ region: process.env.AWS_REGION,
+ credentials,
+})
+
+// upload file to S3 bucket and make it publicly downloadable
+export async function uploadFileToS3Bucket(file: Uint8Array, key: string): Promise {
+ if (!process.env.AWS_S3_BUCKET_NAME) {
+ throw new Error('AWS_S3_BUCKET_NAME is not set');
+ }
+ const s3 = new AWS.S3({
+ apiVersion: '2006-03-01',
+ params: { Bucket: process.env.AWS_S3_BUCKET_NAME },
+ });
+
+ const params = {
+ Bucket: process.env.AWS_S3_BUCKET_NAME,
+ Key: key,
+ Body: file,
+ ACL: 'public-read',
+ };
+
+ const result = await s3.upload(params).promise();
+
+ return result.Location;
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index bf9bdaa..0524794 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1475,10 +1475,10 @@
resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-11.0.0.tgz#719cf05fcc1abb6533610a2e0f5dd1e61eac14fe"
integrity sha512-VoNqai1vR5anRF5Tuh/+SWDFk7xi7oMwHrHrbm1BprYXjB2RJsWLhUrStMssDxEl5lW/z3EUdg8RvH/IUBccSQ==
-"@dotkomonline/design-system@^0.22.0":
- version "0.22.0"
- resolved "https://registry.yarnpkg.com/@dotkomonline/design-system/-/design-system-0.22.0.tgz#a111004f6d464283ebbb6f8a21ea1e2b1fed4e9d"
- integrity sha512-uQxutJjJNcqsHW2ycosFDq94KNVbrZsXwqarlo0o+xdlubt+b8VTEtm6A4+z6Ej/OIS/K32ERFpcYqpf1RfE9g==
+"@dotkomonline/design-system@^0.22.2":
+ version "0.22.2"
+ resolved "https://registry.yarnpkg.com/@dotkomonline/design-system/-/design-system-0.22.2.tgz#9595dbf33c45323155bd6ef201823724c6e43f22"
+ integrity sha512-nX5+3nZKOYGuq5bQ0w8j4PzAYs6gJ3yEz5Zx8uSBx8HuVx9/rK0ySs9R7vllq2IyewE4OuwQFoPRVBoI4i8l6w==
dependencies:
"@storybook/addon-a11y" "^5.3.12"
"@storybook/addon-actions" "^5.3.12"
@@ -2951,6 +2951,13 @@
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0"
integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A==
+"@types/aws-sdk@^2.7.0":
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/@types/aws-sdk/-/aws-sdk-2.7.0.tgz#83588b3d14ebdca1d4ce5e023387577568ce82f3"
+ integrity sha512-bF6brnwPN9+kheqdKCpinMgCkj+sJIUEj+0v0LPug9OQwL5/1jy+kiJwl+Nkw4Kh+7oaL1phhC4gMz6Oq60jMg==
+ dependencies:
+ aws-sdk "*"
+
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
version "7.1.12"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.12.tgz#4d8e9e51eb265552a7e4f1ff2219ab6133bdfb2d"
@@ -4287,6 +4294,43 @@ autoprefixer@^9.7.2:
postcss "^7.0.32"
postcss-value-parser "^4.1.0"
+available-typed-arrays@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz#ac812d8ce5a6b976d738e1c45f08d0b00bc7d725"
+ integrity sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==
+
+aws-sdk@*:
+ version "2.1561.0"
+ resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1561.0.tgz#cfe24c92818f9f4bd4a91a0f45aca26c8688faf6"
+ integrity sha512-YbYQOyvy9mfEGRI4JDZjw6J0zW6bjyV7H3WMWeq69qETvZlkq8koy5CTPMCjnL8i7boDjyW9FuhQzICBbeNgLg==
+ dependencies:
+ buffer "4.9.2"
+ events "1.1.1"
+ ieee754 "1.1.13"
+ jmespath "0.16.0"
+ querystring "0.2.0"
+ sax "1.2.1"
+ url "0.10.3"
+ util "^0.12.4"
+ uuid "8.0.0"
+ xml2js "0.6.2"
+
+aws-sdk@^2.1560.0:
+ version "2.1560.0"
+ resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1560.0.tgz#f43b2b4d212ecf1da86ce1b1f4f0c5308c74f9e5"
+ integrity sha512-nakTZHytnhKWZpwu9d1crqjoegBRG+j1/rflsVnckXxoIwlKM0D/v/NIe+BJmRnCA2aCdwuMx3dtkgLz/AB6VA==
+ dependencies:
+ buffer "4.9.2"
+ events "1.1.1"
+ ieee754 "1.1.13"
+ jmespath "0.16.0"
+ querystring "0.2.0"
+ sax "1.2.1"
+ url "0.10.3"
+ util "^0.12.4"
+ uuid "8.0.0"
+ xml2js "0.6.2"
+
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
@@ -5052,15 +5096,7 @@ buffer-xor@^1.0.3:
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
-buffer@5.6.0:
- version "5.6.0"
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
- integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==
- dependencies:
- base64-js "^1.0.2"
- ieee754 "^1.1.4"
-
-buffer@^4.3.0:
+buffer@4.9.2, buffer@^4.3.0:
version "4.9.2"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
@@ -5069,6 +5105,14 @@ buffer@^4.3.0:
ieee754 "^1.1.4"
isarray "^1.0.0"
+buffer@5.6.0:
+ version "5.6.0"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
+ integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==
+ dependencies:
+ base64-js "^1.0.2"
+ ieee754 "^1.1.4"
+
buffer@^5.2.1, buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
@@ -5185,6 +5229,17 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
+call-bind@^1.0.5:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
+ integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.2.4"
+ set-function-length "^1.2.1"
+
call-limit@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4"
@@ -6509,6 +6564,15 @@ defaults@^1.0.3:
dependencies:
clone "^1.0.2"
+define-data-property@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
+ integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ gopd "^1.0.1"
+
define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -7114,6 +7178,18 @@ es-array-method-boxes-properly@^1.0.0:
resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==
+es-define-property@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
+ integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
+ dependencies:
+ get-intrinsic "^1.2.4"
+
+es-errors@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
+ integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
+
es-get-iterator@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8"
@@ -7470,6 +7546,11 @@ eventemitter3@^4.0.0:
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
+events@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
+ integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==
+
events@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"
@@ -7967,6 +8048,13 @@ fontkit@^1.8.1:
unicode-properties "^1.2.2"
unicode-trie "^0.3.0"
+for-each@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
+ integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
+ dependencies:
+ is-callable "^1.1.3"
+
for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
@@ -8146,6 +8234,11 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+function-bind@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+ integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
+
function.prototype.name@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.2.tgz#5cdf79d7c05db401591dfde83e3b70c5123e9a45"
@@ -8233,6 +8326,17 @@ get-caller-file@^2.0.1:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+get-intrinsic@^1.1.3, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
+ integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
+ dependencies:
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ has-proto "^1.0.1"
+ has-symbols "^1.0.3"
+ hasown "^2.0.0"
+
get-package-type@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
@@ -8448,6 +8552,13 @@ good-listener@^1.2.2:
dependencies:
delegate "^3.1.2"
+gopd@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
+ integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
+ dependencies:
+ get-intrinsic "^1.1.3"
+
got@^6.7.1:
version "6.7.1"
resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
@@ -8540,11 +8651,35 @@ has-flag@^4.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+has-property-descriptors@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
+ integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
+ dependencies:
+ es-define-property "^1.0.0"
+
+has-proto@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
+ integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
+
has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
+has-symbols@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
+ integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
+
+has-tostringtag@^1.0.0, has-tostringtag@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
+ integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
+ dependencies:
+ has-symbols "^1.0.3"
+
has-unicode@^2.0.0, has-unicode@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -8615,6 +8750,13 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.1"
+hasown@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.1.tgz#26f48f039de2c0f8d3356c223fb8d50253519faa"
+ integrity sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==
+ dependencies:
+ function-bind "^1.1.2"
+
hast-to-hyperscript@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.0.tgz#768fb557765fe28749169c885056417342d71e83"
@@ -8950,16 +9092,16 @@ identity-obj-proxy@^3.0.0:
dependencies:
harmony-reflect "^1.4.6"
+ieee754@1.1.13, ieee754@^1.1.4:
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
+ integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
+
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
-ieee754@^1.1.4:
- version "1.1.13"
- resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
- integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
-
iferr@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
@@ -9277,6 +9419,11 @@ is-buffer@^2.0.0:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
+is-callable@^1.1.3:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
+ integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
+
is-callable@^1.1.4, is-callable@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9"
@@ -9441,6 +9588,13 @@ is-generator-fn@^2.0.0:
resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
+is-generator-function@^1.0.7:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
+ integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
is-glob@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
@@ -9634,6 +9788,13 @@ is-text-path@^1.0.1:
dependencies:
text-extensions "^1.0.0"
+is-typed-array@^1.1.3:
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229"
+ integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==
+ dependencies:
+ which-typed-array "^1.1.14"
+
is-typedarray@^1.0.0, is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@@ -10266,6 +10427,11 @@ jest@^26.6.3:
import-local "^3.0.2"
jest-cli "^26.6.3"
+jmespath@0.16.0:
+ version "0.16.0"
+ resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076"
+ integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==
+
js-string-escape@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef"
@@ -14628,6 +14794,16 @@ sass-loader@10.0.2:
schema-utils "^2.7.1"
semver "^7.3.2"
+sax@1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
+ integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==
+
+sax@>=0.6.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
+ integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==
+
sax@~1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@@ -14831,6 +15007,18 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
+set-function-length@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.1.tgz#47cc5945f2c771e2cf261c6737cf9684a2a5e425"
+ integrity sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==
+ dependencies:
+ define-data-property "^1.1.2"
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.2.3"
+ gopd "^1.0.1"
+ has-property-descriptors "^1.0.1"
+
set-value@^2.0.0, set-value@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
@@ -16622,6 +16810,14 @@ url-parse@^1.4.3:
querystringify "^2.1.1"
requires-port "^1.0.0"
+url@0.10.3:
+ version "0.10.3"
+ resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64"
+ integrity sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==
+ dependencies:
+ punycode "1.3.2"
+ querystring "0.2.0"
+
url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -16704,6 +16900,17 @@ util@^0.11.0:
dependencies:
inherits "2.0.3"
+util@^0.12.4:
+ version "0.12.5"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc"
+ integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==
+ dependencies:
+ inherits "^2.0.3"
+ is-arguments "^1.0.4"
+ is-generator-function "^1.0.7"
+ is-typed-array "^1.1.3"
+ which-typed-array "^1.1.2"
+
utila@~0.4:
version "0.4.0"
resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"
@@ -16714,6 +16921,11 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
+uuid@8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c"
+ integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==
+
uuid@^3.3.2, uuid@^3.3.3:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
@@ -17082,6 +17294,17 @@ which-pm-runs@^1.0.0:
resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"
integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=
+which-typed-array@^1.1.14, which-typed-array@^1.1.2:
+ version "1.1.14"
+ resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.14.tgz#1f78a111aee1e131ca66164d8bdc3ab062c95a06"
+ integrity sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==
+ dependencies:
+ available-typed-arrays "^1.0.6"
+ call-bind "^1.0.5"
+ for-each "^0.3.3"
+ gopd "^1.0.1"
+ has-tostringtag "^1.0.1"
+
which@^1.2.9, which@^1.3.0, which@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
@@ -17232,6 +17455,19 @@ xml-name-validator@^3.0.0:
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
+xml2js@0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499"
+ integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==
+ dependencies:
+ sax ">=0.6.0"
+ xmlbuilder "~11.0.0"
+
+xmlbuilder@~11.0.0:
+ version "11.0.1"
+ resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
+ integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
+
xmlchars@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"