diff --git a/.vscode/launch.json b/.vscode/launch.json index 9284c7c..242deed 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "request": "launch", "name": "Launch Program", "skipFiles": ["/**"], - "program": "${workspaceFolder}\\bug.js" + "program": "${workspaceFolder}\\test\\command\\Script\\executeFunctionWithPrint.js" } ] } diff --git a/BasisCore.Server.Node b/BasisCore.Server.Node deleted file mode 160000 index 221ab18..0000000 --- a/BasisCore.Server.Node +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 221ab1884df01fb7da0699a5db3de6b26eaa9c8a diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..1588563 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,5 @@ +export default { + testEnvironment: "node", + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", +}; diff --git a/package-lock.json b/package-lock.json index 30e6f56..b6ffcec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -246,12 +246,13 @@ } }, "node_modules/@azure/msal-node": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.3.tgz", - "integrity": "sha512-95fuxbSq/5PNlxWybQID8ShFBMjYSN0XvHUPmelwgsgJiO3F+TN5SpIvjgLGa+aMVAxEYq6TvKXK+I3qm1EMqQ==", + "version": "1.18.4", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.18.4.tgz", + "integrity": "sha512-Kc/dRvhZ9Q4+1FSfsTFDME/v6+R2Y1fuMty/TfwqE5p9GTPw08BPbKgeWinE8JRHRp+LemjQbUZsn4Q4l6Lszg==", + "deprecated": "A newer major version of this library is available. Please upgrade to the latest available version.", "dependencies": { - "@azure/msal-common": "^8.0.0", - "jsonwebtoken": "^8.5.1", + "@azure/msal-common": "13.3.1", + "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, "engines": { @@ -259,9 +260,9 @@ } }, "node_modules/@azure/msal-node/node_modules/@azure/msal-common": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-8.0.0.tgz", - "integrity": "sha512-KLGVmWoDcpWl/SKb4TZUjWm+l3lim4tUwAAvCM8N8rSHu8r0NtMTySMWBv7d3G8as1SvC4nr3eTae1+9hTp4wg==", + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-13.3.1.tgz", + "integrity": "sha512-Lrk1ozoAtaP/cp53May3v6HtcFSVxdFrg2Pa/1xu5oIvsIwhxW6zSPibKefCOVgd5osgykMi5jjcZHv8XkzZEQ==", "engines": { "node": ">=0.8.0" } @@ -3143,39 +3144,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-instrument/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", @@ -3718,39 +3686,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/jest-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", @@ -3911,9 +3846,9 @@ } }, "node_modules/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -3924,11 +3859,11 @@ "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^5.6.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=4", - "npm": ">=1.4.28" + "node": ">=12", + "npm": ">=6" } }, "node_modules/jsonwebtoken/node_modules/jwa": { @@ -4083,39 +4018,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -4782,13 +4684,35 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5528,19 +5452,19 @@ "integrity": "sha512-XqfbglUTVLdkHQ8F9UQJtKseRr3sSnr9ysboxtoswvaMVaEfvyLtMoHv9XdKUfOc0qKGzNgRFd9yRjIWVepl6Q==" }, "@azure/msal-node": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.3.tgz", - "integrity": "sha512-95fuxbSq/5PNlxWybQID8ShFBMjYSN0XvHUPmelwgsgJiO3F+TN5SpIvjgLGa+aMVAxEYq6TvKXK+I3qm1EMqQ==", + "version": "1.18.4", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.18.4.tgz", + "integrity": "sha512-Kc/dRvhZ9Q4+1FSfsTFDME/v6+R2Y1fuMty/TfwqE5p9GTPw08BPbKgeWinE8JRHRp+LemjQbUZsn4Q4l6Lszg==", "requires": { - "@azure/msal-common": "^8.0.0", - "jsonwebtoken": "^8.5.1", + "@azure/msal-common": "13.3.1", + "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, "dependencies": { "@azure/msal-common": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-8.0.0.tgz", - "integrity": "sha512-KLGVmWoDcpWl/SKb4TZUjWm+l3lim4tUwAAvCM8N8rSHu8r0NtMTySMWBv7d3G8as1SvC4nr3eTae1+9hTp4wg==" + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-13.3.1.tgz", + "integrity": "sha512-Lrk1ozoAtaP/cp53May3v6HtcFSVxdFrg2Pa/1xu5oIvsIwhxW6zSPibKefCOVgd5osgykMi5jjcZHv8XkzZEQ==" } } }, @@ -7635,32 +7559,6 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", "semver": "^7.5.4" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } } }, "istanbul-lib-report": { @@ -8078,32 +7976,6 @@ "natural-compare": "^1.4.0", "pretty-format": "^29.7.0", "semver": "^7.5.3" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } } }, "jest-util": { @@ -8231,9 +8103,9 @@ "dev": true }, "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "requires": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -8244,7 +8116,7 @@ "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^5.6.0" + "semver": "^7.5.4" }, "dependencies": { "jwa": { @@ -8378,32 +8250,6 @@ "dev": true, "requires": { "semver": "^7.5.3" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } } }, "makeerror": { @@ -8857,9 +8703,27 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } }, "shebang-command": { "version": "2.0.0", diff --git a/package.json b/package.json index 8e461b8..71f4015 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,8 @@ "text": "node test/command/rawtext/simple.js", "api": "node test/command/API/simple.js", "testApi": "node test/command/API/runTestApp.js", + "script": "node test/command/Script/simple.js", + "scriptWithPrint": "node test/command/Script/executeFunctionWithPrint.js", "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js", "convertor": "node test/convertFromJsonPartToJsonObject.js" }, diff --git a/renderEngine/Command/ApiCommand.js b/renderEngine/Command/ApiCommand.js index 5e4a09b..57876c0 100644 --- a/renderEngine/Command/ApiCommand.js +++ b/renderEngine/Command/ApiCommand.js @@ -6,6 +6,7 @@ import axios from "axios"; import JsonSource from "../Source/JsonSource.js"; import IToken from "../Token/IToken.js"; import TokenUtil from "../Token/TokenUtil.js"; +import VoidResult from "../Models/VoidResult.js"; export default class ApiCommand extends CommandBase { /*** @type {IToken}*/ url; @@ -55,14 +56,13 @@ export default class ApiCommand extends CommandBase { requestConfig.contentType = this.contentType.value; const response = await axios(requestConfig); - console.log(response.headers); const contentType = response.headers["content-type"]; - console.log(contentType); const data = { content: response.data, contentType, }; const sourceName = this.name.value; context.addSource(new JsonSource([data], sourceName)); + return VoidResult.result } } diff --git a/renderEngine/Command/Renderable/FaceCollection.js b/renderEngine/Command/Renderable/FaceCollection.js index ea63e27..f5a496d 100644 --- a/renderEngine/Command/Renderable/FaceCollection.js +++ b/renderEngine/Command/Renderable/FaceCollection.js @@ -39,7 +39,7 @@ export default class FaceCollection extends Array { retVal = param.replaces.apply(retVal, context.cancellation); } if (firstMatchFace.applyFunction) { - //TODO: apply function + retVal = this.executeContentScripts(retVal, context); } } param.setRendered(); @@ -60,4 +60,35 @@ export default class FaceCollection extends Array { } return retVal; } + /** + * + * @param {string} content + * @param {IContext} context + * @returns {string} + */ + executeContentScripts(content, context) { + const regex = /(?:javascript|python|c#)::\w+\([^)]*\)/g; + const matches = content.match(regex); + let retVal; + if (matches) { + retVal = content.replace(regex, (match, index) => { + return this.executeScript(match, context); + }); + } + return retVal ?? content; + } + /** + * + * @param {string} script + * @param {IContext} context + */ + executeScript(script, context) { + const [language, executeCommand] = script.split("::"); + const regex = /\(([^)]+)\)/; + const match = executeCommand.match(regex); + const parameters = match[1].split(","); + const functionName = executeCommand.split("(")[0].trim(); + const retVal = context.executeFunction(functionName, ...parameters); + return retVal + } } diff --git a/renderEngine/Command/ScriptCommand.js b/renderEngine/Command/ScriptCommand.js new file mode 100644 index 0000000..33a7da1 --- /dev/null +++ b/renderEngine/Command/ScriptCommand.js @@ -0,0 +1,81 @@ +import IContext from "../Context/IContext.js"; +import CommandBase from "./CommandBase.js"; +import BasisCoreException from "../../models/Exceptions/BasisCoreException.js"; +import IToken from "../Token/IToken.js"; +import TokenUtil from "../Token/TokenUtil.js"; +import ContextBase from "../Context/ContextBase.js"; +import VoidResult from "../Models/VoidResult.js"; + +export default class ScriptCommand extends CommandBase { + constructor(scriptIL) { + super(scriptIL); + /*** @type {IToken}*/ + this.language = TokenUtil.getFiled(scriptIL, "language"); + /*** @type {IToken}*/ + this.content = TokenUtil.getFiled(scriptIL, "content"); + } + + /** + * @param {IContext} context + * @returns {Promise} + */ + async _executeCommandAsync(context) { + switch (this.language.value.toLowerCase()) { + case "javascript": + this.findJsFunctions(context); + break; + default: + throw new BasisCoreException( + `Invalid language for tag script; script is not supported in ${this.language}` + ); + } + return VoidResult.result; + } + /** + * + * @param {string,context} jsScript + * @param {*} context + */ + findJsFunctions(context) { + // Named Function Declaration + const regexNamedFunction = + /function\s+([a-zA-Z_$][\w$]*)\s*\(([^)]*)\)\s*{([^]*?)}/g; + + // Anonymous Function Declaration + const regexAnonymousFunction = /function\s*\(([^)]*)\)\s*{([^]*?)}/g; + const regexArrowFunctionWithParenBlock = + /const\s*([a-zA-Z_$][\w$]*)\s*=\s*\(([^)]*)\)\s*=>\s*{([^]*?)}/g; + // Function Expression + const regexFunctionExpression = + /let\s*([a-zA-Z_$][\w$]*)\s*=\s*function\s*\(([^)]*)\)\s*{([^]*?)}/g; + + this.extractFunctions(regexNamedFunction, this.content.value, context); + this.extractFunctions(regexAnonymousFunction, this.content.value, context); + this.extractFunctions( + regexArrowFunctionWithParenBlock, + this.content.value, + context + ); + this.extractFunctions(regexFunctionExpression, this.content.value, context); + } + /** + * + * @param {RegExp} regex + * @param {string} code + * @param {IContext} context + * @returns void + */ + extractFunctions(regex, code, context) { + let match; + while ((match = regex.exec(code)) !== null) { + const functionName = match[1]; + const parameters = match[2]; + const functionCode = match[3]; + const finalFunction = new Function( + ...parameters.split(","), + functionCode + ); + context.addFunction(functionName, finalFunction); + } + } +} diff --git a/renderEngine/Context/ContextBase.js b/renderEngine/Context/ContextBase.js index d7da366..ab759f9 100644 --- a/renderEngine/Context/ContextBase.js +++ b/renderEngine/Context/ContextBase.js @@ -1,16 +1,33 @@ import IDataSource from "../Source/IDataSource.js"; import IContext from "./IContext.js"; import SourceRepository from "./SourceRepository.js"; - +import FunctionRepository from "./FunctionRepository.js"; export default class ContextBase extends IContext { /** @type {SourceRepository} */ repository = new SourceRepository(); - + functions = new FunctionRepository(); /** @param {IDataSource} dataSource */ addSource(dataSource) { this.repository.addSource(dataSource); } + /** + * + * @param {string} key + * @param {Function} userFunction + * @returns void + */ + addFunction(key, userFunction) { + return this.functions.addFunction(key, userFunction); + } + /** + * @param {string} key + * @param {any[]} rest + * @returns any + */ + executeFunction(key, ...rest) { + return this.functions.executeFunction(key, ...rest); + } /** * @param {string} sourceId * @returns {IDataSource?} diff --git a/renderEngine/Context/FunctionRepository.js b/renderEngine/Context/FunctionRepository.js new file mode 100644 index 0000000..3aae3df --- /dev/null +++ b/renderEngine/Context/FunctionRepository.js @@ -0,0 +1,27 @@ +import BasisCoreException from "../../models/Exceptions/BasisCoreException.js"; +export default class FunctionRepository { + /** @type {Map} */ + functions = new Map(); + /** + * @param {string} key + * @param {any[]} rest + * @returns any[] + */ + executeFunction(key, ...rest) { + const userFunction = this.functions.get(key); + if (!userFunction) { + throw new BasisCoreException(`function ${key} is not defined`); + } + const retVal = userFunction(...rest); + return retVal; + } + /** + * + * @param {string} key + * @param {Function} userFunction + * @returns void + */ + addFunction(key, userFunction) { + this.functions.set(key, userFunction); + } +} diff --git a/renderEngine/Context/IContext.js b/renderEngine/Context/IContext.js index 881bd65..9e66bcd 100644 --- a/renderEngine/Context/IContext.js +++ b/renderEngine/Context/IContext.js @@ -12,6 +12,12 @@ export default class IContext { * @param {string} sourceId * @returns {IDataSource} */ + addFunction(key, userFunction) { + throw new Error("method addFunction is not implemented."); + } + executeFunction(key, ...rest) { + throw new Error("method executeFunction is not implemented.") + } tryGetSource(sourceId) { throw new Error("Method 'tryGetSource' not implemented."); } diff --git a/test.js b/test.js new file mode 100644 index 0000000..dcc2138 --- /dev/null +++ b/test.js @@ -0,0 +1,18 @@ +class test { + static executeContentScripts(content) { + const regex = /(?:javascript|python|c#)::\w+\([^)]*\)/g; + const matches = content.match(regex); + let retVal; + if (matches) { + retVal = content.replace(regex, (match, index) => { + console.log(match) + return this.executeScript(match); + }); + } + return retVal ?? content; + } + executeScript(script) { + console.log(script); + } +} +test.executeContentScripts(" @title مجاز [##count.permission.error|(0)##] عدد است شما مجاز به اضافه کردن javascript::m(1,2) @title دیگر هستید python::test(12,34,56)") \ No newline at end of file diff --git a/test/command/CommandUtil.js b/test/command/CommandUtil.js index 13206b7..1a9f433 100644 --- a/test/command/CommandUtil.js +++ b/test/command/CommandUtil.js @@ -8,7 +8,7 @@ import InlineSourceCommand from "../../renderEngine/Command/Source/InlineSourceC import TreeCommand from "../../renderEngine/Command/TreeCommand.js"; import ViewCommand from "../../renderEngine/Command/ViewCommand.js"; import ListCommand from "../../renderEngine/Command/ListCommand.js"; - +import ScriptCommand from "../../renderEngine/Command/ScriptCommand.js"; export default class CommandUtil { /** * @param {Object} commandIl @@ -55,6 +55,9 @@ export default class CommandUtil { retVal = new ApiCommand(commandIl) break } + case "script" : { + retVal = new ScriptCommand(commandIl) + } } return retVal; } diff --git a/test/command/Script/executeFunctionWithPrint.js b/test/command/Script/executeFunctionWithPrint.js new file mode 100644 index 0000000..37fd4b0 --- /dev/null +++ b/test/command/Script/executeFunctionWithPrint.js @@ -0,0 +1,81 @@ +import ScriptCommand from "../../../renderEngine/Command/ScriptCommand.js"; +import ContextBase from "../../../renderEngine/Context/ContextBase.js"; +import CancellationToken from "../../../renderEngine/Cancellation/CancellationToken.js"; +import PrintCommand from "../../../renderEngine/Command/PrintCommand.js"; + +import JsonSource from "../../../renderEngine/Source/JsonSource.js"; +const context = new ContextBase(); +context.cancellation = new CancellationToken(); +const scriptIl = { + $type: "script", + core: "script", + name: "script", + runType: "AtServer", + language: "javascript", + content: ` function add(a, b) { + + return Number(a) + Number(b); + } + function subtract(a, b){ + return a - b; + } + this is a test string + const divide = (e, f) => { + return e / f; + }`, +}; + +context.addSource(new JsonSource([{ data: "ali" }], "tesT1")); +var p = new Promise((r) => { + setTimeout(() => { + context.addSource( + new JsonSource( + [ + { id: 1, name: "qam1" }, + { id: 2, name: "qam2" }, + { id: 3, name: "qam3" }, + ], + "products.lego" + ) + ); + }, 2_000); +}); + +const il = { + $type: "Print", + "data-member-name": "products.lego", + "layout-content": + " @child
", + "else-layout-content": "محصولی موجود نیست", + faces: [ + { + name: "face1", + function: true, + filter : "id=1", + content: + "

-- @name javascript::add(1,5)
", + }, + ], + "divider-content": " ", + "divider-rowcount": 2, + "incomplete-content": "red", + replaces: [ + { + tagname: "i", + template: "@val1", + }, + ], +}; + +//var l = new RawFaceCollection(il.faces); +//console.log(l); +const print = new PrintCommand(il); +const command = new ScriptCommand(scriptIl); + +//console.log(print); +const [result,scriptResult] = await Promise.all([ + print.executeAsync(context),command.executeAsync(context) +]) +console.log(result); + + diff --git a/test/command/Script/simple.js b/test/command/Script/simple.js new file mode 100644 index 0000000..0b5e56e --- /dev/null +++ b/test/command/Script/simple.js @@ -0,0 +1,32 @@ +import ScriptCommand from "../../../renderEngine/Command/ScriptCommand.js"; +import ContextBase from "../../../renderEngine/Context/ContextBase.js"; +import CancellationToken from "../../../renderEngine/Cancellation/CancellationToken.js"; + +const context = new ContextBase(); +context.cancellation = new CancellationToken(); +const il = { + $type: "script", + core: "script", + name: "script", + runType: "AtServer", + language: "javascript", + content: ` function add(a, b) { + return a + b; + } + function subtract(a, b){ + return a - b; + } + this is a test string + const divide = (e, f) => { + return e / f; + }`, +}; +const command = new ScriptCommand(il); +await command.executeAsync(context); +console.log(context); +const res = await context.executeFunction("add", 1, 2); +console.log(res); +const res1 = await context.executeFunction("subtract", 1, 2); +console.log(res1); +const res2 = await context.executeFunction("divide", 1, 2); +console.log(res2); diff --git a/test/command/print/WithDbSource.js b/test/command/print/WithDbSource.js index c58c468..70a662b 100644 --- a/test/command/print/WithDbSource.js +++ b/test/command/print/WithDbSource.js @@ -61,7 +61,7 @@ const printIl = { function: true, "row-type": "even", filter: "id<=2", - template: "

-- @name
", + content: "

-- @name
", }, { name: "face1", @@ -69,7 +69,7 @@ const printIl = { function: true, "row-type": "odd", filter: "id<=2", - template: + content: "[(i)5|@id]

-- @name
", }, { @@ -78,21 +78,21 @@ const printIl = { function: true, "row-type": "even", filter: "id>2", - template: "

-- @name
", + content: "

-- @name
", }, { name: "face1", replace: true, function: true, "row-type": "odd", - template: "

@name
", + content: "

@name
", }, { name: "face1", replace: true, function: true, "row-type": "odd", - template: "

@name
", + content: "

@name
", }, ], "divider-content": " ", @@ -101,7 +101,7 @@ const printIl = { replaces: [ { tagname: "i", - template: "@val1 - @val2", + content: "@val1 - @val2", }, ], }; diff --git a/test/command/print/index.js b/test/command/print/index.js index 7eab420..2a646da 100644 --- a/test/command/print/index.js +++ b/test/command/print/index.js @@ -36,7 +36,7 @@ const il = { function: true, "row-type": "even", filter: "id<=2", - template: "

-- @name
", + content: "

-- @name
", }, { name: "face1", @@ -44,7 +44,7 @@ const il = { function: true, "row-type": "odd", filter: "id<=2", - template: + content: "[(i)5]

-- @name
", }, { @@ -53,21 +53,21 @@ const il = { function: true, "row-type": "even", filter: "id>2", - template: "

-- @name
", + content: "

-- @name
", }, { name: "face1", replace: true, function: true, "row-type": "odd", - template: "

@name
", + content: "

@name
", }, { name: "face1", replace: true, function: true, "row-type": "odd", - template: "

@name
", + content: "

@name
", }, ], "divider-content": " ", @@ -76,7 +76,7 @@ const il = { replaces: [ { tagname: "i", - template: "@val1", + content: "@val1", }, ], };