mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-28 16:06:41 +01:00
Merge branch 'develop' into feature/rowy-285-cms
This commit is contained in:
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 🤔 Support & questions
|
||||
url: https://discord.com/invite/fjBugmvzZP
|
||||
about: Chat with us for live support on discord.
|
||||
- name: 🙌 Want to join our team?
|
||||
url: https://www.rowy.io/jobs
|
||||
about: Get in touch to contribute & work with Rowy
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rowy",
|
||||
"version": "2.3.2",
|
||||
"version": "2.4.0-rc.0",
|
||||
"homepage": "https://rowy.io",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
117
src/components/CodeEditor/rowy.d.ts
vendored
117
src/components/CodeEditor/rowy.d.ts
vendored
@@ -1,32 +1,95 @@
|
||||
/**
|
||||
* utility functions
|
||||
*/
|
||||
declare namespace rowy {
|
||||
type RowyFile = {
|
||||
downloadURL: string;
|
||||
name: string;
|
||||
type: string;
|
||||
lastModifiedTS: number;
|
||||
};
|
||||
type RowyUser = {
|
||||
email: any;
|
||||
emailVerified: boolean;
|
||||
displayName: string;
|
||||
photoURL: string;
|
||||
uid: string;
|
||||
timestamp: number;
|
||||
};
|
||||
type uploadOptions = {
|
||||
bucket?: string;
|
||||
folderPath?: string;
|
||||
fileName?: string;
|
||||
};
|
||||
interface Rowy {
|
||||
metadata: {
|
||||
/**
|
||||
* The project ID of the project running this function.
|
||||
*/
|
||||
projectId: () => Promise<string>;
|
||||
/**
|
||||
* The numeric project ID of the project running this function.
|
||||
*/
|
||||
projectNumber: () => Promise<string>;
|
||||
/**
|
||||
* The email address of service account running this function.
|
||||
* This is the service account that is used to call other APIs.
|
||||
* Ensure that the service account has the correct permissions.
|
||||
*/
|
||||
serviceAccountEmail: () => Promise<string>;
|
||||
/**
|
||||
* a user object of the service account running this function.
|
||||
* Compatible with Rowy audit fields
|
||||
* Can be used to add createdBy or updatedBy fields to a document.
|
||||
*/
|
||||
serviceAccountUser: () => Promise<RowyUser>;
|
||||
};
|
||||
/**
|
||||
* uploads a file to the cloud storage from a url
|
||||
* Gives access to the Secret Manager.
|
||||
* manage your secrets in the Google Cloud Console.
|
||||
*/
|
||||
function url2storage(
|
||||
url: string,
|
||||
storagePath: string,
|
||||
fileName?: string
|
||||
): Promise<{
|
||||
downloadURL: string;
|
||||
name: string;
|
||||
type: string;
|
||||
lastModifiedTS: Date;
|
||||
}>;
|
||||
|
||||
secrets: {
|
||||
/**
|
||||
* Get an existing secret from the secret manager.
|
||||
*/
|
||||
get: (name: string, version?: string) => Promise<string | undefined>;
|
||||
};
|
||||
/**
|
||||
* Gets the secret defined in Google Cloud Secret
|
||||
* Gives access to the Cloud Storage.
|
||||
*/
|
||||
async function getSecret(name: string, v?: string): Promise<string | null>;
|
||||
|
||||
async function getServiceAccountUser(): Promise<{
|
||||
email: string;
|
||||
emailVerified: boolean;
|
||||
displayName: string;
|
||||
photoURL: string;
|
||||
uid: string;
|
||||
timestamp: number;
|
||||
}>;
|
||||
storage: {
|
||||
upload: {
|
||||
/**
|
||||
* uploads a file to storage bucket from an external url.
|
||||
*/
|
||||
url: (
|
||||
url: string,
|
||||
options: uploadOptions
|
||||
) => Promise<RowyFile | undefined>;
|
||||
/**
|
||||
* uploads a file to storage bucket from a buffer or string
|
||||
*/
|
||||
data: (
|
||||
data: Buffer | string,
|
||||
options: uploadOptions
|
||||
) => Promise<RowyFile | undefined>;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* @deprecated will be removed in version 2.0.
|
||||
* use rowy.secrets.get instead.
|
||||
* Get an existing secret from the secret manager.
|
||||
*/
|
||||
getSecret: (name: string, version?: string) => Promise<string | undefined>;
|
||||
/**
|
||||
* @deprecated will be removed in version 2.0.
|
||||
* use rowy.metadata.serviceAccountUser instead.
|
||||
* Compatible with Rowy audit fields
|
||||
* Can be used to add createdBy or updatedBy fields to a document.
|
||||
*/
|
||||
getServiceAccountUser: () => Promise<RowyUser>;
|
||||
/**
|
||||
* @deprecated will be removed in version 2.0.
|
||||
* use rowy.storage.upload.url instead.
|
||||
* uploads a file to storage bucket from an external url.
|
||||
*/
|
||||
url2storage: (url: string) => Promise<RowyFile | undefined>;
|
||||
}
|
||||
|
||||
declare const rowy: Rowy;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createElement, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import _sortBy from "lodash/sortBy";
|
||||
import _isEmpty from "lodash/isEmpty";
|
||||
import _set from "lodash/set";
|
||||
import createPersistedState from "use-persisted-state";
|
||||
|
||||
import { Stack, FormControlLabel, Switch } from "@mui/material";
|
||||
@@ -44,7 +45,16 @@ export default function Form({ values }: IFormProps) {
|
||||
// Get initial values from fields config. This won’t be written to the db
|
||||
// when the SideDrawer is opened. Only dirty fields will be written
|
||||
const initialValues = fields.reduce(
|
||||
(a, { key, type }) => ({ ...a, [key]: getFieldProp("initialValue", type) }),
|
||||
(a, { key, type }) => {
|
||||
const initialValue = getFieldProp("initialValue", type);
|
||||
const nextValues = { ...a };
|
||||
if (key.indexOf('.') !== -1) {
|
||||
_set(nextValues, key, initialValue);
|
||||
} else {
|
||||
nextValues[key] = initialValue;
|
||||
}
|
||||
return nextValues;
|
||||
},
|
||||
{}
|
||||
);
|
||||
const { ref: docRef, ...rowValues } = values;
|
||||
|
||||
@@ -19,6 +19,7 @@ import FiltersPopover from "./FiltersPopover";
|
||||
import FilterInputs from "./FilterInputs";
|
||||
|
||||
import { useFilterInputs, INITIAL_QUERY } from "./useFilterInputs";
|
||||
import { analytics } from "@src/analytics";
|
||||
import type { TableFilter } from "@src/hooks/useTable";
|
||||
import { useProjectContext } from "@src/contexts/ProjectContext";
|
||||
import { useAppContext } from "@src/contexts/AppContext";
|
||||
@@ -30,6 +31,11 @@ const shouldDisableApplyButton = (value: any) =>
|
||||
typeof value !== "number" &&
|
||||
typeof value !== "object";
|
||||
|
||||
enum FilterType {
|
||||
yourFilter = "local_filter",
|
||||
tableFilter = "table_filter",
|
||||
}
|
||||
|
||||
export default function Filters() {
|
||||
const { table, tableState, tableActions } = useProjectContext();
|
||||
const { userDoc, userClaims } = useAppContext();
|
||||
@@ -109,12 +115,14 @@ export default function Filters() {
|
||||
|
||||
// Save table filters to table schema document
|
||||
const setTableFilters = (filters: TableFilter[]) => {
|
||||
analytics.logEvent(FilterType.tableFilter);
|
||||
tableActions?.table.updateConfig("filters", filters);
|
||||
tableActions?.table.updateConfig("filtersOverridable", canOverrideCheckbox);
|
||||
};
|
||||
// Save user filters to user document
|
||||
// null overrides table filters
|
||||
const setUserFilters = (filters: TableFilter[] | null) => {
|
||||
analytics.logEvent(FilterType.yourFilter);
|
||||
userDoc.dispatch({
|
||||
action: DocActions.update,
|
||||
data: {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React, { useState, useCallback } from "react";
|
||||
import React, { useState, useCallback, useRef } from "react";
|
||||
import clsx from "clsx";
|
||||
import parse from "csv-parse";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import { useSnackbar } from "notistack";
|
||||
|
||||
import { makeStyles, createStyles } from "@mui/styles";
|
||||
import {
|
||||
@@ -27,6 +28,7 @@ import ImportIcon from "@src/assets/icons/Import";
|
||||
import FileUploadIcon from "@src/assets/icons/Upload";
|
||||
import CheckIcon from "@mui/icons-material/CheckCircle";
|
||||
|
||||
import { analytics } from "@src/analytics";
|
||||
import ImportCsvWizard, {
|
||||
IImportCsvWizardProps,
|
||||
} from "@src/components/Wizards/ImportCsvWizard";
|
||||
@@ -79,6 +81,17 @@ const useStyles = makeStyles((theme) =>
|
||||
})
|
||||
);
|
||||
|
||||
export enum ImportType {
|
||||
csv = "csv",
|
||||
tsv = "tsv",
|
||||
}
|
||||
|
||||
export enum ImportMethod {
|
||||
paste = "paste",
|
||||
upload = "upload",
|
||||
url = "url",
|
||||
}
|
||||
|
||||
export interface IImportCsvProps {
|
||||
render?: (
|
||||
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void
|
||||
@@ -90,7 +103,10 @@ export default function ImportCsv({ render, PopoverProps }: IImportCsvProps) {
|
||||
const classes = useStyles();
|
||||
const { userClaims } = useAppContext();
|
||||
const { table } = useProjectContext();
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const importTypeRef = useRef(ImportType.csv);
|
||||
const importMethodRef = useRef(ImportMethod.upload);
|
||||
const [open, setOpen] = useState<HTMLButtonElement | null>(null);
|
||||
const [tab, setTab] = useState("upload");
|
||||
const [csvData, setCsvData] =
|
||||
@@ -128,21 +144,53 @@ export default function ImportCsv({ render, PopoverProps }: IImportCsvProps) {
|
||||
});
|
||||
|
||||
const onDrop = useCallback(async (acceptedFiles) => {
|
||||
const file = acceptedFiles[0];
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event: any) => parseCsv(event.target.result);
|
||||
reader.readAsText(file);
|
||||
try {
|
||||
const file = acceptedFiles[0];
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event: any) => parseCsv(event.target.result);
|
||||
reader.readAsText(file);
|
||||
importTypeRef.current =
|
||||
file.type === "text/tab-separated-values"
|
||||
? ImportType.tsv
|
||||
: ImportType.csv;
|
||||
} catch (error) {
|
||||
enqueueSnackbar(`Please import a .tsv or .csv file`, {
|
||||
variant: "error",
|
||||
anchorOrigin: {
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
},
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
||||
onDrop,
|
||||
multiple: false,
|
||||
accept: ["text/csv", "text/tab-separated-values"],
|
||||
});
|
||||
|
||||
const [handlePaste] = useDebouncedCallback(
|
||||
(value: string) => parseCsv(value),
|
||||
1000
|
||||
);
|
||||
function setDataTypeRef(data: string) {
|
||||
const getFirstLine = data?.match(/^(.*)/)?.[0];
|
||||
/**
|
||||
* Catching edge case with regex
|
||||
* EG: "hello\tworld"\tFirst
|
||||
* - find \t between quotes, and replace with '\s'
|
||||
* - w/ the \t pattern test it against the formatted string
|
||||
*/
|
||||
const strInQuotes = /"(.*?)"/;
|
||||
const tabsWithSpace = (str: string) => str.replace("\t", "s");
|
||||
const formatString =
|
||||
getFirstLine?.replace(strInQuotes, tabsWithSpace) ?? "";
|
||||
const tabPattern = /\t/;
|
||||
return tabPattern.test(formatString)
|
||||
? (importTypeRef.current = ImportType.tsv)
|
||||
: (importTypeRef.current = ImportType.csv);
|
||||
}
|
||||
const [handlePaste] = useDebouncedCallback((value: string) => {
|
||||
parseCsv(value);
|
||||
setDataTypeRef(value);
|
||||
}, 1000);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [handleUrl] = useDebouncedCallback((value: string) => {
|
||||
@@ -152,6 +200,7 @@ export default function ImportCsv({ render, PopoverProps }: IImportCsvProps) {
|
||||
.then((res) => res.text())
|
||||
.then((data) => {
|
||||
parseCsv(data);
|
||||
setDataTypeRef(data);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((e) => {
|
||||
@@ -204,9 +253,21 @@ export default function ImportCsv({ render, PopoverProps }: IImportCsvProps) {
|
||||
}
|
||||
variant="fullWidth"
|
||||
>
|
||||
<Tab label="Upload" value="upload" />
|
||||
<Tab label="Paste" value="paste" />
|
||||
<Tab label="URL" value="url" />
|
||||
<Tab
|
||||
label="Upload"
|
||||
value="upload"
|
||||
onClick={() => (importMethodRef.current = ImportMethod.upload)}
|
||||
/>
|
||||
<Tab
|
||||
label="Paste"
|
||||
value="paste"
|
||||
onClick={() => (importMethodRef.current = ImportMethod.paste)}
|
||||
/>
|
||||
<Tab
|
||||
label="URL"
|
||||
value="url"
|
||||
onClick={() => (importMethodRef.current = ImportMethod.url)}
|
||||
/>
|
||||
</TabList>
|
||||
<Divider style={{ marginTop: -1 }} />
|
||||
|
||||
@@ -295,7 +356,12 @@ export default function ImportCsv({ render, PopoverProps }: IImportCsvProps) {
|
||||
color="primary"
|
||||
disabled={!validCsv}
|
||||
className={classes.continueButton}
|
||||
onClick={() => setOpenWizard(true)}
|
||||
onClick={() => {
|
||||
setOpenWizard(true);
|
||||
analytics.logEvent(`import_${importMethodRef.current}`, {
|
||||
type: importTypeRef.current,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
@@ -303,6 +369,7 @@ export default function ImportCsv({ render, PopoverProps }: IImportCsvProps) {
|
||||
|
||||
{openWizard && csvData && (
|
||||
<ImportCsvWizard
|
||||
importType={importTypeRef.current}
|
||||
handleClose={() => setOpenWizard(false)}
|
||||
csvData={csvData}
|
||||
/>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useSnackbar } from "notistack";
|
||||
|
||||
import { MenuItem, DialogContentText, LinearProgress } from "@mui/material";
|
||||
|
||||
import { analytics } from "@src/analytics";
|
||||
import Modal from "@src/components/Modal";
|
||||
import CodeEditor from "@src/components/CodeEditor";
|
||||
|
||||
@@ -49,6 +50,7 @@ export default function ExportSettings({
|
||||
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const handleExport = () => {
|
||||
analytics.logEvent("export_tableSettings");
|
||||
navigator.clipboard.writeText(formattedJson);
|
||||
enqueueSnackbar("Copied to clipboard");
|
||||
handleClose();
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useSnackbar } from "notistack";
|
||||
|
||||
import { MenuItem, DialogContentText, FormHelperText } from "@mui/material";
|
||||
|
||||
import { analytics } from "@src/analytics";
|
||||
import Modal from "@src/components/Modal";
|
||||
import DiffEditor from "@src/components/CodeEditor/DiffEditor";
|
||||
|
||||
@@ -59,8 +60,8 @@ export default function ImportSettings({
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const { setValue } = useFormMethods;
|
||||
const handleImport = () => {
|
||||
analytics.logEvent("import_tableSettings");
|
||||
const { id, collection, ...newValues } = JSON.parse(newSettings);
|
||||
|
||||
for (const key in newValues) {
|
||||
setValue(key, newValues[key], {
|
||||
shouldDirty: true,
|
||||
|
||||
@@ -21,6 +21,7 @@ import { ColumnConfig } from "@src/hooks/useTable/useTableConfig";
|
||||
import { useProjectContext } from "@src/contexts/ProjectContext";
|
||||
import { getFieldProp } from "@src/components/fields";
|
||||
import { analytics } from "@src/analytics";
|
||||
import { ImportType } from "@src/components/TableHeader/ImportCsv";
|
||||
|
||||
export type CsvConfig = {
|
||||
pairs: { csvKey: string; columnKey: string }[];
|
||||
@@ -36,6 +37,7 @@ export interface IStepProps {
|
||||
}
|
||||
|
||||
export interface IImportCsvWizardProps {
|
||||
importType: ImportType;
|
||||
handleClose: () => void;
|
||||
csvData: {
|
||||
columns: string[];
|
||||
@@ -44,6 +46,7 @@ export interface IImportCsvWizardProps {
|
||||
}
|
||||
|
||||
export default function ImportCsvWizard({
|
||||
importType,
|
||||
handleClose,
|
||||
csvData,
|
||||
}: IImportCsvWizardProps) {
|
||||
@@ -96,7 +99,7 @@ export default function ImportCsvWizard({
|
||||
for (const col of config.newColumns) {
|
||||
tableActions.column.add(col.name, col.type, col);
|
||||
}
|
||||
analytics.logEvent("import_csv");
|
||||
analytics.logEvent("import_success", { type: importType }); //change this import_success
|
||||
// Close wizard
|
||||
setOpen(false);
|
||||
setTimeout(handleClose, 300);
|
||||
|
||||
@@ -31,7 +31,7 @@ import Json from "./Json";
|
||||
import Code from "./Code";
|
||||
import Action from "./Action";
|
||||
import Derivative from "./Derivative";
|
||||
import Aggregate from "./Aggregate";
|
||||
// import Aggregate from "./Aggregate";
|
||||
import CreatedBy from "./CreatedBy";
|
||||
import UpdatedBy from "./UpdatedBy";
|
||||
import CreatedAt from "./CreatedAt";
|
||||
@@ -77,7 +77,7 @@ export const FIELDS: IFieldConfig[] = [
|
||||
// CLOUD FUNCTION
|
||||
Action,
|
||||
Derivative,
|
||||
Aggregate,
|
||||
// Aggregate,
|
||||
Status,
|
||||
// AUDITING
|
||||
CreatedBy,
|
||||
|
||||
57
yarn.lock
57
yarn.lock
@@ -3753,25 +3753,25 @@ acorn-walk@^7.1.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
|
||||
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
|
||||
|
||||
acorn-walk@^8.2.0:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
|
||||
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
|
||||
|
||||
acorn@^6.4.1:
|
||||
version "6.4.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
|
||||
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
|
||||
|
||||
acorn@^7.1.0, acorn@^7.4.0:
|
||||
acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0:
|
||||
version "7.4.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
||||
acorn@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
|
||||
integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
|
||||
|
||||
acorn@^8.2.4:
|
||||
version "8.4.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c"
|
||||
integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==
|
||||
acorn@^8.2.4, acorn@^8.7.0:
|
||||
version "8.7.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
|
||||
integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
|
||||
|
||||
address@1.1.2, address@^1.0.1:
|
||||
version "1.1.2"
|
||||
@@ -8011,9 +8011,9 @@ fn.name@1.x.x:
|
||||
integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
version "1.14.7"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
|
||||
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
|
||||
version "1.14.8"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
|
||||
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
@@ -14052,9 +14052,9 @@ querystring@^0.2.0:
|
||||
integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==
|
||||
|
||||
querystringify@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e"
|
||||
integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
|
||||
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
|
||||
|
||||
queue-microtask@^1.2.2:
|
||||
version "1.2.3"
|
||||
@@ -17108,18 +17108,10 @@ url-parse-lax@^3.0.0:
|
||||
dependencies:
|
||||
prepend-http "^2.0.0"
|
||||
|
||||
url-parse@^1.4.3:
|
||||
version "1.4.7"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
|
||||
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
|
||||
dependencies:
|
||||
querystringify "^2.1.1"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
url-parse@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b"
|
||||
integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==
|
||||
url-parse@^1.4.3, url-parse@^1.5.1:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
|
||||
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
|
||||
dependencies:
|
||||
querystringify "^2.1.1"
|
||||
requires-port "^1.0.0"
|
||||
@@ -17320,9 +17312,12 @@ vm-browserify@^1.0.1:
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
|
||||
vm2@^3.9.3:
|
||||
version "3.9.5"
|
||||
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496"
|
||||
integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==
|
||||
version "3.9.7"
|
||||
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.7.tgz#bb87aa677c97c61e23a6cb6547e44e990517a6f6"
|
||||
integrity sha512-g/GZ7V0Mlmch3eDVOATvAXr1GsJNg6kQ5PjvYy3HbJMCRn5slNbo/u73Uy7r5yUej1cRa3ZjtoVwcWSQuQ/fow==
|
||||
dependencies:
|
||||
acorn "^8.7.0"
|
||||
acorn-walk "^8.2.0"
|
||||
|
||||
w3c-hr-time@^1.0.2:
|
||||
version "1.0.2"
|
||||
|
||||
Reference in New Issue
Block a user