fix: update rts logic to use updated shared AST logic (#16849)
* update rts logic to use updated shared AST logic * Make changes to naming conventions * Add test cases for RTS and rename ast functions * Add running jest test to RTS workflow * Install dependencies and then trigger jest tests in workflow * Close server connection after test ends * Remove logs * Improve jest test descriptions
This commit is contained in:
parent
9d32752abb
commit
610509506e
10
.github/workflows/rts-build.yml
vendored
10
.github/workflows/rts-build.yml
vendored
|
|
@ -119,6 +119,16 @@ jobs:
|
||||||
echo ::set-output name=version::$next_version-SNAPSHOT
|
echo ::set-output name=version::$next_version-SNAPSHOT
|
||||||
echo ::set-output name=tag::$(echo ${GITHUB_REF:11})
|
echo ::set-output name=tag::$(echo ${GITHUB_REF:11})
|
||||||
|
|
||||||
|
# Install all the dependencies
|
||||||
|
- name: Install dependencies
|
||||||
|
if: steps.run_result.outputs.run_result != 'success'
|
||||||
|
run: yarn install --frozen-lockfile
|
||||||
|
|
||||||
|
# Run the Jest tests only if the workflow has been invoked in a PR
|
||||||
|
- name: Run the jest tests
|
||||||
|
if: steps.run_result.outputs.run_result != 'success'
|
||||||
|
run: yarn run test:unit
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
if: steps.run_result.outputs.run_result != 'success'
|
if: steps.run_result.outputs.run_result != 'success'
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import {
|
||||||
getDynamicBindings,
|
getDynamicBindings,
|
||||||
extraLibrariesNames,
|
extraLibrariesNames,
|
||||||
} from "utils/DynamicBindingUtils";
|
} from "utils/DynamicBindingUtils";
|
||||||
import { extractInfoFromCode } from "@shared/ast";
|
import { extractIdentifierInfoFromCode } from "@shared/ast";
|
||||||
import { convertPathToString, isWidget } from "../evaluationUtils";
|
import { convertPathToString, isWidget } from "../evaluationUtils";
|
||||||
import { DataTreeWidget } from "entities/DataTree/dataTreeFactory";
|
import { DataTreeWidget } from "entities/DataTree/dataTreeFactory";
|
||||||
import {
|
import {
|
||||||
|
|
@ -31,7 +31,7 @@ export const extractInfoFromBinding = (
|
||||||
script: string,
|
script: string,
|
||||||
allPaths: Record<string, true>,
|
allPaths: Record<string, true>,
|
||||||
): { validReferences: string[]; invalidReferences: string[] } => {
|
): { validReferences: string[]; invalidReferences: string[] } => {
|
||||||
const { references } = extractInfoFromCode(
|
const { references } = extractIdentifierInfoFromCode(
|
||||||
script,
|
script,
|
||||||
self.evaluationVersion,
|
self.evaluationVersion,
|
||||||
invalidEntityIdentifiers,
|
invalidEntityIdentifiers,
|
||||||
|
|
|
||||||
23
app/rts/jest.config.js
Normal file
23
app/rts/jest.config.js
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
module.exports = {
|
||||||
|
roots: ["<rootDir>/src"],
|
||||||
|
transform: {
|
||||||
|
"^.+\\.(png|js|ts|tsx)$": "ts-jest",
|
||||||
|
},
|
||||||
|
testTimeout: 9000,
|
||||||
|
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(tsx|ts|js)?$",
|
||||||
|
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node", "css"],
|
||||||
|
moduleDirectories: ["node_modules", "src", "test"],
|
||||||
|
moduleNameMapper: {
|
||||||
|
"@constants/(.*)": ["<rootDir>/src/constants/$1"],
|
||||||
|
"@services/(.*)": ["<rootDir>/src/services/$1"],
|
||||||
|
"@middlewares/(.*)": ["<rootDir>/src/middlewares/$1"],
|
||||||
|
"@controllers/(.*)": ["<rootDir>/src/controllers/$1"],
|
||||||
|
"@rules/(.*)": ["<rootDir>/src/middlewares/rules/$1"],
|
||||||
|
"@utils/(.*)": ["<rootDir>/src/utils/$1"],
|
||||||
|
},
|
||||||
|
globals: {
|
||||||
|
"ts-jest": {
|
||||||
|
isolatedModules: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -12,17 +12,22 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^4.17.11",
|
"@types/express": "^4.17.11",
|
||||||
|
"@types/jest": "^29.0.3",
|
||||||
"@types/mongodb": "^3.6.10",
|
"@types/mongodb": "^3.6.10",
|
||||||
"axios": "^0.21.2",
|
"axios": "^0.21.2",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
|
"jest": "^29.0.3",
|
||||||
"loglevel": "^1.7.1",
|
"loglevel": "^1.7.1",
|
||||||
"mongodb": "^3.6.4",
|
"mongodb": "^3.6.4",
|
||||||
"socket.io": "^4.5.1",
|
"socket.io": "^4.5.1",
|
||||||
"socket.io-adapter": "^2.3.2",
|
"socket.io-adapter": "^2.3.2",
|
||||||
"source-map-support": "^0.5.19",
|
"source-map-support": "^0.5.19",
|
||||||
|
"ts-jest": "^29.0.2",
|
||||||
"typescript": "^4.2.3"
|
"typescript": "^4.2.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"test:unit": "export APPSMITH_API_BASE_URL=http APPSMITH_MONGODB_URI=mongodb && $(npm bin)/jest -b --colors --no-cache --silent --coverage --collectCoverage=true --coverageDirectory='../../' --coverageReporters='json-summary'",
|
||||||
|
"test:jest": "export APPSMITH_API_BASE_URL=http APPSMITH_MONGODB_URI=mongodb && $(npm bin)/jest --watch ",
|
||||||
"preinstall": "CURRENT_SCOPE=rts node ../shared/build-shared-dep.js",
|
"preinstall": "CURRENT_SCOPE=rts node ../shared/build-shared-dep.js",
|
||||||
"build": "./build.sh",
|
"build": "./build.sh",
|
||||||
"postinstall": "CURRENT_SCOPE=rts node ../shared/install-dependencies.js",
|
"postinstall": "CURRENT_SCOPE=rts node ../shared/install-dependencies.js",
|
||||||
|
|
@ -31,6 +36,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express-validator": "^6.14.2",
|
"express-validator": "^6.14.2",
|
||||||
"http-status-codes": "^2.2.0",
|
"http-status-codes": "^2.2.0",
|
||||||
|
"supertest": "^6.2.4",
|
||||||
"tsc-alias": "^1.7.0"
|
"tsc-alias": "^1.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ export default class AstController extends BaseController {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDependentIdentifiers(req: Request, res: Response) {
|
async getIdentifierDataFromScript(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
// By default the application eval version is set to be 2
|
// By default the application eval version is set to be 2
|
||||||
const { script, evalVersion = 2 }: ScriptToIdentifiersType = req.body;
|
const { script, evalVersion = 2 }: ScriptToIdentifiersType = req.body;
|
||||||
const data = await AstService.getIdentifiersFromScript(
|
const data = await AstService.extractIdentifierDataFromScript(
|
||||||
script,
|
script,
|
||||||
evalVersion
|
evalVersion
|
||||||
);
|
);
|
||||||
|
|
@ -37,7 +37,7 @@ export default class AstController extends BaseController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMultipleDependentIdentifiers(req: Request, res: Response) {
|
async getIdentifierDataFromMultipleScripts(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
// By default the application eval version is set to be 2
|
// By default the application eval version is set to be 2
|
||||||
const { scripts, evalVersion = 2 }: MultipleScriptToIdentifiersType =
|
const { scripts, evalVersion = 2 }: MultipleScriptToIdentifiersType =
|
||||||
|
|
@ -46,7 +46,10 @@ export default class AstController extends BaseController {
|
||||||
Promise.all(
|
Promise.all(
|
||||||
scripts.map(
|
scripts.map(
|
||||||
async (script) =>
|
async (script) =>
|
||||||
await AstService.getIdentifiersFromScript(script, evalVersion)
|
await AstService.extractIdentifierDataFromScript(
|
||||||
|
script,
|
||||||
|
evalVersion
|
||||||
|
)
|
||||||
)
|
)
|
||||||
).then((data) => {
|
).then((data) => {
|
||||||
return super.sendResponse(res, data);
|
return super.sendResponse(res, data);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Response } from "express";
|
import { Response } from "express";
|
||||||
import { ValidationError } from "express-validator";
|
import { ValidationError } from "express-validator";
|
||||||
import { StatusCodes } from "http-status-codes";
|
import { StatusCodes } from "http-status-codes";
|
||||||
|
import { IdentifierInfo } from "@shared/ast";
|
||||||
|
|
||||||
type ErrorData = {
|
type ErrorData = {
|
||||||
error: string | string[];
|
error: string | string[];
|
||||||
|
|
@ -16,7 +17,7 @@ type ErrorBag = {
|
||||||
type ResponseData = {
|
type ResponseData = {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message?: string;
|
message?: string;
|
||||||
data: unknown; //setting unknown for now, to be modified later.
|
data: IdentifierInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class BaseController {
|
export default class BaseController {
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,17 @@ const astController = new AstController();
|
||||||
const validator = new Validator();
|
const validator = new Validator();
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
"/single-script-identifiers",
|
"/single-script-data",
|
||||||
AstRules.getScriptValidator(),
|
AstRules.getScriptValidator(),
|
||||||
validator.validateRequest,
|
validator.validateRequest,
|
||||||
astController.getDependentIdentifiers
|
astController.getIdentifierDataFromScript
|
||||||
);
|
);
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
"/multiple-script-identifiers",
|
"/multiple-script-data",
|
||||||
AstRules.getMultipleScriptValidator(),
|
AstRules.getMultipleScriptValidator(),
|
||||||
validator.validateRequest,
|
validator.validateRequest,
|
||||||
astController.getMultipleDependentIdentifiers
|
astController.getIdentifierDataFromMultipleScripts
|
||||||
);
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { initializeSockets } from "./sockets";
|
||||||
import ast_routes from "./routes/ast_routes";
|
import ast_routes from "./routes/ast_routes";
|
||||||
|
|
||||||
const RTS_BASE_PATH = "/rts";
|
const RTS_BASE_PATH = "/rts";
|
||||||
const RTS_BASE_API_PATH = "/rts-api/v1";
|
export const RTS_BASE_API_PATH = "/rts-api/v1";
|
||||||
|
|
||||||
// Setting the logLevel for all log messages
|
// Setting the logLevel for all log messages
|
||||||
const logLevel: LogLevelDesc = (process.env.APPSMITH_LOG_LEVEL ||
|
const logLevel: LogLevelDesc = (process.env.APPSMITH_LOG_LEVEL ||
|
||||||
|
|
@ -36,32 +36,30 @@ if (API_BASE_URL == null || API_BASE_URL === "") {
|
||||||
|
|
||||||
const PORT = process.env.PORT || 8091;
|
const PORT = process.env.PORT || 8091;
|
||||||
|
|
||||||
main();
|
//Disable x-powered-by header to prevent information disclosure
|
||||||
|
const app = express();
|
||||||
function main() {
|
app.disable("x-powered-by");
|
||||||
const app = express();
|
const server = new http.Server(app);
|
||||||
//Disable x-powered-by header to prevent information disclosure
|
const io = new Server(server, {
|
||||||
app.disable("x-powered-by");
|
|
||||||
const server = new http.Server(app);
|
|
||||||
const io = new Server(server, {
|
|
||||||
path: RTS_BASE_PATH,
|
path: RTS_BASE_PATH,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initializing Sockets
|
// Initializing Sockets
|
||||||
initializeSockets(io);
|
initializeSockets(io);
|
||||||
|
|
||||||
// parse incoming json requests
|
// parse incoming json requests
|
||||||
app.use(express.json({ limit: "5mb" }));
|
app.use(express.json({ limit: "5mb" }));
|
||||||
// Initializing Routes
|
// Initializing Routes
|
||||||
app.use(express.static(path.join(__dirname, "static")));
|
app.use(express.static(path.join(__dirname, "static")));
|
||||||
app.get("/", (_, res) => {
|
app.get("/", (_, res) => {
|
||||||
res.redirect("/index.html");
|
res.redirect("/index.html");
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(`${RTS_BASE_API_PATH}/ast`, ast_routes);
|
app.use(`${RTS_BASE_API_PATH}/ast`, ast_routes);
|
||||||
|
|
||||||
// Run the server
|
// Run the server
|
||||||
server.listen(PORT, () => {
|
server.listen(PORT, () => {
|
||||||
log.info(`RTS version ${buildVersion} running at http://localhost:${PORT}`);
|
log.info(`RTS version ${buildVersion} running at http://localhost:${PORT}`);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
export default server;
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
import { extractInfoFromCode } from "@shared/ast";
|
import { extractIdentifierInfoFromCode } from "@shared/ast";
|
||||||
|
|
||||||
export default class AstService {
|
export default class AstService {
|
||||||
static async getIdentifiersFromScript(
|
static async extractIdentifierDataFromScript(
|
||||||
script,
|
script,
|
||||||
evalVersion
|
evalVersion,
|
||||||
|
invalidIdentifiers = {}
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
const extractions = extractInfoFromCode(
|
const identifierInfo = extractIdentifierInfoFromCode(
|
||||||
script,
|
script,
|
||||||
evalVersion
|
evalVersion,
|
||||||
|
invalidIdentifiers
|
||||||
);
|
);
|
||||||
|
|
||||||
resolve(extractions);
|
resolve(identifierInfo);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
67
app/rts/src/test/server.test.ts
Normal file
67
app/rts/src/test/server.test.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
import app, { RTS_BASE_API_PATH } from "../server";
|
||||||
|
import supertest from "supertest";
|
||||||
|
|
||||||
|
const singleScript = {
|
||||||
|
script:
|
||||||
|
"(function abc() { let Api2 = { }; return Api2.data ? str.data + Api1.data : [] })()",
|
||||||
|
};
|
||||||
|
|
||||||
|
const multipleScripts = {
|
||||||
|
scripts: [
|
||||||
|
"(function abc() { return Api1.data })() ",
|
||||||
|
"(function abc() { let str = ''; return str ? Api1.data : [] })()",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
afterAll((done) => {
|
||||||
|
app.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("AST tests", () => {
|
||||||
|
it("Checks to see if single script is parsed correctly using the API", async () => {
|
||||||
|
const expectedResponse = {
|
||||||
|
references: ["str.data", "Api1.data"],
|
||||||
|
functionalParams: [],
|
||||||
|
variables: ["Api2"],
|
||||||
|
};
|
||||||
|
|
||||||
|
await supertest(app)
|
||||||
|
.post(`${RTS_BASE_API_PATH}/ast/single-script-data`, {
|
||||||
|
JSON: true,
|
||||||
|
})
|
||||||
|
.send(singleScript)
|
||||||
|
.expect(200)
|
||||||
|
.then((response) => {
|
||||||
|
expect(response.body.success).toEqual(true);
|
||||||
|
expect(response.body.data).toEqual(expectedResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Checks to see if multiple scripts are parsed correctly using the API", async () => {
|
||||||
|
const expectedResponse = [
|
||||||
|
{
|
||||||
|
references: ["Api1.data"],
|
||||||
|
functionalParams: [],
|
||||||
|
variables: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
references: ["Api1.data"],
|
||||||
|
functionalParams: [],
|
||||||
|
variables: ["str"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
await supertest(app)
|
||||||
|
.post(`${RTS_BASE_API_PATH}/ast/multiple-script-data`, {
|
||||||
|
JSON: true,
|
||||||
|
})
|
||||||
|
.send(multipleScripts)
|
||||||
|
.expect(200)
|
||||||
|
.then((response) => {
|
||||||
|
expect(response.body.success).toEqual(true);
|
||||||
|
expect(response.body.data.length).toBeGreaterThan(1);
|
||||||
|
expect(response.body.data).toEqual(expectedResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"@middlewares/*": ["./src/middlewares/*"],
|
"@middlewares/*": ["./src/middlewares/*"],
|
||||||
"@controllers/*": ["./src/controllers/*"],
|
"@controllers/*": ["./src/controllers/*"],
|
||||||
"@rules/*": ["./src/middlewares/rules/*"],
|
"@rules/*": ["./src/middlewares/rules/*"],
|
||||||
"@utils/*": ["./src/utils/*"],
|
"@utils/*": ["./src/utils/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lib": ["es2015"]
|
"lib": ["es2015"]
|
||||||
|
|
|
||||||
2285
app/rts/yarn.lock
2285
app/rts/yarn.lock
File diff suppressed because it is too large
Load Diff
|
|
@ -8,21 +8,27 @@ import {
|
||||||
isPropertyNode,
|
isPropertyNode,
|
||||||
isPropertyAFunctionNode,
|
isPropertyAFunctionNode,
|
||||||
getAST,
|
getAST,
|
||||||
extractInfoFromCode,
|
extractIdentifierInfoFromCode,
|
||||||
extractInvalidTopLevelMemberExpressionsFromCode,
|
extractInvalidTopLevelMemberExpressionsFromCode,
|
||||||
getFunctionalParamsFromNode,
|
getFunctionalParamsFromNode,
|
||||||
isTypeOfFunction,
|
isTypeOfFunction,
|
||||||
MemberExpressionData,
|
MemberExpressionData,
|
||||||
} from './src';
|
IdentifierInfo,
|
||||||
|
} from "./src";
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
import { ECMA_VERSION, SourceType, NodeTypes } from './src/constants';
|
import { ECMA_VERSION, SourceType, NodeTypes } from "./src/constants";
|
||||||
|
|
||||||
// JSObjects
|
// JSObjects
|
||||||
import { parseJSObjectWithAST } from './src/jsObject';
|
import { parseJSObjectWithAST } from "./src/jsObject";
|
||||||
|
|
||||||
// types or intefaces should be exported with type keyword, while enums can be exported like normal functions
|
// types or intefaces should be exported with type keyword, while enums can be exported like normal functions
|
||||||
export type { ObjectExpression, PropertyNode, MemberExpressionData };
|
export type {
|
||||||
|
ObjectExpression,
|
||||||
|
PropertyNode,
|
||||||
|
MemberExpressionData,
|
||||||
|
IdentifierInfo,
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
isIdentifierNode,
|
isIdentifierNode,
|
||||||
|
|
@ -32,7 +38,7 @@ export {
|
||||||
isPropertyNode,
|
isPropertyNode,
|
||||||
isPropertyAFunctionNode,
|
isPropertyAFunctionNode,
|
||||||
getAST,
|
getAST,
|
||||||
extractInfoFromCode,
|
extractIdentifierInfoFromCode,
|
||||||
extractInvalidTopLevelMemberExpressionsFromCode,
|
extractInvalidTopLevelMemberExpressionsFromCode,
|
||||||
getFunctionalParamsFromNode,
|
getFunctionalParamsFromNode,
|
||||||
isTypeOfFunction,
|
isTypeOfFunction,
|
||||||
|
|
|
||||||
|
|
@ -1,85 +1,85 @@
|
||||||
import { extractInfoFromCode } from '../src/index';
|
import { extractIdentifierInfoFromCode } from "../src/index";
|
||||||
import { parseJSObjectWithAST } from '../src/jsObject';
|
import { parseJSObjectWithAST } from "../src/jsObject";
|
||||||
|
|
||||||
describe('getAllIdentifiers', () => {
|
describe("getAllIdentifiers", () => {
|
||||||
it('works properly', () => {
|
it("works properly", () => {
|
||||||
const cases: { script: string; expectedResults: string[] }[] = [
|
const cases: { script: string; expectedResults: string[] }[] = [
|
||||||
{
|
{
|
||||||
// Entity reference
|
// Entity reference
|
||||||
script: 'DirectTableReference',
|
script: "DirectTableReference",
|
||||||
expectedResults: ['DirectTableReference'],
|
expectedResults: ["DirectTableReference"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// One level nesting
|
// One level nesting
|
||||||
script: 'TableDataReference.data',
|
script: "TableDataReference.data",
|
||||||
expectedResults: ['TableDataReference.data'],
|
expectedResults: ["TableDataReference.data"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Deep nesting
|
// Deep nesting
|
||||||
script: 'TableDataDetailsReference.data.details',
|
script: "TableDataDetailsReference.data.details",
|
||||||
expectedResults: ['TableDataDetailsReference.data.details'],
|
expectedResults: ["TableDataDetailsReference.data.details"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Deep nesting
|
// Deep nesting
|
||||||
script: 'TableDataDetailsMoreReference.data.details.more',
|
script: "TableDataDetailsMoreReference.data.details.more",
|
||||||
expectedResults: ['TableDataDetailsMoreReference.data.details.more'],
|
expectedResults: ["TableDataDetailsMoreReference.data.details.more"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Deep optional chaining
|
// Deep optional chaining
|
||||||
script: 'TableDataOptionalReference.data?.details.more',
|
script: "TableDataOptionalReference.data?.details.more",
|
||||||
expectedResults: ['TableDataOptionalReference.data'],
|
expectedResults: ["TableDataOptionalReference.data"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Deep optional chaining with logical operator
|
// Deep optional chaining with logical operator
|
||||||
script:
|
script:
|
||||||
'TableDataOptionalWithLogical.data?.details.more || FallbackTableData.data',
|
"TableDataOptionalWithLogical.data?.details.more || FallbackTableData.data",
|
||||||
expectedResults: [
|
expectedResults: [
|
||||||
'TableDataOptionalWithLogical.data',
|
"TableDataOptionalWithLogical.data",
|
||||||
'FallbackTableData.data',
|
"FallbackTableData.data",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// null coalescing
|
// null coalescing
|
||||||
script: 'TableDataOptionalWithLogical.data ?? FallbackTableData.data',
|
script: "TableDataOptionalWithLogical.data ?? FallbackTableData.data",
|
||||||
expectedResults: [
|
expectedResults: [
|
||||||
'TableDataOptionalWithLogical.data',
|
"TableDataOptionalWithLogical.data",
|
||||||
'FallbackTableData.data',
|
"FallbackTableData.data",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Basic map function
|
// Basic map function
|
||||||
script: 'Table5.data.map(c => ({ name: c.name }))',
|
script: "Table5.data.map(c => ({ name: c.name }))",
|
||||||
expectedResults: ['Table5.data.map'],
|
expectedResults: ["Table5.data.map"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Literal property search
|
// Literal property search
|
||||||
script: "Table6['data']",
|
script: "Table6['data']",
|
||||||
expectedResults: ['Table6'],
|
expectedResults: ["Table6"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Deep literal property search
|
// Deep literal property search
|
||||||
script: "TableDataOptionalReference['data'].details",
|
script: "TableDataOptionalReference['data'].details",
|
||||||
expectedResults: ['TableDataOptionalReference'],
|
expectedResults: ["TableDataOptionalReference"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Array index search
|
// Array index search
|
||||||
script: 'array[8]',
|
script: "array[8]",
|
||||||
expectedResults: ['array[8]'],
|
expectedResults: ["array[8]"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Deep array index search
|
// Deep array index search
|
||||||
script: 'Table7.data[4]',
|
script: "Table7.data[4]",
|
||||||
expectedResults: ['Table7.data[4]'],
|
expectedResults: ["Table7.data[4]"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Deep array index search
|
// Deep array index search
|
||||||
script: 'Table7.data[4].value',
|
script: "Table7.data[4].value",
|
||||||
expectedResults: ['Table7.data[4].value'],
|
expectedResults: ["Table7.data[4].value"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// string literal and array index search
|
// string literal and array index search
|
||||||
script: "Table['data'][9]",
|
script: "Table['data'][9]",
|
||||||
expectedResults: ['Table'],
|
expectedResults: ["Table"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// array index and string literal search
|
// array index and string literal search
|
||||||
|
|
@ -88,29 +88,29 @@ describe('getAllIdentifiers', () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Index identifier search
|
// Index identifier search
|
||||||
script: 'Table8.data[row][name]',
|
script: "Table8.data[row][name]",
|
||||||
expectedResults: ['Table8.data', 'row'],
|
expectedResults: ["Table8.data", "row"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Index identifier search with global
|
// Index identifier search with global
|
||||||
script: 'Table9.data[appsmith.store.row]',
|
script: "Table9.data[appsmith.store.row]",
|
||||||
expectedResults: ['Table9.data', 'appsmith.store.row'],
|
expectedResults: ["Table9.data", "appsmith.store.row"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Index literal with further nested lookups
|
// Index literal with further nested lookups
|
||||||
script: 'Table10.data[row].name',
|
script: "Table10.data[row].name",
|
||||||
expectedResults: ['Table10.data', 'row'],
|
expectedResults: ["Table10.data", "row"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// IIFE and if conditions
|
// IIFE and if conditions
|
||||||
script:
|
script:
|
||||||
'(function(){ if(Table11.isVisible) { return Api1.data } else { return Api2.data } })()',
|
"(function(){ if(Table11.isVisible) { return Api1.data } else { return Api2.data } })()",
|
||||||
expectedResults: ['Table11.isVisible', 'Api1.data', 'Api2.data'],
|
expectedResults: ["Table11.isVisible", "Api1.data", "Api2.data"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Functions and arguments
|
// Functions and arguments
|
||||||
script: 'JSObject1.run(Api1.data, Api2.data)',
|
script: "JSObject1.run(Api1.data, Api2.data)",
|
||||||
expectedResults: ['JSObject1.run', 'Api1.data', 'Api2.data'],
|
expectedResults: ["JSObject1.run", "Api1.data", "Api2.data"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// IIFE - without braces
|
// IIFE - without braces
|
||||||
|
|
@ -124,7 +124,7 @@ describe('getAllIdentifiers', () => {
|
||||||
return obj[index]
|
return obj[index]
|
||||||
|
|
||||||
}()`,
|
}()`,
|
||||||
expectedResults: ['Input1.text'],
|
expectedResults: ["Input1.text"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// IIFE
|
// IIFE
|
||||||
|
|
@ -138,7 +138,7 @@ describe('getAllIdentifiers', () => {
|
||||||
return obj[index]
|
return obj[index]
|
||||||
|
|
||||||
})()`,
|
})()`,
|
||||||
expectedResults: ['Input2.text'],
|
expectedResults: ["Input2.text"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// arrow IIFE - without braces - will fail
|
// arrow IIFE - without braces - will fail
|
||||||
|
|
@ -166,19 +166,19 @@ describe('getAllIdentifiers', () => {
|
||||||
return obj[index]
|
return obj[index]
|
||||||
|
|
||||||
})()`,
|
})()`,
|
||||||
expectedResults: ['Input4.text'],
|
expectedResults: ["Input4.text"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Direct object access
|
// Direct object access
|
||||||
script: `{ "a": 123 }[Input5.text]`,
|
script: `{ "a": 123 }[Input5.text]`,
|
||||||
expectedResults: ['Input5.text'],
|
expectedResults: ["Input5.text"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Function declaration and default arguments
|
// Function declaration and default arguments
|
||||||
script: `function run(apiData = Api1.data) {
|
script: `function run(apiData = Api1.data) {
|
||||||
return apiData;
|
return apiData;
|
||||||
}`,
|
}`,
|
||||||
expectedResults: ['Api1.data'],
|
expectedResults: ["Api1.data"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Function declaration with arguments
|
// Function declaration with arguments
|
||||||
|
|
@ -197,7 +197,7 @@ describe('getAllIdentifiers', () => {
|
||||||
row = row += 1;
|
row = row += 1;
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
expectedResults: ['Table12.data'],
|
expectedResults: ["Table12.data"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// function with variables
|
// function with variables
|
||||||
|
|
@ -209,17 +209,17 @@ describe('getAllIdentifiers', () => {
|
||||||
row = row += 1;
|
row = row += 1;
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
expectedResults: ['Table13.data'],
|
expectedResults: ["Table13.data"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// expression with arithmetic operations
|
// expression with arithmetic operations
|
||||||
script: `Table14.data + 15`,
|
script: `Table14.data + 15`,
|
||||||
expectedResults: ['Table14.data'],
|
expectedResults: ["Table14.data"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// expression with logical operations
|
// expression with logical operations
|
||||||
script: `Table15.data || [{}]`,
|
script: `Table15.data || [{}]`,
|
||||||
expectedResults: ['Table15.data'],
|
expectedResults: ["Table15.data"],
|
||||||
},
|
},
|
||||||
// JavaScript built in classes should not be valid identifiers
|
// JavaScript built in classes should not be valid identifiers
|
||||||
{
|
{
|
||||||
|
|
@ -229,7 +229,7 @@ describe('getAllIdentifiers', () => {
|
||||||
const randomNumber = Math.random();
|
const randomNumber = Math.random();
|
||||||
return Promise.all([firstApiRun, secondApiRun])
|
return Promise.all([firstApiRun, secondApiRun])
|
||||||
}()`,
|
}()`,
|
||||||
expectedResults: ['Api1.run', 'Api2.run'],
|
expectedResults: ["Api1.run", "Api2.run"],
|
||||||
},
|
},
|
||||||
// Global dependencies should not be valid identifiers
|
// Global dependencies should not be valid identifiers
|
||||||
{
|
{
|
||||||
|
|
@ -251,7 +251,7 @@ describe('getAllIdentifiers', () => {
|
||||||
console.log(joinedName)
|
console.log(joinedName)
|
||||||
return Api2.name
|
return Api2.name
|
||||||
}()`,
|
}()`,
|
||||||
expectedResults: ['Api2.name'],
|
expectedResults: ["Api2.name"],
|
||||||
},
|
},
|
||||||
// identifiers and member expressions derived from params should not be valid identifiers
|
// identifiers and member expressions derived from params should not be valid identifiers
|
||||||
{
|
{
|
||||||
|
|
@ -274,19 +274,19 @@ describe('getAllIdentifiers', () => {
|
||||||
script: `function(){
|
script: `function(){
|
||||||
return appsmith.user
|
return appsmith.user
|
||||||
}()`,
|
}()`,
|
||||||
expectedResults: ['appsmith.user'],
|
expectedResults: ["appsmith.user"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
cases.forEach((perCase) => {
|
cases.forEach((perCase) => {
|
||||||
const { references } = extractInfoFromCode(perCase.script, 2);
|
const { references } = extractIdentifierInfoFromCode(perCase.script, 2);
|
||||||
expect(references).toStrictEqual(perCase.expectedResults);
|
expect(references).toStrictEqual(perCase.expectedResults);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('parseJSObjectWithAST', () => {
|
describe("parseJSObjectWithAST", () => {
|
||||||
it('parse js object', () => {
|
it("parse js object", () => {
|
||||||
const body = `{
|
const body = `{
|
||||||
myVar1: [],
|
myVar1: [],
|
||||||
myVar2: {},
|
myVar2: {},
|
||||||
|
|
@ -299,25 +299,25 @@ describe('parseJSObjectWithAST', () => {
|
||||||
}`;
|
}`;
|
||||||
const parsedObject = [
|
const parsedObject = [
|
||||||
{
|
{
|
||||||
key: 'myVar1',
|
key: "myVar1",
|
||||||
value: '[]',
|
value: "[]",
|
||||||
type: 'ArrayExpression',
|
type: "ArrayExpression",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'myVar2',
|
key: "myVar2",
|
||||||
value: '{}',
|
value: "{}",
|
||||||
type: 'ObjectExpression',
|
type: "ObjectExpression",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'myFun1',
|
key: "myFun1",
|
||||||
value: '() => {}',
|
value: "() => {}",
|
||||||
type: 'ArrowFunctionExpression',
|
type: "ArrowFunctionExpression",
|
||||||
arguments: [],
|
arguments: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'myFun2',
|
key: "myFun2",
|
||||||
value: 'async () => {}',
|
value: "async () => {}",
|
||||||
type: 'ArrowFunctionExpression',
|
type: "ArrowFunctionExpression",
|
||||||
arguments: [],
|
arguments: [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -325,7 +325,7 @@ describe('parseJSObjectWithAST', () => {
|
||||||
expect(resultParsedObject).toStrictEqual(parsedObject);
|
expect(resultParsedObject).toStrictEqual(parsedObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parse js object with literal', () => {
|
it("parse js object with literal", () => {
|
||||||
const body = `{
|
const body = `{
|
||||||
myVar1: [],
|
myVar1: [],
|
||||||
myVar2: {
|
myVar2: {
|
||||||
|
|
@ -340,25 +340,25 @@ describe('parseJSObjectWithAST', () => {
|
||||||
}`;
|
}`;
|
||||||
const parsedObject = [
|
const parsedObject = [
|
||||||
{
|
{
|
||||||
key: 'myVar1',
|
key: "myVar1",
|
||||||
value: '[]',
|
value: "[]",
|
||||||
type: 'ArrayExpression',
|
type: "ArrayExpression",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'myVar2',
|
key: "myVar2",
|
||||||
value: '{\n "a": "app"\n}',
|
value: '{\n "a": "app"\n}',
|
||||||
type: 'ObjectExpression',
|
type: "ObjectExpression",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'myFun1',
|
key: "myFun1",
|
||||||
value: '() => {}',
|
value: "() => {}",
|
||||||
type: 'ArrowFunctionExpression',
|
type: "ArrowFunctionExpression",
|
||||||
arguments: [],
|
arguments: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'myFun2',
|
key: "myFun2",
|
||||||
value: 'async () => {}',
|
value: "async () => {}",
|
||||||
type: 'ArrowFunctionExpression',
|
type: "ArrowFunctionExpression",
|
||||||
arguments: [],
|
arguments: [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -366,7 +366,7 @@ describe('parseJSObjectWithAST', () => {
|
||||||
expect(resultParsedObject).toStrictEqual(parsedObject);
|
expect(resultParsedObject).toStrictEqual(parsedObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parse js object with variable declaration inside function', () => {
|
it("parse js object with variable declaration inside function", () => {
|
||||||
const body = `{
|
const body = `{
|
||||||
myFun1: () => {
|
myFun1: () => {
|
||||||
const a = {
|
const a = {
|
||||||
|
|
@ -382,7 +382,7 @@ describe('parseJSObjectWithAST', () => {
|
||||||
}`;
|
}`;
|
||||||
const parsedObject = [
|
const parsedObject = [
|
||||||
{
|
{
|
||||||
key: 'myFun1',
|
key: "myFun1",
|
||||||
value: `() => {
|
value: `() => {
|
||||||
const a = {
|
const a = {
|
||||||
conditions: [],
|
conditions: [],
|
||||||
|
|
@ -391,13 +391,13 @@ describe('parseJSObjectWithAST', () => {
|
||||||
testFunc2: function () {}
|
testFunc2: function () {}
|
||||||
};
|
};
|
||||||
}`,
|
}`,
|
||||||
type: 'ArrowFunctionExpression',
|
type: "ArrowFunctionExpression",
|
||||||
arguments: [],
|
arguments: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'myFun2',
|
key: "myFun2",
|
||||||
value: 'async () => {}',
|
value: "async () => {}",
|
||||||
type: 'ArrowFunctionExpression',
|
type: "ArrowFunctionExpression",
|
||||||
arguments: [],
|
arguments: [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -405,7 +405,7 @@ describe('parseJSObjectWithAST', () => {
|
||||||
expect(resultParsedObject).toStrictEqual(parsedObject);
|
expect(resultParsedObject).toStrictEqual(parsedObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parse js object with params of all types', () => {
|
it("parse js object with params of all types", () => {
|
||||||
const body = `{
|
const body = `{
|
||||||
myFun2: async (a,b = Array(1,2,3),c = "", d = [], e = this.myVar1, f = {}, g = function(){}, h = Object.assign({}), i = String(), j = storeValue()) => {
|
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
|
//use async-await or promises
|
||||||
|
|
@ -414,49 +414,49 @@ describe('parseJSObjectWithAST', () => {
|
||||||
|
|
||||||
const parsedObject = [
|
const parsedObject = [
|
||||||
{
|
{
|
||||||
key: 'myFun2',
|
key: "myFun2",
|
||||||
value:
|
value:
|
||||||
'async (a, b = Array(1, 2, 3), c = "", d = [], e = this.myVar1, f = {}, g = function () {}, h = Object.assign({}), i = String(), j = storeValue()) => {}',
|
'async (a, b = Array(1, 2, 3), c = "", d = [], e = this.myVar1, f = {}, g = function () {}, h = Object.assign({}), i = String(), j = storeValue()) => {}',
|
||||||
type: 'ArrowFunctionExpression',
|
type: "ArrowFunctionExpression",
|
||||||
arguments: [
|
arguments: [
|
||||||
{
|
{
|
||||||
paramName: 'a',
|
paramName: "a",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'b',
|
paramName: "b",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'c',
|
paramName: "c",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'd',
|
paramName: "d",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'e',
|
paramName: "e",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'f',
|
paramName: "f",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'g',
|
paramName: "g",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'h',
|
paramName: "h",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'i',
|
paramName: "i",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
paramName: 'j',
|
paramName: "j",
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { parse, Node, SourceLocation, Options } from 'acorn';
|
import { parse, Node, SourceLocation, Options } from "acorn";
|
||||||
import { ancestor, simple } from 'acorn-walk';
|
import { ancestor, simple } from "acorn-walk";
|
||||||
import { ECMA_VERSION, NodeTypes } from './constants/ast';
|
import { ECMA_VERSION, NodeTypes } from "./constants/ast";
|
||||||
import { has, isFinite, isString, memoize, toPath } from 'lodash';
|
import { has, isFinite, isString, memoize, toPath } from "lodash";
|
||||||
import { isTrueObject, sanitizeScript } from './utils';
|
import { isTrueObject, sanitizeScript } from "./utils";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valuable links:
|
* Valuable links:
|
||||||
|
|
@ -90,7 +90,7 @@ export interface PropertyNode extends Node {
|
||||||
type: NodeTypes.Property;
|
type: NodeTypes.Property;
|
||||||
key: LiteralNode | IdentifierNode;
|
key: LiteralNode | IdentifierNode;
|
||||||
value: Node;
|
value: Node;
|
||||||
kind: 'init' | 'get' | 'set';
|
kind: "init" | "get" | "set";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node with location details
|
// Node with location details
|
||||||
|
|
@ -98,7 +98,7 @@ type NodeWithLocation<NodeType> = NodeType & {
|
||||||
loc: SourceLocation;
|
loc: SourceLocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
type AstOptions = Omit<Options, 'ecmaVersion'>;
|
type AstOptions = Omit<Options, "ecmaVersion">;
|
||||||
|
|
||||||
/* We need these functions to typescript casts the nodes with the correct types */
|
/* We need these functions to typescript casts the nodes with the correct types */
|
||||||
export const isIdentifierNode = (node: Node): node is IdentifierNode => {
|
export const isIdentifierNode = (node: Node): node is IdentifierNode => {
|
||||||
|
|
@ -196,23 +196,23 @@ export const getAST = memoize((code: string, options?: AstOptions) =>
|
||||||
* @param code: The piece of script where references need to be extracted from
|
* @param code: The piece of script where references need to be extracted from
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface ExtractInfoFromCode {
|
export interface IdentifierInfo {
|
||||||
references: string[];
|
references: string[];
|
||||||
functionalParams: string[];
|
functionalParams: string[];
|
||||||
variables: string[];
|
variables: string[];
|
||||||
}
|
}
|
||||||
export const extractInfoFromCode = (
|
export const extractIdentifierInfoFromCode = (
|
||||||
code: string,
|
code: string,
|
||||||
evaluationVersion: number,
|
evaluationVersion: number,
|
||||||
invalidIdentifiers?: Record<string, unknown>
|
invalidIdentifiers?: Record<string, unknown>
|
||||||
): ExtractInfoFromCode => {
|
): IdentifierInfo => {
|
||||||
// List of all references found
|
// List of all references found
|
||||||
const references = new Set<string>();
|
const references = new Set<string>();
|
||||||
// List of variables declared within the script. All identifiers and member expressions derived from declared variables will be removed
|
// List of variables declared within the script. All identifiers and member expressions derived from declared variables will be removed
|
||||||
const variableDeclarations = new Set<string>();
|
const variableDeclarations = new Set<string>();
|
||||||
// List of functional params declared within the script. All identifiers and member expressions derived from functional params will be removed
|
// List of functional params declared within the script. All identifiers and member expressions derived from functional params will be removed
|
||||||
let functionalParams = new Set<string>();
|
let functionalParams = new Set<string>();
|
||||||
let ast: Node = { end: 0, start: 0, type: '' };
|
let ast: Node = { end: 0, start: 0, type: "" };
|
||||||
try {
|
try {
|
||||||
const sanitizedScript = sanitizeScript(code, evaluationVersion);
|
const sanitizedScript = sanitizeScript(code, evaluationVersion);
|
||||||
/* wrapCode - Wrapping code in a function, since all code/script get wrapped with a function during evaluation.
|
/* wrapCode - Wrapping code in a function, since all code/script get wrapped with a function during evaluation.
|
||||||
|
|
@ -377,7 +377,7 @@ export const getFunctionalParamsFromNode = (
|
||||||
|
|
||||||
const constructFinalMemberExpIdentifier = (
|
const constructFinalMemberExpIdentifier = (
|
||||||
node: MemberExpressionNode,
|
node: MemberExpressionNode,
|
||||||
child = ''
|
child = ""
|
||||||
): string => {
|
): string => {
|
||||||
const propertyAccessor = getPropertyAccessor(node.property);
|
const propertyAccessor = getPropertyAccessor(node.property);
|
||||||
if (isIdentifierNode(node.object)) {
|
if (isIdentifierNode(node.object)) {
|
||||||
|
|
@ -438,7 +438,7 @@ export const extractInvalidTopLevelMemberExpressionsFromCode = (
|
||||||
const invalidTopLevelMemberExpressions = new Set<MemberExpressionData>();
|
const invalidTopLevelMemberExpressions = new Set<MemberExpressionData>();
|
||||||
const variableDeclarations = new Set<string>();
|
const variableDeclarations = new Set<string>();
|
||||||
let functionalParams = new Set<string>();
|
let functionalParams = new Set<string>();
|
||||||
let ast: Node = { end: 0, start: 0, type: '' };
|
let ast: Node = { end: 0, start: 0, type: "" };
|
||||||
try {
|
try {
|
||||||
const sanitizedScript = sanitizeScript(code, evaluationVersion);
|
const sanitizedScript = sanitizeScript(code, evaluationVersion);
|
||||||
const wrappedCode = wrapCode(sanitizedScript);
|
const wrappedCode = wrapCode(sanitizedScript);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user