From b80b0ca3fae593b344f7a96db74b11af0d0d9e83 Mon Sep 17 00:00:00 2001 From: Favour Ohanekwu Date: Mon, 3 Apr 2023 11:41:15 +0100 Subject: [PATCH] feat: show lint errors in async functions bound to sync fields (#21187) ## Description This PR improves the error resolution journey for users. Lint warnings are added to async JS functions which are bound to data fields (sync fields). - JSObjects are "linted" by individual properties (as opposed to being "linted" as a whole) - Only edited jsobject properties get "linted", improving jsObject linting by ~35%.(This largely depends on the size of the JSObject) Screenshot 2023-04-03 at 11 17 45 Screenshot 2023-03-14 at 11 26 00 Screenshot 2023-03-14 at 11 41 11 Fixes #20289 Fixes #20008 ## Type of change - Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - CYPRESS - JEST ### Test Plan > Add Testsmith test cases links that relate to this PR ### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) ## Checklist: ### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag ### QA activity: - [ ] Test plan has been approved by relevant developers - [x] Test plan has been peer reviewed by QA - [x] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reveiwing all Cypress test --- .../Autocomplete/autocomplete_spec.js | 3 +- .../AsyncFunctionsBoundInSyncFields_Spec.ts | 130 ++ .../cypress/support/Objects/CommonLocators.ts | 1 + app/client/package.json | 2 - app/client/src/actions/lintingActions.ts | 8 +- app/client/src/ce/reducers/index.tsx | 4 +- .../src/ce/workers/Evaluation/Actions.ts | 28 +- .../ce/workers/Evaluation/evaluationUtils.ts | 13 + .../CodeEditor/EvaluatedValuePopup.tsx | 76 +- .../editorComponents/CodeEditor/index.tsx | 1 + .../CodeEditor/lintHelpers.test.ts | 22 +- .../CodeEditor/lintHelpers.ts | 45 +- .../CodeEditor/utils/entityNavigationUtils.ts | 14 + .../lintingReducers/lintErrorsReducers.ts | 15 +- app/client/src/sagas/DebuggerSagas.ts | 2 +- app/client/src/sagas/EvalWorkerActionSagas.ts | 16 +- app/client/src/sagas/EvaluationsSaga.ts | 1 + app/client/src/sagas/LintingSagas.ts | 77 +- app/client/src/sagas/PostLintingSagas.ts | 4 +- app/client/src/selectors/lintingSelectors.ts | 4 - .../src/selectors/navigationSelectors.ts | 23 +- app/client/src/utils/DynamicBindingUtils.ts | 11 + .../asyncJSFunctionBoundToDataField.ts | 247 +++ .../src/workers/Evaluation/JSObject/index.ts | 153 +- .../Evaluation/JSObject/jsPropertiesState.ts | 79 + .../src/workers/Evaluation/JSObject/test.ts | 1497 ++++++++++++++- .../src/workers/Evaluation/JSObject/utils.ts | 1 - .../__tests__/errorModifier.test.ts | 20 +- .../Evaluation/__tests__/evaluate.test.ts | 3 + .../src/workers/Evaluation/errorModifier.ts | 71 +- app/client/src/workers/Evaluation/evaluate.ts | 30 +- .../workers/Evaluation/handlers/evalTree.ts | 72 +- app/client/src/workers/Evaluation/types.ts | 2 + app/client/src/workers/Linting/constants.ts | 36 +- app/client/src/workers/Linting/globalData.ts | 47 + app/client/src/workers/Linting/index.ts | 202 +-- app/client/src/workers/Linting/lint.worker.ts | 29 +- app/client/src/workers/Linting/types.ts | 68 +- app/client/src/workers/Linting/utils.ts | 407 +++-- .../workers/common/DataTreeEvaluator/index.ts | 17 +- .../workers/common/DataTreeEvaluator/utils.ts | 52 + .../src/workers/common/DependencyMap/index.ts | 102 +- .../src/workers/common/DependencyMap/utils.ts | 24 +- app/client/yarn.lock | 7 +- app/shared/ast/index.ts | 12 +- app/shared/ast/package.json | 3 + app/shared/ast/src/index.test.ts | 246 ++- app/shared/ast/src/index.ts | 26 +- app/shared/ast/src/jsObject/index.ts | 146 +- app/shared/ast/src/utils.ts | 46 +- app/shared/ast/yarn.lock | 1598 +++++++++-------- 51 files changed, 4383 insertions(+), 1360 deletions(-) create mode 100644 app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Linting/AsyncFunctionsBoundInSyncFields_Spec.ts create mode 100644 app/client/src/components/editorComponents/CodeEditor/utils/entityNavigationUtils.ts create mode 100644 app/client/src/workers/Evaluation/JSObject/asyncJSFunctionBoundToDataField.ts create mode 100644 app/client/src/workers/Evaluation/JSObject/jsPropertiesState.ts create mode 100644 app/client/src/workers/Linting/globalData.ts diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Autocomplete/autocomplete_spec.js b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Autocomplete/autocomplete_spec.js index 12e6450ec0..6856fbc1c5 100644 --- a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Autocomplete/autocomplete_spec.js +++ b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Autocomplete/autocomplete_spec.js @@ -1,6 +1,5 @@ const dsl = require("../../../../fixtures/autocomp.json"); const dynamicInputLocators = require("../../../../locators/DynamicInput.json"); -const apiwidget = require("../../../../locators/apiWidgetslocator.json"); describe("Dynamic input autocomplete", () => { before(() => { @@ -72,7 +71,7 @@ describe("Dynamic input autocomplete", () => { cy.wait(1000); cy.evaluateErrorMessage( - "Found a reference to {{actionName}} during evaluation. Sync fields cannot execute framework actions. Please remove any direct/indirect references to {{actionName}} and try again.".replaceAll( + "Found a reference to {{actionName}} during evaluation. Data fields cannot execute framework actions. Please remove any direct/indirect references to {{actionName}} and try again.".replaceAll( "{{actionName}}", "storeValue()", ), diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Linting/AsyncFunctionsBoundInSyncFields_Spec.ts b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Linting/AsyncFunctionsBoundInSyncFields_Spec.ts new file mode 100644 index 0000000000..84191b728a --- /dev/null +++ b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Linting/AsyncFunctionsBoundInSyncFields_Spec.ts @@ -0,0 +1,130 @@ +import * as _ from "../../../../support/Objects/ObjectsCore"; + +describe("Linting async JSFunctions bound to data fields", () => { + before(() => { + _.entityExplorer.DragDropWidgetNVerify("buttonwidget", 300, 300); + _.entityExplorer.NavigateToSwitcher("explorer"); + }); + + it("1. Doesn't show lint warnings in debugger but shows on Hover only", () => { + _.apiPage.CreateApi(); + const JS_OBJECT_CONTENT = `export default { + myFun1: () => { + //write code here + Api1.run() + }, + myFun2: async () => { + //use async-await or promises + } + }`; + + _.jsEditor.CreateJSObject(JS_OBJECT_CONTENT, { + paste: true, + completeReplace: true, + toRun: false, + shouldCreateNewJSObj: true, + }); + _.entityExplorer.SelectEntityByName("Button1", "Widgets"); + _.propPane.UpdatePropertyFieldValue("Label", "{{JSObject1.myFun2()}}"); + cy.get(_.locators._evaluateMsg).should("be.visible"); + cy.contains("View Source").click(); // should route to jsobject page + cy.get(_.locators._lintWarningElement).should("have.length", 1); + MouseHoverNVerify( + "myFun2", + `Cannot bind async functions to data fields. Convert this to a sync function or remove references to "JSObject1.myFun2" on the following data field: Button1.text`, + false, + ); + // remove async tag from function + _.jsEditor.EditJSObj(`export default { + myFun1: () => { + //write code here + Api1.run() + }, + myFun2: () => { + //use async-await or promises + } + }`); + + cy.get(_.locators._lintWarningElement).should("not.exist"); + + // Add async tag from function + _.jsEditor.EditJSObj(`export default { + myFun1: () => { + //write code here + Api1.run() + }, + myFun2: async () => { + //use async-await or promises + } + }`); + + cy.get(_.locators._lintWarningElement).should("have.length", 1); + MouseHoverNVerify( + "myFun2", + `Cannot bind async functions to data fields. Convert this to a sync function or remove references to "JSObject1.myFun2" on the following data field: Button1.text`, + false, + ); + + _.entityExplorer.SelectEntityByName("Button1", "Widgets"); + _.propPane.UpdatePropertyFieldValue("Label", "{{JSObject1.myFun1()}}"); + cy.get(_.locators._evaluateMsg).should("be.visible"); + cy.contains("View Source").click(); // should route to jsobject page + cy.get(_.locators._lintWarningElement).should("have.length", 2); + MouseHoverNVerify( + "myFun1", + `Functions bound to data fields cannot execute async code. Remove async statements highlighted below or remove references to "JSObject1.myFun1" on the following data field: Button1.text`, + false, + ); + MouseHoverNVerify( + "run", + `Cannot execute async code on functions bound to data fields`, + false, + ); + _.jsEditor.EditJSObj(`export default { + myFun1: () => { + //write code here + Api1.run() + }, + myFun2: async () => { + //use async-await or promises + } + }`); + // Remove binding from label, and add to onClick. Expect no error + _.entityExplorer.SelectEntityByName("Button1", "Widgets"); + _.propPane.UpdatePropertyFieldValue("Label", "Click here"); + _.propPane.EnterJSContext( + "onClick", + `{{ + () => { + JSObject1.myFun1(); + JSObject1.myFun2() + }}}`, + ); + _.entityExplorer.ExpandCollapseEntity("Queries/JS"); + _.entityExplorer.SelectEntityByName("JSObject1", "Queries/JS"); + cy.get(_.locators._lintWarningElement).should("not.exist"); + }); + + function MouseHoverNVerify(lintOn: string, debugMsg: string, isError = true) { + _.agHelper.Sleep(); + const element = isError + ? cy.get(_.locators._lintErrorElement) + : cy.get(_.locators._lintWarningElement); + element.contains(lintOn).should("exist").first().trigger("mouseover"); + _.agHelper.AssertContains(debugMsg); + } + + after(() => { + //deleting all test data + _.entityExplorer.ActionContextMenuByEntityName( + "Api1", + "Delete", + "Are you sure?", + ); + _.entityExplorer.ActionContextMenuByEntityName( + "JSObject1", + "Delete", + "Are you sure?", + ); + }); +}); diff --git a/app/client/cypress/support/Objects/CommonLocators.ts b/app/client/cypress/support/Objects/CommonLocators.ts index b065dc8064..73374173cf 100644 --- a/app/client/cypress/support/Objects/CommonLocators.ts +++ b/app/client/cypress/support/Objects/CommonLocators.ts @@ -176,5 +176,6 @@ export class CommonLocators { _commentString = ".cm-comment"; _modalWrapper = "[data-cy='modal-wrapper']"; _editorBackButton = ".t--close-editor"; + _evaluateMsg = ".t--evaluatedPopup-error"; _canvas = "[data-testid=widgets-editor]"; } diff --git a/app/client/package.json b/app/client/package.json index 14cef1e4ca..1afd07ed12 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -64,9 +64,7 @@ "@uppy/url": "^1.5.16", "@uppy/webcam": "^1.8.4", "@welldone-software/why-did-you-render": "^4.2.5", - "acorn-walk": "^8.2.0", "algoliasearch": "^4.2.0", - "astring": "^1.7.5", "axios": "^0.27.2", "classnames": "^2.3.1", "codemirror": "^5.59.2", diff --git a/app/client/src/actions/lintingActions.ts b/app/client/src/actions/lintingActions.ts index 654b59ee38..1cc94caa9d 100644 --- a/app/client/src/actions/lintingActions.ts +++ b/app/client/src/actions/lintingActions.ts @@ -1,11 +1,11 @@ +import type { LintErrorsStore } from "reducers/lintingReducers/lintErrorsReducers"; import type { ReduxAction } from "@appsmith/constants/ReduxActionConstants"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; -import type { LintErrors } from "reducers/lintingReducers/lintErrorsReducers"; -export type SetLintErrorsAction = ReduxAction<{ errors: LintErrors }>; +export type SetLintErrorsAction = ReduxAction<{ errors: LintErrorsStore }>; export const setLintingErrors = ( - errors: LintErrors, -): ReduxAction<{ errors: LintErrors }> => { + errors: LintErrorsStore, +): ReduxAction<{ errors: LintErrorsStore }> => { return { type: ReduxActionTypes.SET_LINT_ERRORS, payload: { errors }, diff --git a/app/client/src/ce/reducers/index.tsx b/app/client/src/ce/reducers/index.tsx index c0033e0534..190d3634b6 100644 --- a/app/client/src/ce/reducers/index.tsx +++ b/app/client/src/ce/reducers/index.tsx @@ -68,7 +68,7 @@ import type { EditorContextState } from "reducers/uiReducers/editorContextReduce import type { LibraryState } from "reducers/uiReducers/libraryReducer"; import type { AutoHeightLayoutTreeReduxState } from "reducers/entityReducers/autoHeightReducers/autoHeightLayoutTreeReducer"; import type { CanvasLevelsReduxState } from "reducers/entityReducers/autoHeightReducers/canvasLevelsReducer"; -import type { LintErrors } from "reducers/lintingReducers/lintErrorsReducers"; +import type { LintErrorsStore } from "reducers/lintingReducers/lintErrorsReducers"; import lintErrorReducer from "reducers/lintingReducers"; import type { AutoHeightUIState } from "reducers/uiReducers/autoHeightReducer"; import type { AnalyticsReduxState } from "reducers/uiReducers/analyticsReducer"; @@ -159,7 +159,7 @@ export interface AppState { triggers: TriggerValuesEvaluationState; }; linting: { - errors: LintErrors; + errors: LintErrorsStore; }; form: { [key: string]: any; diff --git a/app/client/src/ce/workers/Evaluation/Actions.ts b/app/client/src/ce/workers/Evaluation/Actions.ts index a9609bef75..7e04151ca3 100644 --- a/app/client/src/ce/workers/Evaluation/Actions.ts +++ b/app/client/src/ce/workers/Evaluation/Actions.ts @@ -8,6 +8,7 @@ import { entityFns, getPlatformFunctions, } from "@appsmith/workers/Evaluation/fns"; +import { klona } from "klona/full"; declare global { /** All identifiers added to the worker global scope should also * be included in the DEDICATED_WORKER_GLOBAL_SCOPE_IDENTIFIERS in @@ -33,21 +34,21 @@ export enum ExecutionType { export const addDataTreeToContext = (args: { EVAL_CONTEXT: EvalContext; dataTree: Readonly; - skipEntityFunctions?: boolean; + removeEntityFunctions?: boolean; isTriggerBased: boolean; }) => { const { dataTree, EVAL_CONTEXT, isTriggerBased, - skipEntityFunctions = false, + removeEntityFunctions = false, } = args; const dataTreeEntries = Object.entries(dataTree); const entityFunctionCollection: Record> = {}; for (const [entityName, entity] of dataTreeEntries) { EVAL_CONTEXT[entityName] = entity; - if (skipEntityFunctions || !isTriggerBased) continue; + if (!removeEntityFunctions && !isTriggerBased) continue; for (const entityFn of entityFns) { if (!entityFn.qualifier(entity)) continue; const func = entityFn.fn(entity, entityName); @@ -56,6 +57,12 @@ export const addDataTreeToContext = (args: { } } + if (removeEntityFunctions) + return removeEntityFunctionsFromEvalContext( + entityFunctionCollection, + EVAL_CONTEXT, + ); + // if eval is not trigger based i.e., sync eval then we skip adding entity and platform function to evalContext if (!isTriggerBased) return; @@ -87,3 +94,18 @@ export const getAllAsyncFunctions = (dataTree: DataTree) => { } return asyncFunctionNameMap; }; + +export const removeEntityFunctionsFromEvalContext = ( + entityFunctionCollection: Record>, + evalContext: EvalContext, +) => { + for (const [entityName, funcObj] of Object.entries( + entityFunctionCollection, + )) { + const entity = klona(evalContext[entityName]); + Object.keys(funcObj).forEach((entityFn) => { + delete entity[entityFn]; + }); + evalContext[entityName] = entity; + } +}; diff --git a/app/client/src/ce/workers/Evaluation/evaluationUtils.ts b/app/client/src/ce/workers/Evaluation/evaluationUtils.ts index 6b32900e38..d9623dda1e 100644 --- a/app/client/src/ce/workers/Evaluation/evaluationUtils.ts +++ b/app/client/src/ce/workers/Evaluation/evaluationUtils.ts @@ -391,6 +391,15 @@ export function isJSAction(entity: DataTreeEntity): entity is JSActionEntity { entity.ENTITY_TYPE === ENTITY_TYPE.JSACTION ); } +export function isJSActionConfig( + entity: DataTreeEntityConfig, +): entity is JSActionEntityConfig { + return ( + typeof entity === "object" && + "ENTITY_TYPE" in entity && + entity.ENTITY_TYPE === ENTITY_TYPE.JSACTION + ); +} export function isJSObject(entity: DataTreeEntity): entity is JSActionEntity { return ( @@ -402,6 +411,10 @@ export function isJSObject(entity: DataTreeEntity): entity is JSActionEntity { ); } +export function isDataTreeEntity(entity: unknown) { + return !!entity && typeof entity === "object" && "ENTITY_TYPE" in entity; +} + // We need to remove functions from data tree to avoid any unexpected identifier while JSON parsing // Check issue https://github.com/appsmithorg/appsmith/issues/719 export const removeFunctions = (value: any) => { diff --git a/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx b/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx index cee3e75654..e8f9034ccf 100644 --- a/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx @@ -24,6 +24,7 @@ import { ReactComponent as CopyIcon } from "assets/icons/menu/copy-snippet.svg"; import copy from "copy-to-clipboard"; import type { EvaluationError } from "utils/DynamicBindingUtils"; +import { PropertyEvaluationErrorCategory } from "utils/DynamicBindingUtils"; import * as Sentry from "@sentry/react"; import { Severity } from "@sentry/react"; import type { CodeEditorExpected } from "components/editorComponents/CodeEditor/index"; @@ -33,6 +34,11 @@ import { useDispatch, useSelector } from "react-redux"; import { getEvaluatedPopupState } from "selectors/editorContextSelectors"; import type { AppState } from "@appsmith/reducers"; import { setEvalPopupState } from "actions/editorContextActions"; +import { Link } from "react-router-dom"; +import { showDebugger } from "actions/debuggerActions"; +import { modText } from "utils/helpers"; +import { getEntityNameAndPropertyPath } from "@appsmith/workers/Evaluation/evaluationUtils"; +import { getJSFunctionNavigationUrl } from "selectors/navigationSelectors"; const modifiers: IPopoverSharedProps["modifiers"] = { offset: { @@ -183,6 +189,24 @@ const StyledTitleName = styled.p` cursor: pointer; `; +const AsyncFunctionErrorLink = styled(Link)` + color: ${(props) => props.theme.colors.debugger.entityLink}; + font-weight: 600; + font-size: 12px; + line-height: 14px; + cursor: pointer; + letter-spacing: 0.6px; + &:hover { + color: ${(props) => props.theme.colors.debugger.entityLink}; + } +`; + +const AsyncFunctionErrorView = styled.div` + display: flex; + margin-top: 12px; + justify-content: space-between; +`; + function CollapseToggle(props: { isOpen: boolean }) { const { isOpen } = props; return ( @@ -462,16 +486,38 @@ function PopoverContent(props: PopoverContentProps) { ? popupContext.value : true, ); + const { errors, expected, hasError, onMouseEnter, onMouseLeave, theme } = + props; + const { entityName } = getEntityNameAndPropertyPath(props.dataTreePath || ""); + const JSFunctionInvocationError = errors.find( + ({ kind }) => + kind && + kind.category === + PropertyEvaluationErrorCategory.INVALID_JS_FUNCTION_INVOCATION_IN_DATA_FIELD && + kind.rootcause, + ); + const errorNavigationUrl = useSelector((state: AppState) => + getJSFunctionNavigationUrl( + state, + entityName, + JSFunctionInvocationError?.kind?.rootcause, + ), + ); const toggleExpectedDataType = () => setOpenExpectedDataType(!openExpectedDataType); const toggleExpectedExample = () => setOpenExpectedExample(!openExpectedExample); - const { errors, expected, hasError, onMouseEnter, onMouseLeave, theme } = - props; + let error: EvaluationError | undefined; if (hasError) { error = errors[0]; } + const openDebugger = ( + event: React.MouseEvent, + ) => { + event.preventDefault(); + dispatch(showDebugger()); + }; useEffect(() => { dispatch( @@ -508,13 +554,25 @@ function PopoverContent(props: PopoverContentProps) { {/* errorMessage could be an empty string */} {getErrorMessage(error.errorMessage)} - + + {errorNavigationUrl ? ( + + openDebugger(e)} to=""> + See Error ({modText()} D) + + + View Source + + + ) : ( + + )} )} {props.expected && props.expected.type !== UNDEFINED_VALIDATION && ( diff --git a/app/client/src/components/editorComponents/CodeEditor/index.tsx b/app/client/src/components/editorComponents/CodeEditor/index.tsx index 28ef127ae7..e819334201 100644 --- a/app/client/src/components/editorComponents/CodeEditor/index.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/index.tsx @@ -1263,6 +1263,7 @@ class CodeEditor extends Component { text="/" /> )} + { } `; - const errors: LintError[] = []; + const errors: LintError[] = [ + { + errorType: PropertyEvaluationErrorType.LINT, + errorSegment: "", + originalBinding: value, + line: 0, + ch: 0, + code: INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE, + variables: [], + raw: value, + errorMessage: { + name: "LintingError", + message: INVALID_JSOBJECT_START_STATEMENT, + }, + severity: Severity.ERROR, + }, + ]; const res = getLintAnnotations(value, errors, { isJSObject: true }); expect(res).toEqual([ diff --git a/app/client/src/components/editorComponents/CodeEditor/lintHelpers.ts b/app/client/src/components/editorComponents/CodeEditor/lintHelpers.ts index 8229c1c831..1b33c90012 100644 --- a/app/client/src/components/editorComponents/CodeEditor/lintHelpers.ts +++ b/app/client/src/components/editorComponents/CodeEditor/lintHelpers.ts @@ -13,7 +13,7 @@ import { CUSTOM_LINT_ERRORS, IDENTIFIER_NOT_DEFINED_LINT_ERROR_CODE, INVALID_JSOBJECT_START_STATEMENT, - JS_OBJECT_START_STATEMENT, + INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE, } from "workers/Linting/constants"; export const getIndexOfRegex = ( str: string, @@ -123,33 +123,32 @@ export const getLintAnnotations = ( const lintErrors = filterInvalidLintErrors(errors, contextData); const lines = value.split("\n"); - // The binding position of every valid JS Object is constant, so we need not - // waste time checking for position of binding. - // For JS Objects not starting with the expected "export default" statement, we return early - // with a "invalid start statement" lint error - if ( - isJSObject && - !isEmpty(lines) && - !lines[0].startsWith(JS_OBJECT_START_STATEMENT) - ) { - return [ - { - from: CODE_EDITOR_START_POSITION, - to: getFirstNonEmptyPosition(lines), - message: INVALID_JSOBJECT_START_STATEMENT, - severity: Severity.ERROR, - }, - ]; - } - lintErrors.forEach((error) => { - const { ch, errorMessage, line, originalBinding, severity, variables } = - error; + const { + ch, + code, + errorMessage, + line, + originalBinding, + severity, + variables, + } = error; if (!originalBinding) { return annotations; } - + if (code === INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE) { + // The binding position of every valid JS Object is constant, so we need not + // waste time checking for position of binding. + // For JS Objects not starting with the expected "export default" statement, we return early + // with a "invalid start statement" lint error + return annotations.push({ + from: CODE_EDITOR_START_POSITION, + to: getFirstNonEmptyPosition(lines), + message: INVALID_JSOBJECT_START_STATEMENT, + severity: Severity.ERROR, + }); + } let variableLength = 1; // Find the variable with minimal length if (variables) { diff --git a/app/client/src/components/editorComponents/CodeEditor/utils/entityNavigationUtils.ts b/app/client/src/components/editorComponents/CodeEditor/utils/entityNavigationUtils.ts new file mode 100644 index 0000000000..e141767ae8 --- /dev/null +++ b/app/client/src/components/editorComponents/CodeEditor/utils/entityNavigationUtils.ts @@ -0,0 +1,14 @@ +import type { EntityNavigationData } from "selectors/navigationSelectors"; + +export const addThisReference = ( + navigationData: EntityNavigationData, + entityName?: string, +) => { + if (entityName && entityName in navigationData) { + return { + ...navigationData, + this: navigationData[entityName], + }; + } + return navigationData; +}; diff --git a/app/client/src/reducers/lintingReducers/lintErrorsReducers.ts b/app/client/src/reducers/lintingReducers/lintErrorsReducers.ts index 1f2be651a0..b484c0337c 100644 --- a/app/client/src/reducers/lintingReducers/lintErrorsReducers.ts +++ b/app/client/src/reducers/lintingReducers/lintErrorsReducers.ts @@ -4,22 +4,21 @@ import { createImmerReducer } from "utils/ReducerUtils"; import type { SetLintErrorsAction } from "actions/lintingActions"; import { isEqual } from "lodash"; -export interface LintErrors { - [entityName: string]: LintError[]; -} +export type LintErrorsStore = Record; -const initialState: LintErrors = {}; +const initialState: LintErrorsStore = {}; export const lintErrorReducer = createImmerReducer(initialState, { [ReduxActionTypes.FETCH_PAGE_INIT]: () => initialState, [ReduxActionTypes.SET_LINT_ERRORS]: ( - state: LintErrors, + state: LintErrorsStore, action: SetLintErrorsAction, ) => { const { errors } = action.payload; - for (const entityName of Object.keys(errors)) { - if (isEqual(state[entityName], errors[entityName])) continue; - state[entityName] = errors[entityName]; + for (const entityPath of Object.keys(errors)) { + const entityPathLintErrors = errors[entityPath]; + if (isEqual(entityPathLintErrors, state[entityPath])) continue; + state[entityPath] = entityPathLintErrors; } }, }); diff --git a/app/client/src/sagas/DebuggerSagas.ts b/app/client/src/sagas/DebuggerSagas.ts index 7cc404147c..7462b6489f 100644 --- a/app/client/src/sagas/DebuggerSagas.ts +++ b/app/client/src/sagas/DebuggerSagas.ts @@ -404,7 +404,7 @@ function* logDebuggerErrorAnalyticsSaga( ); const pluginId = action?.pluginId || payload?.analytics?.pluginId || ""; const plugin: Plugin = yield select(getPlugin, pluginId); - const pluginName = plugin.name.replace(/ /g, ""); + const pluginName = plugin?.name.replace(/ /g, ""); let propertyPath = `${pluginName}`; if (payload.propertyPath) { diff --git a/app/client/src/sagas/EvalWorkerActionSagas.ts b/app/client/src/sagas/EvalWorkerActionSagas.ts index 29a5cb95a4..aea8705a99 100644 --- a/app/client/src/sagas/EvalWorkerActionSagas.ts +++ b/app/client/src/sagas/EvalWorkerActionSagas.ts @@ -20,6 +20,7 @@ import { logJSFunctionExecution } from "@appsmith/sagas/JSFunctionExecutionSaga" import { handleStoreOperations } from "./ActionExecution/StoreActionSaga"; import isEmpty from "lodash/isEmpty"; import { sortJSExecutionDataByCollectionId } from "workers/Evaluation/JSObject/utils"; +import type { LintTreeSagaRequestData } from "workers/Linting/types"; export function* handleEvalWorkerRequestSaga(listenerChannel: Channel) { while (true) { @@ -31,12 +32,21 @@ export function* handleEvalWorkerRequestSaga(listenerChannel: Channel) { export function* lintTreeActionHandler(message: any) { const { body } = message; const { data } = body; + const { + asyncJSFunctionsInDataFields, + configTree, + jsPropertiesState, + pathsToLint: lintOrder, + unevalTree, + } = data as LintTreeSagaRequestData; yield put({ type: ReduxActionTypes.LINT_TREE, payload: { - pathsToLint: data.lintOrder, - unevalTree: data.unevalTree, - configTree: data.configTree, + pathsToLint: lintOrder, + unevalTree, + jsPropertiesState, + asyncJSFunctionsInDataFields, + configTree, }, }); } diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index 7cfbe0e6de..540e408be3 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -165,6 +165,7 @@ export function* evaluateTreeSaga( requiresLinting: isEditMode && requiresLinting, forceEvaluation, metaWidgets, + appMode, }; const workerResponse: EvalTreeResponseData = yield call( diff --git a/app/client/src/sagas/LintingSagas.ts b/app/client/src/sagas/LintingSagas.ts index 557a10f1d5..ec367c39d9 100644 --- a/app/client/src/sagas/LintingSagas.ts +++ b/app/client/src/sagas/LintingSagas.ts @@ -14,6 +14,11 @@ import type { import { LINT_WORKER_ACTIONS } from "workers/Linting/types"; import { logLatestLintPropertyErrors } from "./PostLintingSagas"; import { getAppsmithConfigs } from "@appsmith/configs"; +import type { AppState } from "@appsmith/reducers"; +import type { LintError } from "utils/DynamicBindingUtils"; +import { get, set, union } from "lodash"; +import type { LintErrorsStore } from "reducers/lintingReducers/lintErrorsReducers"; +import type { TJSPropertiesState } from "workers/Evaluation/JSObject/jsPropertiesState"; const APPSMITH_CONFIGS = getAppsmithConfigs(); @@ -35,8 +40,58 @@ function* updateLintGlobals(action: ReduxAction) { ); } +function* getValidOldJSCollectionLintErrors( + jsEntities: string[], + errors: LintErrorsStore, + jsObjectsState: TJSPropertiesState, +) { + const updatedJSCollectionLintErrors: LintErrorsStore = {}; + for (const jsObjectName of jsEntities) { + const jsObjectBodyPath = `["${jsObjectName}.body"]`; + const oldJsBodyLintErrors: LintError[] = yield select((state: AppState) => + get(state.linting.errors, jsObjectBodyPath, []), + ); + const newJSBodyLintErrors = get( + errors, + jsObjectBodyPath, + [] as LintError[], + ); + + const newJSBodyLintErrorsOriginalPaths = newJSBodyLintErrors.reduce( + (paths, currentError) => { + if (currentError.originalPath) + return union(paths, [currentError.originalPath]); + return paths; + }, + [] as string[], + ); + + const jsObjectState = get(jsObjectsState, jsObjectName, {}); + const jsObjectProperties = Object.keys(jsObjectState); + + const filteredOldJsObjectBodyLintErrors = oldJsBodyLintErrors.filter( + (lintError) => + lintError.originalPath && + lintError.originalPath in jsObjectProperties && + !(lintError.originalPath in newJSBodyLintErrorsOriginalPaths), + ); + const updatedLintErrors = [ + ...filteredOldJsObjectBodyLintErrors, + ...newJSBodyLintErrors, + ]; + set(updatedJSCollectionLintErrors, jsObjectBodyPath, updatedLintErrors); + } + return updatedJSCollectionLintErrors; +} + export function* lintTreeSaga(action: ReduxAction) { - const { configTree, pathsToLint, unevalTree } = action.payload; + const { + asyncJSFunctionsInDataFields, + configTree, + jsPropertiesState, + pathsToLint, + unevalTree, + } = action.payload; // only perform lint operations in edit mode const appMode: APP_MODE = yield select(getAppMode); if (appMode !== APP_MODE.EDIT) return; @@ -44,18 +99,32 @@ export function* lintTreeSaga(action: ReduxAction) { const lintTreeRequestData: LintTreeRequest = { pathsToLint, unevalTree, + jsPropertiesState, configTree, cloudHosting: !!APPSMITH_CONFIGS.cloudHosting, + asyncJSFunctionsInDataFields, }; - const { errors }: LintTreeResponse = yield call( + const { errors, updatedJSEntities }: LintTreeResponse = yield call( lintWorker.request, LINT_WORKER_ACTIONS.LINT_TREE, lintTreeRequestData, ); - yield put(setLintingErrors(errors)); - yield call(logLatestLintPropertyErrors, { errors, dataTree: unevalTree }); + const oldJSCollectionLintErrors: LintErrorsStore = + yield getValidOldJSCollectionLintErrors( + updatedJSEntities, + errors, + jsPropertiesState, + ); + + const updatedErrors = { ...errors, ...oldJSCollectionLintErrors }; + + yield put(setLintingErrors(updatedErrors)); + yield call(logLatestLintPropertyErrors, { + errors, + dataTree: unevalTree, + }); } export default function* lintTreeSagaWatcher() { diff --git a/app/client/src/sagas/PostLintingSagas.ts b/app/client/src/sagas/PostLintingSagas.ts index fa53c297d3..1cc56b0c30 100644 --- a/app/client/src/sagas/PostLintingSagas.ts +++ b/app/client/src/sagas/PostLintingSagas.ts @@ -2,19 +2,19 @@ import { ENTITY_TYPE, Severity } from "entities/AppsmithConsole"; import LOG_TYPE from "entities/AppsmithConsole/logtype"; import type { DataTree } from "entities/DataTree/dataTreeFactory"; import { isEmpty } from "lodash"; -import type { LintErrors } from "reducers/lintingReducers/lintErrorsReducers"; import AppsmithConsole from "utils/AppsmithConsole"; import { getEntityNameAndPropertyPath, isJSAction, } from "@appsmith/workers/Evaluation/evaluationUtils"; +import type { LintErrorsStore } from "reducers/lintingReducers/lintErrorsReducers"; // We currently only log lint errors in JSObjects export function* logLatestLintPropertyErrors({ dataTree, errors, }: { - errors: LintErrors; + errors: LintErrorsStore; dataTree: DataTree; }) { const errorsToAdd = []; diff --git a/app/client/src/selectors/lintingSelectors.ts b/app/client/src/selectors/lintingSelectors.ts index 0a2a654d55..de7ba2a0b0 100644 --- a/app/client/src/selectors/lintingSelectors.ts +++ b/app/client/src/selectors/lintingSelectors.ts @@ -1,11 +1,7 @@ import type { AppState } from "@appsmith/reducers"; import { get } from "lodash"; -import type { LintErrors } from "reducers/lintingReducers/lintErrorsReducers"; import type { LintError } from "utils/DynamicBindingUtils"; -export const getAllLintErrors = (state: AppState): LintErrors => - state.linting.errors; - const emptyLint: LintError[] = []; export const getEntityLintErrors = (state: AppState, path?: string) => { diff --git a/app/client/src/selectors/navigationSelectors.ts b/app/client/src/selectors/navigationSelectors.ts index 9bb5027cbe..405dea231d 100644 --- a/app/client/src/selectors/navigationSelectors.ts +++ b/app/client/src/selectors/navigationSelectors.ts @@ -19,7 +19,11 @@ import { createNavData } from "utils/NavigationSelector/common"; import { getWidgetChildrenNavData } from "utils/NavigationSelector/WidgetChildren"; import { getJsChildrenNavData } from "utils/NavigationSelector/JsChildren"; import { getAppsmithNavData } from "utils/NavigationSelector/AppsmithNavData"; -import { isJSAction } from "ce/workers/Evaluation/evaluationUtils"; +import { + getEntityNameAndPropertyPath, + isJSAction, +} from "@appsmith/workers/Evaluation/evaluationUtils"; +import type { AppState } from "@appsmith/reducers"; export type NavigationData = { name: string; @@ -124,3 +128,20 @@ export const getEntitiesForNavigation = createSelector( return navigationData; }, ); + +export const getJSFunctionNavigationUrl = createSelector( + [ + (state: AppState, entityName: string) => + getEntitiesForNavigation(state, entityName), + (_, __, jsFunctionFullName: string | undefined) => jsFunctionFullName, + ], + (entitiesForNavigation, jsFunctionFullName) => { + if (!jsFunctionFullName) return undefined; + const { entityName: jsObjectName, propertyPath: jsFunctionName } = + getEntityNameAndPropertyPath(jsFunctionFullName); + const jsObjectNavigationData = entitiesForNavigation[jsObjectName]; + const jsFuncNavigationData = + jsObjectNavigationData && jsObjectNavigationData.children[jsFunctionName]; + return jsFuncNavigationData?.url; + }, +); diff --git a/app/client/src/utils/DynamicBindingUtils.ts b/app/client/src/utils/DynamicBindingUtils.ts index 3c1b21725d..39f62a03ae 100644 --- a/app/client/src/utils/DynamicBindingUtils.ts +++ b/app/client/src/utils/DynamicBindingUtils.ts @@ -353,6 +353,15 @@ export enum PropertyEvaluationErrorType { PARSE = "PARSE", LINT = "LINT", } + +export enum PropertyEvaluationErrorCategory { + INVALID_JS_FUNCTION_INVOCATION_IN_DATA_FIELD = "INVALID_JS_FUNCTION_INVOCATION_IN_DATA_FIELD", +} +export interface PropertyEvaluationErrorKind { + category: PropertyEvaluationErrorCategory; + rootcause: string; +} + export interface DataTreeError { raw: string; errorMessage: Error; @@ -364,6 +373,7 @@ export interface EvaluationError extends DataTreeError { | PropertyEvaluationErrorType.PARSE | PropertyEvaluationErrorType.VALIDATION; originalBinding?: string; + kind?: PropertyEvaluationErrorKind; } export interface LintError extends DataTreeError { @@ -374,6 +384,7 @@ export interface LintError extends DataTreeError { code: string; line: number; ch: number; + originalPath?: string; } export interface DataTreeEvaluationProps { diff --git a/app/client/src/workers/Evaluation/JSObject/asyncJSFunctionBoundToDataField.ts b/app/client/src/workers/Evaluation/JSObject/asyncJSFunctionBoundToDataField.ts new file mode 100644 index 0000000000..8acd2f8203 --- /dev/null +++ b/app/client/src/workers/Evaluation/JSObject/asyncJSFunctionBoundToDataField.ts @@ -0,0 +1,247 @@ +import { + getEntityNameAndPropertyPath, + isATriggerPath, +} from "@appsmith/workers/Evaluation/evaluationUtils"; +import { APP_MODE } from "entities/App"; +import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory"; +import { difference, get, isString } from "lodash"; +import type { DependencyMap } from "utils/DynamicBindingUtils"; +import { getDynamicBindings } from "utils/DynamicBindingUtils"; +import { isChildPropertyPath } from "utils/DynamicBindingUtils"; +import { + isDataField, + isWidgetActionOrJsObject, +} from "workers/common/DataTreeEvaluator/utils"; +import { + isAsyncJSFunction, + isJSFunction, + updateMap, +} from "workers/common/DependencyMap/utils"; + +export class AsyncJsFunctionInDataField { + private asyncFunctionsInDataFieldsMap: DependencyMap = {}; + private isDisabled = true; + initialize(appMode: APP_MODE | undefined) { + this.isDisabled = !(appMode === APP_MODE.EDIT); + this.asyncFunctionsInDataFieldsMap = {}; + } + + update( + fullPath: string, + referencesInPath: string[], + unEvalDataTree: DataTree, + configTree: ConfigTree, + ) { + if (this.isDisabled) return []; + const updatedAsyncJSFunctionsInMap = new Set(); + // Only datafields can cause updates + if (!isDataField(fullPath, configTree)) return []; + + const asyncJSFunctionsInvokedInPath = getAsyncJSFunctionInvocationsInPath( + referencesInPath, + unEvalDataTree, + configTree, + fullPath, + ); + + for (const asyncJSFunc of asyncJSFunctionsInvokedInPath) { + updatedAsyncJSFunctionsInMap.add(asyncJSFunc); + updateMap(this.asyncFunctionsInDataFieldsMap, asyncJSFunc, [fullPath], { + deleteOnEmpty: true, + }); + } + return Array.from(updatedAsyncJSFunctionsInMap); + } + + handlePathDeletion( + deletedPath: string, + unevalTree: DataTree, + configTree: ConfigTree, + ) { + if (this.isDisabled) return []; + const updatedAsyncJSFunctionsInMap = new Set(); + const { entityName, propertyPath } = + getEntityNameAndPropertyPath(deletedPath); + const entity = unevalTree[entityName]; + const entityConfig = configTree[entityName]; + if ( + isWidgetActionOrJsObject(entity) || + isATriggerPath(entityConfig, propertyPath) + ) + return []; + + Object.keys(this.asyncFunctionsInDataFieldsMap).forEach((asyncFuncName) => { + if (isChildPropertyPath(deletedPath, asyncFuncName)) { + this.deleteFunctionFromMap(asyncFuncName); + } else { + const toRemove: string[] = []; + this.asyncFunctionsInDataFieldsMap[asyncFuncName].forEach( + (dependantPath) => { + if (isChildPropertyPath(deletedPath, dependantPath)) { + updatedAsyncJSFunctionsInMap.add(asyncFuncName); + toRemove.push(dependantPath); + } + }, + ); + const newAsyncFunctiondependents = difference( + this.asyncFunctionsInDataFieldsMap[asyncFuncName], + toRemove, + ); + updateMap( + this.asyncFunctionsInDataFieldsMap, + asyncFuncName, + newAsyncFunctiondependents, + { replaceValue: true, deleteOnEmpty: true }, + ); + } + }); + return Array.from(updatedAsyncJSFunctionsInMap); + } + handlePathEdit( + editedPath: string, + dependenciesInPath: string[], + unevalTree: DataTree, + inverseDependencyMap: DependencyMap, + configTree: ConfigTree, + ) { + if (this.isDisabled) return []; + const updatedAsyncJSFunctionsInMap = new Set(); + if (isDataField(editedPath, configTree)) { + const asyncJSFunctionInvocationsInPath = + getAsyncJSFunctionInvocationsInPath( + dependenciesInPath, + unevalTree, + configTree, + editedPath, + ); + asyncJSFunctionInvocationsInPath.forEach((funcName) => { + updatedAsyncJSFunctionsInMap.add(funcName); + updateMap(this.asyncFunctionsInDataFieldsMap, funcName, [editedPath], { + deleteOnEmpty: true, + }); + }); + + Object.keys(this.asyncFunctionsInDataFieldsMap).forEach( + (asyncFuncName) => { + const toRemove: string[] = []; + this.asyncFunctionsInDataFieldsMap[asyncFuncName].forEach( + (dependantPath) => { + if ( + editedPath === dependantPath && + !asyncJSFunctionInvocationsInPath.includes(asyncFuncName) + ) { + updatedAsyncJSFunctionsInMap.add(asyncFuncName); + toRemove.push(dependantPath); + } + }, + ); + const newAsyncFunctiondependents = difference( + this.asyncFunctionsInDataFieldsMap[asyncFuncName], + toRemove, + ); + updateMap( + this.asyncFunctionsInDataFieldsMap, + asyncFuncName, + newAsyncFunctiondependents, + { replaceValue: true, deleteOnEmpty: true }, + ); + }, + ); + } else if (isJSFunction(configTree, editedPath)) { + if ( + !isAsyncJSFunction(configTree, editedPath) && + Object.keys(this.asyncFunctionsInDataFieldsMap).includes(editedPath) + ) { + updatedAsyncJSFunctionsInMap.add(editedPath); + delete this.asyncFunctionsInDataFieldsMap[editedPath]; + } else if (isAsyncJSFunction(configTree, editedPath)) { + const boundFields = inverseDependencyMap[editedPath]; + let boundDataFields: string[] = []; + if (boundFields) { + boundDataFields = boundFields.filter((path) => + isDataField(path, configTree), + ); + for (const dataFieldPath of boundDataFields) { + const asyncJSFunctionInvocationsInPath = + getAsyncJSFunctionInvocationsInPath( + [editedPath], + unevalTree, + configTree, + dataFieldPath, + ); + if (asyncJSFunctionInvocationsInPath) { + updatedAsyncJSFunctionsInMap.add(editedPath); + updateMap( + this.asyncFunctionsInDataFieldsMap, + editedPath, + [dataFieldPath], + { deleteOnEmpty: true }, + ); + } + } + } + } + } + return Array.from(updatedAsyncJSFunctionsInMap); + } + + getMap() { + return this.asyncFunctionsInDataFieldsMap; + } + deleteFunctionFromMap(funcName: string) { + this.asyncFunctionsInDataFieldsMap[funcName] && + delete this.asyncFunctionsInDataFieldsMap[funcName]; + } + getAsyncFunctionBindingInDataField(fullPath: string): string | undefined { + let hasAsyncFunctionInvocation: string | undefined = undefined; + Object.keys(this.asyncFunctionsInDataFieldsMap).forEach((path) => { + if (this.asyncFunctionsInDataFieldsMap[path].includes(fullPath)) { + return (hasAsyncFunctionInvocation = path); + } + }); + return hasAsyncFunctionInvocation; + } +} + +function getAsyncJSFunctionInvocationsInPath( + dependencies: string[], + unEvalTree: DataTree, + configTree: ConfigTree, + fullPath: string, +) { + const invokedAsyncJSFunctions = new Set(); + const { entityName, propertyPath } = getEntityNameAndPropertyPath(fullPath); + const entity = unEvalTree[entityName]; + const unevalPropValue = get(entity, propertyPath); + + dependencies.forEach((dependant) => { + if ( + isAsyncJSFunction(configTree, dependant) && + isFunctionInvoked(dependant, unevalPropValue) + ) { + invokedAsyncJSFunctions.add(dependant); + } + }); + + return Array.from(invokedAsyncJSFunctions); +} + +function getFunctionInvocationRegex(funcName: string) { + return new RegExp(`${funcName}[.call | .apply]*\s*\\(.*?\\)`, "g"); +} + +export function isFunctionInvoked( + functionName: string, + unevalPropValue: unknown, +) { + if (!isString(unevalPropValue)) return false; + const { jsSnippets } = getDynamicBindings(unevalPropValue); + for (const jsSnippet of jsSnippets) { + if (!jsSnippet.includes(functionName)) continue; + const isInvoked = getFunctionInvocationRegex(functionName).test(jsSnippet); + if (isInvoked) return true; + } + return false; +} + +export const asyncJsFunctionInDataFields = new AsyncJsFunctionInDataField(); diff --git a/app/client/src/workers/Evaluation/JSObject/index.ts b/app/client/src/workers/Evaluation/JSObject/index.ts index 22e231ea93..167e430198 100644 --- a/app/client/src/workers/Evaluation/JSObject/index.ts +++ b/app/client/src/workers/Evaluation/JSObject/index.ts @@ -2,7 +2,7 @@ import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory"; import { isEmpty, set } from "lodash"; import { EvalErrorTypes } from "utils/DynamicBindingUtils"; import type { JSUpdate, ParsedJSSubAction } from "utils/JSPaneUtils"; -import { isTypeOfFunction, parseJSObjectWithAST } from "@shared/ast"; +import { parseJSObject, isJSFunctionProperty } from "@shared/ast"; import type DataTreeEvaluator from "workers/common/DataTreeEvaluator"; import evaluateSync from "workers/Evaluation/evaluate"; import type { DataTreeDiff } from "@appsmith/workers/Evaluation/evaluationUtils"; @@ -16,7 +16,9 @@ import { updateJSCollectionInUnEvalTree, } from "workers/Evaluation/JSObject/utils"; import { functionDeterminer } from "../functionDeterminer"; +import { jsPropertiesState } from "./jsPropertiesState"; import type { JSActionEntity } from "entities/DataTree/types"; +import { getFixedTimeDifference } from "workers/common/DataTreeEvaluator/utils"; /** * Here we update our unEvalTree according to the change in JSObject's body @@ -81,94 +83,100 @@ export function saveResolvedFunctionsAndJSUpdates( unEvalDataTree: DataTree, entityName: string, ) { + jsPropertiesState.delete(entityName); const correctFormat = regex.test(entity.body); if (correctFormat) { - const body = entity.body.replace(/export default/g, ""); try { delete dataTreeEvalRef.resolvedFunctions[`${entityName}`]; delete dataTreeEvalRef.currentJSCollectionState[`${entityName}`]; const parseStartTime = performance.now(); - const parsedObject = parseJSObjectWithAST(body); + const { parsedObject, success } = parseJSObject(entity.body); const parseEndTime = performance.now(); - const JSObjectASTParseTime = parseEndTime - parseStartTime; + const JSObjectASTParseTime = getFixedTimeDifference( + parseEndTime, + parseStartTime, + ); dataTreeEvalRef.logs.push({ JSObjectName: entityName, JSObjectASTParseTime, }); const actions: any = []; const variables: any = []; - if (!!parsedObject) { - parsedObject.forEach((parsedElement) => { - if (isTypeOfFunction(parsedElement.type)) { - try { - const { result } = evaluateSync( - parsedElement.value, - unEvalDataTree, - {}, - false, - undefined, - undefined, - ); - if (!!result) { - let params: Array<{ key: string; value: unknown }> = []; + if (success) { + if (!!parsedObject) { + jsPropertiesState.update(entityName, parsedObject); + parsedObject.forEach((parsedElement) => { + if (isJSFunctionProperty(parsedElement)) { + try { + const { result } = evaluateSync( + parsedElement.value, + unEvalDataTree, + {}, + false, + undefined, + undefined, + ); + if (!!result) { + let params: Array<{ key: string; value: unknown }> = []; - if (parsedElement.arguments) { - params = parsedElement.arguments.map( - ({ defaultValue, paramName }) => ({ - key: paramName, - value: defaultValue, - }), + if (parsedElement.arguments) { + params = parsedElement.arguments.map( + ({ defaultValue, paramName }) => ({ + key: paramName, + value: defaultValue, + }), + ); + } + + const functionString = parsedElement.value; + set( + dataTreeEvalRef.resolvedFunctions, + `${entityName}.${parsedElement.key}`, + result, ); + set( + dataTreeEvalRef.currentJSCollectionState, + `${entityName}.${parsedElement.key}`, + functionString, + ); + actions.push({ + name: parsedElement.key, + body: functionString, + arguments: params, + parsedFunction: result, + isAsync: false, + }); } - - const functionString = parsedElement.value; - set( - dataTreeEvalRef.resolvedFunctions, - `${entityName}.${parsedElement.key}`, - result, - ); - set( - dataTreeEvalRef.currentJSCollectionState, - `${entityName}.${parsedElement.key}`, - functionString, - ); - actions.push({ - name: parsedElement.key, - body: functionString, - arguments: params, - parsedFunction: result, - isAsync: false, - }); + } catch { + // in case we need to handle error state } - } catch { - // in case we need to handle error state + } else if (parsedElement.type !== "literal") { + variables.push({ + name: parsedElement.key, + value: parsedElement.value, + }); + set( + dataTreeEvalRef.currentJSCollectionState, + `${entityName}.${parsedElement.key}`, + parsedElement.value, + ); } - } else if (parsedElement.type !== "literal") { - variables.push({ - name: parsedElement.key, - value: parsedElement.value, - }); - set( - dataTreeEvalRef.currentJSCollectionState, - `${entityName}.${parsedElement.key}`, - parsedElement.value, - ); - } - }); - const parsedBody = { - body: entity.body, - actions: actions, - variables, - }; - set(jsUpdates, `${entityName}`, { - parsedBody, - id: entity.actionId, - }); - } else { - set(jsUpdates, `${entityName}`, { - parsedBody: undefined, - id: entity.actionId, - }); + }); + const parsedBody = { + body: entity.body, + actions: actions, + variables, + }; + set(jsUpdates, `${entityName}`, { + parsedBody, + id: entity.actionId, + }); + } else { + set(jsUpdates, `${entityName}`, { + parsedBody: undefined, + id: entity.actionId, + }); + } } } catch (e) { //if we need to push error as popup in case @@ -194,6 +202,7 @@ export function parseJSActions( differences?: DataTreeDiff[], ) { let jsUpdates: Record = {}; + jsPropertiesState.startUpdate(); if (!!differences && !!oldUnEvalTree) { differences.forEach((diff) => { const { entityName, propertyPath } = getEntityNameAndPropertyPath( @@ -249,7 +258,7 @@ export function parseJSActions( ); }); } - + jsPropertiesState.stopUpdate(); functionDeterminer.setupEval( unEvalDataTree, dataTreeEvalRef.resolvedFunctions, diff --git a/app/client/src/workers/Evaluation/JSObject/jsPropertiesState.ts b/app/client/src/workers/Evaluation/JSObject/jsPropertiesState.ts new file mode 100644 index 0000000000..5460897fd4 --- /dev/null +++ b/app/client/src/workers/Evaluation/JSObject/jsPropertiesState.ts @@ -0,0 +1,79 @@ +import type { JSPropertyPosition, TParsedJSProperty } from "@shared/ast"; +import { isJSFunctionProperty } from "@shared/ast"; +import { diff } from "deep-diff"; +import { klona } from "klona/full"; +import { set, union } from "lodash"; + +class JsPropertiesState { + private jsPropertiesState: TJSPropertiesState = {}; + private oldJsPropertiesState: TJSPropertiesState = {}; + private updatedProperties: string[] = []; + + startUpdate() { + this.oldJsPropertiesState = klona(this.jsPropertiesState); + } + + delete(jsObjectName: string) { + delete this.jsPropertiesState[`${jsObjectName}`]; + } + + update(jsObjectName: string, properties: TParsedJSProperty[]) { + for (const jsObjectProperty of properties) { + const { key, position, rawContent, type } = jsObjectProperty; + if (isJSFunctionProperty(jsObjectProperty)) { + set( + this.jsPropertiesState, + `[${jsObjectName}.${jsObjectProperty.key}]`, + { + position: position, + value: rawContent, + isMarkedAsync: jsObjectProperty.isMarkedAsync, + }, + ); + } else if (type !== "literal") { + set(this.jsPropertiesState, `[${jsObjectName}.${key}]`, { + position: position, + value: rawContent, + }); + } + } + } + stopUpdate() { + const difference = diff(this.oldJsPropertiesState, this.jsPropertiesState); + let updatedJSProperties: string[] = []; + if (difference) { + updatedJSProperties = difference.reduce( + (updatedProperties, currentDiff) => { + if (!currentDiff.path) return updatedProperties; + const updatedProperty = currentDiff.path.slice(0, 2).join("."); + return union(updatedProperties, [updatedProperty]); + }, + [] as string[], + ); + } + this.updatedProperties = updatedJSProperties; + } + getMap() { + return this.jsPropertiesState; + } + getUpdatedJSProperties() { + return this.updatedProperties; + } +} + +export const jsPropertiesState = new JsPropertiesState(); + +export interface TBasePropertyState { + value: string; + position: JSPropertyPosition; +} +export interface TJSFunctionPropertyState extends TBasePropertyState { + isMarkedAsync: boolean; +} + +export type TJSpropertyState = TBasePropertyState | TJSFunctionPropertyState; + +export type TJSPropertiesState = Record< + string, + Record +>; diff --git a/app/client/src/workers/Evaluation/JSObject/test.ts b/app/client/src/workers/Evaluation/JSObject/test.ts index 967d9b8f71..d104dbff0e 100644 --- a/app/client/src/workers/Evaluation/JSObject/test.ts +++ b/app/client/src/workers/Evaluation/JSObject/test.ts @@ -1,5 +1,483 @@ -import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory"; +import { APP_MODE } from "entities/App"; +import type { ConfigTree, UnEvalTree } from "entities/DataTree/dataTreeFactory"; +import type { DependencyMap } from "utils/DynamicBindingUtils"; import { getUpdatedLocalUnEvalTreeAfterJSUpdates } from "."; +import { + AsyncJsFunctionInDataField, + isFunctionInvoked, +} from "./asyncJSFunctionBoundToDataField"; + +const mockDataTree = { + unevalTree: { + Api1: { + actionId: "6425db8b3c6952132524e6ea", + run: {}, + clear: {}, + isLoading: false, + responseMeta: { + isExecutionSuccess: false, + }, + config: { + timeoutInMillisecond: 10000, + paginationType: "NONE", + headers: [ + { + key: "", + value: "", + }, + { + key: "", + value: "", + }, + ], + encodeParamsToggle: true, + queryParameters: [ + { + key: "", + value: "", + }, + { + key: "", + value: "", + }, + ], + body: "", + bodyFormData: [], + httpMethod: "GET", + selfReferencingDataPaths: [], + pluginSpecifiedTemplates: [ + { + value: true, + }, + ], + formData: { + apiContentType: "none", + }, + }, + ENTITY_TYPE: "ACTION", + datasourceUrl: "", + }, + JSObject1: { + myVar1: "[]", + myVar2: "{}", + myFun2: { + data: {}, + }, + myFun1: { + data: {}, + }, + myFun3: { + data: {}, + }, + body: 'export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tmyFun1: () => {\n\t\treturn "value"\n\t},\n\tmyFun2: async () => {\n\treturn "value"\n\t},\n\tmyFun3: ()=>{\n\t\tApi1.run()\n\t}\n}', + ENTITY_TYPE: "JSACTION", + actionId: "6425db2ef02d0b4638f2a1b3", + }, + MainContainer: { + ENTITY_TYPE: "WIDGET", + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 4896, + snapColumns: 64, + widgetId: "0", + topRow: 0, + bottomRow: 380, + containerStyle: "none", + snapRows: 124, + parentRowSpace: 1, + canExtend: true, + minHeight: 1292, + parentColumnSpace: 1, + leftColumn: 0, + meta: {}, + type: "CANVAS_WIDGET", + }, + Button1: { + ENTITY_TYPE: "WIDGET", + isVisible: true, + animateLoading: true, + text: "{{JSObject1.myFun2()}} ", + buttonVariant: "PRIMARY", + placement: "CENTER", + widgetName: "Button1", + isDisabled: false, + isDefaultClickDisabled: true, + disabledWhenInvalid: false, + resetFormOnClick: false, + recaptchaType: "V3", + responsiveBehavior: "hug", + minWidth: 120, + key: "lj612scwwe", + widgetId: "5c14ze6dtv", + buttonColor: "{{appsmith.theme.colors.primaryColor}}", + borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}", + boxShadow: "none", + isLoading: false, + parentColumnSpace: 7.5625, + parentRowSpace: 10, + leftColumn: 20, + rightColumn: 36, + topRow: 15, + bottomRow: 19, + meta: {}, + type: "BUTTON_WIDGET", + }, + pageList: [ + { + pageName: "Page1", + pageId: "6425db193c6952132524e6e2", + isDefault: true, + isHidden: false, + slug: "page1", + userPermissions: [ + "read:pages", + "manage:pages", + "create:pageActions", + "delete:pages", + ], + }, + ], + appsmith: { + user: { + email: "favour@appsmith.com", + workspaceIds: [ + "5f7add8687af934ed846dd6a", + "60fa970664d41f773aab20b8", + "60a7dccf98f6c43a4b854dcb", + "61bc28259229e87746b78969", + "618bdd29da7cd651ee273494", + "60c1a5273535574772b6377b", + "6225f57945ea27345b497529", + "61e7be9feb0501052b9fed2a", + "622666f2b49d5451b1cd070a", + "61431979a67ce2289d3c7c6d", + "627a49410b47255c281326a6", + "62e7948c4003a7259a3027c8", + ], + username: "favour@appsmith.com", + name: "Favour Ohanekwu", + photoId: "62a963ac84b91337251a632f", + enableTelemetry: true, + accountNonExpired: true, + accountNonLocked: true, + credentialsNonExpired: true, + emptyInstance: false, + isAnonymous: false, + isEnabled: true, + isSuperUser: false, + isConfigurable: true, + adminSettingsVisible: false, + }, + URL: { + fullPath: + "https://dev.appsmith.com/app/untitled-application-39/page1-6425db193c6952132524e6e2/edit", + host: "dev.appsmith.com", + hostname: "dev.appsmith.com", + queryParams: {}, + protocol: "https:", + pathname: + "/app/untitled-application-39/page1-6425db193c6952132524e6e2/edit", + port: "", + hash: "", + }, + store: {}, + geolocation: { + canBeRequested: true, + currentPosition: {}, + }, + mode: "EDIT", + theme: { + colors: { + primaryColor: "#553DE9", + backgroundColor: "#F8FAFC", + }, + borderRadius: { + appBorderRadius: "0.375rem", + }, + boxShadow: { + appBoxShadow: + "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)", + }, + fontFamily: { + appFont: "Nunito Sans", + }, + }, + ENTITY_TYPE: "APPSMITH", + }, + }, + configTree: { + Api1: { + actionId: "6425db8b3c6952132524e6ea", + name: "Api1", + pluginId: "5ca385dc81b37f0004b4db85", + pluginType: "API", + dynamicBindingPathList: [], + ENTITY_TYPE: "ACTION", + bindingPaths: { + "config.path": "TEMPLATE", + "config.body": "SMART_SUBSTITUTE", + "config.queryParameters[0].key": "TEMPLATE", + "config.queryParameters[0].value": "TEMPLATE", + "config.queryParameters[1].key": "TEMPLATE", + "config.queryParameters[1].value": "TEMPLATE", + "config.headers[0].key": "TEMPLATE", + "config.headers[0].value": "TEMPLATE", + "config.headers[1].key": "TEMPLATE", + "config.headers[1].value": "TEMPLATE", + "config.pluginSpecifiedTemplates[1].value": "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.offset.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.cursor.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.cursor.value": + "SMART_SUBSTITUTE", + }, + reactivePaths: { + data: "TEMPLATE", + isLoading: "TEMPLATE", + datasourceUrl: "TEMPLATE", + "config.path": "TEMPLATE", + "config.body": "SMART_SUBSTITUTE", + "config.queryParameters[0].key": "TEMPLATE", + "config.queryParameters[0].value": "TEMPLATE", + "config.queryParameters[1].key": "TEMPLATE", + "config.queryParameters[1].value": "TEMPLATE", + "config.headers[0].key": "TEMPLATE", + "config.headers[0].value": "TEMPLATE", + "config.headers[1].key": "TEMPLATE", + "config.headers[1].value": "TEMPLATE", + "config.pluginSpecifiedTemplates[1].value": "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.offset.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.cursor.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.cursor.value": + "SMART_SUBSTITUTE", + }, + dependencyMap: { + "config.body": ["config.pluginSpecifiedTemplates[0].value"], + }, + logBlackList: {}, + }, + JSObject1: { + actionId: "6425db2ef02d0b4638f2a1b3", + meta: { + myFun2: { + arguments: [], + isAsync: true, + confirmBeforeExecute: false, + }, + myFun1: { + arguments: [], + isAsync: false, + confirmBeforeExecute: false, + }, + myFun3: { + arguments: [], + isAsync: false, + confirmBeforeExecute: false, + }, + }, + name: "JSObject1", + pluginType: "JS", + ENTITY_TYPE: "JSACTION", + bindingPaths: { + body: "SMART_SUBSTITUTE", + myVar1: "SMART_SUBSTITUTE", + myVar2: "SMART_SUBSTITUTE", + myFun2: "SMART_SUBSTITUTE", + myFun1: "SMART_SUBSTITUTE", + myFun3: "SMART_SUBSTITUTE", + }, + reactivePaths: { + body: "SMART_SUBSTITUTE", + myVar1: "SMART_SUBSTITUTE", + myVar2: "SMART_SUBSTITUTE", + myFun2: "SMART_SUBSTITUTE", + myFun1: "SMART_SUBSTITUTE", + myFun3: "SMART_SUBSTITUTE", + }, + dynamicBindingPathList: [ + { + key: "body", + }, + { + key: "myVar1", + }, + { + key: "myVar2", + }, + { + key: "myFun2", + }, + { + key: "myFun1", + }, + { + key: "myFun3", + }, + ], + variables: ["myVar1", "myVar2"], + dependencyMap: { + body: ["myFun2", "myFun1", "myFun3"], + }, + }, + MainContainer: { + defaultProps: {}, + defaultMetaProps: [], + dynamicBindingPathList: [], + logBlackList: {}, + bindingPaths: {}, + reactivePaths: {}, + triggerPaths: {}, + validationPaths: {}, + ENTITY_TYPE: "WIDGET", + privateWidgets: {}, + propertyOverrideDependency: {}, + overridingPropertyPaths: {}, + type: "CANVAS_WIDGET", + dynamicTriggerPathList: [], + isMetaPropDirty: false, + widgetId: "0", + }, + Button1: { + defaultProps: {}, + defaultMetaProps: ["recaptchaToken"], + dynamicBindingPathList: [ + { + key: "buttonColor", + }, + { + key: "borderRadius", + }, + { + key: "text", + }, + ], + logBlackList: {}, + bindingPaths: { + text: "TEMPLATE", + tooltip: "TEMPLATE", + isVisible: "TEMPLATE", + isDisabled: "TEMPLATE", + animateLoading: "TEMPLATE", + googleRecaptchaKey: "TEMPLATE", + recaptchaType: "TEMPLATE", + disabledWhenInvalid: "TEMPLATE", + resetFormOnClick: "TEMPLATE", + buttonVariant: "TEMPLATE", + iconName: "TEMPLATE", + placement: "TEMPLATE", + buttonColor: "TEMPLATE", + borderRadius: "TEMPLATE", + boxShadow: "TEMPLATE", + }, + reactivePaths: { + recaptchaToken: "TEMPLATE", + buttonColor: "TEMPLATE", + borderRadius: "TEMPLATE", + text: "TEMPLATE", + tooltip: "TEMPLATE", + isVisible: "TEMPLATE", + isDisabled: "TEMPLATE", + animateLoading: "TEMPLATE", + googleRecaptchaKey: "TEMPLATE", + recaptchaType: "TEMPLATE", + disabledWhenInvalid: "TEMPLATE", + resetFormOnClick: "TEMPLATE", + buttonVariant: "TEMPLATE", + iconName: "TEMPLATE", + placement: "TEMPLATE", + boxShadow: "TEMPLATE", + }, + triggerPaths: { + onClick: true, + }, + validationPaths: { + text: { + type: "TEXT", + }, + tooltip: { + type: "TEXT", + }, + isVisible: { + type: "BOOLEAN", + }, + isDisabled: { + type: "BOOLEAN", + }, + animateLoading: { + type: "BOOLEAN", + }, + googleRecaptchaKey: { + type: "TEXT", + }, + recaptchaType: { + type: "TEXT", + params: { + allowedValues: ["V3", "V2"], + default: "V3", + }, + }, + disabledWhenInvalid: { + type: "BOOLEAN", + }, + resetFormOnClick: { + type: "BOOLEAN", + }, + buttonVariant: { + type: "TEXT", + params: { + allowedValues: ["PRIMARY", "SECONDARY", "TERTIARY"], + default: "PRIMARY", + }, + }, + iconName: { + type: "TEXT", + }, + placement: { + type: "TEXT", + params: { + allowedValues: ["START", "BETWEEN", "CENTER"], + default: "CENTER", + }, + }, + buttonColor: { + type: "TEXT", + }, + borderRadius: { + type: "TEXT", + }, + boxShadow: { + type: "TEXT", + }, + }, + ENTITY_TYPE: "WIDGET", + privateWidgets: {}, + propertyOverrideDependency: {}, + overridingPropertyPaths: {}, + type: "BUTTON_WIDGET", + dynamicTriggerPathList: [], + isMetaPropDirty: false, + widgetId: "5c14ze6dtv", + }, + }, +} as unknown as { + unevalTree: UnEvalTree; + configTree: ConfigTree; +}; describe("updateJSCollectionInUnEvalTree", function () { it("updates async value of jsAction", () => { @@ -107,7 +585,7 @@ describe("updateJSCollectionInUnEvalTree", function () { Object.setPrototypeOf(JSObject1, JSObject1Prototype); const localUnEvalTree = { JSObject1, - } as unknown as DataTree; + } as unknown as UnEvalTree; const actualResult = getUpdatedLocalUnEvalTreeAfterJSUpdates( jsUpdates, @@ -143,3 +621,1018 @@ describe("updateJSCollectionInUnEvalTree", function () { expect(expectedResult).toStrictEqual(actualResult); }); }); + +describe("asyncJSFunctionInDataField", function () { + const asyncJSFunctionInDataField = new AsyncJsFunctionInDataField(); + it("Does not update when in view mode", function () { + asyncJSFunctionInDataField.initialize(APP_MODE.PUBLISHED); + const updatedAsyncJSFunctionsInMap = asyncJSFunctionInDataField.update( + "Button1.text", + ["JSObject1.myFun2"], + mockDataTree.unevalTree, + mockDataTree.configTree, + ); + // Expect no update + expect(updatedAsyncJSFunctionsInMap).toStrictEqual([]); + // Expect empty object + expect(asyncJSFunctionInDataField.getMap()).toStrictEqual({}); + }); + + it("updates map correctly in EDIT mode", function () { + asyncJSFunctionInDataField.initialize(APP_MODE.EDIT); + let updatedAsyncJSFunctionsInMap = asyncJSFunctionInDataField.update( + "Button1.text", + ["JSObject1.myFun2"], + mockDataTree.unevalTree, + mockDataTree.configTree, + ); + // It updates JSObject1.myFun2 + expect(updatedAsyncJSFunctionsInMap).toStrictEqual(["JSObject1.myFun2"]); + expect(asyncJSFunctionInDataField.getMap()).toStrictEqual({ + "JSObject1.myFun2": ["Button1.text"], + }); + + // Delete {{JSObject1.myFun2()}} from Button1.text field + let newDataTree = { + unevalTree: { + Api1: { + actionId: "6425db8b3c6952132524e6ea", + run: {}, + clear: {}, + isLoading: false, + responseMeta: { + isExecutionSuccess: false, + }, + config: { + timeoutInMillisecond: 10000, + paginationType: "NONE", + headers: [ + { + key: "", + value: "", + }, + { + key: "", + value: "", + }, + ], + encodeParamsToggle: true, + queryParameters: [ + { + key: "", + value: "", + }, + { + key: "", + value: "", + }, + ], + body: "", + bodyFormData: [], + httpMethod: "GET", + selfReferencingDataPaths: [], + pluginSpecifiedTemplates: [ + { + value: true, + }, + ], + formData: { + apiContentType: "none", + }, + }, + ENTITY_TYPE: "ACTION", + datasourceUrl: "", + }, + JSObject1: { + myVar1: "[]", + myVar2: "{}", + myFun1: { + data: {}, + }, + myFun2: { + data: {}, + }, + myFun3: { + data: {}, + }, + body: 'export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tmyFun1: () => {\n\t\treturn "value"\n\t},\n\tmyFun2: async () => {\n\treturn "value"\n\t},\n\tmyFun3: ()=>{\n\t\tApi1.run()\n\t}\n}', + ENTITY_TYPE: "JSACTION", + actionId: "6425db2ef02d0b4638f2a1b3", + }, + MainContainer: { + ENTITY_TYPE: "WIDGET", + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 4896, + snapColumns: 64, + widgetId: "0", + topRow: 0, + bottomRow: 380, + containerStyle: "none", + snapRows: 124, + parentRowSpace: 1, + canExtend: true, + minHeight: 1292, + parentColumnSpace: 1, + leftColumn: 0, + meta: {}, + type: "CANVAS_WIDGET", + }, + Button1: { + ENTITY_TYPE: "WIDGET", + resetFormOnClick: false, + boxShadow: "none", + widgetName: "Button1", + buttonColor: "{{appsmith.theme.colors.primaryColor}}", + topRow: 15, + bottomRow: 19, + parentRowSpace: 10, + animateLoading: true, + parentColumnSpace: 7.5625, + leftColumn: 20, + text: "{{}} ", + isDisabled: false, + key: "lj612scwwe", + rightColumn: 36, + isDefaultClickDisabled: true, + widgetId: "5c14ze6dtv", + minWidth: 120, + isVisible: true, + recaptchaType: "V3", + isLoading: false, + responsiveBehavior: "hug", + disabledWhenInvalid: false, + borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}", + buttonVariant: "PRIMARY", + placement: "CENTER", + meta: {}, + type: "BUTTON_WIDGET", + }, + pageList: [ + { + pageName: "Page1", + pageId: "6425db193c6952132524e6e2", + isDefault: true, + isHidden: false, + slug: "page1", + userPermissions: [ + "read:pages", + "manage:pages", + "create:pageActions", + "delete:pages", + ], + }, + ], + appsmith: { + user: { + email: "favour@appsmith.com", + workspaceIds: [ + "5f7add8687af934ed846dd6a", + "60fa970664d41f773aab20b8", + "60a7dccf98f6c43a4b854dcb", + "61bc28259229e87746b78969", + "618bdd29da7cd651ee273494", + "60c1a5273535574772b6377b", + "6225f57945ea27345b497529", + "61e7be9feb0501052b9fed2a", + "622666f2b49d5451b1cd070a", + "61431979a67ce2289d3c7c6d", + "627a49410b47255c281326a6", + "62e7948c4003a7259a3027c8", + ], + username: "favour@appsmith.com", + name: "Favour Ohanekwu", + photoId: "62a963ac84b91337251a632f", + enableTelemetry: true, + emptyInstance: false, + accountNonExpired: true, + accountNonLocked: true, + credentialsNonExpired: true, + isAnonymous: false, + isEnabled: true, + isSuperUser: false, + isConfigurable: true, + adminSettingsVisible: false, + }, + URL: { + fullPath: + "https://dev.appsmith.com/app/untitled-application-39/page1-6425db193c6952132524e6e2/edit/widgets/5c14ze6dtv", + host: "dev.appsmith.com", + hostname: "dev.appsmith.com", + queryParams: {}, + protocol: "https:", + pathname: + "/app/untitled-application-39/page1-6425db193c6952132524e6e2/edit/widgets/5c14ze6dtv", + port: "", + hash: "", + }, + store: {}, + geolocation: { + canBeRequested: true, + currentPosition: {}, + }, + mode: "EDIT", + theme: { + colors: { + primaryColor: "#553DE9", + backgroundColor: "#F8FAFC", + }, + borderRadius: { + appBorderRadius: "0.375rem", + }, + boxShadow: { + appBoxShadow: + "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)", + }, + fontFamily: { + appFont: "Nunito Sans", + }, + }, + ENTITY_TYPE: "APPSMITH", + }, + }, + configTree: { + Api1: { + actionId: "6425db8b3c6952132524e6ea", + name: "Api1", + pluginId: "5ca385dc81b37f0004b4db85", + pluginType: "API", + dynamicBindingPathList: [], + ENTITY_TYPE: "ACTION", + bindingPaths: { + "config.path": "TEMPLATE", + "config.body": "SMART_SUBSTITUTE", + "config.queryParameters[0].key": "TEMPLATE", + "config.queryParameters[0].value": "TEMPLATE", + "config.queryParameters[1].key": "TEMPLATE", + "config.queryParameters[1].value": "TEMPLATE", + "config.headers[0].key": "TEMPLATE", + "config.headers[0].value": "TEMPLATE", + "config.headers[1].key": "TEMPLATE", + "config.headers[1].value": "TEMPLATE", + "config.pluginSpecifiedTemplates[1].value": "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.offset.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.cursor.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.cursor.value": + "SMART_SUBSTITUTE", + }, + reactivePaths: { + data: "TEMPLATE", + isLoading: "TEMPLATE", + datasourceUrl: "TEMPLATE", + "config.path": "TEMPLATE", + "config.body": "SMART_SUBSTITUTE", + "config.queryParameters[0].key": "TEMPLATE", + "config.queryParameters[0].value": "TEMPLATE", + "config.queryParameters[1].key": "TEMPLATE", + "config.queryParameters[1].value": "TEMPLATE", + "config.headers[0].key": "TEMPLATE", + "config.headers[0].value": "TEMPLATE", + "config.headers[1].key": "TEMPLATE", + "config.headers[1].value": "TEMPLATE", + "config.pluginSpecifiedTemplates[1].value": "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.offset.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.cursor.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.cursor.value": + "SMART_SUBSTITUTE", + }, + dependencyMap: { + "config.body": ["config.pluginSpecifiedTemplates[0].value"], + }, + logBlackList: {}, + }, + JSObject1: { + actionId: "6425db2ef02d0b4638f2a1b3", + meta: { + myFun1: { + arguments: [], + isAsync: false, + confirmBeforeExecute: false, + }, + myFun2: { + arguments: [], + isAsync: true, + confirmBeforeExecute: false, + }, + myFun3: { + arguments: [], + isAsync: true, + confirmBeforeExecute: false, + }, + }, + name: "JSObject1", + pluginType: "JS", + ENTITY_TYPE: "JSACTION", + bindingPaths: { + body: "SMART_SUBSTITUTE", + myVar1: "SMART_SUBSTITUTE", + myVar2: "SMART_SUBSTITUTE", + myFun1: "SMART_SUBSTITUTE", + myFun2: "SMART_SUBSTITUTE", + myFun3: "SMART_SUBSTITUTE", + }, + reactivePaths: { + body: "SMART_SUBSTITUTE", + myVar1: "SMART_SUBSTITUTE", + myVar2: "SMART_SUBSTITUTE", + myFun1: "SMART_SUBSTITUTE", + myFun2: "SMART_SUBSTITUTE", + myFun3: "SMART_SUBSTITUTE", + }, + dynamicBindingPathList: [ + { + key: "body", + }, + { + key: "myVar1", + }, + { + key: "myVar2", + }, + { + key: "myFun1", + }, + { + key: "myFun2", + }, + { + key: "myFun3", + }, + ], + variables: ["myVar1", "myVar2"], + dependencyMap: { + body: ["myFun1", "myFun2", "myFun3"], + }, + }, + MainContainer: { + defaultProps: {}, + defaultMetaProps: [], + dynamicBindingPathList: [], + logBlackList: {}, + bindingPaths: {}, + reactivePaths: {}, + triggerPaths: {}, + validationPaths: {}, + ENTITY_TYPE: "WIDGET", + privateWidgets: {}, + propertyOverrideDependency: {}, + overridingPropertyPaths: {}, + type: "CANVAS_WIDGET", + dynamicTriggerPathList: [], + isMetaPropDirty: false, + widgetId: "0", + }, + Button1: { + defaultProps: {}, + defaultMetaProps: ["recaptchaToken"], + dynamicBindingPathList: [ + { + key: "buttonColor", + }, + { + key: "borderRadius", + }, + { + key: "text", + }, + ], + logBlackList: {}, + bindingPaths: { + text: "TEMPLATE", + tooltip: "TEMPLATE", + isVisible: "TEMPLATE", + isDisabled: "TEMPLATE", + animateLoading: "TEMPLATE", + googleRecaptchaKey: "TEMPLATE", + recaptchaType: "TEMPLATE", + disabledWhenInvalid: "TEMPLATE", + resetFormOnClick: "TEMPLATE", + buttonVariant: "TEMPLATE", + iconName: "TEMPLATE", + placement: "TEMPLATE", + buttonColor: "TEMPLATE", + borderRadius: "TEMPLATE", + boxShadow: "TEMPLATE", + }, + reactivePaths: { + recaptchaToken: "TEMPLATE", + buttonColor: "TEMPLATE", + borderRadius: "TEMPLATE", + text: "TEMPLATE", + tooltip: "TEMPLATE", + isVisible: "TEMPLATE", + isDisabled: "TEMPLATE", + animateLoading: "TEMPLATE", + googleRecaptchaKey: "TEMPLATE", + recaptchaType: "TEMPLATE", + disabledWhenInvalid: "TEMPLATE", + resetFormOnClick: "TEMPLATE", + buttonVariant: "TEMPLATE", + iconName: "TEMPLATE", + placement: "TEMPLATE", + boxShadow: "TEMPLATE", + }, + triggerPaths: { + onClick: true, + }, + validationPaths: { + text: { + type: "TEXT", + }, + tooltip: { + type: "TEXT", + }, + isVisible: { + type: "BOOLEAN", + }, + isDisabled: { + type: "BOOLEAN", + }, + animateLoading: { + type: "BOOLEAN", + }, + googleRecaptchaKey: { + type: "TEXT", + }, + recaptchaType: { + type: "TEXT", + params: { + allowedValues: ["V3", "V2"], + default: "V3", + }, + }, + disabledWhenInvalid: { + type: "BOOLEAN", + }, + resetFormOnClick: { + type: "BOOLEAN", + }, + buttonVariant: { + type: "TEXT", + params: { + allowedValues: ["PRIMARY", "SECONDARY", "TERTIARY"], + default: "PRIMARY", + }, + }, + iconName: { + type: "TEXT", + }, + placement: { + type: "TEXT", + params: { + allowedValues: ["START", "BETWEEN", "CENTER"], + default: "CENTER", + }, + }, + buttonColor: { + type: "TEXT", + }, + borderRadius: { + type: "TEXT", + }, + boxShadow: { + type: "TEXT", + }, + }, + ENTITY_TYPE: "WIDGET", + privateWidgets: {}, + propertyOverrideDependency: {}, + overridingPropertyPaths: {}, + type: "BUTTON_WIDGET", + dynamicTriggerPathList: [], + isMetaPropDirty: false, + widgetId: "5c14ze6dtv", + }, + }, + } as unknown as { + unevalTree: UnEvalTree; + configTree: ConfigTree; + }; + // This should cause an Edit of Button1.text + updatedAsyncJSFunctionsInMap = asyncJSFunctionInDataField.handlePathEdit( + "Button1.text", + [], + newDataTree.unevalTree, + { + "appsmith.theme.borderRadius.appBorderRadius": [ + "appsmith.theme.borderRadius", + "Button1.borderRadius", + ], + "appsmith.theme.colors.primaryColor": [ + "appsmith.theme.colors", + "Button1.buttonColor", + ], + "appsmith.theme.colors": ["appsmith.theme"], + "appsmith.theme.borderRadius": ["appsmith.theme"], + "appsmith.theme": ["appsmith"], + "JSObject1.myFun2": ["Button1.text", "JSObject1.body", "JSObject1"], + "Button1.buttonColor": ["Button1"], + "Button1.borderRadius": ["Button1"], + "Button1.text": ["Button1"], + "Api1.run": ["Api1", "JSObject1.myFun3"], + "JSObject1.myFun1": ["JSObject1.body", "JSObject1"], + "JSObject1.myFun3": ["JSObject1.body", "JSObject1"], + "JSObject1.body": ["JSObject1"], + "JSObject1.myVar1": ["JSObject1"], + "JSObject1.myVar2": ["JSObject1"], + } as DependencyMap, + newDataTree.configTree, + ); + expect(updatedAsyncJSFunctionsInMap).toStrictEqual(["JSObject1.myFun2"]); + + // Add {{JSObject1.myFun2()}} to Button1.text + // This should cause an Edit of Button1.text + updatedAsyncJSFunctionsInMap = asyncJSFunctionInDataField.handlePathEdit( + "Button1.text", + ["JSObject1.myFun2"], + mockDataTree.unevalTree, + { + "appsmith.theme.borderRadius.appBorderRadius": [ + "appsmith.theme.borderRadius", + "Button1.borderRadius", + ], + "appsmith.theme.colors.primaryColor": [ + "appsmith.theme.colors", + "Button1.buttonColor", + ], + "appsmith.theme.colors": ["appsmith.theme"], + "appsmith.theme.borderRadius": ["appsmith.theme"], + "appsmith.theme": ["appsmith"], + "Button1.buttonColor": ["Button1"], + "Button1.borderRadius": ["Button1"], + "Button1.text": ["Button1"], + "Api1.run": ["Api1", "JSObject1.myFun3"], + "JSObject1.myFun1": ["JSObject1.body", "JSObject1"], + "JSObject1.myFun2": ["JSObject1.body", "JSObject1"], + "JSObject1.myFun3": ["JSObject1.body", "JSObject1"], + "JSObject1.body": ["JSObject1"], + "JSObject1.myVar1": ["JSObject1"], + "JSObject1.myVar2": ["JSObject1"], + } as DependencyMap, + mockDataTree.configTree, + ); + expect(updatedAsyncJSFunctionsInMap).toStrictEqual(["JSObject1.myFun2"]); + + // Delete JSObject + newDataTree = { + unevalTree: { + Api1: { + actionId: "6425db8b3c6952132524e6ea", + run: {}, + clear: {}, + isLoading: false, + responseMeta: { + isExecutionSuccess: false, + }, + config: { + timeoutInMillisecond: 10000, + paginationType: "NONE", + headers: [ + { + key: "", + value: "", + }, + { + key: "", + value: "", + }, + ], + encodeParamsToggle: true, + queryParameters: [ + { + key: "", + value: "", + }, + { + key: "", + value: "", + }, + ], + body: "", + bodyFormData: [], + httpMethod: "GET", + selfReferencingDataPaths: [], + pluginSpecifiedTemplates: [ + { + value: true, + }, + ], + formData: { + apiContentType: "none", + }, + }, + ENTITY_TYPE: "ACTION", + datasourceUrl: "", + }, + MainContainer: { + ENTITY_TYPE: "WIDGET", + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 4896, + snapColumns: 64, + widgetId: "0", + topRow: 0, + bottomRow: 380, + containerStyle: "none", + snapRows: 124, + parentRowSpace: 1, + canExtend: true, + minHeight: 1292, + parentColumnSpace: 1, + leftColumn: 0, + meta: {}, + type: "CANVAS_WIDGET", + }, + Button1: { + ENTITY_TYPE: "WIDGET", + resetFormOnClick: false, + boxShadow: "none", + widgetName: "Button1", + buttonColor: "{{appsmith.theme.colors.primaryColor}}", + topRow: 15, + bottomRow: 19, + parentRowSpace: 10, + animateLoading: true, + parentColumnSpace: 7.5625, + leftColumn: 20, + text: "{{JSObject1.myFun2()}} ", + isDisabled: false, + key: "lj612scwwe", + rightColumn: 36, + isDefaultClickDisabled: true, + widgetId: "5c14ze6dtv", + minWidth: 120, + isVisible: true, + recaptchaType: "V3", + isLoading: false, + responsiveBehavior: "hug", + disabledWhenInvalid: false, + borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}", + buttonVariant: "PRIMARY", + placement: "CENTER", + meta: {}, + type: "BUTTON_WIDGET", + }, + pageList: [ + { + pageName: "Page1", + pageId: "6425db193c6952132524e6e2", + isDefault: true, + isHidden: false, + slug: "page1", + userPermissions: [ + "read:pages", + "manage:pages", + "create:pageActions", + "delete:pages", + ], + }, + ], + appsmith: { + user: { + email: "favour@appsmith.com", + workspaceIds: [ + "5f7add8687af934ed846dd6a", + "60fa970664d41f773aab20b8", + "60a7dccf98f6c43a4b854dcb", + "61bc28259229e87746b78969", + "618bdd29da7cd651ee273494", + "60c1a5273535574772b6377b", + "6225f57945ea27345b497529", + "61e7be9feb0501052b9fed2a", + "622666f2b49d5451b1cd070a", + "61431979a67ce2289d3c7c6d", + "627a49410b47255c281326a6", + "62e7948c4003a7259a3027c8", + ], + username: "favour@appsmith.com", + name: "Favour Ohanekwu", + photoId: "62a963ac84b91337251a632f", + enableTelemetry: true, + emptyInstance: false, + accountNonExpired: true, + accountNonLocked: true, + credentialsNonExpired: true, + isAnonymous: false, + isEnabled: true, + isSuperUser: false, + isConfigurable: true, + adminSettingsVisible: false, + }, + URL: { + fullPath: + "https://dev.appsmith.com/app/untitled-application-39/page1-6425db193c6952132524e6e2/edit/widgets/5c14ze6dtv", + host: "dev.appsmith.com", + hostname: "dev.appsmith.com", + queryParams: {}, + protocol: "https:", + pathname: + "/app/untitled-application-39/page1-6425db193c6952132524e6e2/edit/widgets/5c14ze6dtv", + port: "", + hash: "", + }, + store: {}, + geolocation: { + canBeRequested: true, + currentPosition: {}, + }, + mode: "EDIT", + theme: { + colors: { + primaryColor: "#553DE9", + backgroundColor: "#F8FAFC", + }, + borderRadius: { + appBorderRadius: "0.375rem", + }, + boxShadow: { + appBoxShadow: + "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)", + }, + fontFamily: { + appFont: "Nunito Sans", + }, + }, + ENTITY_TYPE: "APPSMITH", + }, + }, + configTree: { + Api1: { + actionId: "6425db8b3c6952132524e6ea", + name: "Api1", + pluginId: "5ca385dc81b37f0004b4db85", + pluginType: "API", + dynamicBindingPathList: [], + ENTITY_TYPE: "ACTION", + bindingPaths: { + "config.path": "TEMPLATE", + "config.body": "SMART_SUBSTITUTE", + "config.queryParameters[0].key": "TEMPLATE", + "config.queryParameters[0].value": "TEMPLATE", + "config.queryParameters[1].key": "TEMPLATE", + "config.queryParameters[1].value": "TEMPLATE", + "config.headers[0].key": "TEMPLATE", + "config.headers[0].value": "TEMPLATE", + "config.headers[1].key": "TEMPLATE", + "config.headers[1].value": "TEMPLATE", + "config.pluginSpecifiedTemplates[1].value": "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.offset.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.cursor.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.cursor.value": + "SMART_SUBSTITUTE", + }, + reactivePaths: { + data: "TEMPLATE", + isLoading: "TEMPLATE", + datasourceUrl: "TEMPLATE", + "config.path": "TEMPLATE", + "config.body": "SMART_SUBSTITUTE", + "config.queryParameters[0].key": "TEMPLATE", + "config.queryParameters[0].value": "TEMPLATE", + "config.queryParameters[1].key": "TEMPLATE", + "config.queryParameters[1].value": "TEMPLATE", + "config.headers[0].key": "TEMPLATE", + "config.headers[0].value": "TEMPLATE", + "config.headers[1].key": "TEMPLATE", + "config.headers[1].value": "TEMPLATE", + "config.pluginSpecifiedTemplates[1].value": "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.limitBased.offset.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.previous.cursor.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.limit.value": + "SMART_SUBSTITUTE", + "config.pluginSpecifiedTemplates[2].value.cursorBased.next.cursor.value": + "SMART_SUBSTITUTE", + }, + dependencyMap: { + "config.body": ["config.pluginSpecifiedTemplates[0].value"], + }, + logBlackList: {}, + }, + MainContainer: { + defaultProps: {}, + defaultMetaProps: [], + dynamicBindingPathList: [], + logBlackList: {}, + bindingPaths: {}, + reactivePaths: {}, + triggerPaths: {}, + validationPaths: {}, + ENTITY_TYPE: "WIDGET", + privateWidgets: {}, + propertyOverrideDependency: {}, + overridingPropertyPaths: {}, + type: "CANVAS_WIDGET", + dynamicTriggerPathList: [], + isMetaPropDirty: false, + widgetId: "0", + }, + Button1: { + defaultProps: {}, + defaultMetaProps: ["recaptchaToken"], + dynamicBindingPathList: [ + { + key: "buttonColor", + }, + { + key: "borderRadius", + }, + { + key: "text", + }, + ], + logBlackList: {}, + bindingPaths: { + text: "TEMPLATE", + tooltip: "TEMPLATE", + isVisible: "TEMPLATE", + isDisabled: "TEMPLATE", + animateLoading: "TEMPLATE", + googleRecaptchaKey: "TEMPLATE", + recaptchaType: "TEMPLATE", + disabledWhenInvalid: "TEMPLATE", + resetFormOnClick: "TEMPLATE", + buttonVariant: "TEMPLATE", + iconName: "TEMPLATE", + placement: "TEMPLATE", + buttonColor: "TEMPLATE", + borderRadius: "TEMPLATE", + boxShadow: "TEMPLATE", + }, + reactivePaths: { + recaptchaToken: "TEMPLATE", + buttonColor: "TEMPLATE", + borderRadius: "TEMPLATE", + text: "TEMPLATE", + tooltip: "TEMPLATE", + isVisible: "TEMPLATE", + isDisabled: "TEMPLATE", + animateLoading: "TEMPLATE", + googleRecaptchaKey: "TEMPLATE", + recaptchaType: "TEMPLATE", + disabledWhenInvalid: "TEMPLATE", + resetFormOnClick: "TEMPLATE", + buttonVariant: "TEMPLATE", + iconName: "TEMPLATE", + placement: "TEMPLATE", + boxShadow: "TEMPLATE", + }, + triggerPaths: { + onClick: true, + }, + validationPaths: { + text: { + type: "TEXT", + }, + tooltip: { + type: "TEXT", + }, + isVisible: { + type: "BOOLEAN", + }, + isDisabled: { + type: "BOOLEAN", + }, + animateLoading: { + type: "BOOLEAN", + }, + googleRecaptchaKey: { + type: "TEXT", + }, + recaptchaType: { + type: "TEXT", + params: { + allowedValues: ["V3", "V2"], + default: "V3", + }, + }, + disabledWhenInvalid: { + type: "BOOLEAN", + }, + resetFormOnClick: { + type: "BOOLEAN", + }, + buttonVariant: { + type: "TEXT", + params: { + allowedValues: ["PRIMARY", "SECONDARY", "TERTIARY"], + default: "PRIMARY", + }, + }, + iconName: { + type: "TEXT", + }, + placement: { + type: "TEXT", + params: { + allowedValues: ["START", "BETWEEN", "CENTER"], + default: "CENTER", + }, + }, + buttonColor: { + type: "TEXT", + }, + borderRadius: { + type: "TEXT", + }, + boxShadow: { + type: "TEXT", + }, + }, + ENTITY_TYPE: "WIDGET", + privateWidgets: {}, + propertyOverrideDependency: {}, + overridingPropertyPaths: {}, + type: "BUTTON_WIDGET", + dynamicTriggerPathList: [], + isMetaPropDirty: false, + widgetId: "5c14ze6dtv", + }, + }, + } as unknown as { + unevalTree: UnEvalTree; + configTree: ConfigTree; + }; + + updatedAsyncJSFunctionsInMap = + asyncJSFunctionInDataField.handlePathDeletion( + "JSObject1", + newDataTree.unevalTree, + newDataTree.configTree, + ); + expect(updatedAsyncJSFunctionsInMap).toStrictEqual([]); + expect(asyncJSFunctionInDataField.getMap()).toStrictEqual({}); + }); +}); + +describe("isFunctionInvoked", () => { + it("Works correctly", () => { + const data = [ + { + textContent: "{{JSObject1.myFun2()}}", + expectedResult: true, + }, + { + textContent: "{{JSObject1.myFun2.call()}}", + expectedResult: true, + }, + { + textContent: "{{JSObject1.myFun2.apply()}}", + expectedResult: true, + }, + { + textContent: "{{JSObject1.myFun2.bind()}}", + expectedResult: false, + }, + { + textContent: "{{JSObject1.myFun2}}", + expectedResult: false, + }, + { + textContent: "JSObject1.myFun2.apply(){{JSObject1.myFun2}}", + expectedResult: false, + }, + { + textContent: {}, + expectedResult: false, + }, + ]; + + for (const datum of data) { + const actualResult = isFunctionInvoked( + "JSObject1.myFun2", + datum.textContent, + ); + expect(actualResult).toStrictEqual(datum.expectedResult); + } + }); +}); diff --git a/app/client/src/workers/Evaluation/JSObject/utils.ts b/app/client/src/workers/Evaluation/JSObject/utils.ts index 0db3646d09..a06464d017 100644 --- a/app/client/src/workers/Evaluation/JSObject/utils.ts +++ b/app/client/src/workers/Evaluation/JSObject/utils.ts @@ -216,7 +216,6 @@ export const removeFunctionsAndVariableJSCollection = ( unset(modifiedDataTree[entityName], varName); } //remove functions - const reactivePaths = entity.reactivePaths; const meta = entity.meta; diff --git a/app/client/src/workers/Evaluation/__tests__/errorModifier.test.ts b/app/client/src/workers/Evaluation/__tests__/errorModifier.test.ts index 46d48c42b7..ddba404fb9 100644 --- a/app/client/src/workers/Evaluation/__tests__/errorModifier.test.ts +++ b/app/client/src/workers/Evaluation/__tests__/errorModifier.test.ts @@ -124,46 +124,46 @@ describe("Test error modifier", () => { errorModifier.updateAsyncFunctions(dataTree); }); - it("TypeError for defined Api in sync field ", () => { + it("TypeError for defined Api in data field ", () => { const error = new Error(); error.name = "TypeError"; error.message = "Api2.run is not a function"; - const result = errorModifier.run(error); + const { errorMessage: result } = errorModifier.run(error); expect(result).toEqual({ name: "ValidationError", message: - "Found a reference to Api2.run() during evaluation. Sync fields cannot execute framework actions. Please remove any direct/indirect references to Api2.run() and try again.", + "Found a reference to Api2.run() during evaluation. Data fields cannot execute framework actions. Please remove any direct/indirect references to Api2.run() and try again.", }); }); - it("TypeError for undefined Api in sync field ", () => { + it("TypeError for undefined Api in data field ", () => { const error = new Error(); error.name = "TypeError"; error.message = "Api1.run is not a function"; - const result = errorModifier.run(error); + const { errorMessage: result } = errorModifier.run(error); expect(result).toEqual({ name: "TypeError", message: "Api1.run is not a function", }); }); - it("ReferenceError for platform function in sync field", () => { + it("ReferenceError for platform function in data field", () => { const error = new Error(); error.name = "ReferenceError"; error.message = "storeValue is not defined"; - const result = errorModifier.run(error); + const { errorMessage: result } = errorModifier.run(error); expect(result).toEqual({ name: "ValidationError", message: - "Found a reference to storeValue() during evaluation. Sync fields cannot execute framework actions. Please remove any direct/indirect references to storeValue() and try again.", + "Found a reference to storeValue() during evaluation. Data fields cannot execute framework actions. Please remove any direct/indirect references to storeValue() and try again.", }); }); - it("ReferenceError for undefined function in sync field", () => { + it("ReferenceError for undefined function in data field", () => { const error = new Error(); error.name = "ReferenceError"; error.message = "storeValue2 is not defined"; - const result = errorModifier.run(error); + const { errorMessage: result } = errorModifier.run(error); expect(result).toEqual({ name: error.name, message: error.message, diff --git a/app/client/src/workers/Evaluation/__tests__/evaluate.test.ts b/app/client/src/workers/Evaluation/__tests__/evaluate.test.ts index 1c04aa1cb7..5450921b90 100644 --- a/app/client/src/workers/Evaluation/__tests__/evaluate.test.ts +++ b/app/client/src/workers/Evaluation/__tests__/evaluate.test.ts @@ -76,6 +76,7 @@ describe("evaluateSync", () => { message: "wrongJS is not defined", }, errorType: "PARSE", + kind: undefined, raw: ` function $$closedFn () { const $$result = wrongJS @@ -98,6 +99,7 @@ describe("evaluateSync", () => { message: "{}.map is not a function", }, errorType: "PARSE", + kind: undefined, raw: ` function $$closedFn () { const $$result = {}.map() @@ -128,6 +130,7 @@ describe("evaluateSync", () => { message: "setImmediate is not defined", }, errorType: "PARSE", + kind: undefined, raw: ` function $$closedFn () { const $$result = setImmediate(() => {}, 100) diff --git a/app/client/src/workers/Evaluation/errorModifier.ts b/app/client/src/workers/Evaluation/errorModifier.ts index ca3bd8767b..ee66aedd2b 100644 --- a/app/client/src/workers/Evaluation/errorModifier.ts +++ b/app/client/src/workers/Evaluation/errorModifier.ts @@ -1,9 +1,12 @@ import type { DataTree } from "entities/DataTree/dataTreeFactory"; import { getAllAsyncFunctions } from "@appsmith/workers/Evaluation/Actions"; +import type { EvaluationError } from "utils/DynamicBindingUtils"; +import { PropertyEvaluationErrorCategory } from "utils/DynamicBindingUtils"; +const FOUND_ASYNC_IN_SYNC_EVAL_MESSAGE = + "Found an action invocation during evaluation. Data fields cannot execute actions."; const UNDEFINED_ACTION_IN_SYNC_EVAL_ERROR = - "Found a reference to {{actionName}} during evaluation. Sync fields cannot execute framework actions. Please remove any direct/indirect references to {{actionName}} and try again."; - + "Found a reference to {{actionName}} during evaluation. Data fields cannot execute framework actions. Please remove any direct/indirect references to {{actionName}} and try again."; class ErrorModifier { private errorNamesToScan = ["ReferenceError", "TypeError"]; // Note all regex below groups the async function name @@ -14,10 +17,23 @@ class ErrorModifier { this.asyncFunctionsNameMap = getAllAsyncFunctions(dataTree); } - run(error: Error) { + run(error: Error): { + errorMessage: ReturnType; + errorCategory?: PropertyEvaluationErrorCategory; + } { const errorMessage = getErrorMessage(error); + if ( + error instanceof FoundPromiseInSyncEvalError || + error instanceof ActionCalledInSyncFieldError + ) { + return { + errorMessage, + errorCategory: + PropertyEvaluationErrorCategory.INVALID_JS_FUNCTION_INVOCATION_IN_DATA_FIELD, + }; + } - if (!this.errorNamesToScan.includes(error.name)) return errorMessage; + if (!this.errorNamesToScan.includes(error.name)) return { errorMessage }; for (const asyncFunctionFullPath of Object.keys( this.asyncFunctionsNameMap, @@ -25,27 +41,49 @@ class ErrorModifier { const functionNameWithWhiteSpace = " " + asyncFunctionFullPath + " "; if (getErrorMessageWithType(error).match(functionNameWithWhiteSpace)) { return { - name: "ValidationError", - message: UNDEFINED_ACTION_IN_SYNC_EVAL_ERROR.replaceAll( - "{{actionName}}", - asyncFunctionFullPath + "()", - ), + errorMessage: { + name: "ValidationError", + message: UNDEFINED_ACTION_IN_SYNC_EVAL_ERROR.replaceAll( + "{{actionName}}", + asyncFunctionFullPath + "()", + ), + }, + errorCategory: + PropertyEvaluationErrorCategory.INVALID_JS_FUNCTION_INVOCATION_IN_DATA_FIELD, }; } } - return errorMessage; + return { errorMessage }; + } + setAsyncInvocationErrorsRootcause( + errors: EvaluationError[], + asyncFunc: string, + ) { + return errors.map((error) => { + if (isAsyncFunctionCalledInSyncFieldError(error)) { + error.errorMessage.message = FOUND_ASYNC_IN_SYNC_EVAL_MESSAGE; + error.kind = { + category: + PropertyEvaluationErrorCategory.INVALID_JS_FUNCTION_INVOCATION_IN_DATA_FIELD, + rootcause: asyncFunc, + }; + } + return error; + }); } } export const errorModifier = new ErrorModifier(); +const FOUND_PROMISE_IN_SYNC_EVAL_MESSAGE = + "Found a Promise() during evaluation. Data fields cannot execute asynchronous code."; + export class FoundPromiseInSyncEvalError extends Error { constructor() { super(); this.name = ""; - this.message = - "Found a Promise() during evaluation. Sync fields cannot execute asynchronous code."; + this.message = FOUND_PROMISE_IN_SYNC_EVAL_MESSAGE; } } @@ -54,7 +92,7 @@ export class ActionCalledInSyncFieldError extends Error { super(actionName); if (!actionName) { - this.message = "Async function called in a sync field"; + this.message = "Async function called in a data field"; return; } @@ -81,3 +119,10 @@ export const getErrorMessage = (error: Error) => { export const getErrorMessageWithType = (error: Error) => { return error.name ? `${error.name}: ${error.message}` : error.message; }; + +function isAsyncFunctionCalledInSyncFieldError(error: EvaluationError) { + return ( + error.kind?.category === + PropertyEvaluationErrorCategory.INVALID_JS_FUNCTION_INVOCATION_IN_DATA_FIELD + ); +} diff --git a/app/client/src/workers/Evaluation/evaluate.ts b/app/client/src/workers/Evaluation/evaluate.ts index 0f197ed487..647ccfb630 100644 --- a/app/client/src/workers/Evaluation/evaluate.ts +++ b/app/client/src/workers/Evaluation/evaluate.ts @@ -23,6 +23,7 @@ export enum EvaluationScriptType { ANONYMOUS_FUNCTION = "ANONYMOUS_FUNCTION", ASYNC_ANONYMOUS_FUNCTION = "ASYNC_ANONYMOUS_FUNCTION", TRIGGERS = "TRIGGERS", + OBJECT_PROPERTY = "OBJECT_PROPERTY", } export const ScriptTemplate = "<>"; @@ -58,6 +59,13 @@ export const EvaluationScripts: Record = { } $$closedFn.call(THIS_CONTEXT) `, + [EvaluationScriptType.OBJECT_PROPERTY]: ` + function $$closedFn () { + const $$result = {${ScriptTemplate}} + return $$result + } + $$closedFn.call(THIS_CONTEXT) + `, }; const topLevelWorkerAPIs = Object.keys(self).reduce((acc, key: string) => { @@ -120,8 +128,11 @@ export interface createEvaluationContextArgs { context?: EvaluateContext; isTriggerBased: boolean; evalArguments?: Array; - // Whether not to add functions like "run", "clear" to entity in global data - skipEntityFunctions?: boolean; + /* + Whether to remove functions like "run", "clear" from entities in global context + use case => To show lint warning when Api.run is used in a function bound to a data field (Eg. Button.text) + */ + removeEntityFunctions?: boolean; } /** * This method created an object with dataTree and appsmith's framework actions that needs to be added to worker global scope for the JS code evaluation to then consume it. @@ -135,8 +146,8 @@ export const createEvaluationContext = (args: createEvaluationContextArgs) => { dataTree, evalArguments, isTriggerBased, + removeEntityFunctions, resolvedFunctions, - skipEntityFunctions, } = args; const EVAL_CONTEXT: EvalContext = {}; @@ -152,7 +163,7 @@ export const createEvaluationContext = (args: createEvaluationContextArgs) => { addDataTreeToContext({ EVAL_CONTEXT, dataTree, - skipEntityFunctions: !!skipEntityFunctions, + removeEntityFunctions: !!removeEntityFunctions, isTriggerBased, }); @@ -279,18 +290,23 @@ export default function evaluateSync( result = indirectEval(script); if (result instanceof Promise) { /** - * If a promise is returned in sync field then show the error to help understand sync field doesn't await to resolve promise. - * NOTE: Awaiting for promise will make sync field evaluation slower. + * If a promise is returned in data field then show the error to help understand data field doesn't await to resolve promise. + * NOTE: Awaiting for promise will make data field evaluation slower. */ throw new FoundPromiseInSyncEvalError(); } } catch (error) { + const { errorCategory, errorMessage } = errorModifier.run(error as Error); errors.push({ - errorMessage: errorModifier.run(error as Error), + errorMessage, severity: Severity.ERROR, raw: script, errorType: PropertyEvaluationErrorType.PARSE, originalBinding: userScript, + kind: errorCategory && { + category: errorCategory, + rootcause: "", + }, }); } finally { for (const entityName in evalContext) { diff --git a/app/client/src/workers/Evaluation/handlers/evalTree.ts b/app/client/src/workers/Evaluation/handlers/evalTree.ts index b48a077c37..f3c47e2a27 100644 --- a/app/client/src/workers/Evaluation/handlers/evalTree.ts +++ b/app/client/src/workers/Evaluation/handlers/evalTree.ts @@ -1,7 +1,7 @@ import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory"; import type ReplayEntity from "entities/Replay"; import ReplayCanvas from "entities/Replay/ReplayEntity/ReplayCanvas"; -import { isEmpty } from "lodash"; +import { isEmpty, union } from "lodash"; import type { DependencyMap, EvalError } from "utils/DynamicBindingUtils"; import { EvalErrorTypes } from "utils/DynamicBindingUtils"; import type { JSUpdate } from "utils/JSPaneUtils"; @@ -20,6 +20,8 @@ import type { EvalWorkerSyncRequest, } from "../types"; import { clearAllIntervals } from "../fns/overrides/interval"; +import { jsPropertiesState } from "../JSObject/jsPropertiesState"; +import { asyncJsFunctionInDataFields } from "../JSObject/asyncJSFunctionBoundToDataField"; export let replayMap: Record>; export let dataTreeEvaluator: DataTreeEvaluator | undefined; export const CANVAS = "canvas"; @@ -44,6 +46,7 @@ export default function (request: EvalWorkerSyncRequest) { const { allActionValidationConfig, + appMode, forceEvaluation, metaWidgets, requiresLinting, @@ -59,6 +62,7 @@ export default function (request: EvalWorkerSyncRequest) { try { if (!dataTreeEvaluator) { isCreateFirstTree = true; + asyncJsFunctionInDataFields.initialize(appMode); replayMap = replayMap || {}; replayMap[CANVAS] = new ReplayCanvas({ widgets, theme }); dataTreeEvaluator = new DataTreeEvaluator( @@ -71,17 +75,25 @@ export default function (request: EvalWorkerSyncRequest) { configTree, ); evalOrder = setupFirstTreeResponse.evalOrder; - lintOrder = setupFirstTreeResponse.lintOrder; + lintOrder = union( + setupFirstTreeResponse.lintOrder, + jsPropertiesState.getUpdatedJSProperties(), + ); jsUpdates = setupFirstTreeResponse.jsUpdates; - initiateLinting( + initiateLinting({ lintOrder, - makeEntityConfigsAsObjProperties(dataTreeEvaluator.oldUnEvalTree, { - sanitizeDataTree: false, - }), + unevalTree: makeEntityConfigsAsObjProperties( + dataTreeEvaluator.oldUnEvalTree, + { + sanitizeDataTree: false, + }, + ), requiresLinting, - dataTreeEvaluator.oldConfigTree, - ); + jsPropertiesState: jsPropertiesState.getMap(), + asyncJSFunctionsInDataFields: asyncJsFunctionInDataFields.getMap(), + configTree: dataTreeEvaluator.oldConfigTree, + }); const dataTreeResponse = dataTreeEvaluator.evalAndValidateFirstTree(); dataTree = makeEntityConfigsAsObjProperties(dataTreeResponse.evalTree, { @@ -113,17 +125,25 @@ export default function (request: EvalWorkerSyncRequest) { ); isCreateFirstTree = true; evalOrder = setupFirstTreeResponse.evalOrder; - lintOrder = setupFirstTreeResponse.lintOrder; + lintOrder = union( + setupFirstTreeResponse.lintOrder, + jsPropertiesState.getUpdatedJSProperties(), + ); jsUpdates = setupFirstTreeResponse.jsUpdates; - initiateLinting( + initiateLinting({ lintOrder, - makeEntityConfigsAsObjProperties(dataTreeEvaluator.oldUnEvalTree, { - sanitizeDataTree: false, - }), + unevalTree: makeEntityConfigsAsObjProperties( + dataTreeEvaluator.oldUnEvalTree, + { + sanitizeDataTree: false, + }, + ), requiresLinting, - dataTreeEvaluator.oldConfigTree, - ); + jsPropertiesState: jsPropertiesState.getMap(), + asyncJSFunctionsInDataFields: asyncJsFunctionInDataFields.getMap(), + configTree: dataTreeEvaluator.oldConfigTree, + }); const dataTreeResponse = dataTreeEvaluator.evalAndValidateFirstTree(); dataTree = makeEntityConfigsAsObjProperties(dataTreeResponse.evalTree, { @@ -146,20 +166,28 @@ export default function (request: EvalWorkerSyncRequest) { ); evalOrder = setupUpdateTreeResponse.evalOrder; - lintOrder = setupUpdateTreeResponse.lintOrder; + lintOrder = union( + setupUpdateTreeResponse.lintOrder, + jsPropertiesState.getUpdatedJSProperties(), + ); jsUpdates = setupUpdateTreeResponse.jsUpdates; unEvalUpdates = setupUpdateTreeResponse.unEvalUpdates; pathsToClearErrorsFor = setupUpdateTreeResponse.pathsToClearErrorsFor; isNewWidgetAdded = setupUpdateTreeResponse.isNewWidgetAdded; - initiateLinting( + initiateLinting({ lintOrder, - makeEntityConfigsAsObjProperties(dataTreeEvaluator.oldUnEvalTree, { - sanitizeDataTree: false, - }), + unevalTree: makeEntityConfigsAsObjProperties( + dataTreeEvaluator.oldUnEvalTree, + { + sanitizeDataTree: false, + }, + ), requiresLinting, - dataTreeEvaluator.oldConfigTree, - ); + jsPropertiesState: jsPropertiesState.getMap(), + asyncJSFunctionsInDataFields: asyncJsFunctionInDataFields.getMap(), + configTree: dataTreeEvaluator.oldConfigTree, + }); nonDynamicFieldValidationOrder = setupUpdateTreeResponse.nonDynamicFieldValidationOrder; diff --git a/app/client/src/workers/Evaluation/types.ts b/app/client/src/workers/Evaluation/types.ts index f841d890ec..9147d76949 100644 --- a/app/client/src/workers/Evaluation/types.ts +++ b/app/client/src/workers/Evaluation/types.ts @@ -18,6 +18,7 @@ import type { WidgetTypeConfigMap } from "utils/WidgetFactory"; import type { EvalMetaUpdates } from "@appsmith/workers/common/DataTreeEvaluator/types"; import type { WorkerRequest } from "@appsmith/workers/common/types"; import type { DataTreeDiff } from "@appsmith/workers/Evaluation/evaluationUtils"; +import type { APP_MODE } from "entities/App"; export type EvalWorkerSyncRequest = WorkerRequest; export type EvalWorkerASyncRequest = WorkerRequest< @@ -38,6 +39,7 @@ export interface EvalTreeRequestData { requiresLinting: boolean; forceEvaluation: boolean; metaWidgets: MetaWidgetsReduxState; + appMode: APP_MODE | undefined; } export interface EvalTreeResponseData { diff --git a/app/client/src/workers/Linting/constants.ts b/app/client/src/workers/Linting/constants.ts index e3916180e6..d33a32592c 100644 --- a/app/client/src/workers/Linting/constants.ts +++ b/app/client/src/workers/Linting/constants.ts @@ -1,5 +1,6 @@ import { ECMA_VERSION } from "@shared/ast"; import type { LintOptions } from "jshint"; +import { isEntityFunction } from "./utils"; export const lintOptions = (globalData: Record) => ({ @@ -29,6 +30,8 @@ export const lintOptions = (globalData: Record) => } as LintOptions); export const JS_OBJECT_START_STATEMENT = "export default"; export const INVALID_JSOBJECT_START_STATEMENT = `JSObject must start with '${JS_OBJECT_START_STATEMENT}'`; +export const INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE = + "INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE"; // https://github.com/jshint/jshint/blob/d3d84ae1695359aef077ddb143f4be98001343b4/src/messages.js#L204 export const IDENTIFIER_NOT_DEFINED_LINT_ERROR_CODE = "W117"; @@ -37,10 +40,14 @@ export const IDENTIFIER_NOT_DEFINED_LINT_ERROR_CODE = "W117"; export const WARNING_LINT_ERRORS = { W098: "'{a}' is defined but never used.", W014: "Misleading line break before '{a}'; readers may interpret this as an expression boundary.", + ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD: + "Cannot execute async code on functions bound to data fields", }; -export function asyncActionInSyncFieldLintMessage(actionName: string) { - return `Async framework action "${actionName}" cannot be executed in a function that is bound to a sync field.`; +export function asyncActionInSyncFieldLintMessage(isJsObject = false) { + return isJsObject + ? `Cannot execute async code on functions bound to data fields` + : `Data fields cannot execute async code`; } /** These errors should be overlooked @@ -54,7 +61,9 @@ export const SUPPORTED_WEB_APIS = { }; export enum CustomLintErrorCode { INVALID_ENTITY_PROPERTY = "INVALID_ENTITY_PROPERTY", + ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD = "ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD", } + export const CUSTOM_LINT_ERRORS: Record< CustomLintErrorCode, (...args: any[]) => string @@ -62,5 +71,26 @@ export const CUSTOM_LINT_ERRORS: Record< [CustomLintErrorCode.INVALID_ENTITY_PROPERTY]: ( entityName: string, propertyName: string, - ) => `"${propertyName}" doesn't exist in ${entityName}`, + entity: unknown, + isJsObject: boolean, + ) => + isEntityFunction(entity, propertyName) + ? asyncActionInSyncFieldLintMessage(isJsObject) + : `"${propertyName}" doesn't exist in ${entityName}`, + + [CustomLintErrorCode.ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD]: ( + dataFieldBindings: string[], + fullName: string, + isMarkedAsync: boolean, + ) => { + const hasMultipleBindings = dataFieldBindings.length > 1; + const bindings = dataFieldBindings.join(" , "); + return isMarkedAsync + ? `Cannot bind async functions to data fields. Convert this to a sync function or remove references to "${fullName}" on the following data ${ + hasMultipleBindings ? "fields" : "field" + }: ${bindings}` + : `Functions bound to data fields cannot execute async code. Remove async statements highlighted below or remove references to "${fullName}" on the following data ${ + hasMultipleBindings ? "fields" : "field" + }: ${bindings}`; + }, }; diff --git a/app/client/src/workers/Linting/globalData.ts b/app/client/src/workers/Linting/globalData.ts new file mode 100644 index 0000000000..e7bbd176f5 --- /dev/null +++ b/app/client/src/workers/Linting/globalData.ts @@ -0,0 +1,47 @@ +import type { DataTree } from "entities/DataTree/dataTreeFactory"; +import { isEmpty } from "lodash"; +import type { EvalContext } from "workers/Evaluation/evaluate"; +import { getEvaluationContext } from "./utils"; + +class GlobalData { + globalDataWithFunctions: EvalContext = {}; + globalDataWithoutFunctions: EvalContext = {}; + unevalTree: DataTree = {}; + cloudHosting = false; + + initialize(unevalTree: DataTree, cloudHosting: boolean) { + this.globalDataWithFunctions = {}; + this.globalDataWithoutFunctions = {}; + this.unevalTree = unevalTree; + this.cloudHosting = cloudHosting; + } + + getGlobalData(withFunctions: boolean) { + // Our goal is to create global data (with or without functions) only once during a linting cycle + if (withFunctions) { + if (isEmpty(this.globalDataWithFunctions)) { + this.globalDataWithFunctions = getEvaluationContext( + this.unevalTree, + this.cloudHosting, + { + withFunctions: true, + }, + ); + } + return this.globalDataWithFunctions; + } else { + if (isEmpty(this.globalDataWithoutFunctions)) { + this.globalDataWithoutFunctions = getEvaluationContext( + this.unevalTree, + this.cloudHosting, + { + withFunctions: false, + }, + ); + } + return this.globalDataWithoutFunctions; + } + } +} + +export const globalData = new GlobalData(); diff --git a/app/client/src/workers/Linting/index.ts b/app/client/src/workers/Linting/index.ts index 6ded4ae9dc..55ebe44a1a 100644 --- a/app/client/src/workers/Linting/index.ts +++ b/app/client/src/workers/Linting/index.ts @@ -1,126 +1,110 @@ +import { getEntityNameAndPropertyPath } from "@appsmith/workers/Evaluation/evaluationUtils"; +import { get, isEmpty, set } from "lodash"; +import type { LintErrorsStore } from "reducers/lintingReducers/lintErrorsReducers"; +import type { LintError } from "utils/DynamicBindingUtils"; +import { globalData } from "./globalData"; +import type { + getlintErrorsFromTreeProps, + getlintErrorsFromTreeResponse, +} from "./types"; import { - getEntityNameAndPropertyPath, - isATriggerPath, - isJSAction, -} from "ce/workers/Evaluation/evaluationUtils"; -import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory"; -import { get, set } from "lodash"; -import type { LintErrors } from "reducers/lintingReducers/lintErrorsReducers"; -import { createEvaluationContext } from "workers/Evaluation/evaluate"; -import { getActionTriggerFunctionNames } from "workers/Evaluation/fns"; -import { lintBindingPath, lintTriggerPath, pathRequiresLinting } from "./utils"; + lintBindingPath, + lintJSObjectBody, + lintJSObjectProperty, + lintTriggerPath, + sortLintingPathsByType, +} from "./utils"; -export function getlintErrorsFromTree( - pathsToLint: string[], - unEvalTree: DataTree, - configTree: ConfigTree, - cloudHosting: boolean, -): LintErrors { - const lintTreeErrors: LintErrors = {}; - - const evalContext = createEvaluationContext({ - dataTree: unEvalTree, - resolvedFunctions: {}, - isTriggerBased: false, - skipEntityFunctions: true, - }); - - const platformFnNamesMap = Object.values( - getActionTriggerFunctionNames(cloudHosting), - ).reduce( - (acc, name) => ({ ...acc, [name]: true }), - {} as { [x: string]: boolean }, +export function getlintErrorsFromTree({ + asyncJSFunctionsInDataFields, + cloudHosting, + configTree, + jsPropertiesState, + pathsToLint, + unEvalTree, +}: getlintErrorsFromTreeProps): getlintErrorsFromTreeResponse { + const lintTreeErrors: LintErrorsStore = {}; + const updatedJSEntities = new Set(); + globalData.initialize(unEvalTree, cloudHosting); + const { bindingPaths, jsObjectPaths, triggerPaths } = sortLintingPathsByType( + pathsToLint, + unEvalTree, + configTree, ); - Object.assign(evalContext, platformFnNamesMap); - const evalContextWithoutFunctions = createEvaluationContext({ - dataTree: unEvalTree, - resolvedFunctions: {}, - isTriggerBased: true, - skipEntityFunctions: true, - }); - - // trigger paths - const triggerPaths = new Set(); - // Certain paths, like JS Object's body are binding paths where appsmith functions are needed in the global data - const bindingPathsRequiringFunctions = new Set(); - - pathsToLint.forEach((fullPropertyPath) => { - const { entityName, propertyPath } = - getEntityNameAndPropertyPath(fullPropertyPath); + // Lint binding paths + bindingPaths.forEach((bindingPath) => { + const { entityName } = getEntityNameAndPropertyPath(bindingPath); const entity = unEvalTree[entityName]; - const entityConfig = configTree[entityName]; const unEvalPropertyValue = get( unEvalTree, - fullPropertyPath, + bindingPath, ) as unknown as string; - // remove all lint errors from path - set(lintTreeErrors, `["${fullPropertyPath}"]`, []); - - // We are only interested in paths that require linting - if ( - !pathRequiresLinting(unEvalTree, entity, fullPropertyPath, entityConfig) - ) - return; - if (isATriggerPath(entityConfig, propertyPath)) - return triggerPaths.add(fullPropertyPath); - if (isJSAction(entity)) - return bindingPathsRequiringFunctions.add(`${entityName}.body`); const lintErrors = lintBindingPath({ - entity, - fullPropertyPath, - globalData: evalContextWithoutFunctions, dynamicBinding: unEvalPropertyValue, + entity, + fullPropertyPath: bindingPath, + globalData: globalData.getGlobalData(false), }); - set(lintTreeErrors, `["${fullPropertyPath}"]`, lintErrors); + set(lintTreeErrors, `["${bindingPath}"]`, lintErrors); }); - if (triggerPaths.size || bindingPathsRequiringFunctions.size) { - // we only create GLOBAL_DATA_WITH_FUNCTIONS if there are paths requiring it - // In trigger based fields, functions such as showAlert, storeValue, etc need to be added to the global data + // Lint TriggerPaths + triggerPaths.forEach((triggerPath) => { + const { entityName } = getEntityNameAndPropertyPath(triggerPath); + const entity = unEvalTree[entityName]; + const unEvalPropertyValue = get( + unEvalTree, + triggerPath, + ) as unknown as string; + // remove all lint errors from path + set(lintTreeErrors, `["${triggerPath}"]`, []); + const lintErrors = lintTriggerPath({ + userScript: unEvalPropertyValue, + entity, + globalData: globalData.getGlobalData(true), + }); + set(lintTreeErrors, `["${triggerPath}"]`, lintErrors); + }); - // lint binding paths that need GLOBAL_DATA_WITH_FUNCTIONS - if (bindingPathsRequiringFunctions.size) { - bindingPathsRequiringFunctions.forEach((fullPropertyPath) => { - const { entityName } = getEntityNameAndPropertyPath(fullPropertyPath); - const entity = unEvalTree[entityName]; - const unEvalPropertyValue = get( - unEvalTree, - fullPropertyPath, - ) as unknown as string; - // remove all lint errors from path - set(lintTreeErrors, `["${fullPropertyPath}"]`, []); - const lintErrors = lintBindingPath({ - dynamicBinding: unEvalPropertyValue, - entity, - fullPropertyPath, - globalData: evalContext, - }); - set(lintTreeErrors, `["${fullPropertyPath}"]`, lintErrors); - }); - } - - // Lint triggerPaths - if (triggerPaths.size) { - triggerPaths.forEach((triggerPath) => { - const { entityName } = getEntityNameAndPropertyPath(triggerPath); - const entity = unEvalTree[entityName]; - const unEvalPropertyValue = get( - unEvalTree, - triggerPath, - ) as unknown as string; - // remove all lint errors from path - set(lintTreeErrors, `["${triggerPath}"]`, []); - const lintErrors = lintTriggerPath({ - globalData: evalContext, - userScript: unEvalPropertyValue, - entity, - fullPropertyPath: triggerPath, - }); - set(lintTreeErrors, `["${triggerPath}"]`, lintErrors); - }); - } + // Lint jsobject paths + if (jsObjectPaths.size) { + jsObjectPaths.forEach((jsObjectPath) => { + const { entityName: jsObjectName } = + getEntityNameAndPropertyPath(jsObjectPath); + const jsObjectState = get(jsPropertiesState, jsObjectName); + const jsObjectBodyPath = `["${jsObjectName}.body"]`; + updatedJSEntities.add(jsObjectName); + // An empty state shows that there is a parse error in the jsObject or the object is empty, so we lint the entire body + // instead of an individual properties + if (isEmpty(jsObjectState)) { + const jsObjectBodyLintErrors = lintJSObjectBody( + jsObjectName, + globalData.getGlobalData(true), + ); + set(lintTreeErrors, jsObjectBodyPath, jsObjectBodyLintErrors); + } else if (jsObjectPath !== "body") { + const propertyLintErrors = lintJSObjectProperty( + jsObjectPath, + jsObjectState, + asyncJSFunctionsInDataFields, + ); + const currentLintErrorsInBody = get( + lintTreeErrors, + jsObjectBodyPath, + [] as LintError[], + ); + const updatedLintErrors = [ + ...currentLintErrorsInBody, + ...propertyLintErrors, + ]; + set(lintTreeErrors, jsObjectBodyPath, updatedLintErrors); + } + }); } - return lintTreeErrors; + return { + errors: lintTreeErrors, + updatedJSEntities: Array.from(updatedJSEntities), + }; } diff --git a/app/client/src/workers/Linting/lint.worker.ts b/app/client/src/workers/Linting/lint.worker.ts index 56ebefbb24..4d6b4ba1e7 100644 --- a/app/client/src/workers/Linting/lint.worker.ts +++ b/app/client/src/workers/Linting/lint.worker.ts @@ -64,18 +64,32 @@ function eventRequestHandler({ }): LintTreeResponse | unknown { switch (method) { case LINT_WORKER_ACTIONS.LINT_TREE: { - const lintTreeResponse: LintTreeResponse = { errors: {} }; + const lintTreeResponse: LintTreeResponse = { + errors: {}, + updatedJSEntities: [], + }; try { - const { cloudHosting, configTree, pathsToLint, unevalTree } = - requestData as LintTreeRequest; - const lintErrors = getlintErrorsFromTree( - pathsToLint, - unevalTree, - configTree, + const { + asyncJSFunctionsInDataFields, cloudHosting, + configTree, + jsPropertiesState, + pathsToLint, + unevalTree: unEvalTree, + } = requestData as LintTreeRequest; + const { errors: lintErrors, updatedJSEntities } = getlintErrorsFromTree( + { + pathsToLint, + unEvalTree, + jsPropertiesState, + cloudHosting, + asyncJSFunctionsInDataFields, + configTree, + }, ); lintTreeResponse.errors = lintErrors; + lintTreeResponse.updatedJSEntities = updatedJSEntities; } catch (e) {} return lintTreeResponse; } @@ -97,6 +111,7 @@ function eventRequestHandler({ } return true; } + default: { // eslint-disable-next-line no-console console.error("Action not registered on lintWorker ", method); diff --git a/app/client/src/workers/Linting/types.ts b/app/client/src/workers/Linting/types.ts index 2c8eae4cb9..8c7ad43aa6 100644 --- a/app/client/src/workers/Linting/types.ts +++ b/app/client/src/workers/Linting/types.ts @@ -1,6 +1,16 @@ -import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory"; -import type { LintErrors } from "reducers/lintingReducers/lintErrorsReducers"; +import type { + ConfigTree, + DataTree, + DataTreeEntity, +} from "entities/DataTree/dataTreeFactory"; +import type { LintErrorsStore } from "reducers/lintingReducers/lintErrorsReducers"; import type { WorkerRequest } from "@appsmith/workers/common/types"; +import type { + createEvaluationContext, + EvaluationScriptType, +} from "workers/Evaluation/evaluate"; +import type { DependencyMap } from "utils/DynamicBindingUtils"; +import type { TJSPropertiesState } from "workers/Evaluation/JSObject/jsPropertiesState"; export enum LINT_WORKER_ACTIONS { LINT_TREE = "LINT_TREE", @@ -8,14 +18,17 @@ export enum LINT_WORKER_ACTIONS { } export interface LintTreeResponse { - errors: LintErrors; + errors: LintErrorsStore; + updatedJSEntities: string[]; } export interface LintTreeRequest { pathsToLint: string[]; unevalTree: DataTree; + jsPropertiesState: TJSPropertiesState; configTree: ConfigTree; cloudHosting: boolean; + asyncJSFunctionsInDataFields: DependencyMap; } export type LintWorkerRequest = WorkerRequest< @@ -26,5 +39,54 @@ export type LintWorkerRequest = WorkerRequest< export type LintTreeSagaRequestData = { pathsToLint: string[]; unevalTree: DataTree; + jsPropertiesState: TJSPropertiesState; + asyncJSFunctionsInDataFields: DependencyMap; configTree: ConfigTree; }; + +export interface lintTriggerPathProps { + userScript: string; + entity: DataTreeEntity; + globalData: ReturnType; +} + +export interface lintBindingPathProps { + dynamicBinding: string; + entity: DataTreeEntity; + fullPropertyPath: string; + globalData: ReturnType; +} + +export interface getLintingErrorsProps { + script: string; + data: Record; + // {{user's code}} + originalBinding: string; + scriptType: EvaluationScriptType; + options?: { + isJsObject: boolean; + }; +} + +export interface getlintErrorsFromTreeProps { + pathsToLint: string[]; + unEvalTree: DataTree; + jsPropertiesState: TJSPropertiesState; + cloudHosting: boolean; + asyncJSFunctionsInDataFields: DependencyMap; + configTree: ConfigTree; +} + +export interface getlintErrorsFromTreeResponse { + errors: LintErrorsStore; + updatedJSEntities: string[]; +} + +export interface initiateLintingProps { + asyncJSFunctionsInDataFields: DependencyMap; + lintOrder: string[]; + unevalTree: DataTree; + requiresLinting: boolean; + jsPropertiesState: TJSPropertiesState; + configTree: ConfigTree; +} diff --git a/app/client/src/workers/Linting/utils.ts b/app/client/src/workers/Linting/utils.ts index b27e531471..68c021c63b 100644 --- a/app/client/src/workers/Linting/utils.ts +++ b/app/client/src/workers/Linting/utils.ts @@ -1,30 +1,27 @@ import type { - ConfigTree, DataTree, DataTreeEntity, - DataTreeEntityConfig, + ConfigTree, } from "entities/DataTree/dataTreeFactory"; import type { Position } from "codemirror"; import type { LintError } from "utils/DynamicBindingUtils"; -import { - isDynamicValue, - isPathADynamicBinding, - PropertyEvaluationErrorType, -} from "utils/DynamicBindingUtils"; +import type { DependencyMap } from "utils/DynamicBindingUtils"; import { MAIN_THREAD_ACTION } from "@appsmith/workers/Evaluation/evalWorkerActions"; -import type { LintError as JSHintError } from "jshint"; import { JSHINT as jshint } from "jshint"; -import { get, isEmpty, isNumber, keys, last } from "lodash"; +import type { LintError as JSHintError } from "jshint"; +import { isEmpty, isNil, isNumber, keys, last } from "lodash"; import type { MemberExpressionData } from "@shared/ast"; import { extractInvalidTopLevelMemberExpressionsFromCode, isLiteralNode, } from "@shared/ast"; -import { getDynamicBindings } from "utils/DynamicBindingUtils"; - -import type { createEvaluationContext } from "workers/Evaluation/evaluate"; import { + getDynamicBindings, + PropertyEvaluationErrorType, +} from "utils/DynamicBindingUtils"; +import { + createEvaluationContext, EvaluationScripts, EvaluationScriptType, getScriptToEval, @@ -33,13 +30,11 @@ import { } from "workers/Evaluation/evaluate"; import { getEntityNameAndPropertyPath, - isAction, isATriggerPath, + isDataTreeEntity, + isDynamicLeaf, isJSAction, - isWidget, } from "@appsmith/workers/Evaluation/evaluationUtils"; -import { Severity } from "entities/AppsmithConsole"; -import { JSLibraries } from "workers/common/JSLibrary"; import { WorkerMessenger } from "workers/Evaluation/fns/utils/Messenger"; import { asyncActionInSyncFieldLintMessage, @@ -48,19 +43,33 @@ import { IDENTIFIER_NOT_DEFINED_LINT_ERROR_CODE, IGNORED_LINT_ERRORS, INVALID_JSOBJECT_START_STATEMENT, + INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE, JS_OBJECT_START_STATEMENT, lintOptions, SUPPORTED_WEB_APIS, WARNING_LINT_ERRORS, } from "./constants"; import { APPSMITH_GLOBAL_FUNCTIONS } from "components/editorComponents/ActionCreator/constants"; +import type { + getLintingErrorsProps, + initiateLintingProps, + lintBindingPathProps, + LintTreeSagaRequestData, + lintTriggerPathProps, +} from "./types"; +import { JSLibraries } from "workers/common/JSLibrary"; +import { Severity } from "entities/AppsmithConsole"; +import { + entityFns, + getActionTriggerFunctionNames, +} from "workers/Evaluation/fns"; +import type { + TJSFunctionPropertyState, + TJSpropertyState, +} from "workers/Evaluation/JSObject/jsPropertiesState"; +import type { JSActionEntity } from "entities/DataTree/types"; +import { globalData } from "./globalData"; -interface lintBindingPathProps { - dynamicBinding: string; - entity: DataTreeEntity; - fullPropertyPath: string; - globalData: ReturnType; -} export function lintBindingPath({ dynamicBinding, entity, @@ -68,30 +77,6 @@ export function lintBindingPath({ globalData, }: lintBindingPathProps) { let lintErrors: LintError[] = []; - - if (isJSAction(entity)) { - if (!entity.body) return lintErrors; - if (!entity.body.startsWith(JS_OBJECT_START_STATEMENT)) { - return lintErrors.concat([ - { - errorType: PropertyEvaluationErrorType.LINT, - errorSegment: "", - originalBinding: entity.body, - line: 0, - ch: 0, - code: entity.body, - variables: [], - raw: entity.body, - errorMessage: { - name: "LintingError", - message: INVALID_JSOBJECT_START_STATEMENT, - }, - severity: Severity.ERROR, - }, - ]); - } - } - const { propertyPath } = getEntityNameAndPropertyPath(fullPropertyPath); // Get the {{binding}} bound values const { jsSnippets, stringSegments } = getDynamicBindings( @@ -116,8 +101,6 @@ export function lintBindingPath({ data: globalData, originalBinding, scriptType, - entity, - fullPropertyPath, }); lintErrors = lintErrors.concat(lintErrorsFromSnippet); } @@ -125,15 +108,9 @@ export function lintBindingPath({ } return lintErrors; } -interface lintTriggerPathProps { - userScript: string; - entity: DataTreeEntity; - globalData: ReturnType; - fullPropertyPath: string; -} + export function lintTriggerPath({ entity, - fullPropertyPath, globalData, userScript, }: lintTriggerPathProps) { @@ -145,35 +122,9 @@ export function lintTriggerPath({ data: globalData, originalBinding: jsSnippets[0], scriptType: EvaluationScriptType.TRIGGERS, - entity, - fullPropertyPath, }); } -export function pathRequiresLinting( - dataTree: DataTree, - entity: DataTreeEntity, - fullPropertyPath: string, - entityConfig: DataTreeEntityConfig, -): boolean { - const { propertyPath } = getEntityNameAndPropertyPath(fullPropertyPath); - const unEvalPropertyValue = get( - dataTree, - fullPropertyPath, - ) as unknown as string; - - if (isATriggerPath(entityConfig, propertyPath)) { - return isDynamicValue(unEvalPropertyValue); - } - const isADynamicBindingPath = - (isAction(entity) || isWidget(entity) || isJSAction(entity)) && - isPathADynamicBinding(entityConfig, propertyPath); - const requiresLinting = - (isADynamicBindingPath && isDynamicValue(unEvalPropertyValue)) || - isJSAction(entity); - return requiresLinting; -} - // Removes "export default" statement from js Object export function getJSToLint( entity: DataTreeEntity, @@ -278,19 +229,26 @@ function sanitizeJSHintErrors( return result; }, []); } -const getLintSeverity = (code: string): Severity.WARNING | Severity.ERROR => { +const getLintSeverity = ( + code: string, + errorMessage: string, +): Severity.WARNING | Severity.ERROR => { const severity = - code in WARNING_LINT_ERRORS ? Severity.WARNING : Severity.ERROR; + code in WARNING_LINT_ERRORS || + errorMessage === asyncActionInSyncFieldLintMessage(true) + ? Severity.WARNING + : Severity.ERROR; return severity; }; const getLintErrorMessage = ( reason: string, code: string, variables: string[], + isJSObject = false, ): string => { switch (code) { case IDENTIFIER_NOT_DEFINED_LINT_ERROR_CODE: { - return getRefinedW117Error(variables[0], reason); + return getRefinedW117Error(variables[0], reason, isJSObject); } default: { return reason; @@ -302,6 +260,7 @@ function convertJsHintErrorToAppsmithLintError( script: string, originalBinding: string, scriptPos: Position, + isJSObject = false, ): LintError { const { a, b, c, code, d, evidence, reason } = jsHintError; @@ -311,14 +270,20 @@ function convertJsHintErrorToAppsmithLintError( jsHintError.line === scriptPos.line ? jsHintError.character - scriptPos.ch : jsHintError.character; + const lintErrorMessage = getLintErrorMessage( + reason, + code, + [a, b, c, d], + isJSObject, + ); return { errorType: PropertyEvaluationErrorType.LINT, raw: script, - severity: getLintSeverity(code), + severity: getLintSeverity(code, lintErrorMessage), errorMessage: { name: "LintingError", - message: getLintErrorMessage(reason, code, [a, b, c, d]), + message: lintErrorMessage, }, errorSegment: evidence, originalBinding, @@ -329,17 +294,10 @@ function convertJsHintErrorToAppsmithLintError( ch: actualErrorCh, }; } -interface getLintingErrorsProps { - script: string; - data: Record; - // {{user's code}} - originalBinding: string; - scriptType: EvaluationScriptType; - entity: DataTreeEntity; - fullPropertyPath: string; -} + export function getLintingErrors({ data, + options, originalBinding, script, scriptType, @@ -356,6 +314,7 @@ export function getLintingErrors({ script, originalBinding, scriptPos, + options?.isJsObject, ), ); const invalidPropertyErrors = getInvalidPropertyErrorsFromScript( @@ -363,6 +322,7 @@ export function getLintingErrors({ data, scriptPos, originalBinding, + options?.isJsObject, ); return jshintErrors.concat(invalidPropertyErrors); } @@ -373,6 +333,7 @@ function getInvalidPropertyErrorsFromScript( data: Record, scriptPos: Position, originalBinding: string, + isJSObject = false, ): LintError[] { let invalidTopLevelMemberExpressions: MemberExpressionData[] = []; try { @@ -394,15 +355,19 @@ function getInvalidPropertyErrorsFromScript( const propertyStartColumn = !isLiteralNode(property) ? property.loc.start.column + 1 : property.loc.start.column + 2; + const lintErrorMessage = CUSTOM_LINT_ERRORS[ + CustomLintErrorCode.INVALID_ENTITY_PROPERTY + ](object.name, propertyName, data[object.name], isJSObject); return { errorType: PropertyEvaluationErrorType.LINT, raw: script, - severity: getLintSeverity(CustomLintErrorCode.INVALID_ENTITY_PROPERTY), + severity: getLintSeverity( + CustomLintErrorCode.INVALID_ENTITY_PROPERTY, + lintErrorMessage, + ), errorMessage: { name: "LintingError", - message: CUSTOM_LINT_ERRORS[ - CustomLintErrorCode.INVALID_ENTITY_PROPERTY - ](object.name, propertyName), + message: lintErrorMessage, }, errorSegment: `${object.name}.${propertyName}`, originalBinding, @@ -419,19 +384,24 @@ function getInvalidPropertyErrorsFromScript( return invalidPropertyErrors; } -export function initiateLinting( - lintOrder: string[], - unevalTree: DataTree, - requiresLinting: boolean, - configTree: ConfigTree, -) { +export function initiateLinting({ + asyncJSFunctionsInDataFields, + configTree, + jsPropertiesState, + lintOrder, + requiresLinting, + unevalTree, +}: initiateLintingProps) { + const data = { + pathsToLint: lintOrder, + unevalTree, + jsPropertiesState, + asyncJSFunctionsInDataFields, + configTree, + } as LintTreeSagaRequestData; if (!requiresLinting) return; WorkerMessenger.ping({ - data: { - lintOrder, - unevalTree, - configTree, - }, + data, method: MAIN_THREAD_ACTION.LINT_TREE, }); } @@ -439,14 +409,227 @@ export function initiateLinting( export function getRefinedW117Error( undefinedVar: string, originalReason: string, + isJsObject = false, ) { // Refine error message for await using in field not marked as async if (undefinedVar === "await") { return "'await' expressions are only allowed within async functions. Did you mean to mark this function as 'async'?"; } - // Handle case where platform functions are used in sync fields + // Handle case where platform functions are used in data fields if (APPSMITH_GLOBAL_FUNCTIONS.hasOwnProperty(undefinedVar)) { - return asyncActionInSyncFieldLintMessage(undefinedVar); + return asyncActionInSyncFieldLintMessage(isJsObject); } return originalReason; } + +export function lintJSProperty( + jsPropertyFullName: string, + jsPropertyState: TJSpropertyState, + globalData: DataTree, +): LintError[] { + if (isNil(jsPropertyState)) { + return []; + } + const { propertyPath: jsPropertyPath } = + getEntityNameAndPropertyPath(jsPropertyFullName); + const scriptType = getScriptType(false, false); + const scriptToLint = getScriptToEval( + jsPropertyState.value, + EvaluationScriptType.OBJECT_PROPERTY, + ); + const propLintErrors = getLintingErrors({ + script: scriptToLint, + data: globalData, + originalBinding: jsPropertyState.value, + scriptType, + options: { isJsObject: true }, + }); + const refinedErrors = propLintErrors.map((lintError) => { + return { + ...lintError, + line: lintError.line + jsPropertyState.position.startLine - 1, + ch: + lintError.line === 0 + ? lintError.ch + jsPropertyState.position.startColumn + : lintError.ch, + originalPath: jsPropertyPath, + }; + }); + + return refinedErrors; +} + +export function lintJSObjectProperty( + jsPropertyFullName: string, + jsObjectState: Record, + asyncJSFunctionsInDataFields: DependencyMap, +) { + let lintErrors: LintError[] = []; + const { propertyPath: jsPropertyName } = + getEntityNameAndPropertyPath(jsPropertyFullName); + const jsPropertyState = jsObjectState[jsPropertyName]; + const isAsyncJSFunctionBoundToSyncField = + asyncJSFunctionsInDataFields.hasOwnProperty(jsPropertyFullName); + + const jsPropertyLintErrors = lintJSProperty( + jsPropertyFullName, + jsPropertyState, + globalData.getGlobalData(!isAsyncJSFunctionBoundToSyncField), + ); + lintErrors = lintErrors.concat(jsPropertyLintErrors); + + // if function is async, and bound to a data field, then add custom lint error + if (isAsyncJSFunctionBoundToSyncField) { + lintErrors.push( + generateAsyncFunctionBoundToDataFieldCustomError( + asyncJSFunctionsInDataFields[jsPropertyFullName], + jsPropertyState, + jsPropertyFullName, + ), + ); + } + return lintErrors; +} + +export function lintJSObjectBody( + jsObjectName: string, + globalData: DataTree, +): LintError[] { + const jsObject = globalData[jsObjectName]; + const rawJSObjectbody = (jsObject as unknown as JSActionEntity).body; + if (!rawJSObjectbody) return []; + if (!rawJSObjectbody.startsWith(JS_OBJECT_START_STATEMENT)) { + return [ + { + errorType: PropertyEvaluationErrorType.LINT, + errorSegment: "", + originalBinding: rawJSObjectbody, + line: 0, + ch: 0, + code: INVALID_JSOBJECT_START_STATEMENT_ERROR_CODE, + variables: [], + raw: rawJSObjectbody, + errorMessage: { + name: "LintingError", + message: INVALID_JSOBJECT_START_STATEMENT, + }, + severity: Severity.ERROR, + }, + ]; + } + const scriptType = getScriptType(false, false); + const jsbodyToLint = getJSToLint(jsObject, rawJSObjectbody, "body"); // remove "export default" + const scriptToLint = getScriptToEval(jsbodyToLint, scriptType); + return getLintingErrors({ + script: scriptToLint, + data: globalData, + originalBinding: jsbodyToLint, + scriptType, + }); +} + +export function getEvaluationContext( + unevalTree: DataTree, + cloudHosting: boolean, + options: { withFunctions: boolean }, +) { + if (!options.withFunctions) + return createEvaluationContext({ + dataTree: unevalTree, + resolvedFunctions: {}, + isTriggerBased: false, + removeEntityFunctions: true, + }); + + const evalContext = createEvaluationContext({ + dataTree: unevalTree, + resolvedFunctions: {}, + isTriggerBased: false, + removeEntityFunctions: false, + }); + + const platformFnNamesMap = Object.values( + getActionTriggerFunctionNames(cloudHosting), + ).reduce( + (acc, name) => ({ ...acc, [name]: true }), + {} as { [x: string]: boolean }, + ); + Object.assign(evalContext, platformFnNamesMap); + + return evalContext; +} + +export function sortLintingPathsByType( + pathsToLint: string[], + unevalTree: DataTree, + configTree: ConfigTree, +) { + const triggerPaths = new Set(); + const bindingPaths = new Set(); + const jsObjectPaths = new Set(); + + for (const fullPropertyPath of pathsToLint) { + const { entityName, propertyPath } = + getEntityNameAndPropertyPath(fullPropertyPath); + const entity = unevalTree[entityName]; + const entityConfig = configTree[entityName]; + + // We are only interested in dynamic leaves + if (!isDynamicLeaf(unevalTree, fullPropertyPath, configTree)) continue; + if (isATriggerPath(entityConfig, propertyPath)) { + triggerPaths.add(fullPropertyPath); + continue; + } + if (isJSAction(entity)) { + jsObjectPaths.add(fullPropertyPath); + continue; + } + bindingPaths.add(fullPropertyPath); + } + + return { triggerPaths, bindingPaths, jsObjectPaths }; +} +function generateAsyncFunctionBoundToDataFieldCustomError( + dataFieldBindings: string[], + jsPropertyState: TJSpropertyState, + jsPropertyFullName: string, +): LintError { + const { propertyPath: jsPropertyName } = + getEntityNameAndPropertyPath(jsPropertyFullName); + const lintErrorMessage = + CUSTOM_LINT_ERRORS.ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD( + dataFieldBindings, + jsPropertyFullName, + (jsPropertyState as TJSFunctionPropertyState).isMarkedAsync, + ); + + return { + errorType: PropertyEvaluationErrorType.LINT, + raw: jsPropertyState.value, + severity: getLintSeverity( + CustomLintErrorCode.ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD, + lintErrorMessage, + ), + errorMessage: { + name: "LintingError", + message: lintErrorMessage, + }, + errorSegment: jsPropertyFullName, + originalBinding: jsPropertyState.value, + // By keeping track of these variables we can highlight the exact text that caused the error. + variables: [jsPropertyName, null, null, null], + code: CustomLintErrorCode.ASYNC_FUNCTION_BOUND_TO_SYNC_FIELD, + line: jsPropertyState.position.keyStartLine - 1, + ch: jsPropertyState.position.keyStartColumn + 1, + originalPath: jsPropertyName, + }; +} + +export function isEntityFunction(entity: unknown, propertyName: string) { + if (!isDataTreeEntity(entity)) return false; + return entityFns.find( + (entityFn) => + entityFn.name === propertyName && + entityFn.qualifier(entity as DataTreeEntity), + ); +} diff --git a/app/client/src/workers/common/DataTreeEvaluator/index.ts b/app/client/src/workers/common/DataTreeEvaluator/index.ts index 172b1a0746..2027585665 100644 --- a/app/client/src/workers/common/DataTreeEvaluator/index.ts +++ b/app/client/src/workers/common/DataTreeEvaluator/index.ts @@ -97,7 +97,10 @@ import { getUpdatedLocalUnEvalTreeAfterJSUpdates, parseJSActions, } from "workers/Evaluation/JSObject"; -import { getFixedTimeDifference } from "./utils"; +import { + addRootcauseToAsyncInvocationErrors, + getFixedTimeDifference, +} from "./utils"; import { isJSObjectFunction } from "workers/Evaluation/JSObject/utils"; import { getValidatedTree, @@ -1063,7 +1066,7 @@ export default class DataTreeEvaluator { }); } - const result = this.evaluateDynamicBoundValue( + const { errors: evalErrors, result } = this.evaluateDynamicBoundValue( toBeSentForEval, data, resolvedFunctions, @@ -1071,16 +1074,20 @@ export default class DataTreeEvaluator { contextData, callBackData, ); - if (fullPropertyPath && result.errors.length) { + if (fullPropertyPath && evalErrors.length) { addErrorToEntityProperty({ - errors: result.errors, + errors: addRootcauseToAsyncInvocationErrors( + fullPropertyPath, + configTree, + evalErrors, + ), evalProps: this.evalProps, fullPropertyPath, dataTree: data, configTree, }); } - return result.result; + return result; } else { return stringSegments[index]; } diff --git a/app/client/src/workers/common/DataTreeEvaluator/utils.ts b/app/client/src/workers/common/DataTreeEvaluator/utils.ts index 33a9800aba..2aa540eb04 100644 --- a/app/client/src/workers/common/DataTreeEvaluator/utils.ts +++ b/app/client/src/workers/common/DataTreeEvaluator/utils.ts @@ -1,3 +1,55 @@ +import { + getEntityNameAndPropertyPath, + isAction, + isJSAction, + isWidget, +} from "@appsmith/workers/Evaluation/evaluationUtils"; +import type { + ConfigTree, + DataTreeEntity, + WidgetEntity, +} from "entities/DataTree/dataTreeFactory"; +import type { ActionEntity, JSActionEntity } from "entities/DataTree/types"; +import type { EvaluationError } from "utils/DynamicBindingUtils"; +import { errorModifier } from "workers/Evaluation/errorModifier"; +import { asyncJsFunctionInDataFields } from "workers/Evaluation/JSObject/asyncJSFunctionBoundToDataField"; + export function getFixedTimeDifference(endTime: number, startTime: number) { return (endTime - startTime).toFixed(2) + " ms"; } +export function isDataField(fullPath: string, configTree: ConfigTree) { + const { entityName, propertyPath } = getEntityNameAndPropertyPath(fullPath); + const entityConfig = configTree[entityName]; + if ("triggerPaths" in entityConfig) { + return !(propertyPath in entityConfig.triggerPaths); + } + return false; +} + +export function isWidgetActionOrJsObject( + entity: DataTreeEntity, +): entity is ActionEntity | WidgetEntity | JSActionEntity { + return isWidget(entity) || isAction(entity) || isJSAction(entity); +} + +export function addRootcauseToAsyncInvocationErrors( + fullPropertyPath: string, + configTree: ConfigTree, + errors: EvaluationError[], +) { + let updatedErrors = errors; + + if (isDataField(fullPropertyPath, configTree)) { + const asyncFunctionBindingInPath = + asyncJsFunctionInDataFields.getAsyncFunctionBindingInDataField( + fullPropertyPath, + ); + if (asyncFunctionBindingInPath) { + updatedErrors = errorModifier.setAsyncInvocationErrorsRootcause( + errors, + asyncFunctionBindingInPath, + ); + } + } + return updatedErrors; +} diff --git a/app/client/src/workers/common/DependencyMap/index.ts b/app/client/src/workers/common/DependencyMap/index.ts index 1a48afdab9..66a2bd1983 100644 --- a/app/client/src/workers/common/DependencyMap/index.ts +++ b/app/client/src/workers/common/DependencyMap/index.ts @@ -37,7 +37,9 @@ import { updateMap, } from "./utils"; import type DataTreeEvaluator from "workers/common/DataTreeEvaluator"; -import { difference, isEmpty, set } from "lodash"; +import { difference, isEmpty, set, uniq } from "lodash"; +import { isWidgetActionOrJsObject } from "../DataTreeEvaluator/utils"; +import { asyncJsFunctionInDataFields } from "workers/Evaluation/JSObject/asyncJSFunctionBoundToDataField"; interface CreateDependencyMap { dependencyMap: DependencyMap; @@ -100,11 +102,18 @@ export function createDependencyMap( const { errors, invalidReferences, validReferences } = extractInfoFromBindings(dependencyMap[key], dataTreeEvalRef.allKeys); dependencyMap[key] = validReferences; - // To keep invalidReferencesMap as minimal as possible, only paths with invalid references - // are stored. - if (invalidReferences.length) { - invalidReferencesMap[key] = invalidReferences; - } + + updateMap(invalidReferencesMap, key, invalidReferences, { + deleteOnEmpty: true, + replaceValue: true, + }); + + asyncJsFunctionInDataFields.update( + key, + validReferences, + unEvalTree, + configTree, + ); errors.forEach((error) => { dataTreeEvalRef.errors.push(error); }); @@ -169,11 +178,12 @@ export const updateDependencyMap = ({ let didUpdateValidationDependencyMap = false; const dependenciesOfRemovedPaths: Array = []; const removedPaths: Array = []; - const extraPathsToLint = new Set(); + let extraPathsToLint: string[] = []; const pathsToClearErrorsFor: any[] = []; const { dependencyMap, invalidReferencesMap, + inverseDependencyMap, oldConfigTree, oldUnEvalTree, triggerFieldDependencyMap, @@ -207,7 +217,7 @@ export const updateDependencyMap = ({ if (entityType !== "noop") { switch (event) { case DataTreeDiffEvent.NEW: { - if (isWidget(entity) || isAction(entity) || isJSAction(entity)) { + if (isWidgetActionOrJsObject(entity)) { if (!isDynamicLeaf(unEvalDataTree, fullPropertyPath, configTree)) { const entityDependencyMap: DependencyMap = listEntityDependencies( entity, @@ -236,6 +246,19 @@ export const updateDependencyMap = ({ invalidReferences, { deleteOnEmpty: true, replaceValue: true }, ); + // Update asyncJSFunctionsInDatafieldsMap + const updatedAsyncJSFunctions = + asyncJsFunctionInDataFields.update( + entityDependent, + validReferences, + unEvalDataTree, + configTree, + ); + + extraPathsToLint = extraPathsToLint.concat( + updatedAsyncJSFunctions, + ); + dataTreeEvalErrors = dataTreeEvalErrors.concat( extractDependencyErrors, ); @@ -367,7 +390,7 @@ export const updateDependencyMap = ({ if (isChildPropertyPath(fullPropertyPath, invalidReference)) { updateMap(newlyValidReferencesMap, invalidReference, [path]); if (!dependencyMap[invalidReference]) { - extraPathsToLint.add(path); + extraPathsToLint.push(path); } } }); @@ -403,6 +426,17 @@ export const updateDependencyMap = ({ fullPath, validReferences, ); + // Update asyncJSMap + const updatedAsyncJSFunctions = + asyncJsFunctionInDataFields.update( + fullPath, + validReferences, + unEvalDataTree, + configTree, + ); + extraPathsToLint = extraPathsToLint.concat( + updatedAsyncJSFunctions, + ); // Since the previously invalid reference has become valid, // remove it from the invalidReferencesMap @@ -434,7 +468,7 @@ export const updateDependencyMap = ({ if ( isChildPropertyPath(fullPropertyPath, triggerPathDependency) ) { - extraPathsToLint.add(triggerPath); + extraPathsToLint.push(triggerPath); } }, ); @@ -463,7 +497,7 @@ export const updateDependencyMap = ({ } if ( - (isWidget(entity) || isAction(entity) || isJSAction(entity)) && + isWidgetActionOrJsObject(entity) && fullPropertyPath === entityName ) { const entityDependencies = listEntityDependencies( @@ -502,6 +536,7 @@ export const updateDependencyMap = ({ didUpdateValidationDependencyMap = true; } } + // Either an existing entity or an existing property path has been deleted. Update the global dependency map // by removing the bindings from the same. Object.keys(dependencyMap).forEach((dependencyPath) => { @@ -532,7 +567,7 @@ export const updateDependencyMap = ({ if ( isChildPropertyPath(fullPropertyPath, invalidReference) ) { - extraPathsToLint.add(dependencyPath); + extraPathsToLint.push(dependencyPath); } }, ); @@ -571,7 +606,7 @@ export const updateDependencyMap = ({ if ( isChildPropertyPath(fullPropertyPath, invalidReference) ) { - extraPathsToLint.add(dependencyPath); + extraPathsToLint.push(dependencyPath); } }, ); @@ -579,15 +614,21 @@ export const updateDependencyMap = ({ } }); + // update asyncJsFunctionInDataFields + const updatedAsyncJSFunctions = + asyncJsFunctionInDataFields.handlePathDeletion( + fullPropertyPath, + unEvalDataTree, + configTree, + ); + extraPathsToLint = extraPathsToLint.concat(updatedAsyncJSFunctions); + break; } case DataTreeDiffEvent.EDIT: { // We only care if the difference is in dynamic bindings since static values do not need // an evaluation. - if ( - (isWidget(entity) || isAction(entity) || isJSAction(entity)) && - typeof value === "string" - ) { + if (isWidgetActionOrJsObject(entity) && typeof value === "string") { const entity: ActionEntity | WidgetEntity | JSActionEntity = unEvalDataTree[entityName] as | ActionEntity @@ -623,7 +664,18 @@ export const updateDependencyMap = ({ dataTreeEvalErrors = dataTreeEvalErrors.concat( extractDependencyErrors, ); - + // update asyncFunctionInSyncfieldsMap + const updatedAsyncJSFunctions = + asyncJsFunctionInDataFields.handlePathEdit( + fullPropertyPath, + validReferences, + unEvalDataTree, + inverseDependencyMap, + configTree, + ); + extraPathsToLint = extraPathsToLint.concat( + updatedAsyncJSFunctions, + ); // We found a new dynamic binding for this property path. We update the dependency map by overwriting the // dependencies for this property path with the newly found dependencies @@ -673,6 +725,18 @@ export const updateDependencyMap = ({ didUpdateDependencyMap = true; delete dependencyMap[fullPropertyPath]; delete invalidReferencesMap[fullPropertyPath]; + // update asyncFunctionInSyncfieldsMap + const updatedAsyncJSFunctions = + asyncJsFunctionInDataFields.handlePathEdit( + fullPropertyPath, + [], + unEvalDataTree, + inverseDependencyMap, + configTree, + ); + extraPathsToLint = extraPathsToLint.concat( + updatedAsyncJSFunctions, + ); } } if ( @@ -783,6 +847,6 @@ export const updateDependencyMap = ({ pathsToClearErrorsFor, dependenciesOfRemovedPaths, removedPaths, - extraPathsToLint: Array.from(extraPathsToLint), + extraPathsToLint: uniq(extraPathsToLint), }; }; diff --git a/app/client/src/workers/common/DependencyMap/utils.ts b/app/client/src/workers/common/DependencyMap/utils.ts index f5ce356fb0..9c1a9a5d5c 100644 --- a/app/client/src/workers/common/DependencyMap/utils.ts +++ b/app/client/src/workers/common/DependencyMap/utils.ts @@ -13,12 +13,13 @@ import { getEntityNameAndPropertyPath, isAction, isJSAction, + isJSActionConfig, isWidget, } from "@appsmith/workers/Evaluation/evaluationUtils"; import type { - ConfigTree, DataTree, + ConfigTree, DataTreeEntity, DataTreeEntityConfig, WidgetEntity, @@ -427,3 +428,24 @@ export function updateMap( map[path] = updatedEntries; } } + +export function isAsyncJSFunction(configTree: ConfigTree, fullPath: string) { + const { entityName, propertyPath } = getEntityNameAndPropertyPath(fullPath); + const configEntity = configTree[entityName]; + return ( + isJSActionConfig(configEntity) && + propertyPath && + propertyPath in configEntity.meta && + configEntity.meta[propertyPath].isAsync + ); +} + +export function isJSFunction(configTree: ConfigTree, fullPath: string) { + const { entityName, propertyPath } = getEntityNameAndPropertyPath(fullPath); + const entityConfig = configTree[entityName]; + return ( + isJSActionConfig(entityConfig) && + propertyPath && + propertyPath in entityConfig.meta + ); +} diff --git a/app/client/yarn.lock b/app/client/yarn.lock index d1ed370257..44c1b70d50 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -6816,7 +6816,7 @@ acorn-walk@^7.0.0, acorn-walk@^7.1.1, acorn-walk@^7.2.0: version "7.2.0" resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" -acorn-walk@^8.1.1, acorn-walk@^8.2.0: +acorn-walk@^8.1.1: version "8.2.0" resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== @@ -7363,11 +7363,6 @@ astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" -astring@^1.7.5: - version "1.8.3" - resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.3.tgz#1a0ae738c7cc558f8e5ddc8e3120636f5cebcb85" - integrity sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A== - async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" diff --git a/app/shared/ast/index.ts b/app/shared/ast/index.ts index 4fb4231cbe..89b1afcc29 100644 --- a/app/shared/ast/index.ts +++ b/app/shared/ast/index.ts @@ -21,7 +21,12 @@ import { import { ECMA_VERSION, SourceType, NodeTypes } from "./src/constants"; // JSObjects -import { parseJSObjectWithAST } from "./src/jsObject"; +import { + parseJSObject, + isJSFunctionProperty, + TParsedJSProperty, + JSPropertyPosition, +} from "./src/jsObject"; // types or intefaces should be exported with type keyword, while enums can be exported like normal functions export type { @@ -29,6 +34,8 @@ export type { PropertyNode, MemberExpressionData, IdentifierInfo, + TParsedJSProperty, + JSPropertyPosition, }; export { @@ -44,8 +51,9 @@ export { extractInvalidTopLevelMemberExpressionsFromCode, getFunctionalParamsFromNode, isTypeOfFunction, - parseJSObjectWithAST, + parseJSObject, ECMA_VERSION, SourceType, NodeTypes, + isJSFunctionProperty, }; diff --git a/app/shared/ast/package.json b/app/shared/ast/package.json index 7854df9226..dcf5c41ba1 100644 --- a/app/shared/ast/package.json +++ b/app/shared/ast/package.json @@ -20,9 +20,11 @@ "link-package": "yarn install && rollup -c && cd build && cp -R ../node_modules ./node_modules && yarn link" }, "dependencies": { + "@babel/runtime": "^7.21.0", "acorn": "^8.8.0", "acorn-walk": "^8.2.0", "astring": "^1.7.5", + "escodegen": "^2.0.0", "lodash": "^4.17.21", "rollup": "^2.77.0", "typescript": "4.5.5", @@ -31,6 +33,7 @@ "devDependencies": { "@babel/preset-typescript": "^7.17.12", "@rollup/plugin-commonjs": "^22.0.0", + "@types/escodegen": "^0.0.7", "@types/jest": "29.0.3", "@types/lodash": "^4.14.120", "@typescript-eslint/eslint-plugin": "^5.25.0", diff --git a/app/shared/ast/src/index.test.ts b/app/shared/ast/src/index.test.ts index 1fef1e4f88..966b0f7b2a 100644 --- a/app/shared/ast/src/index.test.ts +++ b/app/shared/ast/src/index.test.ts @@ -1,5 +1,5 @@ +import { parseJSObject } from "../index"; import { extractIdentifierInfoFromCode } from "../src/index"; -import { parseJSObjectWithAST } from "../src/jsObject"; describe("getAllIdentifiers", () => { it("works properly", () => { @@ -306,7 +306,7 @@ describe("getAllIdentifiers", () => { const { references } = extractIdentifierInfoFromCode( perCase.script, 2, - perCase.invalidIdentifiers + perCase.invalidIdentifiers, ); expect(references).toStrictEqual(perCase.expectedResults); }); @@ -315,7 +315,7 @@ describe("getAllIdentifiers", () => { describe("parseJSObjectWithAST", () => { it("parse js object", () => { - const body = `{ + const body = `export default{ myVar1: [], myVar2: {}, myFun1: () => { @@ -325,36 +325,84 @@ describe("parseJSObjectWithAST", () => { //use async-await or promises } }`; - const parsedObject = [ + + const expectedParsedObject = [ { key: "myVar1", value: "[]", + rawContent: "myVar1: []", type: "ArrayExpression", + position: { + startLine: 2, + startColumn: 1, + endLine: 2, + endColumn: 11, + keyStartLine: 2, + keyEndLine: 2, + keyStartColumn: 1, + keyEndColumn: 7, + }, }, { key: "myVar2", value: "{}", + rawContent: "myVar2: {}", type: "ObjectExpression", + position: { + startLine: 3, + startColumn: 1, + endLine: 3, + endColumn: 11, + keyStartLine: 3, + keyEndLine: 3, + keyStartColumn: 1, + keyEndColumn: 7, + }, }, { key: "myFun1", value: "() => {}", + rawContent: "myFun1: () => {\n\t\t//write code here\n\t}", type: "ArrowFunctionExpression", + position: { + startLine: 4, + startColumn: 1, + endLine: 6, + endColumn: 2, + keyStartLine: 4, + keyEndLine: 4, + keyStartColumn: 1, + keyEndColumn: 7, + }, arguments: [], + isMarkedAsync: false }, { key: "myFun2", value: "async () => {}", + rawContent: + "myFun2: async () => {\n\t\t//use async-await or promises\n\t}", type: "ArrowFunctionExpression", + position: { + startLine: 7, + startColumn: 1, + endLine: 9, + endColumn: 2, + keyStartLine: 7, + keyEndLine: 7, + keyStartColumn: 1, + keyEndColumn: 7, + }, arguments: [], + isMarkedAsync: true, }, ]; - const resultParsedObject = parseJSObjectWithAST(body); - expect(resultParsedObject).toStrictEqual(parsedObject); + const { parsedObject } = parseJSObject(body); + expect(parsedObject).toStrictEqual(expectedParsedObject); }); it("parse js object with literal", () => { - const body = `{ + const body = `export default{ myVar1: [], myVar2: { "a": "app", @@ -366,36 +414,83 @@ describe("parseJSObjectWithAST", () => { //use async-await or promises } }`; - const parsedObject = [ + const expectedParsedObject = [ { key: "myVar1", value: "[]", + rawContent: "myVar1: []", type: "ArrayExpression", + position: { + startLine: 2, + startColumn: 1, + endLine: 2, + endColumn: 11, + keyStartLine: 2, + keyEndLine: 2, + keyStartColumn: 1, + keyEndColumn: 7, + }, }, { key: "myVar2", value: '{\n "a": "app"\n}', + rawContent: 'myVar2: {\n\t\t"a": "app",\n\t}', type: "ObjectExpression", + position: { + startLine: 3, + startColumn: 1, + endLine: 5, + endColumn: 2, + keyStartLine: 3, + keyEndLine: 3, + keyStartColumn: 1, + keyEndColumn: 7, + }, }, { key: "myFun1", value: "() => {}", + rawContent: "myFun1: () => {\n\t\t//write code here\n\t}", type: "ArrowFunctionExpression", + position: { + startLine: 6, + startColumn: 1, + endLine: 8, + endColumn: 2, + keyStartLine: 6, + keyEndLine: 6, + keyStartColumn: 1, + keyEndColumn: 7, + }, arguments: [], + isMarkedAsync: false }, { key: "myFun2", value: "async () => {}", + rawContent: + "myFun2: async () => {\n\t\t//use async-await or promises\n\t}", type: "ArrowFunctionExpression", + position: { + startLine: 9, + startColumn: 1, + endLine: 11, + endColumn: 2, + keyStartLine: 9, + keyEndLine: 9, + keyStartColumn: 1, + keyEndColumn: 7, + }, arguments: [], + isMarkedAsync: true, }, ]; - const resultParsedObject = parseJSObjectWithAST(body); - expect(resultParsedObject).toStrictEqual(parsedObject); + const { parsedObject } = parseJSObject(body); + expect(parsedObject).toStrictEqual(expectedParsedObject); }); it("parse js object with variable declaration inside function", () => { - const body = `{ + const body = `export default{ myFun1: () => { const a = { conditions: [], @@ -408,89 +503,108 @@ describe("parseJSObjectWithAST", () => { //use async-await or promises } }`; - const parsedObject = [ + const expectedParsedObject = [ { key: "myFun1", - value: `() => { - const a = { - conditions: [], - requires: 1, - testFunc: () => {}, - testFunc2: function () {} - }; -}`, + value: + "() => {\n" + + " const a = {\n" + + " conditions: [],\n" + + " requires: 1,\n" + + " testFunc: () => {},\n" + + " testFunc2: function () {}\n" + + " };\n" + + "}", + rawContent: + "myFun1: () => {\n" + + " const a = {\n" + + " conditions: [],\n" + + " requires: 1,\n" + + " testFunc: () => {},\n" + + " testFunc2: function(){}\n" + + " };\n" + + " }", type: "ArrowFunctionExpression", + position: { + startLine: 2, + startColumn: 6, + endLine: 9, + endColumn: 7, + keyStartLine: 2, + keyEndLine: 2, + keyStartColumn: 6, + keyEndColumn: 12, + }, arguments: [], + isMarkedAsync: false, }, { key: "myFun2", value: "async () => {}", + rawContent: + "myFun2: async () => {\n //use async-await or promises\n }", type: "ArrowFunctionExpression", + position: { + startLine: 10, + startColumn: 6, + endLine: 12, + endColumn: 7, + keyStartLine: 10, + keyEndLine: 10, + keyStartColumn: 6, + keyEndColumn: 12, + }, arguments: [], + isMarkedAsync: true, }, ]; - const resultParsedObject = parseJSObjectWithAST(body); - expect(resultParsedObject).toStrictEqual(parsedObject); + const { parsedObject } = parseJSObject(body); + expect(parsedObject).toStrictEqual(expectedParsedObject); }); it("parse js object with params of all types", () => { - const body = `{ + const body = `export default{ myFun2: async (a,b = Array(1,2,3),c = "", d = [], e = this.myVar1, f = {}, g = function(){}, h = Object.assign({}), i = String(), j = storeValue()) => { //use async-await or promises }, }`; - const parsedObject = [ + const expectedParsedObject = [ { key: "myFun2", value: 'async (a, b = Array(1, 2, 3), c = "", d = [], e = this.myVar1, f = {}, g = function () {}, h = Object.assign({}), i = String(), j = storeValue()) => {}', + rawContent: + 'myFun2: async (a,b = Array(1,2,3),c = "", d = [], e = this.myVar1, f = {}, g = function(){}, h = Object.assign({}), i = String(), j = storeValue()) => {\n' + + " //use async-await or promises\n" + + " }", type: "ArrowFunctionExpression", + position: { + startLine: 2, + startColumn: 6, + endLine: 4, + endColumn: 7, + keyStartLine: 2, + keyEndLine: 2, + keyStartColumn: 6, + keyEndColumn: 12, + }, arguments: [ - { - paramName: "a", - defaultValue: undefined, - }, - { - paramName: "b", - defaultValue: undefined, - }, - { - paramName: "c", - defaultValue: undefined, - }, - { - paramName: "d", - defaultValue: undefined, - }, - { - paramName: "e", - defaultValue: undefined, - }, - { - paramName: "f", - defaultValue: undefined, - }, - { - paramName: "g", - defaultValue: undefined, - }, - { - paramName: "h", - defaultValue: undefined, - }, - { - paramName: "i", - defaultValue: undefined, - }, - { - paramName: "j", - defaultValue: undefined, - }, + { paramName: "a", defaultValue: undefined }, + { paramName: "b", defaultValue: undefined }, + { paramName: "c", defaultValue: undefined }, + { paramName: "d", defaultValue: undefined }, + { paramName: "e", defaultValue: undefined }, + { paramName: "f", defaultValue: undefined }, + { paramName: "g", defaultValue: undefined }, + { paramName: "h", defaultValue: undefined }, + { paramName: "i", defaultValue: undefined }, + { paramName: "j", defaultValue: undefined }, ], + isMarkedAsync: true, }, ]; - const resultParsedObject = parseJSObjectWithAST(body); - expect(resultParsedObject).toEqual(parsedObject); + const { parsedObject } = parseJSObject(body); + expect(parsedObject).toStrictEqual(expectedParsedObject); }); }); diff --git a/app/shared/ast/src/index.ts b/app/shared/ast/src/index.ts index 5d3bbb7070..80e3e5fa1f 100644 --- a/app/shared/ast/src/index.ts +++ b/app/shared/ast/src/index.ts @@ -1,4 +1,4 @@ -import { parse, Node, SourceLocation, Options, Comment } from "acorn"; +import { parse, Node, SourceLocation, Options } from "acorn"; import { ancestor, simple } from "acorn-walk"; import { ECMA_VERSION, NodeTypes } from "./constants/ast"; import { has, isFinite, isString, memoize, toPath } from "lodash"; @@ -36,7 +36,7 @@ interface MemberExpressionNode extends Node { } // doc: https://github.com/estree/estree/blob/master/es5.md#identifier -interface IdentifierNode extends Node { +export interface IdentifierNode extends Node { type: NodeTypes.Identifier; name: string; } @@ -69,10 +69,12 @@ interface FunctionDeclarationNode extends Node, Function { // doc: https://github.com/estree/estree/blob/master/es5.md#functionexpression interface FunctionExpressionNode extends Expression, Function { type: NodeTypes.FunctionExpression; + async: boolean; } interface ArrowFunctionExpressionNode extends Expression, Function { type: NodeTypes.ArrowFunctionExpression; + async: boolean; } export interface ObjectExpression extends Expression { @@ -87,7 +89,7 @@ interface AssignmentPatternNode extends Node { } // doc: https://github.com/estree/estree/blob/master/es5.md#literal -interface LiteralNode extends Node { +export interface LiteralNode extends Node { type: NodeTypes.Literal; value: string | boolean | null | number | RegExp; } @@ -107,8 +109,12 @@ export interface PropertyNode extends Node { kind: "init" | "get" | "set"; } +export interface ExportDefaultDeclarationNode extends Node { + declaration: Node; +} + // Node with location details -type NodeWithLocation = NodeType & { +export type NodeWithLocation = NodeType & { loc: SourceLocation; }; @@ -163,6 +169,12 @@ export const isPropertyNode = (node: Node): node is PropertyNode => { return node.type === NodeTypes.Property; }; +export const isExportDefaultDeclarationNode = ( + node: Node, +): node is ExportDefaultDeclarationNode => { + return node.type === NodeTypes.ExportDefaultDeclaration; +}; + export const isPropertyAFunctionNode = ( node: Node, ): node is ArrowFunctionExpressionNode | FunctionExpressionNode => { @@ -211,7 +223,11 @@ const getFunctionalParamNamesFromNode = ( // Since this will be used by both the server and the client, we want to prevent regeneration of ast // for the the same code snippet export const getAST = memoize((code: string, options?: AstOptions) => - parse(code, { ...options, ecmaVersion: ECMA_VERSION }), + parse(code, { + ...options, + ecmaVersion: ECMA_VERSION, + locations: true, // Adds location data to each node + }), ); /** diff --git a/app/shared/ast/src/jsObject/index.ts b/app/shared/ast/src/jsObject/index.ts index b3a4feff74..a3dbc7f221 100644 --- a/app/shared/ast/src/jsObject/index.ts +++ b/app/shared/ast/src/jsObject/index.ts @@ -1,78 +1,140 @@ import { Node } from "acorn"; -import { getAST } from "../index"; -import { generate } from "astring"; import { simple } from "acorn-walk"; +import { + getAST, + IdentifierNode, + isExportDefaultDeclarationNode, + isObjectExpression, + isPropertyNode, + isTypeOfFunction, + LiteralNode, + NodeWithLocation, + PropertyNode, +} from "../index"; +import { generate } from "astring"; import { getFunctionalParamsFromNode, isPropertyAFunctionNode, - isVariableDeclarator, - isObjectExpression, - PropertyNode, functionParam, } from "../index"; - -type JsObjectProperty = { - key: string; - value: string; - type: string; - arguments?: Array; -}; +import { SourceType, NodeTypes } from "../../index"; +import { attachComments } from "escodegen"; +import { extractContentByPosition } from "../utils"; const jsObjectVariableName = "____INTERNAL_JS_OBJECT_NAME_USED_FOR_PARSING_____"; export const jsObjectDeclaration = `var ${jsObjectVariableName} =`; -export const parseJSObjectWithAST = ( - jsObjectBody: string -): Array => { - /* - jsObjectVariableName value is added such actual js code would never name same variable name. - if the variable name will be same then also we won't have problem here as jsObjectVariableName will be last node in VariableDeclarator hence overriding the previous JSObjectProperties. - Keeping this just for sanity check if any caveat was missed. - */ - const jsCode = `${jsObjectDeclaration} ${jsObjectBody}`; +export interface JSPropertyPosition { + startLine: number; + startColumn: number; + endLine: number; + endColumn: number; + keyStartLine: number; + keyEndLine: number; + keyStartColumn: number; + keyEndColumn: number; +} - const ast = getAST(jsCode); +interface baseJSProperty { + key: string; + value: string; + type: string; + position: Partial; + rawContent: string; +} - const parsedObjectProperties = new Set(); - let JSObjectProperties: Array = []; +type JSFunctionProperty = baseJSProperty & { + arguments: functionParam[]; + // If function uses the "async" keyword + isMarkedAsync: boolean; +}; +type JSVarProperty = baseJSProperty; + +export type TParsedJSProperty = JSVarProperty | JSFunctionProperty; + +export const isJSFunctionProperty = ( + t: TParsedJSProperty, +): t is JSFunctionProperty => { + return isTypeOfFunction(t.type); +}; + +export const parseJSObject = (code: string) => { + let ast: Node = { end: 0, start: 0, type: "" }; + const result: TParsedJSProperty[] = []; + try { + const comments: any = []; + const token: any = []; + ast = getAST(code, { + sourceType: SourceType.module, + onComment: comments, + onToken: token, + ranges: true, + }); + attachComments(ast, comments, token); + } catch (e) { + return { parsedObject: result, success: false }; + } + + const parsedObjectProperties = new Set(); + let JSObjectProperties: NodeWithLocation[] = []; simple(ast, { - VariableDeclarator(node: Node) { + ExportDefaultDeclaration(node, ancestors: Node[]) { if ( - isVariableDeclarator(node) && - node.id.name === jsObjectVariableName && - node.init && - isObjectExpression(node.init) - ) { - JSObjectProperties = node.init.properties; - } + !isExportDefaultDeclarationNode(node) || + !isObjectExpression(node.declaration) + ) + return; + JSObjectProperties = node.declaration + .properties as NodeWithLocation[]; }, }); JSObjectProperties.forEach((node) => { - let params = new Set(); - const propertyNode = node; - let property: JsObjectProperty = { - key: generate(propertyNode.key), - value: generate(propertyNode.value), - type: propertyNode.value.type, + const propertyKey = node.key as NodeWithLocation< + LiteralNode | IdentifierNode + >; + let property: TParsedJSProperty = { + key: generate(node.key), + value: generate(node.value), + rawContent: extractContentByPosition(code, { + from: { + line: node.loc.start.line - 1, + ch: node.loc.start.column, + }, + to: { + line: node.loc.end.line - 1, + ch: node.loc.end.column - 1, + }, + }), + type: node.value.type, + position: { + startLine: node.loc.start.line, + startColumn: node.loc.start.column, + endLine: node.loc.end.line, + endColumn: node.loc.end.column, + keyStartLine: propertyKey.loc.start.line, + keyEndLine: propertyKey.loc.end.line, + keyStartColumn: propertyKey.loc.start.column, + keyEndColumn: propertyKey.loc.end.column, + }, }; - if (isPropertyAFunctionNode(propertyNode.value)) { + if (isPropertyAFunctionNode(node.value)) { // if in future we need default values of each param, we could implement that in getFunctionalParamsFromNode // currently we don't consume it anywhere hence avoiding to calculate that. - params = getFunctionalParamsFromNode(propertyNode.value); + const params = getFunctionalParamsFromNode(node.value); property = { ...property, arguments: [...params], + isMarkedAsync: node.value.async, }; } - // here we use `generate` function to convert our AST Node to JSCode parsedObjectProperties.add(property); }); - return [...parsedObjectProperties]; + return { parsedObject: [...parsedObjectProperties], success: true }; }; diff --git a/app/shared/ast/src/utils.ts b/app/shared/ast/src/utils.ts index c3da778764..dbb6979802 100644 --- a/app/shared/ast/src/utils.ts +++ b/app/shared/ast/src/utils.ts @@ -1,4 +1,5 @@ -import unescapeJS from 'unescape-js'; +import unescapeJS from "unescape-js"; +import { isLiteralNode, PropertyNode } from "../index"; const beginsWithLineBreakRegex = /^\s+|\s+$/; @@ -8,14 +9,51 @@ export function sanitizeScript(js: string, evaluationVersion: number) { // so that eval can happen //default value of evalutaion version is 2 evaluationVersion = evaluationVersion ? evaluationVersion : 2; - const trimmedJS = js.replace(beginsWithLineBreakRegex, ''); + const trimmedJS = js.replace(beginsWithLineBreakRegex, ""); return evaluationVersion > 1 ? trimmedJS : unescapeJS(trimmedJS); } // For the times when you need to know if something truly an object like { a: 1, b: 2} // typeof, lodash.isObject and others will return false positives for things like array, null, etc export const isTrueObject = ( - item: unknown + item: unknown, ): item is Record => { - return Object.prototype.toString.call(item) === '[object Object]'; + return Object.prototype.toString.call(item) === "[object Object]"; +}; + +export const getNameFromPropertyNode = (node: PropertyNode): string => + isLiteralNode(node.key) ? String(node.key.value) : node.key.name; + +type Position = { + line: number; + ch: number; +}; + +export const extractContentByPosition = ( + content: string, + position: { from: Position; to: Position }, +) => { + const eachLine = content.split("\n"); + + let returnedString = ""; + + for (let i = position.from.line; i <= position.to.line; i++) { + if (i === position.from.line) { + returnedString = + position.from.line !== position.to.line + ? eachLine[position.from.line].slice(position.from.ch) + : eachLine[position.from.line].slice( + position.from.ch, + position.to.ch + 1, + ); + } else if (i === position.to.line) { + returnedString += eachLine[position.to.line].slice(0, position.to.ch + 1); + } else { + returnedString += eachLine[i]; + } + if (i !== position.to.line) { + returnedString += "\n"; + } + } + return returnedString; }; diff --git a/app/shared/ast/yarn.lock b/app/shared/ast/yarn.lock index b29f4b6e36..f73e0e726f 100644 --- a/app/shared/ast/yarn.lock +++ b/app/shared/ast/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": +"@ampproject/remapping@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== @@ -17,48 +17,40 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.0.tgz#2a592fd89bacb1fcde68de31bee4f2f2dacb0e86" - integrity sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw== +"@babel/compat-data@^7.20.5": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.0.tgz#c241dc454e5b5917e40d37e525e2f4530c399298" + integrity sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g== "@babel/core@^7.11.6", "@babel/core@^7.12.3": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.0.tgz#d2f5f4f2033c00de8096be3c9f45772563e150c3" - integrity sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.0.tgz#1341aefdcc14ccc7553fcc688dd8986a2daffc13" + integrity sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA== dependencies: - "@ampproject/remapping" "^2.1.0" + "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" - "@babel/helper-compilation-targets" "^7.19.0" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helpers" "^7.19.0" - "@babel/parser" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/generator" "^7.21.0" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-module-transforms" "^7.21.0" + "@babel/helpers" "^7.21.0" + "@babel/parser" "^7.21.0" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.0" + "@babel/types" "^7.21.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.1" + json5 "^2.2.2" semver "^6.3.0" -"@babel/generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5" - integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug== +"@babel/generator@^7.21.0", "@babel/generator@^7.21.1", "@babel/generator@^7.7.2": + version "7.21.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.1.tgz#951cc626057bc0af2c35cd23e9c64d384dea83dd" + integrity sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA== dependencies: - "@babel/types" "^7.18.9" - "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" - -"@babel/generator@^7.19.0", "@babel/generator@^7.7.2": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a" - integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg== - dependencies: - "@babel/types" "^7.19.0" + "@babel/types" "^7.21.0" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" "@babel/helper-annotate-as-pure@^7.18.6": @@ -68,27 +60,29 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-compilation-targets@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz#537ec8339d53e806ed422f1e06c8f17d55b96bb0" - integrity sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA== +"@babel/helper-compilation-targets@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb" + integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== dependencies: - "@babel/compat-data" "^7.19.0" + "@babel/compat-data" "^7.20.5" "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.20.2" + browserslist "^4.21.3" + lru-cache "^5.1.1" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.18.6": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce" - integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw== +"@babel/helper-create-class-features-plugin@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz#64f49ecb0020532f19b1d014b03bccaa1ab85fb9" + integrity sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-member-expression-to-functions" "^7.21.0" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-replace-supers" "^7.20.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/helper-split-export-declaration" "^7.18.6" "@babel/helper-environment-visitor@^7.18.9": @@ -96,21 +90,13 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== -"@babel/helper-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" - integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== +"@babel/helper-function-name@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" + integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== dependencies: - "@babel/template" "^7.18.6" - "@babel/types" "^7.18.9" - -"@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" + "@babel/template" "^7.20.7" + "@babel/types" "^7.21.0" "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" @@ -119,12 +105,12 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-member-expression-to-functions@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" - integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== +"@babel/helper-member-expression-to-functions@^7.20.7", "@babel/helper-member-expression-to-functions@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz#319c6a940431a133897148515877d2f3269c3ba5" + integrity sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q== dependencies: - "@babel/types" "^7.18.9" + "@babel/types" "^7.21.0" "@babel/helper-module-imports@^7.18.6": version "7.18.6" @@ -133,19 +119,19 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-module-transforms@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" - integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== +"@babel/helper-module-transforms@^7.21.0": + version "7.21.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz#160caafa4978ac8c00ac66636cb0fa37b024e2d2" + integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ== dependencies: "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.18.6" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.2" + "@babel/types" "^7.21.2" "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" @@ -154,33 +140,36 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" - integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== -"@babel/helper-plugin-utils@^7.18.6": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" - integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== - -"@babel/helper-replace-supers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" - integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== +"@babel/helper-replace-supers@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz#243ecd2724d2071532b2c8ad2f0f9f083bcae331" + integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== dependencies: "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.20.7" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.7" + "@babel/types" "^7.20.7" -"@babel/helper-simple-access@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" - integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== +"@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.20.2" + +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" + integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== + dependencies: + "@babel/types" "^7.20.0" "@babel/helper-split-export-declaration@^7.18.6": version "7.18.6" @@ -189,29 +178,29 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-string-parser@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" - integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== -"@babel/helper-validator-identifier@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" - integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== +"@babel/helper-validator-option@^7.18.6", "@babel/helper-validator-option@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" + integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== -"@babel/helpers@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18" - integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== +"@babel/helpers@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" + integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.0" + "@babel/types" "^7.21.0" "@babel/highlight@^7.18.6": version "7.18.6" @@ -222,15 +211,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.0.tgz#497fcafb1d5b61376959c1c338745ef0577aa02c" - integrity sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw== - -"@babel/parser@^7.18.6", "@babel/parser@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" - integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.0", "@babel/parser@^7.21.2": + version "7.21.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.2.tgz#dacafadfc6d7654c3051a66d6fe55b6cb2f2a0b3" + integrity sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -323,96 +307,70 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.18.6", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" - integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== +"@babel/plugin-syntax-typescript@^7.20.0", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" + integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" -"@babel/plugin-transform-typescript@^7.18.6": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.8.tgz#303feb7a920e650f2213ef37b36bbf327e6fa5a0" - integrity sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA== +"@babel/plugin-transform-typescript@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz#f0956a153679e3b377ae5b7f0143427151e4c848" + integrity sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-typescript" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-typescript" "^7.20.0" "@babel/preset-typescript@^7.17.12": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" - integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz#bcbbca513e8213691fe5d4b23d9251e01f00ebff" + integrity sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-typescript" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-validator-option" "^7.21.0" + "@babel/plugin-transform-typescript" "^7.21.0" -"@babel/template@^7.18.10", "@babel/template@^7.3.3": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== +"@babel/runtime@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" + integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== + dependencies: + regenerator-runtime "^0.13.11" + +"@babel/template@^7.20.7", "@babel/template@^7.3.3": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" -"@babel/template@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" - integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== +"@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.7.2": + version "7.21.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.2.tgz#ac7e1f27658750892e815e60ae90f382a46d8e75" + integrity sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.6" - "@babel/types" "^7.18.6" - -"@babel/traverse@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98" - integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.9" + "@babel/generator" "^7.21.1" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" + "@babel/helper-function-name" "^7.21.0" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/parser" "^7.21.2" + "@babel/types" "^7.21.2" debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.19.0", "@babel/traverse@^7.7.2": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.0.tgz#eb9c561c7360005c592cc645abafe0c3c4548eed" - integrity sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA== +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.21.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.2.tgz#92246f6e00f91755893c2876ad653db70c8310d1" + integrity sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw== dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.19.0" - "@babel/types" "^7.19.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.19.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" - integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA== - dependencies: - "@babel/helper-string-parser" "^7.18.10" - "@babel/helper-validator-identifier" "^7.18.6" - to-fast-properties "^2.0.0" - -"@babel/types@^7.18.6", "@babel/types@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f" - integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -436,109 +394,109 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.0.3.tgz#a222ab87e399317a89db88a58eaec289519e807a" - integrity sha512-cGg0r+klVHSYnfE977S9wmpuQ9L+iYuYgL+5bPXiUlUynLLYunRxswEmhBzvrSKGof5AKiHuTTmUKAqRcDY9dg== +"@jest/console@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.5.0.tgz#593a6c5c0d3f75689835f1b3b4688c4f8544cb57" + integrity sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.0.3" - jest-util "^29.0.3" + jest-message-util "^29.5.0" + jest-util "^29.5.0" slash "^3.0.0" -"@jest/core@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.0.3.tgz#ba22a9cbd0c7ba36e04292e2093c547bf53ec1fd" - integrity sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ== +"@jest/core@^29.0.3", "@jest/core@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.5.0.tgz#76674b96904484e8214614d17261cc491e5f1f03" + integrity sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ== dependencies: - "@jest/console" "^29.0.3" - "@jest/reporters" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/console" "^29.5.0" + "@jest/reporters" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^29.0.0" - jest-config "^29.0.3" - jest-haste-map "^29.0.3" - jest-message-util "^29.0.3" - jest-regex-util "^29.0.0" - jest-resolve "^29.0.3" - jest-resolve-dependencies "^29.0.3" - jest-runner "^29.0.3" - jest-runtime "^29.0.3" - jest-snapshot "^29.0.3" - jest-util "^29.0.3" - jest-validate "^29.0.3" - jest-watcher "^29.0.3" + jest-changed-files "^29.5.0" + jest-config "^29.5.0" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-resolve-dependencies "^29.5.0" + jest-runner "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + jest-watcher "^29.5.0" micromatch "^4.0.4" - pretty-format "^29.0.3" + pretty-format "^29.5.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.0.3.tgz#7745ec30a954e828e8cc6df6a13280d3b51d8f35" - integrity sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA== +"@jest/environment@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.5.0.tgz#9152d56317c1fdb1af389c46640ba74ef0bb4c65" + integrity sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ== dependencies: - "@jest/fake-timers" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" - jest-mock "^29.0.3" + jest-mock "^29.5.0" -"@jest/expect-utils@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.0.3.tgz#f5bb86f5565bf2dacfca31ccbd887684936045b2" - integrity sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q== +"@jest/expect-utils@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" + integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== dependencies: - jest-get-type "^29.0.0" + jest-get-type "^29.4.3" -"@jest/expect@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.0.3.tgz#9dc7c46354eeb7a348d73881fba6402f5fdb2c30" - integrity sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ== +"@jest/expect@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.5.0.tgz#80952f5316b23c483fbca4363ce822af79c38fba" + integrity sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g== dependencies: - expect "^29.0.3" - jest-snapshot "^29.0.3" + expect "^29.5.0" + jest-snapshot "^29.5.0" -"@jest/fake-timers@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.0.3.tgz#ad5432639b715d45a86a75c47fd75019bc36b22c" - integrity sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ== +"@jest/fake-timers@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.5.0.tgz#d4d09ec3286b3d90c60bdcd66ed28d35f1b4dc2c" + integrity sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg== dependencies: - "@jest/types" "^29.0.3" - "@sinonjs/fake-timers" "^9.1.2" + "@jest/types" "^29.5.0" + "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.0.3" - jest-mock "^29.0.3" - jest-util "^29.0.3" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-util "^29.5.0" -"@jest/globals@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.0.3.tgz#681950c430fdc13ff9aa89b2d8d572ac0e4a1bf5" - integrity sha512-YqGHT65rFY2siPIHHFjuCGUsbzRjdqkwbat+Of6DmYRg5shIXXrLdZoVE/+TJ9O1dsKsFmYhU58JvIbZRU1Z9w== +"@jest/globals@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.5.0.tgz#6166c0bfc374c58268677539d0c181f9c1833298" + integrity sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ== dependencies: - "@jest/environment" "^29.0.3" - "@jest/expect" "^29.0.3" - "@jest/types" "^29.0.3" - jest-mock "^29.0.3" + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/types" "^29.5.0" + jest-mock "^29.5.0" -"@jest/reporters@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.0.3.tgz#735f110e08b44b38729d8dbbb74063bdf5aba8a5" - integrity sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw== +"@jest/reporters@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.5.0.tgz#985dfd91290cd78ddae4914ba7921bcbabe8ac9b" + integrity sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/console" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@jridgewell/trace-mapping" "^0.3.15" "@types/node" "*" chalk "^4.0.0" @@ -551,78 +509,77 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.0.3" - jest-util "^29.0.3" - jest-worker "^29.0.3" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + jest-worker "^29.5.0" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" - terminal-link "^2.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^29.0.0": - version "29.0.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" - integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== +"@jest/schemas@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== dependencies: - "@sinclair/typebox" "^0.24.1" + "@sinclair/typebox" "^0.25.16" -"@jest/source-map@^29.0.0": - version "29.0.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.0.0.tgz#f8d1518298089f8ae624e442bbb6eb870ee7783c" - integrity sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ== +"@jest/source-map@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" + integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== dependencies: "@jridgewell/trace-mapping" "^0.3.15" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.0.3.tgz#b03d8ef4c58be84cd5d5d3b24d4b4c8cabbf2746" - integrity sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg== +"@jest/test-result@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.5.0.tgz#7c856a6ca84f45cc36926a4e9c6b57f1973f1408" + integrity sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ== dependencies: - "@jest/console" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/console" "^29.5.0" + "@jest/types" "^29.5.0" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.0.3.tgz#0681061ad21fb8e293b49c4fdf7e631ca79240ba" - integrity sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ== +"@jest/test-sequencer@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz#34d7d82d3081abd523dbddc038a3ddcb9f6d3cc4" + integrity sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ== dependencies: - "@jest/test-result" "^29.0.3" + "@jest/test-result" "^29.5.0" graceful-fs "^4.2.9" - jest-haste-map "^29.0.3" + jest-haste-map "^29.5.0" slash "^3.0.0" -"@jest/transform@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.0.3.tgz#9eb1fed2072a0354f190569807d1250572fb0970" - integrity sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg== +"@jest/transform@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.5.0.tgz#cf9c872d0965f0cbd32f1458aa44a2b1988b00f9" + integrity sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^29.0.3" + "@jest/types" "^29.5.0" "@jridgewell/trace-mapping" "^0.3.15" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" - convert-source-map "^1.4.0" + convert-source-map "^2.0.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.0.3" - jest-regex-util "^29.0.0" - jest-util "^29.0.3" + jest-haste-map "^29.5.0" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" - write-file-atomic "^4.0.1" + write-file-atomic "^4.0.2" -"@jest/types@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.0.3.tgz#0be78fdddb1a35aeb2041074e55b860561c8ef63" - integrity sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A== +"@jest/types@^29.0.3", "@jest/types@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" + integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== dependencies: - "@jest/schemas" "^29.0.0" + "@jest/schemas" "^29.4.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -646,7 +603,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -656,26 +613,18 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15": - version "0.3.15" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" - integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.14" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" - integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -699,9 +648,9 @@ fastq "^1.6.0" "@rollup/plugin-commonjs@^22.0.0": - version "22.0.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.1.tgz#f7cb777d20de3eeeaf994f39080115c336bef810" - integrity sha512-dGfEZvdjDHObBiP5IvwTKMVeq/tBZGMBHZFMdIV1ClMM/YoWS34xrHFGfag9SN2ZtMgNZRFruqvxZQEa70O6nQ== + version "22.0.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz#ee8ca8415cda30d383b4096aad5222435b4b69b6" + integrity sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg== dependencies: "@rollup/pluginutils" "^3.1.0" commondir "^1.0.1" @@ -728,32 +677,32 @@ estree-walker "^2.0.1" picomatch "^2.2.2" -"@sinclair/typebox@^0.24.1": - version "0.24.41" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.41.tgz#45470b8bae32a28f1e0501066d0bacbd8b772804" - integrity sha512-TJCgQurls4FipFvHeC+gfAzb+GGstL0TDwYJKQVtTeSvJIznWzP7g3bAd5gEBlr8+bIxqnWS9VGVWREDhmE8jA== +"@sinclair/typebox@^0.25.16": + version "0.25.24" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" + integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== -"@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== +"@sinonjs/commons@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== +"@sinonjs/fake-timers@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" + integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== dependencies: - "@sinonjs/commons" "^1.7.0" + "@sinonjs/commons" "^2.0.0" "@types/babel__core@^7.1.14": - version "7.1.19" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" - integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== + version "7.20.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" + integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" @@ -774,12 +723,17 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.18.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.1.tgz#ce5e2c8c272b99b7a9fd69fa39f0b4cd85028bd9" - integrity sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA== + version "7.18.3" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.3.tgz#dfc508a85781e5698d5b33443416b6268c4b3e8d" + integrity sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w== dependencies: "@babel/types" "^7.3.0" +"@types/escodegen@^0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@types/escodegen/-/escodegen-0.0.7.tgz#a1c3e3dfd76da89f01d7d196eebe227ebe4b6eec" + integrity sha512-46oENdSRNEJXCNrPJoC3vRolZJpfeEm7yvATkd2bCncKFG0PUEyfBCaoacfpcXH4Y5RRuqdVj3J7TI+wwn2SbQ== + "@types/estree@*": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" @@ -791,9 +745,9 @@ integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== "@types/graceful-fs@^4.1.3": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" @@ -830,14 +784,14 @@ integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/lodash@^4.14.120": - version "4.14.182" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" - integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== + version "4.14.191" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" + integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== "@types/node@*": - version "18.0.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7" - integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw== + version "18.14.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.6.tgz#ae1973dd2b1eeb1825695bb11ebfb746d27e3e93" + integrity sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -845,9 +799,14 @@ integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== "@types/prettier@^2.1.5": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc" - integrity sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A== + version "2.7.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" + integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== + +"@types/semver@^7.3.12": + version "7.3.13" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" + integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== "@types/stack-utils@^2.0.0": version "2.0.1" @@ -860,90 +819,94 @@ integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^17.0.8": - version "17.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.12.tgz#0745ff3e4872b4ace98616d4b7e37ccbd75f9526" - integrity sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ== + version "17.0.22" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.22.tgz#7dd37697691b5f17d020f3c63e7a45971ff71e9a" + integrity sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.25.0": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.7.tgz#1621dabc1ae4084310e19e9efc80dfdbb97e7493" - integrity sha512-l4L6Do+tfeM2OK0GJsU7TUcM/1oN/N25xHm3Jb4z3OiDU4Lj8dIuxX9LpVMS9riSXQs42D1ieX7b85/r16H9Fw== + version "5.54.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.1.tgz#0c5091289ce28372e38ab8d28e861d2dbe1ab29e" + integrity sha512-a2RQAkosH3d3ZIV08s3DcL/mcGc2M/UC528VkPULFxR9VnVPT8pBu0IyBAJJmVsCmhVfwQX1v6q+QGnmSe1bew== dependencies: - "@typescript-eslint/scope-manager" "5.30.7" - "@typescript-eslint/type-utils" "5.30.7" - "@typescript-eslint/utils" "5.30.7" + "@typescript-eslint/scope-manager" "5.54.1" + "@typescript-eslint/type-utils" "5.54.1" + "@typescript-eslint/utils" "5.54.1" debug "^4.3.4" - functional-red-black-tree "^1.0.1" + grapheme-splitter "^1.0.4" ignore "^5.2.0" + natural-compare-lite "^1.4.0" regexpp "^3.2.0" semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/parser@^5.25.0": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.7.tgz#99d09729392aec9e64b1de45cd63cb81a4ddd980" - integrity sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A== + version "5.54.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.54.1.tgz#05761d7f777ef1c37c971d3af6631715099b084c" + integrity sha512-8zaIXJp/nG9Ff9vQNh7TI+C3nA6q6iIsGJ4B4L6MhZ7mHnTMR4YP5vp2xydmFXIy8rpyIVbNAG44871LMt6ujg== dependencies: - "@typescript-eslint/scope-manager" "5.30.7" - "@typescript-eslint/types" "5.30.7" - "@typescript-eslint/typescript-estree" "5.30.7" + "@typescript-eslint/scope-manager" "5.54.1" + "@typescript-eslint/types" "5.54.1" + "@typescript-eslint/typescript-estree" "5.54.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.7.tgz#8269a931ef1e5ae68b5eb80743cc515c4ffe3dd7" - integrity sha512-7BM1bwvdF1UUvt+b9smhqdc/eniOnCKxQT/kj3oXtj3LqnTWCAM0qHRHfyzCzhEfWX0zrW7KqXXeE4DlchZBKw== +"@typescript-eslint/scope-manager@5.54.1": + version "5.54.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.54.1.tgz#6d864b4915741c608a58ce9912edf5a02bb58735" + integrity sha512-zWKuGliXxvuxyM71UA/EcPxaviw39dB2504LqAmFDjmkpO8qNLHcmzlh6pbHs1h/7YQ9bnsO8CCcYCSA8sykUg== dependencies: - "@typescript-eslint/types" "5.30.7" - "@typescript-eslint/visitor-keys" "5.30.7" + "@typescript-eslint/types" "5.54.1" + "@typescript-eslint/visitor-keys" "5.54.1" -"@typescript-eslint/type-utils@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.30.7.tgz#5693dc3db6f313f302764282d614cfdbc8a9fcfd" - integrity sha512-nD5qAE2aJX/YLyKMvOU5jvJyku4QN5XBVsoTynFrjQZaDgDV6i7QHFiYCx10wvn7hFvfuqIRNBtsgaLe0DbWhw== +"@typescript-eslint/type-utils@5.54.1": + version "5.54.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.54.1.tgz#4825918ec27e55da8bb99cd07ec2a8e5f50ab748" + integrity sha512-WREHsTz0GqVYLIbzIZYbmUUr95DKEKIXZNH57W3s+4bVnuF1TKe2jH8ZNH8rO1CeMY3U4j4UQeqPNkHMiGem3g== dependencies: - "@typescript-eslint/utils" "5.30.7" + "@typescript-eslint/typescript-estree" "5.54.1" + "@typescript-eslint/utils" "5.54.1" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.7.tgz#18331487cc92d0f1fb1a6f580c8ec832528079d0" - integrity sha512-ocVkETUs82+U+HowkovV6uxf1AnVRKCmDRNUBUUo46/5SQv1owC/EBFkiu4MOHeZqhKz2ktZ3kvJJ1uFqQ8QPg== +"@typescript-eslint/types@5.54.1": + version "5.54.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.54.1.tgz#29fbac29a716d0f08c62fe5de70c9b6735de215c" + integrity sha512-G9+1vVazrfAfbtmCapJX8jRo2E4MDXxgm/IMOF4oGh3kq7XuK3JRkOg6y2Qu1VsTRmWETyTkWt1wxy7X7/yLkw== -"@typescript-eslint/typescript-estree@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.7.tgz#05da9f1b281985bfedcf62349847f8d168eecc07" - integrity sha512-tNslqXI1ZdmXXrHER83TJ8OTYl4epUzJC0aj2i4DMDT4iU+UqLT3EJeGQvJ17BMbm31x5scSwo3hPM0nqQ1AEA== +"@typescript-eslint/typescript-estree@5.54.1": + version "5.54.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.1.tgz#df7b6ae05fd8fef724a87afa7e2f57fa4a599be1" + integrity sha512-bjK5t+S6ffHnVwA0qRPTZrxKSaFYocwFIkZx5k7pvWfsB1I57pO/0M0Skatzzw1sCkjJ83AfGTL0oFIFiDX3bg== dependencies: - "@typescript-eslint/types" "5.30.7" - "@typescript-eslint/visitor-keys" "5.30.7" + "@typescript-eslint/types" "5.54.1" + "@typescript-eslint/visitor-keys" "5.54.1" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.30.7.tgz#7135be070349e9f7caa262b0ca59dc96123351bb" - integrity sha512-Z3pHdbFw+ftZiGUnm1GZhkJgVqsDL5CYW2yj+TB2mfXDFOMqtbzQi2dNJIyPqPbx9mv2kUxS1gU+r2gKlKi1rQ== +"@typescript-eslint/utils@5.54.1": + version "5.54.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.54.1.tgz#7a3ee47409285387b9d4609ea7e1020d1797ec34" + integrity sha512-IY5dyQM8XD1zfDe5X8jegX6r2EVU5o/WJnLu/znLPWCBF7KNGC+adacXnt5jEYS9JixDcoccI6CvE4RCjHMzCQ== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.30.7" - "@typescript-eslint/types" "5.30.7" - "@typescript-eslint/typescript-estree" "5.30.7" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.54.1" + "@typescript-eslint/types" "5.54.1" + "@typescript-eslint/typescript-estree" "5.54.1" eslint-scope "^5.1.1" eslint-utils "^3.0.0" + semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.7.tgz#c093abae75b4fd822bfbad9fc337f38a7a14909a" - integrity sha512-KrRXf8nnjvcpxDFOKej4xkD7657+PClJs5cJVSG7NNoCNnjEdc46juNAQt7AyuWctuCgs6mVRc1xGctEqrjxWw== +"@typescript-eslint/visitor-keys@5.54.1": + version "5.54.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.1.tgz#d7a8a0f7181d6ac748f4d47b2306e0513b98bf8b" + integrity sha512-q8iSoHTgwCfgcRJ2l2x+xCbu8nBlRAlsQ33k24Adj8eoVBE0f8dUeI+bAa8F84Mv05UGbAx57g2zrRsYIooqQg== dependencies: - "@typescript-eslint/types" "5.30.7" + "@typescript-eslint/types" "5.54.1" eslint-visitor-keys "^3.3.0" acorn-walk@^8.2.0: @@ -952,9 +915,9 @@ acorn-walk@^8.2.0: integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== acorn@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== ansi-escapes@^4.2.1: version "4.3.2" @@ -988,9 +951,9 @@ ansi-styles@^5.0.0: integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== anymatch@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -1008,19 +971,19 @@ array-union@^2.1.0: integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== astring@^1.7.5: - version "1.8.3" - resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.3.tgz#1a0ae738c7cc558f8e5ddc8e3120636f5cebcb85" - integrity sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A== + version "1.8.4" + resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.4.tgz#6d4c5d8de7be2ead9e4a3cc0e2efb8d759378904" + integrity sha512-97a+l2LBU3Op3bBQEff79i/E4jMD2ZLFD8rHx9B6mXyB2uQwhJQYfiDqUwtfjF4QA1F2qs//N6Cw8LetMbQjcw== -babel-jest@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.0.3.tgz#64e156a47a77588db6a669a88dedff27ed6e260f" - integrity sha512-ApPyHSOhS/sVzwUOQIWJmdvDhBsMG01HX9z7ogtkp1TToHGGUWFlnXJUIzCgKPSfiYLn3ibipCYzsKSURHEwLg== +babel-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.5.0.tgz#3fe3ddb109198e78b1c88f9ebdecd5e4fc2f50a5" + integrity sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q== dependencies: - "@jest/transform" "^29.0.3" + "@jest/transform" "^29.5.0" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.0.2" + babel-preset-jest "^29.5.0" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" @@ -1036,10 +999,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^29.0.2: - version "29.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.0.2.tgz#ae61483a829a021b146c016c6ad39b8bcc37c2c8" - integrity sha512-eBr2ynAEFjcebVvu8Ktx580BD1QKCrBG1XwEUTXJe285p9HA/4hOhfWCFRQhTKSyBV0VzjhG7H91Eifz9s29hg== +babel-plugin-jest-hoist@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" + integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -1064,12 +1027,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^29.0.2: - version "29.0.2" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.0.2.tgz#e14a7124e22b161551818d89e5bdcfb3b2b0eac7" - integrity sha512-BeVXp7rH5TK96ofyEnHjznjLMQ2nAeDJ+QzxKnHAAMs0RgrQsCywjAN8m4mOm5Di0pxU//3AoEeJJrerMH5UeA== +babel-preset-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" + integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== dependencies: - babel-plugin-jest-hoist "^29.0.2" + babel-plugin-jest-hoist "^29.5.0" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -1092,15 +1055,15 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.20.2: - version "4.21.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" - integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== +browserslist@^4.21.3: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== dependencies: - caniuse-lite "^1.0.30001370" - electron-to-chromium "^1.4.202" - node-releases "^2.0.6" - update-browserslist-db "^1.0.5" + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" bs-logger@0.x: version "0.2.6" @@ -1136,10 +1099,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001370: - version "1.0.30001399" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001399.tgz#1bf994ca375d7f33f8d01ce03b7d5139e8587873" - integrity sha512-4vQ90tMKS+FkvuVWS5/QY1+d805ODxZiKFzsU8o/RsVJz49ZSRR8EjykLJbqhzdPgadbX6wB538wOzle3JniRA== +caniuse-lite@^1.0.30001449: + version "1.0.30001462" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001462.tgz#b2e801e37536d453731286857c8520d3dcee15fe" + integrity sha512-PDd20WuOBPiasZ7KbFnmQRyuLE7cFXW2PVd7dmALzbkUXEP46upAuCDm9eY9vho8fgNMGmbAX92QBZHzcnWIqw== chalk@^2.0.0: version "2.4.2" @@ -1164,22 +1127,22 @@ char-regex@^1.0.2: integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== ci-info@^3.2.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" - integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== cjs-module-lexer@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" wrap-ansi "^7.0.0" co@^4.6.0: @@ -1226,12 +1189,15 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" +convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== cross-spawn@^7.0.3: version "7.0.3" @@ -1254,10 +1220,15 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + version "4.3.0" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.0.tgz#65491893ec47756d44719ae520e0e2609233b59b" + integrity sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og== detect-indent@^5.0.0: version "5.0.0" @@ -1269,10 +1240,10 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -diff-sequences@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.0.0.tgz#bae49972ef3933556bcb0800b72e8579d19d9e4f" - integrity sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA== +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== dir-glob@^3.0.1: version "3.0.1" @@ -1281,15 +1252,15 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -electron-to-chromium@^1.4.202: - version "1.4.249" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.249.tgz#49c34336c742ee65453dbddf4c84355e59b96e2c" - integrity sha512-GMCxR3p2HQvIw47A599crTKYZprqihoBL4lDSAUmr7IYekXFK5t/WgEBrGJDCa2HWIZFQEkGuMqPCi05ceYqPQ== +electron-to-chromium@^1.4.284: + version "1.4.325" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.325.tgz#7b97238a61192d85d055d97f3149832b3617d37b" + integrity sha512-K1C03NT4I7BuzsRdCU5RWkgZxtswnKDYM6/eMhkEXqKu4e5T+ck610x3FPzu1y7HVFSiQKZqP16gnJzPpji1TQ== -emittery@^0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" - integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== emoji-regex@^8.0.0: version "8.0.0" @@ -1318,6 +1289,18 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -1343,7 +1326,7 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -esprima@^4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -1375,6 +1358,11 @@ estree-walker@^2.0.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -1395,21 +1383,21 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expect@^29.0.0, expect@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.0.3.tgz#6be65ddb945202f143c4e07c083f4f39f3bd326f" - integrity sha512-t8l5DTws3212VbmPL+tBFXhjRHLmctHB0oQbL8eUc6S7NzZtYUhycrFO9mkxA0ZUC6FAWdNi7JchJSkODtcu1Q== +expect@^29.0.0, expect@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" + integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== dependencies: - "@jest/expect-utils" "^29.0.3" - jest-get-type "^29.0.0" - jest-matcher-utils "^29.0.3" - jest-message-util "^29.0.3" - jest-util "^29.0.3" + "@jest/expect-utils" "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -1422,17 +1410,22 @@ fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" @@ -1484,11 +1477,6 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -1550,6 +1538,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.6, graceful-fs@^4.2.0 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1583,9 +1576,9 @@ human-signals@^2.1.0: integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== import-local@^3.0.2: version "3.1.0" @@ -1619,9 +1612,9 @@ is-arrayish@^0.2.1: integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-core-module@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" - integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== dependencies: has "^1.0.3" @@ -1680,9 +1673,9 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" - integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: "@babel/core" "^7.12.3" "@babel/parser" "^7.14.7" @@ -1716,282 +1709,284 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.0.0.tgz#aa238eae42d9372a413dd9a8dadc91ca1806dce0" - integrity sha512-28/iDMDrUpGoCitTURuDqUzWQoWmOmOKOFST1mi2lwh62X4BFf6khgH3uSuo1e49X/UDjuApAj3w0wLOex4VPQ== +jest-changed-files@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" + integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== dependencies: execa "^5.0.0" p-limit "^3.1.0" -jest-circus@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.0.3.tgz#90faebc90295291cfc636b27dbd82e3bfb9e7a48" - integrity sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg== +jest-circus@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.5.0.tgz#b5926989449e75bff0d59944bae083c9d7fb7317" + integrity sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA== dependencies: - "@jest/environment" "^29.0.3" - "@jest/expect" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^29.0.3" - jest-matcher-utils "^29.0.3" - jest-message-util "^29.0.3" - jest-runtime "^29.0.3" - jest-snapshot "^29.0.3" - jest-util "^29.0.3" + jest-each "^29.5.0" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" p-limit "^3.1.0" - pretty-format "^29.0.3" + pretty-format "^29.5.0" + pure-rand "^6.0.0" slash "^3.0.0" stack-utils "^2.0.3" jest-cli@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.0.3.tgz#fd8f0ef363a7a3d9c53ef62e0651f18eeffa77b9" - integrity sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ== + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.5.0.tgz#b34c20a6d35968f3ee47a7437ff8e53e086b4a67" + integrity sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw== dependencies: - "@jest/core" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/core" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.0.3" - jest-util "^29.0.3" - jest-validate "^29.0.3" + jest-config "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.0.3.tgz#c2e52a8f5adbd18de79f99532d8332a19e232f13" - integrity sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew== +jest-config@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.5.0.tgz#3cc972faec8c8aaea9ae158c694541b79f3748da" + integrity sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.0.3" - "@jest/types" "^29.0.3" - babel-jest "^29.0.3" + "@jest/test-sequencer" "^29.5.0" + "@jest/types" "^29.5.0" + babel-jest "^29.5.0" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.0.3" - jest-environment-node "^29.0.3" - jest-get-type "^29.0.0" - jest-regex-util "^29.0.0" - jest-resolve "^29.0.3" - jest-runner "^29.0.3" - jest-util "^29.0.3" - jest-validate "^29.0.3" + jest-circus "^29.5.0" + jest-environment-node "^29.5.0" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-runner "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.0.3" + pretty-format "^29.5.0" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.0.3.tgz#41cc02409ad1458ae1bf7684129a3da2856341ac" - integrity sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg== +jest-diff@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" + integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== dependencies: chalk "^4.0.0" - diff-sequences "^29.0.0" - jest-get-type "^29.0.0" - pretty-format "^29.0.3" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" -jest-docblock@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.0.0.tgz#3151bcc45ed7f5a8af4884dcc049aee699b4ceae" - integrity sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw== +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== dependencies: detect-newline "^3.0.0" -jest-each@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.0.3.tgz#7ef3157580b15a609d7ef663dd4fc9b07f4e1299" - integrity sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg== +jest-each@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.5.0.tgz#fc6e7014f83eac68e22b7195598de8554c2e5c06" + integrity sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.5.0" chalk "^4.0.0" - jest-get-type "^29.0.0" - jest-util "^29.0.3" - pretty-format "^29.0.3" + jest-get-type "^29.4.3" + jest-util "^29.5.0" + pretty-format "^29.5.0" -jest-environment-node@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.0.3.tgz#293804b1e0fa5f0e354dacbe510655caa478a3b2" - integrity sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg== +jest-environment-node@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.5.0.tgz#f17219d0f0cc0e68e0727c58b792c040e332c967" + integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== dependencies: - "@jest/environment" "^29.0.3" - "@jest/fake-timers" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" - jest-mock "^29.0.3" - jest-util "^29.0.3" + jest-mock "^29.5.0" + jest-util "^29.5.0" -jest-get-type@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.0.0.tgz#843f6c50a1b778f7325df1129a0fd7aa713aef80" - integrity sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw== +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== -jest-haste-map@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.0.3.tgz#d7f3f7180f558d760eacc5184aac5a67f20ef939" - integrity sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A== +jest-haste-map@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.5.0.tgz#69bd67dc9012d6e2723f20a945099e972b2e94de" + integrity sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.5.0" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^29.0.0" - jest-util "^29.0.3" - jest-worker "^29.0.3" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" + jest-worker "^29.5.0" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.0.3.tgz#e85cf3391106a7a250850b6766b508bfe9c7bc6f" - integrity sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ== +jest-leak-detector@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c" + integrity sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow== dependencies: - jest-get-type "^29.0.0" - pretty-format "^29.0.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" -jest-matcher-utils@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.0.3.tgz#b8305fd3f9e27cdbc210b21fc7dbba92d4e54560" - integrity sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w== +jest-matcher-utils@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" + integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== dependencies: chalk "^4.0.0" - jest-diff "^29.0.3" - jest-get-type "^29.0.0" - pretty-format "^29.0.3" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" -jest-message-util@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.0.3.tgz#f0254e1ffad21890c78355726202cc91d0a40ea8" - integrity sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg== +jest-message-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" + integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.0.3" + "@jest/types" "^29.5.0" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.0.3" + pretty-format "^29.5.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.0.3.tgz#4f0093f6a9cb2ffdb9c44a07a3912f0c098c8de9" - integrity sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww== +jest-mock@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.5.0.tgz#26e2172bcc71d8b0195081ff1f146ac7e1518aed" + integrity sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.5.0" "@types/node" "*" + jest-util "^29.5.0" jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== -jest-regex-util@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.0.0.tgz#b442987f688289df8eb6c16fa8df488b4cd007de" - integrity sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug== +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== -jest-resolve-dependencies@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.0.3.tgz#f23a54295efc6374b86b198cf8efed5606d6b762" - integrity sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw== +jest-resolve-dependencies@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz#f0ea29955996f49788bf70996052aa98e7befee4" + integrity sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg== dependencies: - jest-regex-util "^29.0.0" - jest-snapshot "^29.0.3" + jest-regex-util "^29.4.3" + jest-snapshot "^29.5.0" -jest-resolve@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.0.3.tgz#329a3431e3b9eb6629a2cd483e9bed95b26827b9" - integrity sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg== +jest-resolve@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.5.0.tgz#b053cc95ad1d5f6327f0ac8aae9f98795475ecdc" + integrity sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.0.3" + jest-haste-map "^29.5.0" jest-pnp-resolver "^1.2.2" - jest-util "^29.0.3" - jest-validate "^29.0.3" + jest-util "^29.5.0" + jest-validate "^29.5.0" resolve "^1.20.0" - resolve.exports "^1.1.0" + resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.0.3.tgz#2e47fe1e8777aea9b8970f37e8f83630b508fb87" - integrity sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw== +jest-runner@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.5.0.tgz#6a57c282eb0ef749778d444c1d758c6a7693b6f8" + integrity sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ== dependencies: - "@jest/console" "^29.0.3" - "@jest/environment" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/console" "^29.5.0" + "@jest/environment" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" - emittery "^0.10.2" + emittery "^0.13.1" graceful-fs "^4.2.9" - jest-docblock "^29.0.0" - jest-environment-node "^29.0.3" - jest-haste-map "^29.0.3" - jest-leak-detector "^29.0.3" - jest-message-util "^29.0.3" - jest-resolve "^29.0.3" - jest-runtime "^29.0.3" - jest-util "^29.0.3" - jest-watcher "^29.0.3" - jest-worker "^29.0.3" + jest-docblock "^29.4.3" + jest-environment-node "^29.5.0" + jest-haste-map "^29.5.0" + jest-leak-detector "^29.5.0" + jest-message-util "^29.5.0" + jest-resolve "^29.5.0" + jest-runtime "^29.5.0" + jest-util "^29.5.0" + jest-watcher "^29.5.0" + jest-worker "^29.5.0" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.0.3.tgz#5a823ec5902257519556a4e5a71a868e8fd788aa" - integrity sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ== +jest-runtime@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.5.0.tgz#c83f943ee0c1da7eb91fa181b0811ebd59b03420" + integrity sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw== dependencies: - "@jest/environment" "^29.0.3" - "@jest/fake-timers" "^29.0.3" - "@jest/globals" "^29.0.3" - "@jest/source-map" "^29.0.0" - "@jest/test-result" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/globals" "^29.5.0" + "@jest/source-map" "^29.4.3" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.0.3" - jest-message-util "^29.0.3" - jest-mock "^29.0.3" - jest-regex-util "^29.0.0" - jest-resolve "^29.0.3" - jest-snapshot "^29.0.3" - jest-util "^29.0.3" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.0.3.tgz#0a024706986a915a6eefae74d7343069d2fc8eef" - integrity sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew== +jest-snapshot@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.5.0.tgz#c9c1ce0331e5b63cd444e2f95a55a73b84b1e8ce" + integrity sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" @@ -1999,69 +1994,69 @@ jest-snapshot@^29.0.3: "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/expect-utils" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.0.3" + expect "^29.5.0" graceful-fs "^4.2.9" - jest-diff "^29.0.3" - jest-get-type "^29.0.0" - jest-haste-map "^29.0.3" - jest-matcher-utils "^29.0.3" - jest-message-util "^29.0.3" - jest-util "^29.0.3" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" natural-compare "^1.4.0" - pretty-format "^29.0.3" + pretty-format "^29.5.0" semver "^7.3.5" -jest-util@^29.0.0, jest-util@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.0.3.tgz#06d1d77f9a1bea380f121897d78695902959fbc0" - integrity sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ== +jest-util@^29.0.0, jest-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" + integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.0.3.tgz#f9521581d7344685428afa0a4d110e9c519aeeb6" - integrity sha512-OebiqqT6lK8cbMPtrSoS3aZP4juID762lZvpf1u+smZnwTEBCBInan0GAIIhv36MxGaJvmq5uJm7dl5gVt+Zrw== +jest-validate@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.5.0.tgz#8e5a8f36178d40e47138dc00866a5f3bd9916ffc" + integrity sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.5.0" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^29.0.0" + jest-get-type "^29.4.3" leven "^3.1.0" - pretty-format "^29.0.3" + pretty-format "^29.5.0" -jest-watcher@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.0.3.tgz#8e220d1cc4f8029875e82015d084cab20f33d57f" - integrity sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw== +jest-watcher@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.5.0.tgz#cf7f0f949828ba65ddbbb45c743a382a4d911363" + integrity sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA== dependencies: - "@jest/test-result" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - emittery "^0.10.2" - jest-util "^29.0.3" + emittery "^0.13.1" + jest-util "^29.5.0" string-length "^4.0.1" -jest-worker@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.0.3.tgz#c2ba0aa7e41eec9eb0be8e8a322ae6518df72647" - integrity sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng== +jest-worker@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.5.0.tgz#bdaefb06811bd3384d93f009755014d8acb4615d" + integrity sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA== dependencies: "@types/node" "*" + jest-util "^29.5.0" merge-stream "^2.0.0" supports-color "^8.0.0" @@ -2098,7 +2093,7 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json5@^2.2.1: +json5@^2.2.1, json5@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -2122,6 +2117,14 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -2144,6 +2147,13 @@ lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -2220,6 +2230,11 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -2230,10 +2245,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== normalize-package-data@^2.5.0: version "2.5.0" @@ -2271,6 +2286,18 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2359,12 +2386,17 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pretty-format@^29.0.0, pretty-format@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.0.3.tgz#23d5f8cabc9cbf209a77d49409d093d61166a811" - integrity sha512-cHudsvQr1K5vNVLbvYF/nv3Qy/F/BcEKxGuIeMiVMRHxPOO1RxXooP8g/ZrwAp7Dx+KdMZoOc7NxLHhMrP2f9Q== +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +pretty-format@^29.0.0, pretty-format@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" + integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== dependencies: - "@jest/schemas" "^29.0.0" + "@jest/schemas" "^29.4.3" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -2376,6 +2408,11 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +pure-rand@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.0.tgz#701996ceefa253507923a0e864c17ab421c04a7c" + integrity sha512-rLSBxJjP+4DQOgcJAx6RZHT2he2pkhQdSnofG5VWyVl6GRq/K02ISOuOLcsMOrtKDIJb8JN2zm3FFzWNbezdPw== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -2396,6 +2433,11 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -2418,10 +2460,10 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== +resolve.exports@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.1.tgz#cee884cd4e3f355660e501fa3276b27d7ffe5a20" + integrity sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw== resolve@^1.10.0, resolve@^1.17.0, resolve@^1.20.0: version "1.22.1" @@ -2462,9 +2504,9 @@ rollup-plugin-typescript2@^0.32.0: tslib "^2.4.0" rollup@^2.77.0: - version "2.77.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.0.tgz#749eaa5ac09b6baa52acc076bc46613eddfd53f4" - integrity sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g== + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== optionalDependencies: fsevents "~2.3.2" @@ -2475,20 +2517,15 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - "semver@2 || 3 || 4 || 5", semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@7.x, semver@^7.3.5, semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== dependencies: lru-cache "^6.0.0" @@ -2539,7 +2576,7 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0, source-map@^0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -2550,9 +2587,9 @@ sourcemap-codec@^1.4.8: integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -2571,9 +2608,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" - integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + version "3.0.12" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779" + integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== sprintf-js@~1.0.2: version "1.0.3" @@ -2581,9 +2618,9 @@ sprintf-js@~1.0.2: integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== stack-utils@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" @@ -2638,7 +2675,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -2652,27 +2689,11 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" - integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -2719,9 +2740,9 @@ tslib@^1.8.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== tsutils@^3.21.0: version "3.21.0" @@ -2730,6 +2751,13 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + dependencies: + prelude-ls "~1.1.2" + type-detect@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -2767,18 +2795,18 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -update-browserslist-db@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" - integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== +update-browserslist-db@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== dependencies: escalade "^3.1.1" picocolors "^1.0.0" v8-to-istanbul@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" - integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + version "9.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" @@ -2806,6 +2834,11 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -2829,7 +2862,7 @@ write-file-atomic@^2.4.2: imurmurhash "^0.1.4" signal-exit "^3.0.2" -write-file-atomic@^4.0.1: +write-file-atomic@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== @@ -2863,28 +2896,33 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@^21.0.0, yargs-parser@^21.0.1: +yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^17.3.1: - version "17.5.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" - integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + version "17.7.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" + integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== dependencies: - cliui "^7.0.2" + cliui "^8.0.1" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^21.0.0" + yargs-parser "^21.1.1" yocto-queue@^0.1.0: version "0.1.0"