From cccb0f3172a394fa27e3a56b1f89ac60ee0730d4 Mon Sep 17 00:00:00 2001 From: Avneesh Raghav Date: Tue, 21 May 2024 14:01:52 +0530 Subject: [PATCH 1/4] Debug flag added Basic auth params added --- package-lock.json | 718 +++++++++++++++++++++++++++++--- package.json | 6 +- src/SklEngine.ts | 888 +++++++++++++++++++++++++++------------- src/SklEngineOptions.ts | 6 +- src/logger.ts | 21 + src/mapping/Mapper.ts | 41 +- src/util/Util.ts | 68 +-- 7 files changed, 1375 insertions(+), 373 deletions(-) create mode 100644 src/logger.ts diff --git a/package-lock.json b/package-lock.json index 96a36ee..d2b40ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,8 +19,8 @@ "memory-level": "^1.0.0", "mime-types": "^2.1.35", "n3": "^1.17.2", - "quadstore": "13.0.0-alpha.1", - "quadstore-comunica": "^3.3.0", + "quadstore": "13.1.1", + "quadstore-comunica": "^4.3.0", "rdf-data-factory": "^1.1.2", "rdf-validate-shacl": "^0.4.4", "sparql-http-client": "^2.4.1", @@ -4008,15 +4008,6 @@ "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, - "node_modules/@types/rdf-js": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/rdf-js/-/rdf-js-4.0.2.tgz", - "integrity": "sha512-soR/+RMogGiDU1lrpuQl5ZL55/L1eq/JlR2dWx052Uh/RYs9okh3XZHFlIJXHZqjqyjEn4WdbOMfBj7vvc2WVQ==", - "deprecated": "This is a stub types definition. rdf-js provides its own type definitions, so you do not need this installed.", - "dependencies": { - "rdf-js": "*" - } - }, "node_modules/@types/rdf-validate-shacl": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@types/rdf-validate-shacl/-/rdf-validate-shacl-0.4.0.tgz", @@ -4461,6 +4452,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -4618,15 +4619,25 @@ "node": ">=0.10.0" } }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "node_modules/asynciterator": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-3.8.1.tgz", - "integrity": "sha512-SmdG0FUY3pYGOZZGdYq8Qb/DCRDXBFZUk08V1/4lbBXdAQvcC3Kxzz9FUDPBTik7VAVltt4cZirAPtJv3gOpEw==" + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-3.9.0.tgz", + "integrity": "sha512-bwLLTAnoE6Ap6XdjK/j8vDk2Vi9p3ojk0PFwM0SwktAG1k8pfRJF9ng+mmkaRFKdZCQQlOxcWnvOmX2NQ1HV0g==" }, "node_modules/asyncjoin": { "version": "1.1.2", @@ -5727,6 +5738,20 @@ "once": "^1.4.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -5983,6 +6008,62 @@ "eslint-plugin-unicorn": "37.0.1" } }, + "node_modules/eslint-config-es/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/eslint-config-es/node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/eslint-config-es/node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-config-es/node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "peer": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, "node_modules/eslint-config-es/node_modules/@typescript-eslint/eslint-plugin": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.2.0.tgz", @@ -6140,6 +6221,104 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/eslint-config-es/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/eslint-config-es/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint-config-es/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/eslint-config-es/node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint-config-es/node_modules/eslint-plugin-react": { "version": "7.26.1", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz", @@ -6189,6 +6368,77 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-config-es/node_modules/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "peer": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-config-es/node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-config-es/node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-config-es/node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-config-es/node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "peer": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/eslint-config-es/node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, "node_modules/eslint-config-es/node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", @@ -6198,6 +6448,40 @@ "node": ">=4.0" } }, + "node_modules/eslint-config-es/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/eslint-config-es/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint-config-es/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "peer": true + }, "node_modules/eslint-config-es/node_modules/resolve": { "version": "2.0.0-next.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", @@ -9413,6 +9697,13 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "peer": true + }, "node_modules/logform": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", @@ -10277,6 +10568,16 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/promise-polyfill": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-1.1.6.tgz", @@ -10364,34 +10665,34 @@ } }, "node_modules/quadstore": { - "version": "13.0.0-alpha.1", - "resolved": "https://registry.npmjs.org/quadstore/-/quadstore-13.0.0-alpha.1.tgz", - "integrity": "sha512-nr5NiJ5hVRhsBj+kFVsvYjQkw2fwJNLyrHxsujuAMcpmTXt+mIgNIB+Nk6CykyFB5Av8N4v/XyNpzmxQnom1Vg==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/quadstore/-/quadstore-13.1.1.tgz", + "integrity": "sha512-VFXGfcXvJCv0dKW3NbX0Mrx03lhecPec1Ad3iRj6l5vNwxSomXYoyQehhBK8GpE7KiTsNxs6AQfGbE9uzjGdZg==", "dependencies": { - "@types/rdf-js": "^4.0.1", + "@rdfjs/types": "^1.1.0", "abstract-level": "^1.0.3", - "asynciterator": "^3.8.0", + "asynciterator": "^3.9.0", "js-sorted-set": "^0.7.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/quadstore-comunica": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/quadstore-comunica/-/quadstore-comunica-3.3.0.tgz", - "integrity": "sha512-VqblQdKXMh675GAdi3t/GQR7aGhuJOFclxsIzDXivXLZoWFC7MgYpPHe8HwP943MWoZKpz7iUxBWIWMbBU0D3g==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/quadstore-comunica/-/quadstore-comunica-4.3.0.tgz", + "integrity": "sha512-xoRN+l7VTaXq/YQLOKD/8KKzDqqBJaeorjVo253jj6VtSTGtEqVRNMpE666xZvPI7BdQ7t8U38EdsBKZ/L7WzA==", "dependencies": { "@rdfjs/types": "^1.1.0", - "sparqlalgebrajs": "^4.2.0", + "sparqlalgebrajs": "^4.3.4", "sparqljs": "^3.7.1" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "asynciterator": "^3.7.0", - "quadstore": "^12.0.0-alpha.1" + "asynciterator": "^3.9.0", + "quadstore": "^13.1.0" } }, "node_modules/queue-microtask": { @@ -11249,6 +11550,24 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, "node_modules/slimdom": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/slimdom/-/slimdom-4.0.2.tgz", @@ -11319,9 +11638,9 @@ } }, "node_modules/sparqlalgebrajs": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/sparqlalgebrajs/-/sparqlalgebrajs-4.3.0.tgz", - "integrity": "sha512-l6Urelb/X5CozXEhfHis37Kbr0iZLS6uuE3pB/NYqvE0A7aYqkkFy+9n8vxEnkfNTg5CLFftYN7ukPyicYrVyw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/sparqlalgebrajs/-/sparqlalgebrajs-4.3.4.tgz", + "integrity": "sha512-BUpd79w3SfrfRPyA+gHA23B3masuD2wLK47IOnglyIK6hx4BC+4TWtOmP5D8RTbmbPCuLKYfLGyLDF/RQsKgWg==", "dependencies": { "@rdfjs/types": "*", "@types/sparqljs": "^3.1.3", @@ -11681,6 +12000,23 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -16089,14 +16425,6 @@ "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, - "@types/rdf-js": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/rdf-js/-/rdf-js-4.0.2.tgz", - "integrity": "sha512-soR/+RMogGiDU1lrpuQl5ZL55/L1eq/JlR2dWx052Uh/RYs9okh3XZHFlIJXHZqjqyjEn4WdbOMfBj7vvc2WVQ==", - "requires": { - "rdf-js": "*" - } - }, "@types/rdf-validate-shacl": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@types/rdf-validate-shacl/-/rdf-validate-shacl-0.4.0.tgz", @@ -16382,7 +16710,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -16411,6 +16740,13 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "peer": true + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -16522,15 +16858,22 @@ "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "peer": true + }, "async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "asynciterator": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-3.8.1.tgz", - "integrity": "sha512-SmdG0FUY3pYGOZZGdYq8Qb/DCRDXBFZUk08V1/4lbBXdAQvcC3Kxzz9FUDPBTik7VAVltt4cZirAPtJv3gOpEw==" + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-3.9.0.tgz", + "integrity": "sha512-bwLLTAnoE6Ap6XdjK/j8vDk2Vi9p3ojk0PFwM0SwktAG1k8pfRJF9ng+mmkaRFKdZCQQlOxcWnvOmX2NQ1HV0g==" }, "asyncjoin": { "version": "1.1.2", @@ -17375,6 +17718,17 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "peer": true, + "requires": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + } + }, "entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -17609,6 +17963,55 @@ "eslint-plugin-unicorn": "37.0.1" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "peer": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "peer": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "peer": true + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "peer": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, "@typescript-eslint/eslint-plugin": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.2.0.tgz", @@ -17692,6 +18095,120 @@ "eslint-visitor-keys": "^3.0.0" } }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "peer": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "peer": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "peer": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "peer": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "peer": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "peer": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "peer": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "peer": true + } + } + }, "eslint-plugin-react": { "version": "7.26.1", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz", @@ -17731,12 +18248,61 @@ } } }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "peer": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "peer": true + } + } + }, "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "peer": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "peer": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "peer": true + }, "resolve": { "version": "2.0.0-next.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", @@ -19437,7 +20003,8 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "29.4.3", @@ -20069,6 +20636,13 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "peer": true + }, "logform": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", @@ -20708,6 +21282,13 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "peer": true + }, "promise-polyfill": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-1.1.6.tgz", @@ -20780,23 +21361,23 @@ "dev": true }, "quadstore": { - "version": "13.0.0-alpha.1", - "resolved": "https://registry.npmjs.org/quadstore/-/quadstore-13.0.0-alpha.1.tgz", - "integrity": "sha512-nr5NiJ5hVRhsBj+kFVsvYjQkw2fwJNLyrHxsujuAMcpmTXt+mIgNIB+Nk6CykyFB5Av8N4v/XyNpzmxQnom1Vg==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/quadstore/-/quadstore-13.1.1.tgz", + "integrity": "sha512-VFXGfcXvJCv0dKW3NbX0Mrx03lhecPec1Ad3iRj6l5vNwxSomXYoyQehhBK8GpE7KiTsNxs6AQfGbE9uzjGdZg==", "requires": { - "@types/rdf-js": "^4.0.1", + "@rdfjs/types": "^1.1.0", "abstract-level": "^1.0.3", - "asynciterator": "^3.8.0", + "asynciterator": "^3.9.0", "js-sorted-set": "^0.7.0" } }, "quadstore-comunica": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/quadstore-comunica/-/quadstore-comunica-3.3.0.tgz", - "integrity": "sha512-VqblQdKXMh675GAdi3t/GQR7aGhuJOFclxsIzDXivXLZoWFC7MgYpPHe8HwP943MWoZKpz7iUxBWIWMbBU0D3g==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/quadstore-comunica/-/quadstore-comunica-4.3.0.tgz", + "integrity": "sha512-xoRN+l7VTaXq/YQLOKD/8KKzDqqBJaeorjVo253jj6VtSTGtEqVRNMpE666xZvPI7BdQ7t8U38EdsBKZ/L7WzA==", "requires": { "@rdfjs/types": "^1.1.0", - "sparqlalgebrajs": "^4.2.0", + "sparqlalgebrajs": "^4.3.4", "sparqljs": "^3.7.1" } }, @@ -21482,6 +22063,18 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, "slimdom": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/slimdom/-/slimdom-4.0.2.tgz", @@ -21542,9 +22135,9 @@ } }, "sparqlalgebrajs": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/sparqlalgebrajs/-/sparqlalgebrajs-4.3.0.tgz", - "integrity": "sha512-l6Urelb/X5CozXEhfHis37Kbr0iZLS6uuE3pB/NYqvE0A7aYqkkFy+9n8vxEnkfNTg5CLFftYN7ukPyicYrVyw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/sparqlalgebrajs/-/sparqlalgebrajs-4.3.4.tgz", + "integrity": "sha512-BUpd79w3SfrfRPyA+gHA23B3masuD2wLK47IOnglyIK6hx4BC+4TWtOmP5D8RTbmbPCuLKYfLGyLDF/RQsKgWg==", "requires": { "@rdfjs/types": "*", "@types/sparqljs": "^3.1.3", @@ -21841,6 +22434,20 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, + "peer": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + } + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -22378,7 +22985,8 @@ "version": "8.8.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", - "dev": true + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "4.0.0", diff --git a/package.json b/package.json index 5d91ee7..069acef 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,8 @@ "memory-level": "^1.0.0", "mime-types": "^2.1.35", "n3": "^1.17.2", - "quadstore": "13.0.0-alpha.1", - "quadstore-comunica": "^3.3.0", + "quadstore": "13.1.1", + "quadstore-comunica": "^4.3.0", "rdf-data-factory": "^1.1.2", "rdf-validate-shacl": "^0.4.4", "sparql-http-client": "^2.4.1", @@ -93,4 +93,4 @@ "peerDependencies": { "axios": "^0.27.2" } -} +} \ No newline at end of file diff --git a/src/SklEngine.ts b/src/SklEngine.ts index d94ef9f..728fa74 100644 --- a/src/SklEngine.ts +++ b/src/SklEngine.ts @@ -2,29 +2,39 @@ import type { OpenApi, OpenApiClientConfiguration, -} from '@comake/openapi-operation-executor'; -import { OpenApiOperationExecutor } from '@comake/openapi-operation-executor'; -import { getIdFromNodeObjectIfDefined, type ReferenceNodeObject } from '@comake/rmlmapper-js'; -import axios from 'axios'; -import type { AxiosError, AxiosResponse } from 'axios'; -import type { ContextDefinition, GraphObject, NodeObject } from 'jsonld'; -import type { Frame } from 'jsonld/jsonld-spec'; -import { JSONPath } from 'jsonpath-plus'; -import SHACLValidator from 'rdf-validate-shacl'; -import type ValidationReport from 'rdf-validate-shacl/src/validation-report'; -import { Mapper } from './mapping/Mapper'; -import type { SklEngineOptions } from './SklEngineOptions'; -import type { FindOperator } from './storage/FindOperator'; -import type { FindAllOptions, FindOneOptions, FindOptionsWhere } from './storage/FindOptionsTypes'; -import { Exists } from './storage/operator/Exists'; -import { In } from './storage/operator/In'; -import { InversePath } from './storage/operator/InversePath'; -import { Not } from './storage/operator/Not'; -import { OneOrMorePath } from './storage/operator/OneOrMorePath'; -import { SequencePath } from './storage/operator/SequencePath'; -import { ZeroOrMorePath } from './storage/operator/ZeroOrMorePath'; -import type { QueryAdapter, RawQueryResult } from './storage/query-adapter/QueryAdapter'; -import { SparqlQueryAdapter } from './storage/query-adapter/sparql/SparqlQueryAdapter'; +} from "@comake/openapi-operation-executor"; +import { OpenApiOperationExecutor } from "@comake/openapi-operation-executor"; +import { + getIdFromNodeObjectIfDefined, + type ReferenceNodeObject, +} from "@comake/rmlmapper-js"; +import axios from "axios"; +import type { AxiosError, AxiosResponse } from "axios"; +import type { ContextDefinition, GraphObject, NodeObject } from "jsonld"; +import type { Frame } from "jsonld/jsonld-spec"; +import { JSONPath } from "jsonpath-plus"; +import SHACLValidator from "rdf-validate-shacl"; +import type ValidationReport from "rdf-validate-shacl/src/validation-report"; +import { Mapper } from "./mapping/Mapper"; +import type { SklEngineOptions } from "./SklEngineOptions"; +import type { FindOperator } from "./storage/FindOperator"; +import type { + FindAllOptions, + FindOneOptions, + FindOptionsWhere, +} from "./storage/FindOptionsTypes"; +import { Exists } from "./storage/operator/Exists"; +import { In } from "./storage/operator/In"; +import { InversePath } from "./storage/operator/InversePath"; +import { Not } from "./storage/operator/Not"; +import { OneOrMorePath } from "./storage/operator/OneOrMorePath"; +import { SequencePath } from "./storage/operator/SequencePath"; +import { ZeroOrMorePath } from "./storage/operator/ZeroOrMorePath"; +import type { + QueryAdapter, + RawQueryResult, +} from "./storage/query-adapter/QueryAdapter"; +import { SparqlQueryAdapter } from "./storage/query-adapter/sparql/SparqlQueryAdapter"; import type { Callbacks, OrArray, @@ -44,22 +54,25 @@ import type { MappingWithSeries, MappingWithParallel, JSONValue, -} from './util/Types'; +} from "./util/Types"; import { convertJsonLdToQuads, toJSON, getValueIfDefined, ensureArray, -} from './util/Util'; -import { SKL, SHACL, RDFS, SKL_ENGINE, XSD, RDF } from './util/Vocabularies'; +} from "./util/Util"; +import { SKL, SHACL, RDFS, SKL_ENGINE, XSD, RDF } from "./util/Vocabularies"; +import { Logger } from "./logger"; export type VerbHandler = = OrArray>( params: JSONObject, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ) => Promise; export type VerbInterface = Record; -export type MappingResponseOption = T extends true ? JSONObject : NodeObject; +export type MappingResponseOption = T extends true + ? JSONObject + : NodeObject; export class SKLEngine { private readonly queryAdapter: QueryAdapter; @@ -68,6 +81,7 @@ export class SKLEngine { private readonly globalCallbacks?: Callbacks; private readonly disableValidation?: boolean; public readonly verb: VerbInterface; + private readonly isDebugMode: boolean; public constructor(options: SklEngineOptions) { this.queryAdapter = new SparqlQueryAdapter(options); @@ -75,18 +89,23 @@ export class SKLEngine { this.globalCallbacks = options.callbacks; this.inputFiles = options.inputFiles; this.functions = options.functions; + this.isDebugMode = options.debugMode ?? false; + Logger.getInstance(this.isDebugMode); // eslint-disable-next-line func-style - const getVerbHandler = (getTarget: VerbInterface, property: string): VerbHandler => - async = OrArray>( + const getVerbHandler = + (getTarget: VerbInterface, property: string): VerbHandler => + async = OrArray>( verbArgs: JSONObject, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise => this.executeVerbByName(property, verbArgs, verbConfig) as Promise; this.verb = new Proxy({} as VerbInterface, { get: getVerbHandler }); } - public async executeRawQuery(query: string): Promise { + public async executeRawQuery( + query: string + ): Promise { return await this.queryAdapter.executeRawQuery(query); } @@ -94,7 +113,10 @@ export class SKLEngine { return await this.queryAdapter.executeRawUpdate(query); } - public async executeRawConstructQuery(query: string, frame?: Frame): Promise { + public async executeRawConstructQuery( + query: string, + frame?: Frame + ): Promise { return await this.queryAdapter.executeRawConstructQuery(query, frame); } @@ -103,18 +125,28 @@ export class SKLEngine { if (entity) { return entity; } - throw new Error(`No schema found with fields matching ${JSON.stringify(options)}`); + throw new Error( + `No schema found with fields matching ${JSON.stringify(options)}` + ); } - public async findBy(where: FindOptionsWhere, notFoundErrorMessage?: string): Promise { + public async findBy( + where: FindOptionsWhere, + notFoundErrorMessage?: string + ): Promise { const entity = await this.queryAdapter.findBy(where); if (entity) { return entity; } - throw new Error(notFoundErrorMessage ?? `No schema found with fields matching ${JSON.stringify(where)}`); + throw new Error( + notFoundErrorMessage ?? + `No schema found with fields matching ${JSON.stringify(where)}` + ); } - public async findByIfExists(options: FindOptionsWhere): Promise { + public async findByIfExists( + options: FindOptionsWhere + ): Promise { try { const entity = await this.findBy(options); return entity; @@ -141,7 +173,9 @@ export class SKLEngine { public async save(entity: Entity): Promise; public async save(entities: Entity[]): Promise; - public async save(entityOrEntities: Entity | Entity[]): Promise { + public async save( + entityOrEntities: Entity | Entity[] + ): Promise { if (Array.isArray(entityOrEntities)) { await this.validateEntitiesConformToNounSchema(entityOrEntities); return await this.queryAdapter.save(entityOrEntities); @@ -151,35 +185,53 @@ export class SKLEngine { } public async update(id: string, attributes: Partial): Promise; - public async update(ids: string[], attributes: Partial): Promise; - public async update(idOrIds: string | string[], attributes: Partial): Promise { + public async update( + ids: string[], + attributes: Partial + ): Promise; + + public async update( + idOrIds: string | string[], + attributes: Partial + ): Promise { if (Array.isArray(idOrIds)) { - await this.validateEntitiesWithIdsConformsToNounSchemaForAttributes(idOrIds, attributes); + await this.validateEntitiesWithIdsConformsToNounSchemaForAttributes( + idOrIds, + attributes + ); return await this.queryAdapter.update(idOrIds, attributes); } - await this.validateEntityWithIdConformsToNounSchemaForAttributes(idOrIds, attributes); + await this.validateEntityWithIdConformsToNounSchemaForAttributes( + idOrIds, + attributes + ); return await this.queryAdapter.update(idOrIds, attributes); } private async validateEntitiesConformToNounSchema( - entities: Entity[], + entities: Entity[] ): Promise { const entitiesByType = this.groupEntitiesByType(entities); for (const type of Object.keys(entitiesByType)) { const noun = await this.findByIfExists({ id: type }); if (noun) { const parentNouns = await this.getSuperClassesOfNoun(type); - for (const currentNoun of [ noun, ...parentNouns ]) { + for (const currentNoun of [noun, ...parentNouns]) { const entitiesOfType = entitiesByType[type]; const nounSchemaWithTarget = { ...currentNoun, - [SHACL.targetNode]: entitiesOfType.map((entity): ReferenceNodeObject => ({ '@id': entity['@id'] })), + [SHACL.targetNode]: entitiesOfType.map( + (entity): ReferenceNodeObject => ({ "@id": entity["@id"] }) + ), }; - const report = await this.convertToQuadsAndValidateAgainstShape(entitiesOfType, nounSchemaWithTarget); + const report = await this.convertToQuadsAndValidateAgainstShape( + entitiesOfType, + nounSchemaWithTarget + ); if (!report.conforms) { this.throwValidationReportError( report, - `An entity does not conform to the ${currentNoun['@id']} schema.`, + `An entity does not conform to the ${currentNoun["@id"]} schema.` ); } } @@ -188,16 +240,24 @@ export class SKLEngine { } private groupEntitiesByType(entities: Entity[]): Record { - return entities.reduce((groupedEntities: Record, entity): Record => { - const entityTypes = Array.isArray(entity['@type']) ? entity['@type'] : [ entity['@type'] ]; - for (const type of entityTypes) { - if (!groupedEntities[type]) { - groupedEntities[type] = []; + return entities.reduce( + ( + groupedEntities: Record, + entity + ): Record => { + const entityTypes = Array.isArray(entity["@type"]) + ? entity["@type"] + : [entity["@type"]]; + for (const type of entityTypes) { + if (!groupedEntities[type]) { + groupedEntities[type] = []; + } + groupedEntities[type].push(entity); } - groupedEntities[type].push(entity); - } - return groupedEntities; - }, {}); + return groupedEntities; + }, + {} + ); } private async getSuperClassesOfNoun(noun: string): Promise { @@ -208,7 +268,9 @@ export class SKLEngine { return await this.getParentsOfSelector(In(nouns)); } - private async getParentsOfSelector(selector: string | FindOperator): Promise { + private async getParentsOfSelector( + selector: string | FindOperator + ): Promise { return await this.findAll({ where: { id: InversePath({ @@ -220,23 +282,28 @@ export class SKLEngine { } private async validateEntityConformsToNounSchema( - entity: Entity, + entity: Entity ): Promise { - const nounIds = Array.isArray(entity['@type']) ? entity['@type'] : [ entity['@type'] ]; + const nounIds = Array.isArray(entity["@type"]) + ? entity["@type"] + : [entity["@type"]]; const directNouns = await this.findAllBy({ id: In(nounIds) }); if (directNouns.length > 0) { - const existingNounIds = directNouns.map((noun): string => noun['@id']); + const existingNounIds = directNouns.map((noun): string => noun["@id"]); const parentNouns = await this.getSuperClassesOfNouns(existingNounIds); - for (const currentNoun of [ ...directNouns, ...parentNouns ]) { + for (const currentNoun of [...directNouns, ...parentNouns]) { const nounSchemaWithTarget = { ...currentNoun, - [SHACL.targetNode]: { '@id': entity['@id'] }, + [SHACL.targetNode]: { "@id": entity["@id"] }, }; - const report = await this.convertToQuadsAndValidateAgainstShape(entity, nounSchemaWithTarget); + const report = await this.convertToQuadsAndValidateAgainstShape( + entity, + nounSchemaWithTarget + ); if (!report.conforms) { this.throwValidationReportError( report, - `Entity ${entity['@id']} does not conform to the ${currentNoun['@id']} schema.`, + `Entity ${entity["@id"]} does not conform to the ${currentNoun["@id"]} schema.` ); } } @@ -245,10 +312,13 @@ export class SKLEngine { private async validateEntitiesWithIdsConformsToNounSchemaForAttributes( ids: string[], - attributes: Partial, + attributes: Partial ): Promise { for (const id of ids) { - await this.validateEntityWithIdConformsToNounSchemaForAttributes(id, attributes); + await this.validateEntityWithIdConformsToNounSchemaForAttributes( + id, + attributes + ); } } @@ -268,34 +338,42 @@ export class SKLEngine { private async validateEntityWithIdConformsToNounSchemaForAttributes( id: string, - attributes: Partial, + attributes: Partial ): Promise { const nouns = await this.getNounsAndParentNounsOfEntity(id); for (const currentNoun of nouns) { if (SHACL.property in currentNoun) { - const nounProperties = ensureArray(currentNoun[SHACL.property] as OrArray) - .filter((property): boolean => { - const path = property[SHACL.path]; - if (typeof path === 'string' && path in attributes) { - return true; - } - if (typeof path === 'object' && '@id' in path! && (path['@id'] as string) in attributes) { - return true; - } - return false; - }); + const nounProperties = ensureArray( + currentNoun[SHACL.property] as OrArray + ).filter((property): boolean => { + const path = property[SHACL.path]; + if (typeof path === "string" && path in attributes) { + return true; + } + if ( + typeof path === "object" && + "@id" in path! && + (path["@id"] as string) in attributes + ) { + return true; + } + return false; + }); if (nounProperties.length > 0) { const nounSchemaWithTarget = { - '@type': SHACL.NodeShape, - [SHACL.targetNode]: { '@id': id }, + "@type": SHACL.NodeShape, + [SHACL.targetNode]: { "@id": id }, [SHACL.property]: nounProperties, }; - const attributesWithId = { ...attributes, '@id': id }; - const report = await this.convertToQuadsAndValidateAgainstShape(attributesWithId, nounSchemaWithTarget); + const attributesWithId = { ...attributes, "@id": id }; + const report = await this.convertToQuadsAndValidateAgainstShape( + attributesWithId, + nounSchemaWithTarget + ); if (!report.conforms) { this.throwValidationReportError( report, - `Entity ${id} does not conform to the ${currentNoun['@id']} schema.`, + `Entity ${id} does not conform to the ${currentNoun["@id"]} schema.` ); } } @@ -314,7 +392,9 @@ export class SKLEngine { public async destroy(entity: Entity): Promise; public async destroy(entities: Entity[]): Promise; - public async destroy(entityOrEntities: Entity | Entity[]): Promise { + public async destroy( + entityOrEntities: Entity | Entity[] + ): Promise { if (Array.isArray(entityOrEntities)) { return await this.queryAdapter.destroy(entityOrEntities); } @@ -329,7 +409,7 @@ export class SKLEngine { args: JSONValue, mapping: OrArray, frame?: Record, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise { const functions = { ...this.functions, @@ -341,31 +421,39 @@ export class SKLEngine { public async executeTrigger( integration: string, - payload: any, + payload: any ): Promise { const triggerToVerbMapping = await this.findTriggerVerbMapping(integration); - const verbArgs = await this.performParameterMappingOnArgsIfDefined(payload, triggerToVerbMapping); - const verbId = await this.performVerbMappingWithArgs(payload, triggerToVerbMapping); + const verbArgs = await this.performParameterMappingOnArgsIfDefined( + payload, + triggerToVerbMapping + ); + const verbId = await this.performVerbMappingWithArgs( + payload, + triggerToVerbMapping + ); if (verbId) { const mappedVerb = (await this.findBy({ id: verbId })) as Verb; await this.executeVerb(mappedVerb, verbArgs); } } - private async findTriggerVerbMapping(integration: string): Promise { + private async findTriggerVerbMapping( + integration: string + ): Promise { return (await this.findBy( { type: SKL.TriggerVerbMapping, [SKL.integration]: integration, }, - `Failed to find a Trigger Verb mapping for integration ${integration}`, + `Failed to find a Trigger Verb mapping for integration ${integration}` )) as TriggerMapping; } private async executeVerbByName( verbName: string, verbArgs: JSONObject, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise> { const verb = await this.findVerbWithName(verbName); return await this.executeVerb(verb, verbArgs, verbConfig); @@ -374,34 +462,51 @@ export class SKLEngine { private async findVerbWithName(verbName: string): Promise { return (await this.findBy( { type: SKL.Verb, [RDFS.label]: verbName }, - `Failed to find the verb ${verbName} in the schema.`, + `Failed to find the verb ${verbName} in the schema.` )) as Verb; } - private async executeVerb(verb: Verb, verbArgs: JSONObject, verbConfig?: VerbConfig): Promise> { - this.globalCallbacks?.onVerbStart?.(verb['@id'], verbArgs); + private async executeVerb( + verb: Verb, + verbArgs: JSONObject, + verbConfig?: VerbConfig + ): Promise> { + this.globalCallbacks?.onVerbStart?.(verb["@id"], verbArgs); if (verbConfig?.callbacks?.onVerbStart) { - verbConfig.callbacks.onVerbStart(verb['@id'], verbArgs); + Logger.getInstance().log("Verb arguments", verbArgs); + verbConfig.callbacks.onVerbStart(verb["@id"], verbArgs); } - const { mapping, account } = await this.findMappingForVerbContextually(verb['@id'], verbArgs); + const { mapping, account } = await this.findMappingForVerbContextually( + verb["@id"], + verbArgs + ); + Logger.getInstance().log("Mapping", JSON.stringify(mapping)); const shouldValidate = this.shouldValidate(verbConfig); if (shouldValidate) { await this.assertVerbParamsMatchParameterSchemas(verbArgs, verb); } - const verbReturnValue = await this.executeMapping(mapping, verbArgs, verbConfig, account); + const verbReturnValue = await this.executeMapping( + mapping, + verbArgs, + verbConfig, + account + ); if (shouldValidate) { - await this.assertVerbReturnValueMatchesReturnTypeSchema(verbReturnValue, verb); + await this.assertVerbReturnValueMatchesReturnTypeSchema( + verbReturnValue, + verb + ); } - this.globalCallbacks?.onVerbEnd?.(verb['@id'], verbReturnValue); + this.globalCallbacks?.onVerbEnd?.(verb["@id"], verbReturnValue); if (verbConfig?.callbacks?.onVerbEnd) { - verbConfig.callbacks.onVerbEnd(verb['@id'], verbReturnValue); + verbConfig.callbacks.onVerbEnd(verb["@id"], verbReturnValue); } return verbReturnValue; } private async findMappingForVerbContextually( verbId: string, - args: JSONObject, + args: JSONObject ): Promise<{ mapping: VerbMapping; account?: Entity }> { if (args.mapping) { const mapping = await this.findByIfExists({ id: args.mapping as string }); @@ -411,15 +516,23 @@ export class SKLEngine { return { mapping: mapping as VerbMapping }; } if (args.noun) { - const mapping = await this.findVerbNounMapping(verbId, args.noun as string); + const mapping = await this.findVerbNounMapping( + verbId, + args.noun as string + ); if (mapping) { return { mapping }; } } if (args.account) { const account = await this.findBy({ id: args.account as string }); - const integrationId = (account[SKL.integration] as ReferenceNodeObject)['@id']; - const mapping = await this.findVerbIntegrationMapping(verbId, integrationId); + const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ + "@id" + ]; + const mapping = await this.findVerbIntegrationMapping( + verbId, + integrationId + ); if (mapping) { return { mapping, account }; } @@ -435,13 +548,21 @@ export class SKLEngine { return { mapping: mappings[0] as VerbMapping }; } if (mappings.length > 1) { - throw new Error('Multiple mappings found for verb, please specify one.'); + throw new Error("Multiple mappings found for verb, please specify one."); } if (args.noun) { - throw new Error(`Mapping between noun ${args.noun as string} and verb ${verbId} not found.`); + throw new Error( + `Mapping between noun ${ + args.noun as string + } and verb ${verbId} not found.` + ); } if (args.account) { - throw new Error(`Mapping between account ${args.account as string} and verb ${verbId} not found.`); + throw new Error( + `Mapping between account ${ + args.account as string + } and verb ${verbId} not found.` + ); } throw new Error(`No mapping found.`); } @@ -450,43 +571,54 @@ export class SKLEngine { mapping: Mapping, args: JSONObject, verbConfig?: VerbConfig, - account?: Entity, + account?: Entity ): Promise> { args = await this.addPreProcessingMappingToArgs(mapping, args, verbConfig); let returnValue: OrArray; if (SKL.verbId in mapping || SKL.verbMapping in mapping) { - const verbId = await this.performVerbMappingWithArgs(args, mapping, verbConfig); + const verbId = await this.performVerbMappingWithArgs( + args, + mapping, + verbConfig + ); const mappedArgs = await this.performParameterMappingOnArgsIfDefined( { ...args, verbId }, mapping as MappingWithParameterMapping, - verbConfig, + verbConfig + ); + Logger.getInstance().log("Mapped args", mappedArgs); + returnValue = await this.executeVerbMapping( + mapping, + args, + mappedArgs, + verbConfig ); - returnValue = await this.executeVerbMapping(mapping, args, mappedArgs, verbConfig); } else { const mappedArgs = await this.performParameterMappingOnArgsIfDefined( args, mapping as MappingWithParameterMapping, - verbConfig, + verbConfig ); + Logger.getInstance().log("Mapped args", mappedArgs); if (SKL.operationId in mapping || SKL.operationMapping in mapping) { - returnValue = await this.executeOperationMapping( + returnValue = (await this.executeOperationMapping( mapping, mappedArgs, args, account!, - verbConfig, - ) as NodeObject; + verbConfig + )) as NodeObject; } else if (SKL.series in mapping) { returnValue = await this.executeSeriesMapping( mapping as MappingWithSeries, mappedArgs, - verbConfig, + verbConfig ); } else if (SKL.parallel in mapping) { returnValue = await this.executeParallelMapping( mapping as MappingWithParallel, mappedArgs, - verbConfig, + verbConfig ); } else { returnValue = mappedArgs; @@ -495,7 +627,7 @@ export class SKLEngine { return await this.performReturnValueMappingWithFrameIfDefined( returnValue as JSONValue, mapping as MappingWithReturnValueMapping, - verbConfig, + verbConfig ); } @@ -510,52 +642,74 @@ export class SKLEngine { mappedArgs: JSONObject, originalArgs: JSONObject, account: Entity, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise { - const operationInfo = await this.performOperationMappingWithArgs(originalArgs, mapping, verbConfig); - return await this.performOperation( + const operationInfo = await this.performOperationMappingWithArgs( + originalArgs, + mapping, + verbConfig + ); + const response = await this.performOperation( operationInfo, mappedArgs, originalArgs, account, - verbConfig, + verbConfig ); + + Logger.getInstance().log("Original response", JSON.stringify(response)); + return response; } private async executeSeriesMapping( mapping: MappingWithSeries, args: JSONObject, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise> { const seriesVerbMappingsList = this.rdfListToArray(mapping[SKL.series]!); - const seriesVerbArgs = { originalVerbParameters: args, previousVerbReturnValue: {}}; - return await this.executeSeriesFromList(seriesVerbMappingsList, seriesVerbArgs, verbConfig); + const seriesVerbArgs = { + originalVerbParameters: args, + previousVerbReturnValue: {}, + }; + return await this.executeSeriesFromList( + seriesVerbMappingsList, + seriesVerbArgs, + verbConfig + ); } - private rdfListToArray(list: { '@list': VerbMapping[] } | RdfList): VerbMapping[] { - if (!('@list' in list)) { + private rdfListToArray( + list: { "@list": VerbMapping[] } | RdfList + ): VerbMapping[] { + if (!("@list" in list)) { return [ list[RDF.first], - ...getIdFromNodeObjectIfDefined(list[RDF.rest] as ReferenceNodeObject) === RDF.nil + ...(getIdFromNodeObjectIfDefined( + list[RDF.rest] as ReferenceNodeObject + ) === RDF.nil ? [] - : this.rdfListToArray(list[RDF.rest] as RdfList), + : this.rdfListToArray(list[RDF.rest] as RdfList)), ]; } - return list['@list']; + return list["@list"]; } private async executeSeriesFromList( list: Mapping[], args: SeriesVerbArgs, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise> { const nextVerbMapping = list[0]; - const returnValue = await this.executeMapping(nextVerbMapping, args, verbConfig); + const returnValue = await this.executeMapping( + nextVerbMapping, + args, + verbConfig + ); if (list.length > 1) { return await this.executeSeriesFromList( list.slice(1), { ...args, previousVerbReturnValue: returnValue as JSONObject }, - verbConfig, + verbConfig ); } return returnValue; @@ -565,9 +719,13 @@ export class SKLEngine { verbMapping: Mapping, originalArgs: JSONObject, mappedArgs: JSONObject, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise> { - const verbId = await this.performVerbMappingWithArgs(originalArgs, verbMapping, verbConfig); + const verbId = await this.performVerbMappingWithArgs( + originalArgs, + verbMapping, + verbConfig + ); if (verbId) { if (verbId === SKL_ENGINE.update) { await this.updateEntityFromVerbArgs(mappedArgs); @@ -599,48 +757,58 @@ export class SKLEngine { private async addPreProcessingMappingToArgs( verbMapping: Mapping, args: JSONObject, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise { if (SKL.preProcessingMapping in verbMapping) { const preMappingArgs = await this.performMapping( args, verbMapping[SKL.preProcessingMapping] as NodeObject, getValueIfDefined(verbMapping[SKL.preProcessingMappingFrame]), - verbConfig, + verbConfig ); return { ...args, preProcessedParameters: preMappingArgs as JSONObject }; } return args; } - private async updateEntityFromVerbArgs(args: Record): Promise { + private async updateEntityFromVerbArgs( + args: Record + ): Promise { await this.update(args.id ?? args.ids, args.attributes); } - private async saveEntityOrEntitiesFromVerbArgs(args: Record): Promise> { + private async saveEntityOrEntitiesFromVerbArgs( + args: Record + ): Promise> { return await this.save(args.entity ?? args.entities); } - private async destroyEntityOrEntitiesFromVerbArgs(args: Record): Promise> { + private async destroyEntityOrEntitiesFromVerbArgs( + args: Record + ): Promise> { return await this.destroy(args.entity ?? args.entities); } - private async countAndWrapValueFromVerbArgs(args: Record): Promise { + private async countAndWrapValueFromVerbArgs( + args: Record + ): Promise { const count = await this.count(args); return { [SKL_ENGINE.countResult]: { - '@value': count, - '@type': XSD.integer, + "@value": count, + "@type": XSD.integer, }, }; } - private async existsAndWrapValueFromVerbArgs(args: Record): Promise { + private async existsAndWrapValueFromVerbArgs( + args: Record + ): Promise { const exists = await this.exists(args); return { [SKL_ENGINE.existsResult]: { - '@value': exists, - '@type': XSD.boolean, + "@value": exists, + "@type": XSD.boolean, }, }; } @@ -648,7 +816,7 @@ export class SKLEngine { private async findAndExecuteVerb( verbId: string, args: Record, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise> { const verb = (await this.findBy({ id: verbId })) as Verb; return await this.executeVerb(verb, args, verbConfig); @@ -657,17 +825,24 @@ export class SKLEngine { private async executeParallelMapping( mapping: MappingWithParallel, args: JSONObject, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise { - const parallelVerbMappings = ensureArray(mapping[SKL.parallel] as unknown as OrArray); + const parallelVerbMappings = ensureArray( + mapping[SKL.parallel] as unknown as OrArray + ); const nestedReturnValues = await Promise.all>>( - parallelVerbMappings.map((verbMapping): Promise> => - this.executeMapping(verbMapping, args, verbConfig)), + parallelVerbMappings.map( + (verbMapping): Promise> => + this.executeMapping(verbMapping, args, verbConfig) + ) ); return nestedReturnValues.flat(); } - private async findVerbIntegrationMapping(verbId: string, integrationId: string): Promise { + private async findVerbIntegrationMapping( + verbId: string, + integrationId: string + ): Promise { return (await this.findByIfExists({ type: SKL.VerbIntegrationMapping, [SKL.verb]: verbId, @@ -678,7 +853,7 @@ export class SKLEngine { private async performOperationMappingWithArgs( args: JSONValue, mapping: Mapping, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise { if (mapping[SKL.operationId]) { return { [SKL.operationId]: mapping[SKL.operationId] }; @@ -690,7 +865,7 @@ export class SKLEngine { args, mapping[SKL.operationMapping] as OrArray, undefined, - verbConfig, + verbConfig ); } @@ -700,39 +875,45 @@ export class SKLEngine { originalArgs: JSONObject, account: Entity, verbConfig?: VerbConfig, - securityCredentials?: Entity, + securityCredentials?: Entity ): Promise { if (operationInfo[SKL.schemeName]) { return await this.performOauthSecuritySchemeStageWithCredentials( operationInfo, operationArgs, account, - securityCredentials, + securityCredentials ); } if (operationInfo[SKL.dataSource]) { return await this.getDataFromDataSource( - getIdFromNodeObjectIfDefined(operationInfo[SKL.dataSource] as string | ReferenceNodeObject)!, - verbConfig, + getIdFromNodeObjectIfDefined( + operationInfo[SKL.dataSource] as string | ReferenceNodeObject + )!, + verbConfig ); } if (operationInfo[SKL.operationId]) { const response = await this.performOpenapiOperationWithCredentials( getValueIfDefined(operationInfo[SKL.operationId])!, operationArgs, - account, + account + ); + return this.axiosResponseAndParamsToOperationResponse( + response, + operationArgs, + originalArgs ); - return this.axiosResponseAndParamsToOperationResponse(response, operationArgs, originalArgs); } - throw new Error('Operation not supported.'); + throw new Error("Operation not supported."); } private axiosResponseAndParamsToOperationResponse( response: AxiosResponse, operationParameters: JSONObject, - originalArgs: JSONObject, + originalArgs: JSONObject ): OperationResponse { - return { + const responseMapping = { operationParameters, originalVerbParameters: originalArgs, data: response.data, @@ -746,19 +927,20 @@ export class SKLEngine { data: response.config.data, } as JSONObject, }; + return responseMapping; } private async performReturnValueMappingWithFrameIfDefined( returnValue: JSONValue, mapping: MappingWithReturnValueMapping, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise { if (SKL.returnValueMapping in mapping) { return await this.performMapping( returnValue, mapping[SKL.returnValueMapping], getValueIfDefined(mapping[SKL.returnValueFrame]), - verbConfig, + verbConfig ); } return returnValue as NodeObject; @@ -766,12 +948,16 @@ export class SKLEngine { private async performParameterMappingOnArgsIfDefined( args: JSONObject, - mapping: Partial | Partial, + mapping: + | Partial + | Partial, verbConfig?: VerbConfig, - convertToJsonDeep = false, + convertToJsonDeep = false ): Promise> { if (SKL.parameterReference in mapping) { - const reference = getValueIfDefined(mapping[SKL.parameterReference])!; + const reference = getValueIfDefined( + mapping[SKL.parameterReference] + )!; return this.getDataAtReference(reference, args); } if (SKL.parameterMapping in mapping) { @@ -779,7 +965,7 @@ export class SKLEngine { args, (mapping as MappingWithParameterMapping)[SKL.parameterMapping]!, getValueIfDefined(mapping[SKL.parameterMappingFrame]), - verbConfig, + verbConfig ); return toJSON(mappedData, convertToJsonDeep); } @@ -790,34 +976,45 @@ export class SKLEngine { const results = JSONPath({ path: reference, json: data, - resultType: 'value', + resultType: "value", }); const isArrayOfLengthOne = Array.isArray(results) && results.length === 1; return isArrayOfLengthOne ? results[0] : results; } - private async getOpenApiDescriptionForIntegration(integrationId: string): Promise { + private async getOpenApiDescriptionForIntegration( + integrationId: string + ): Promise { const openApiDescriptionSchema = await this.findBy({ type: SKL.OpenApiDescription, [SKL.integration]: integrationId, }); - return getValueIfDefined(openApiDescriptionSchema[SKL.openApiDescription])!; + return getValueIfDefined( + openApiDescriptionSchema[SKL.openApiDescription] + )!; } - private async findSecurityCredentialsForAccountIfDefined(accountId: string): Promise { + private async findSecurityCredentialsForAccountIfDefined( + accountId: string + ): Promise { return await this.findByIfExists({ type: SKL.SecurityCredentials, [SKL.account]: accountId, }); } - private async createOpenApiOperationExecutorWithSpec(openApiDescription: OpenApi): Promise { + private async createOpenApiOperationExecutorWithSpec( + openApiDescription: OpenApi + ): Promise { const executor = new OpenApiOperationExecutor(); await executor.setOpenapiSpec(openApiDescription); return executor; } - private async findVerbNounMapping(verbId: string, noun: string): Promise { + private async findVerbNounMapping( + verbId: string, + noun: string + ): Promise { return (await this.findByIfExists({ type: SKL.VerbNounMapping, [SKL.verb]: verbId, @@ -831,7 +1028,7 @@ export class SKLEngine { private async performVerbMappingWithArgs( args: JSONValue, mapping: Mapping, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise { if (mapping[SKL.verbId]) { return getValueIfDefined(mapping[SKL.verbId])!; @@ -840,27 +1037,42 @@ export class SKLEngine { args, mapping[SKL.verbMapping] as NodeObject, undefined, - verbConfig, + verbConfig ); return getValueIfDefined(verbInfoJsonLd[SKL.verbId])!; } - private async assertVerbParamsMatchParameterSchemas(verbParams: any, verb: Verb): Promise { + private async assertVerbParamsMatchParameterSchemas( + verbParams: any, + verb: Verb + ): Promise { let parametersSchemaObject = verb[SKL.parameters]; - if (parametersSchemaObject?.['@id'] && Object.keys(parametersSchemaObject).length === 1) { - parametersSchemaObject = await this.findBy({ id: parametersSchemaObject['@id'] }); + if ( + parametersSchemaObject?.["@id"] && + Object.keys(parametersSchemaObject).length === 1 + ) { + parametersSchemaObject = await this.findBy({ + id: parametersSchemaObject["@id"], + }); } if (verbParams && parametersSchemaObject) { const verbParamsAsJsonLd = { - '@context': getValueIfDefined(verb[SKL.parametersContext]), - '@type': SKL.Parameters, + "@context": getValueIfDefined( + verb[SKL.parametersContext] + ), + "@type": SKL.Parameters, ...verbParams, }; - const report = await this.convertToQuadsAndValidateAgainstShape(verbParamsAsJsonLd, parametersSchemaObject); + const report = await this.convertToQuadsAndValidateAgainstShape( + verbParamsAsJsonLd, + parametersSchemaObject + ); if (!report.conforms) { this.throwValidationReportError( report, - `${getValueIfDefined(verb[RDFS.label])} parameters do not conform to the schema`, + `${getValueIfDefined( + verb[RDFS.label] + )} parameters do not conform to the schema` ); } } @@ -869,46 +1081,84 @@ export class SKLEngine { private async performOpenapiOperationWithCredentials( operationId: string, operationArgs: JSONObject, - account: Entity, + account: Entity ): Promise { - const integrationId = (account[SKL.integration] as ReferenceNodeObject)['@id']; - const openApiDescription = await this.getOpenApiDescriptionForIntegration(integrationId); - const openApiExecutor = await this.createOpenApiOperationExecutorWithSpec(openApiDescription); - const securityCredentials = await this.findSecurityCredentialsForAccountIfDefined(account['@id']); + const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ + "@id" + ]; + const openApiDescription = await this.getOpenApiDescriptionForIntegration( + integrationId + ); + const openApiExecutor = await this.createOpenApiOperationExecutorWithSpec( + openApiDescription + ); + const securityCredentials = + await this.findSecurityCredentialsForAccountIfDefined(account["@id"]); + + Logger.getInstance().log("Security Credentials", securityCredentials); const configuration = { - accessToken: getValueIfDefined(securityCredentials?.[SKL.accessToken]), - bearerToken: getValueIfDefined(securityCredentials?.[SKL.bearerToken]), + accessToken: getValueIfDefined( + securityCredentials?.[SKL.accessToken] + ), + bearerToken: getValueIfDefined( + securityCredentials?.[SKL.bearerToken] + ), apiKey: getValueIfDefined(securityCredentials?.[SKL.apiKey]), basePath: getValueIfDefined(account[SKL.overrideBasePath]), + username: getValueIfDefined(securityCredentials?.[SKL.clientId]), + password: getValueIfDefined( + securityCredentials?.[SKL.clientSecret] + ), }; - return await openApiExecutor.executeOperation(operationId, configuration, operationArgs) - .catch(async(error: Error | AxiosError): Promise => { - if (axios.isAxiosError(error) && await this.isInvalidTokenError(error, integrationId) && securityCredentials) { + const response = await openApiExecutor + .executeOperation(operationId, configuration, operationArgs) + .catch(async (error: Error | AxiosError): Promise => { + if ( + axios.isAxiosError(error) && + (await this.isInvalidTokenError(error, integrationId)) && + securityCredentials + ) { const refreshedConfiguration = await this.refreshSecurityCredentials( securityCredentials, integrationId, - account, + account + ); + return await openApiExecutor.executeOperation( + operationId, + refreshedConfiguration, + operationArgs ); - return await openApiExecutor.executeOperation(operationId, refreshedConfiguration, operationArgs); } throw error; }); + return response; } - private async isInvalidTokenError(error: AxiosError, integrationId: string): Promise { + private async isInvalidTokenError( + error: AxiosError, + integrationId: string + ): Promise { const integration = await this.findBy({ id: integrationId }); - const errorMatcher = integration[SKL.invalidTokenErrorMatcher] as NodeObject; - const errorMatcherStatus = errorMatcher && - getValueIfDefined(errorMatcher[SKL.invalidTokenErrorMatcherStatus]); - const errorMatcherRegex = errorMatcher && - getValueIfDefined(errorMatcher[SKL.invalidTokenErrorMatcherMessageRegex])!; - if (errorMatcher && (error.response?.status === errorMatcherStatus)) { + const errorMatcher = integration[ + SKL.invalidTokenErrorMatcher + ] as NodeObject; + const errorMatcherStatus = + errorMatcher && + getValueIfDefined( + errorMatcher[SKL.invalidTokenErrorMatcherStatus] + ); + const errorMatcherRegex = + errorMatcher && + getValueIfDefined( + errorMatcher[SKL.invalidTokenErrorMatcherMessageRegex] + )!; + if (errorMatcher && error.response?.status === errorMatcherStatus) { if (!errorMatcherRegex) { return true; } if ( error.response?.statusText && - new RegExp(errorMatcherRegex, 'u').test(error.response?.statusText) + new RegExp(errorMatcherRegex, "u").test(error.response?.statusText) ) { return true; } @@ -921,36 +1171,67 @@ export class SKLEngine { securityCredentials: Entity, integrationId: string, account: Entity, - verbConfig?: VerbConfig, + verbConfig?: VerbConfig ): Promise { - const getOauthTokenVerb = (await this.findBy({ type: SKL.Verb, [RDFS.label]: 'getOauthTokens' })) as Verb; - const mapping = await this.findVerbIntegrationMapping(getOauthTokenVerb['@id'], integrationId); + const getOauthTokenVerb = (await this.findBy({ + type: SKL.Verb, + [RDFS.label]: "getOauthTokens", + })) as Verb; + const mapping = await this.findVerbIntegrationMapping( + getOauthTokenVerb["@id"], + integrationId + ); if (!mapping) { - throw new Error(`No mapping found for verb ${getOauthTokenVerb['@id']} and integration ${integrationId}`); + throw new Error( + `No mapping found for verb ${getOauthTokenVerb["@id"]} and integration ${integrationId}` + ); } const args = { - refreshToken: getValueIfDefined(securityCredentials[SKL.refreshToken])!, - jwtBearerOptions: getValueIfDefined(securityCredentials[SKL.jwtBearerOptions])!, + refreshToken: getValueIfDefined( + securityCredentials[SKL.refreshToken] + )!, + jwtBearerOptions: getValueIfDefined( + securityCredentials[SKL.jwtBearerOptions] + )!, }; - const operationArgs = await this.performParameterMappingOnArgsIfDefined(args, mapping, verbConfig, true); - const operationInfoJsonLd = await this.performOperationMappingWithArgs({}, mapping, verbConfig); + const operationArgs = await this.performParameterMappingOnArgsIfDefined( + args, + mapping, + verbConfig, + true + ); + const operationInfoJsonLd = await this.performOperationMappingWithArgs( + {}, + mapping, + verbConfig + ); const rawReturnValue = await this.performOperation( operationInfoJsonLd, operationArgs, args, account, verbConfig, - securityCredentials, + securityCredentials ); - const mappedReturnValue = await this.performReturnValueMappingWithFrameIfDefined( - rawReturnValue, - mapping as MappingWithReturnValueMapping, - verbConfig, + const mappedReturnValue = + await this.performReturnValueMappingWithFrameIfDefined( + rawReturnValue, + mapping as MappingWithReturnValueMapping, + verbConfig + ); + await this.assertVerbReturnValueMatchesReturnTypeSchema( + mappedReturnValue, + getOauthTokenVerb + ); + const bearerToken = getValueIfDefined( + mappedReturnValue[SKL.bearerToken] + ); + const accessToken = getValueIfDefined( + mappedReturnValue[SKL.accessToken] + ); + const refreshToken = getValueIfDefined( + mappedReturnValue[SKL.refreshToken] ); - await this.assertVerbReturnValueMatchesReturnTypeSchema(mappedReturnValue, getOauthTokenVerb); - const bearerToken = getValueIfDefined(mappedReturnValue[SKL.bearerToken]); - const accessToken = getValueIfDefined(mappedReturnValue[SKL.accessToken]); - const refreshToken = getValueIfDefined(mappedReturnValue[SKL.refreshToken]); if (bearerToken) { securityCredentials[SKL.bearerToken] = bearerToken; } @@ -965,75 +1246,110 @@ export class SKLEngine { } private getOauthConfigurationFromSecurityCredentials( - securityCredentialsSchema: Entity, + securityCredentialsSchema: Entity ): OpenApiClientConfiguration { - const username = getValueIfDefined(securityCredentialsSchema[SKL.clientId]); - const password = getValueIfDefined(securityCredentialsSchema[SKL.clientSecret]); - const accessToken = getValueIfDefined(securityCredentialsSchema[SKL.accessToken]); + const username = getValueIfDefined( + securityCredentialsSchema[SKL.clientId] + ); + const password = getValueIfDefined( + securityCredentialsSchema[SKL.clientSecret] + ); + const accessToken = getValueIfDefined( + securityCredentialsSchema[SKL.accessToken] + ); return { username, password, accessToken }; } private async assertVerbReturnValueMatchesReturnTypeSchema( returnValue: OrArray, - verb: Verb, + verb: Verb ): Promise { let returnTypeSchemaObject = verb[SKL.returnValue]; - if (returnTypeSchemaObject?.['@id'] && Object.keys(returnTypeSchemaObject).length === 1) { - returnTypeSchemaObject = await this.findBy({ id: returnTypeSchemaObject['@id'] }); + if ( + returnTypeSchemaObject?.["@id"] && + Object.keys(returnTypeSchemaObject).length === 1 + ) { + returnTypeSchemaObject = await this.findBy({ + id: returnTypeSchemaObject["@id"], + }); } let report: ValidationReport | undefined; if (returnValue && returnTypeSchemaObject) { if (Array.isArray(returnValue)) { - if (returnValue.some((valueItem): boolean => '@id' in valueItem)) { - returnTypeSchemaObject[SHACL.targetNode] = returnValue - .reduce((nodes: ReferenceNodeObject[], returnValueItem): ReferenceNodeObject[] => { - if (returnValueItem['@id']) { - nodes.push({ '@id': returnValueItem['@id'] }); + if (returnValue.some((valueItem): boolean => "@id" in valueItem)) { + returnTypeSchemaObject[SHACL.targetNode] = returnValue.reduce( + ( + nodes: ReferenceNodeObject[], + returnValueItem + ): ReferenceNodeObject[] => { + if (returnValueItem["@id"]) { + nodes.push({ "@id": returnValueItem["@id"] }); } return nodes; - }, []); + }, + [] + ); } else { - const targetClasses = returnValue - .reduce((nodes: ReferenceNodeObject[], returnValueItem): ReferenceNodeObject[] => { - if (returnValueItem['@type']) { - const type = Array.isArray(returnValueItem['@type']) - ? returnValueItem['@type'][0] - : returnValueItem['@type']; - if (!nodes.includes({ '@id': type })) { - nodes.push({ '@id': type }); + const targetClasses = returnValue.reduce( + ( + nodes: ReferenceNodeObject[], + returnValueItem + ): ReferenceNodeObject[] => { + if (returnValueItem["@type"]) { + const type = Array.isArray(returnValueItem["@type"]) + ? returnValueItem["@type"][0] + : returnValueItem["@type"]; + if (!nodes.includes({ "@id": type })) { + nodes.push({ "@id": type }); } } return nodes; - }, []); + }, + [] + ); if (targetClasses.length > 0) { returnTypeSchemaObject[SHACL.targetClass] = targetClasses; } } - report = await this.convertToQuadsAndValidateAgainstShape(returnValue, returnTypeSchemaObject); + report = await this.convertToQuadsAndValidateAgainstShape( + returnValue, + returnTypeSchemaObject + ); } else if (Object.keys(returnValue).length > 0) { - if (returnValue['@id']) { - returnTypeSchemaObject[SHACL.targetNode] = { '@id': returnValue['@id'] }; - } else if (returnValue['@type']) { + if (returnValue["@id"]) { + returnTypeSchemaObject[SHACL.targetNode] = { + "@id": returnValue["@id"], + }; + } else if (returnValue["@type"]) { returnTypeSchemaObject[SHACL.targetClass] = { - '@id': Array.isArray(returnValue['@type']) ? returnValue['@type'][0] : returnValue['@type']!, + "@id": Array.isArray(returnValue["@type"]) + ? returnValue["@type"][0] + : returnValue["@type"]!, }; } - report = await this.convertToQuadsAndValidateAgainstShape(returnValue, returnTypeSchemaObject); + report = await this.convertToQuadsAndValidateAgainstShape( + returnValue, + returnTypeSchemaObject + ); } } if (report && !report?.conforms) { throw new Error( - `Return value ${Array.isArray(returnValue) ? 'array' : returnValue['@id']} does not conform to the schema`, + `Return value ${ + Array.isArray(returnValue) ? "array" : returnValue["@id"] + } does not conform to the schema` ); } } private async convertToQuadsAndValidateAgainstShape( value: OrArray, - shape: NodeObject, + shape: NodeObject ): Promise { - const valueAsQuads = await convertJsonLdToQuads(Array.isArray(value) ? value : [ value ]); + const valueAsQuads = await convertJsonLdToQuads( + Array.isArray(value) ? value : [value] + ); const shapeQuads = await convertJsonLdToQuads(shape); const validator = new SHACLValidator(shapeQuads); return validator.validate(valueAsQuads); @@ -1043,45 +1359,65 @@ export class SKLEngine { operationInfo: NodeObject, operationParameters: JSONObject, account: Entity, - securityCredentials?: Entity, + securityCredentials?: Entity ): Promise { - const integrationId = (account[SKL.integration] as ReferenceNodeObject)['@id']; - const openApiDescription = await this.getOpenApiDescriptionForIntegration(integrationId); - securityCredentials ||= await this.findSecurityCredentialsForAccountIfDefined(account['@id']); + const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ + "@id" + ]; + const openApiDescription = await this.getOpenApiDescriptionForIntegration( + integrationId + ); + securityCredentials ||= + await this.findSecurityCredentialsForAccountIfDefined(account["@id"]); let configuration: OpenApiClientConfiguration; if (securityCredentials) { - configuration = this.getOauthConfigurationFromSecurityCredentials(securityCredentials); - operationParameters.client_id = getValueIfDefined(securityCredentials[SKL.clientId])!; + configuration = + this.getOauthConfigurationFromSecurityCredentials(securityCredentials); + operationParameters.client_id = getValueIfDefined( + securityCredentials[SKL.clientId] + )!; } else { configuration = {}; } - const openApiExecutor = await this.createOpenApiOperationExecutorWithSpec(openApiDescription); + const openApiExecutor = await this.createOpenApiOperationExecutorWithSpec( + openApiDescription + ); const response = await openApiExecutor.executeSecuritySchemeStage( getValueIfDefined(operationInfo[SKL.schemeName])!, getValueIfDefined(operationInfo[SKL.oauthFlow])!, getValueIfDefined(operationInfo[SKL.stage])!, configuration, - operationParameters, + operationParameters ); - if ('codeVerifier' in response && 'authorizationUrl' in response) { + if ("codeVerifier" in response && "authorizationUrl" in response) { return { data: response as unknown as JSONObject, operationParameters, }; } - return this.axiosResponseAndParamsToOperationResponse(response, operationParameters, operationParameters); + return this.axiosResponseAndParamsToOperationResponse( + response, + operationParameters, + operationParameters + ); } - private async getDataFromDataSource(dataSourceId: string, verbConfig?: VerbConfig): Promise { + private async getDataFromDataSource( + dataSourceId: string, + verbConfig?: VerbConfig + ): Promise { const dataSource = await this.findBy({ id: dataSourceId }); - if (dataSource['@type'] === SKL.JsonDataSource) { + if (dataSource["@type"] === SKL.JsonDataSource) { const data = this.getDataFromJsonDataSource(dataSource, verbConfig); - return { data, operationParameters: {}}; + return { data, operationParameters: {} }; } - throw new Error(`DataSource type ${dataSource['@type']} is not supported.`); + throw new Error(`DataSource type ${dataSource["@type"]} is not supported.`); } - private getDataFromJsonDataSource(dataSource: NodeObject, verbConfig?: VerbConfig): JSONObject { + private getDataFromJsonDataSource( + dataSource: NodeObject, + verbConfig?: VerbConfig + ): JSONObject { if (dataSource[SKL.source]) { const sourceValue = getValueIfDefined(dataSource[SKL.source])!; return this.getJsonDataFromSource(sourceValue, verbConfig); @@ -1089,14 +1425,17 @@ export class SKLEngine { return getValueIfDefined(dataSource[SKL.data])!; } - private getJsonDataFromSource(source: string, verbConfig?: VerbConfig): JSONObject { + private getJsonDataFromSource( + source: string, + verbConfig?: VerbConfig + ): JSONObject { const inputFiles = { ...this.inputFiles, ...verbConfig?.inputFiles, }; if (source in inputFiles) { const file = inputFiles[source]; - if (typeof file === 'string') { + if (typeof file === "string") { return JSON.parse(file); } return file; @@ -1106,11 +1445,12 @@ export class SKLEngine { throw new Error(`Failed to get data from source ${source}`); } - private throwValidationReportError(report: ValidationReport, errorMessage: string): void { + private throwValidationReportError( + report: ValidationReport, + errorMessage: string + ): void { const reportMessages = this.validationReportToMessages(report); - throw new Error( - `${errorMessage}\n\n${reportMessages.join('\n')}`, - ); + throw new Error(`${errorMessage}\n\n${reportMessages.join("\n")}`); } private validationReportToMessages(report: ValidationReport): string[] { @@ -1123,7 +1463,7 @@ export class SKLEngine { } else { const resultMessages = result.message .map((message): string => `${message.value}`) - .join(', '); + .join(", "); const message = `${pathValue}: ${resultMessages}`; reportMessages.push(message); } diff --git a/src/SklEngineOptions.ts b/src/SklEngineOptions.ts index 9953ecb..86c60a6 100644 --- a/src/SklEngineOptions.ts +++ b/src/SklEngineOptions.ts @@ -1,5 +1,5 @@ -import type { SparqlQueryAdapterOptions } from './storage/query-adapter/sparql/SparqlQueryAdapterOptions'; -import type { Callbacks } from './util/Types'; +import type { SparqlQueryAdapterOptions } from "./storage/query-adapter/sparql/SparqlQueryAdapterOptions"; +import type { Callbacks } from "./util/Types"; export type SklEngineOptions = SparqlQueryAdapterOptions & { /** @@ -18,4 +18,6 @@ export type SklEngineOptions = SparqlQueryAdapterOptions & { * An object containing files keyed on their title that can be used in mappings. */ readonly inputFiles?: Record; + + readonly debugMode?: boolean; }; diff --git a/src/logger.ts b/src/logger.ts new file mode 100644 index 0000000..e49ff51 --- /dev/null +++ b/src/logger.ts @@ -0,0 +1,21 @@ +export class Logger { + private static instance: Logger; + private isDebug: boolean; + + private constructor(isDebug: boolean) { + this.isDebug = isDebug; + } + + public static getInstance(isDebug?: boolean): Logger { + if (!Logger.instance) { + Logger.instance = new Logger(isDebug ?? false); + } + return Logger.instance; + } + + public log(...args: any[]): void { + if (this.isDebug) { + console.log(...args); + } + } +} diff --git a/src/mapping/Mapper.ts b/src/mapping/Mapper.ts index 2f768d7..5237c7e 100644 --- a/src/mapping/Mapper.ts +++ b/src/mapping/Mapper.ts @@ -1,8 +1,9 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import * as RmlParser from '@comake/rmlmapper-js'; -import type { NodeObject } from 'jsonld'; -import jsonld from 'jsonld'; -import type { OrArray, JSONValue } from '../util/Types'; +import * as RmlParser from "@comake/rmlmapper-js"; +import type { NodeObject } from "jsonld"; +import jsonld from "jsonld"; +import type { OrArray, JSONValue } from "../util/Types"; +import { Logger } from "../logger"; export interface MapperArgs { functions?: Record any>; @@ -18,33 +19,45 @@ export class Mapper { public async apply( data: JSONValue, mapping: OrArray, - frame: Record, + frame: Record ): Promise { const result = await this.doMapping(data, mapping); - return await this.frame(result, frame); + Logger.getInstance().log("Mapping result", JSON.stringify(result)); + const frameResult = await this.frame(result, frame); + Logger.getInstance().log("Frame Result", frameResult); + return frameResult; } - private async doMapping(data: JSONValue, mapping: OrArray): Promise { - const sources = { 'input.json': JSON.stringify(data) }; + private async doMapping( + data: JSONValue, + mapping: OrArray + ): Promise { + const sources = { "input.json": JSON.stringify(data) }; const options = { functions: this.functions }; const mappingNodeObject = Array.isArray(mapping) - ? { '@graph': mapping } + ? { "@graph": mapping } : mapping; - return await RmlParser.parseJsonLd(mappingNodeObject, sources, options) as NodeObject[]; + const rmlResult = (await RmlParser.parseJsonLd( + mappingNodeObject, + sources, + options + )) as NodeObject[]; + + return rmlResult; } private async frame( jsonldDoc: any[], - overrideFrame: Record, + overrideFrame: Record ): Promise { let frame: Record = { - '@context': {}, - '@embed': '@always', + "@context": {}, + "@embed": "@always", }; frame = { ...frame, ...overrideFrame, - '@context': { ...frame['@context'], ...overrideFrame?.['@context'] }, + "@context": { ...frame["@context"], ...overrideFrame?.["@context"] }, }; return await jsonld.frame(jsonldDoc, frame); } diff --git a/src/util/Util.ts b/src/util/Util.ts index 6e345f6..61cbd23 100644 --- a/src/util/Util.ts +++ b/src/util/Util.ts @@ -1,14 +1,21 @@ -import type { ReferenceNodeObject } from '@comake/rmlmapper-js'; -import { getIdFromNodeObjectIfDefined } from '@comake/rmlmapper-js'; -import * as jsonld from 'jsonld'; -import type { NodeObject, ValueObject } from 'jsonld'; -import { Parser, Store } from 'n3'; -import type { EntityFieldSingularValue, EntityFieldValue, JSONObject, RdfList } from './Types'; -import { RDF } from './Vocabularies'; +import type { ReferenceNodeObject } from "@comake/rmlmapper-js"; +import { getIdFromNodeObjectIfDefined } from "@comake/rmlmapper-js"; +import * as jsonld from "jsonld"; +import type { NodeObject, ValueObject } from "jsonld"; +import { Parser, Store } from "n3"; +import type { + EntityFieldSingularValue, + EntityFieldValue, + JSONObject, + RdfList, +} from "./Types"; +import { RDF } from "./Vocabularies"; export async function convertJsonLdToQuads(jsonldDoc: any): Promise { - const nquads = await jsonld.toRDF(jsonldDoc, { format: 'application/n-quads' }) as unknown as string; - const turtleParser = new Parser({ format: 'application/n-quads' }); + const nquads = (await jsonld.toRDF(jsonldDoc, { + format: "application/n-quads", + })) as unknown as string; + const turtleParser = new Parser({ format: "application/n-quads" }); const store = new Store(); turtleParser.parse(nquads).forEach((quad): void => { store.addQuad(quad); @@ -16,8 +23,11 @@ export async function convertJsonLdToQuads(jsonldDoc: any): Promise { return store; } -export function toJSON(jsonLd: NodeObject, convertBeyondFirstLevel = true): JSONObject { - [ '@context', '@id', '@type' ].forEach((key): void => { +export function toJSON( + jsonLd: NodeObject, + convertBeyondFirstLevel = true +): JSONObject { + ["@context", "@id", "@type"].forEach((key): void => { // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete jsonLd[key]; }); @@ -25,11 +35,11 @@ export function toJSON(jsonLd: NodeObject, convertBeyondFirstLevel = true): JSON Object.keys(jsonLd).forEach((key): void => { if (Array.isArray(jsonLd[key])) { (jsonLd[key] as any[])!.forEach((item, index): void => { - if (typeof item === 'object') { + if (typeof item === "object") { (jsonLd[key] as any[])[index] = toJSON(item); } }); - } else if (typeof jsonLd[key] === 'object') { + } else if (typeof jsonLd[key] === "object") { jsonLd[key] = toJSON(jsonLd[key] as NodeObject); } }); @@ -39,18 +49,22 @@ export function toJSON(jsonLd: NodeObject, convertBeyondFirstLevel = true): JSON export function ensureArray(arrayable: T | T[]): T[] { if (arrayable !== null && arrayable !== undefined) { - return Array.isArray(arrayable) ? arrayable : [ arrayable ]; + return Array.isArray(arrayable) ? arrayable : [arrayable]; } return []; } -export function getValueIfDefined(fieldValue?: EntityFieldValue): T | undefined { +export function getValueIfDefined( + fieldValue?: EntityFieldValue +): T | undefined { if (fieldValue && Array.isArray(fieldValue)) { - return fieldValue.map((valueItem): EntityFieldSingularValue => - getValueIfDefined(valueItem)!) as unknown as T; + return fieldValue.map( + (valueItem): EntityFieldSingularValue => + getValueIfDefined(valueItem)! + ) as unknown as T; } - if (fieldValue && typeof fieldValue === 'object') { - return (fieldValue as ValueObject)['@value'] as unknown as T; + if (fieldValue && typeof fieldValue === "object") { + return (fieldValue as ValueObject)["@value"] as unknown as T; } if (fieldValue !== undefined && fieldValue !== null) { return fieldValue as unknown as T; @@ -58,7 +72,7 @@ export function getValueIfDefined(fieldValue?: EntityFieldValue): T | undefin } export function isUrl(value: any): boolean { - if (typeof value !== 'string') { + if (typeof value !== "string") { return false; } try { @@ -71,14 +85,18 @@ export function isUrl(value: any): boolean { } // eslint-disable-next-line @typescript-eslint/naming-convention -export function rdfListToArray(list: { '@list': T[] } | RdfList): T[] { - if (!('@list' in list)) { +export function rdfListToArray( + list: { "@list": T[] } | RdfList +): T[] { + if (!("@list" in list)) { return [ list[RDF.first], - ...getIdFromNodeObjectIfDefined(list[RDF.rest] as ReferenceNodeObject) === RDF.nil + ...(getIdFromNodeObjectIfDefined( + list[RDF.rest] as ReferenceNodeObject + ) === RDF.nil ? [] - : rdfListToArray(list[RDF.rest] as RdfList), + : rdfListToArray(list[RDF.rest] as RdfList)), ]; } - return list['@list']; + return list["@list"]; } From 5c8169638c8550c88b539e9869379d8f5247da5a Mon Sep 17 00:00:00 2001 From: Avneesh Raghav Date: Tue, 21 May 2024 20:07:56 +0530 Subject: [PATCH 2/4] nvmrc added --- .nvmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..238155b --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.12.2 \ No newline at end of file From cf2cb19a8077fa5cb1bb265f3b63e8a940bdc22a Mon Sep 17 00:00:00 2001 From: Avneesh Raghav Date: Sat, 25 May 2024 17:43:44 +0530 Subject: [PATCH 3/4] feat: Added contains handling for partial string match --- src/SklEngine.ts | 528 +++++++++--------- src/index.ts | 1 + src/storage/FindOperator.ts | 3 +- src/storage/FindOptionsTypes.ts | 4 +- src/storage/operator/Contains.ts | 11 + .../sparql/SparqlQueryBuilder.ts | 15 + src/util/SparqlUtil.ts | 16 + 7 files changed, 311 insertions(+), 267 deletions(-) create mode 100644 src/storage/operator/Contains.ts diff --git a/src/SklEngine.ts b/src/SklEngine.ts index 728fa74..78b0281 100644 --- a/src/SklEngine.ts +++ b/src/SklEngine.ts @@ -2,39 +2,40 @@ import type { OpenApi, OpenApiClientConfiguration, -} from "@comake/openapi-operation-executor"; -import { OpenApiOperationExecutor } from "@comake/openapi-operation-executor"; +} from '@comake/openapi-operation-executor'; +import { OpenApiOperationExecutor } from '@comake/openapi-operation-executor'; import { getIdFromNodeObjectIfDefined, type ReferenceNodeObject, -} from "@comake/rmlmapper-js"; -import axios from "axios"; -import type { AxiosError, AxiosResponse } from "axios"; -import type { ContextDefinition, GraphObject, NodeObject } from "jsonld"; -import type { Frame } from "jsonld/jsonld-spec"; -import { JSONPath } from "jsonpath-plus"; -import SHACLValidator from "rdf-validate-shacl"; -import type ValidationReport from "rdf-validate-shacl/src/validation-report"; -import { Mapper } from "./mapping/Mapper"; -import type { SklEngineOptions } from "./SklEngineOptions"; -import type { FindOperator } from "./storage/FindOperator"; +} from '@comake/rmlmapper-js'; +import axios from 'axios'; +import type { AxiosError, AxiosResponse } from 'axios'; +import type { ContextDefinition, GraphObject, NodeObject } from 'jsonld'; +import type { Frame } from 'jsonld/jsonld-spec'; +import { JSONPath } from 'jsonpath-plus'; +import SHACLValidator from 'rdf-validate-shacl'; +import type ValidationReport from 'rdf-validate-shacl/src/validation-report'; +import { Logger } from './logger'; +import { Mapper } from './mapping/Mapper'; +import type { SklEngineOptions } from './SklEngineOptions'; +import type { FindOperator } from './storage/FindOperator'; import type { FindAllOptions, FindOneOptions, FindOptionsWhere, -} from "./storage/FindOptionsTypes"; -import { Exists } from "./storage/operator/Exists"; -import { In } from "./storage/operator/In"; -import { InversePath } from "./storage/operator/InversePath"; -import { Not } from "./storage/operator/Not"; -import { OneOrMorePath } from "./storage/operator/OneOrMorePath"; -import { SequencePath } from "./storage/operator/SequencePath"; -import { ZeroOrMorePath } from "./storage/operator/ZeroOrMorePath"; +} from './storage/FindOptionsTypes'; +import { Exists } from './storage/operator/Exists'; +import { In } from './storage/operator/In'; +import { InversePath } from './storage/operator/InversePath'; +import { Not } from './storage/operator/Not'; +import { OneOrMorePath } from './storage/operator/OneOrMorePath'; +import { SequencePath } from './storage/operator/SequencePath'; +import { ZeroOrMorePath } from './storage/operator/ZeroOrMorePath'; import type { QueryAdapter, RawQueryResult, -} from "./storage/query-adapter/QueryAdapter"; -import { SparqlQueryAdapter } from "./storage/query-adapter/sparql/SparqlQueryAdapter"; +} from './storage/query-adapter/QueryAdapter'; +import { SparqlQueryAdapter } from './storage/query-adapter/sparql/SparqlQueryAdapter'; import type { Callbacks, OrArray, @@ -54,15 +55,14 @@ import type { MappingWithSeries, MappingWithParallel, JSONValue, -} from "./util/Types"; +} from './util/Types'; import { convertJsonLdToQuads, toJSON, getValueIfDefined, ensureArray, -} from "./util/Util"; -import { SKL, SHACL, RDFS, SKL_ENGINE, XSD, RDF } from "./util/Vocabularies"; -import { Logger } from "./logger"; +} from './util/Util'; +import { SKL, SHACL, RDFS, SKL_ENGINE, XSD, RDF } from './util/Vocabularies'; export type VerbHandler = = OrArray>( params: JSONObject, @@ -95,16 +95,16 @@ export class SKLEngine { // eslint-disable-next-line func-style const getVerbHandler = (getTarget: VerbInterface, property: string): VerbHandler => - async = OrArray>( - verbArgs: JSONObject, - verbConfig?: VerbConfig - ): Promise => - this.executeVerbByName(property, verbArgs, verbConfig) as Promise; + async = OrArray>( + verbArgs: JSONObject, + verbConfig?: VerbConfig, + ): Promise => + this.executeVerbByName(property, verbArgs, verbConfig) as Promise; this.verb = new Proxy({} as VerbInterface, { get: getVerbHandler }); } public async executeRawQuery( - query: string + query: string, ): Promise { return await this.queryAdapter.executeRawQuery(query); } @@ -115,7 +115,7 @@ export class SKLEngine { public async executeRawConstructQuery( query: string, - frame?: Frame + frame?: Frame, ): Promise { return await this.queryAdapter.executeRawConstructQuery(query, frame); } @@ -126,13 +126,13 @@ export class SKLEngine { return entity; } throw new Error( - `No schema found with fields matching ${JSON.stringify(options)}` + `No schema found with fields matching ${JSON.stringify(options)}`, ); } public async findBy( where: FindOptionsWhere, - notFoundErrorMessage?: string + notFoundErrorMessage?: string, ): Promise { const entity = await this.queryAdapter.findBy(where); if (entity) { @@ -140,12 +140,12 @@ export class SKLEngine { } throw new Error( notFoundErrorMessage ?? - `No schema found with fields matching ${JSON.stringify(where)}` + `No schema found with fields matching ${JSON.stringify(where)}`, ); } public async findByIfExists( - options: FindOptionsWhere + options: FindOptionsWhere, ): Promise { try { const entity = await this.findBy(options); @@ -174,7 +174,7 @@ export class SKLEngine { public async save(entity: Entity): Promise; public async save(entities: Entity[]): Promise; public async save( - entityOrEntities: Entity | Entity[] + entityOrEntities: Entity | Entity[], ): Promise { if (Array.isArray(entityOrEntities)) { await this.validateEntitiesConformToNounSchema(entityOrEntities); @@ -192,46 +192,46 @@ export class SKLEngine { public async update( idOrIds: string | string[], - attributes: Partial + attributes: Partial, ): Promise { if (Array.isArray(idOrIds)) { await this.validateEntitiesWithIdsConformsToNounSchemaForAttributes( idOrIds, - attributes + attributes, ); return await this.queryAdapter.update(idOrIds, attributes); } await this.validateEntityWithIdConformsToNounSchemaForAttributes( idOrIds, - attributes + attributes, ); return await this.queryAdapter.update(idOrIds, attributes); } private async validateEntitiesConformToNounSchema( - entities: Entity[] + entities: Entity[], ): Promise { const entitiesByType = this.groupEntitiesByType(entities); for (const type of Object.keys(entitiesByType)) { const noun = await this.findByIfExists({ id: type }); if (noun) { const parentNouns = await this.getSuperClassesOfNoun(type); - for (const currentNoun of [noun, ...parentNouns]) { + for (const currentNoun of [ noun, ...parentNouns ]) { const entitiesOfType = entitiesByType[type]; const nounSchemaWithTarget = { ...currentNoun, [SHACL.targetNode]: entitiesOfType.map( - (entity): ReferenceNodeObject => ({ "@id": entity["@id"] }) + (entity): ReferenceNodeObject => ({ '@id': entity['@id'] }), ), }; const report = await this.convertToQuadsAndValidateAgainstShape( entitiesOfType, - nounSchemaWithTarget + nounSchemaWithTarget, ); if (!report.conforms) { this.throwValidationReportError( report, - `An entity does not conform to the ${currentNoun["@id"]} schema.` + `An entity does not conform to the ${currentNoun['@id']} schema.`, ); } } @@ -243,11 +243,11 @@ export class SKLEngine { return entities.reduce( ( groupedEntities: Record, - entity + entity, ): Record => { - const entityTypes = Array.isArray(entity["@type"]) - ? entity["@type"] - : [entity["@type"]]; + const entityTypes = Array.isArray(entity['@type']) + ? entity['@type'] + : [ entity['@type'] ]; for (const type of entityTypes) { if (!groupedEntities[type]) { groupedEntities[type] = []; @@ -256,7 +256,7 @@ export class SKLEngine { } return groupedEntities; }, - {} + {}, ); } @@ -269,7 +269,7 @@ export class SKLEngine { } private async getParentsOfSelector( - selector: string | FindOperator + selector: string | FindOperator, ): Promise { return await this.findAll({ where: { @@ -282,28 +282,28 @@ export class SKLEngine { } private async validateEntityConformsToNounSchema( - entity: Entity + entity: Entity, ): Promise { - const nounIds = Array.isArray(entity["@type"]) - ? entity["@type"] - : [entity["@type"]]; + const nounIds = Array.isArray(entity['@type']) + ? entity['@type'] + : [ entity['@type'] ]; const directNouns = await this.findAllBy({ id: In(nounIds) }); if (directNouns.length > 0) { - const existingNounIds = directNouns.map((noun): string => noun["@id"]); + const existingNounIds = directNouns.map((noun): string => noun['@id']); const parentNouns = await this.getSuperClassesOfNouns(existingNounIds); - for (const currentNoun of [...directNouns, ...parentNouns]) { + for (const currentNoun of [ ...directNouns, ...parentNouns ]) { const nounSchemaWithTarget = { ...currentNoun, - [SHACL.targetNode]: { "@id": entity["@id"] }, + [SHACL.targetNode]: { '@id': entity['@id'] }, }; const report = await this.convertToQuadsAndValidateAgainstShape( entity, - nounSchemaWithTarget + nounSchemaWithTarget, ); if (!report.conforms) { this.throwValidationReportError( report, - `Entity ${entity["@id"]} does not conform to the ${currentNoun["@id"]} schema.` + `Entity ${entity['@id']} does not conform to the ${currentNoun['@id']} schema.`, ); } } @@ -312,12 +312,12 @@ export class SKLEngine { private async validateEntitiesWithIdsConformsToNounSchemaForAttributes( ids: string[], - attributes: Partial + attributes: Partial, ): Promise { for (const id of ids) { await this.validateEntityWithIdConformsToNounSchemaForAttributes( id, - attributes + attributes, ); } } @@ -338,22 +338,22 @@ export class SKLEngine { private async validateEntityWithIdConformsToNounSchemaForAttributes( id: string, - attributes: Partial + attributes: Partial, ): Promise { const nouns = await this.getNounsAndParentNounsOfEntity(id); for (const currentNoun of nouns) { if (SHACL.property in currentNoun) { const nounProperties = ensureArray( - currentNoun[SHACL.property] as OrArray + currentNoun[SHACL.property] as OrArray, ).filter((property): boolean => { const path = property[SHACL.path]; - if (typeof path === "string" && path in attributes) { + if (typeof path === 'string' && path in attributes) { return true; } if ( - typeof path === "object" && - "@id" in path! && - (path["@id"] as string) in attributes + typeof path === 'object' && + '@id' in path! && + (path['@id'] as string) in attributes ) { return true; } @@ -361,19 +361,19 @@ export class SKLEngine { }); if (nounProperties.length > 0) { const nounSchemaWithTarget = { - "@type": SHACL.NodeShape, - [SHACL.targetNode]: { "@id": id }, + '@type': SHACL.NodeShape, + [SHACL.targetNode]: { '@id': id }, [SHACL.property]: nounProperties, }; - const attributesWithId = { ...attributes, "@id": id }; + const attributesWithId = { ...attributes, '@id': id }; const report = await this.convertToQuadsAndValidateAgainstShape( attributesWithId, - nounSchemaWithTarget + nounSchemaWithTarget, ); if (!report.conforms) { this.throwValidationReportError( report, - `Entity ${id} does not conform to the ${currentNoun["@id"]} schema.` + `Entity ${id} does not conform to the ${currentNoun['@id']} schema.`, ); } } @@ -393,7 +393,7 @@ export class SKLEngine { public async destroy(entity: Entity): Promise; public async destroy(entities: Entity[]): Promise; public async destroy( - entityOrEntities: Entity | Entity[] + entityOrEntities: Entity | Entity[], ): Promise { if (Array.isArray(entityOrEntities)) { return await this.queryAdapter.destroy(entityOrEntities); @@ -409,7 +409,7 @@ export class SKLEngine { args: JSONValue, mapping: OrArray, frame?: Record, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const functions = { ...this.functions, @@ -421,16 +421,16 @@ export class SKLEngine { public async executeTrigger( integration: string, - payload: any + payload: any, ): Promise { const triggerToVerbMapping = await this.findTriggerVerbMapping(integration); const verbArgs = await this.performParameterMappingOnArgsIfDefined( payload, - triggerToVerbMapping + triggerToVerbMapping, ); const verbId = await this.performVerbMappingWithArgs( payload, - triggerToVerbMapping + triggerToVerbMapping, ); if (verbId) { const mappedVerb = (await this.findBy({ id: verbId })) as Verb; @@ -439,21 +439,21 @@ export class SKLEngine { } private async findTriggerVerbMapping( - integration: string + integration: string, ): Promise { return (await this.findBy( { type: SKL.TriggerVerbMapping, [SKL.integration]: integration, }, - `Failed to find a Trigger Verb mapping for integration ${integration}` + `Failed to find a Trigger Verb mapping for integration ${integration}`, )) as TriggerMapping; } private async executeVerbByName( verbName: string, verbArgs: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const verb = await this.findVerbWithName(verbName); return await this.executeVerb(verb, verbArgs, verbConfig); @@ -462,25 +462,25 @@ export class SKLEngine { private async findVerbWithName(verbName: string): Promise { return (await this.findBy( { type: SKL.Verb, [RDFS.label]: verbName }, - `Failed to find the verb ${verbName} in the schema.` + `Failed to find the verb ${verbName} in the schema.`, )) as Verb; } private async executeVerb( verb: Verb, verbArgs: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { - this.globalCallbacks?.onVerbStart?.(verb["@id"], verbArgs); + this.globalCallbacks?.onVerbStart?.(verb['@id'], verbArgs); if (verbConfig?.callbacks?.onVerbStart) { - Logger.getInstance().log("Verb arguments", verbArgs); - verbConfig.callbacks.onVerbStart(verb["@id"], verbArgs); + Logger.getInstance().log('Verb arguments', verbArgs); + verbConfig.callbacks.onVerbStart(verb['@id'], verbArgs); } const { mapping, account } = await this.findMappingForVerbContextually( - verb["@id"], - verbArgs + verb['@id'], + verbArgs, ); - Logger.getInstance().log("Mapping", JSON.stringify(mapping)); + Logger.getInstance().log('Mapping', JSON.stringify(mapping)); const shouldValidate = this.shouldValidate(verbConfig); if (shouldValidate) { await this.assertVerbParamsMatchParameterSchemas(verbArgs, verb); @@ -489,24 +489,24 @@ export class SKLEngine { mapping, verbArgs, verbConfig, - account + account, ); if (shouldValidate) { await this.assertVerbReturnValueMatchesReturnTypeSchema( verbReturnValue, - verb + verb, ); } - this.globalCallbacks?.onVerbEnd?.(verb["@id"], verbReturnValue); + this.globalCallbacks?.onVerbEnd?.(verb['@id'], verbReturnValue); if (verbConfig?.callbacks?.onVerbEnd) { - verbConfig.callbacks.onVerbEnd(verb["@id"], verbReturnValue); + verbConfig.callbacks.onVerbEnd(verb['@id'], verbReturnValue); } return verbReturnValue; } private async findMappingForVerbContextually( verbId: string, - args: JSONObject + args: JSONObject, ): Promise<{ mapping: VerbMapping; account?: Entity }> { if (args.mapping) { const mapping = await this.findByIfExists({ id: args.mapping as string }); @@ -518,7 +518,7 @@ export class SKLEngine { if (args.noun) { const mapping = await this.findVerbNounMapping( verbId, - args.noun as string + args.noun as string, ); if (mapping) { return { mapping }; @@ -527,11 +527,11 @@ export class SKLEngine { if (args.account) { const account = await this.findBy({ id: args.account as string }); const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ - "@id" + '@id' ]; const mapping = await this.findVerbIntegrationMapping( verbId, - integrationId + integrationId, ); if (mapping) { return { mapping, account }; @@ -548,20 +548,20 @@ export class SKLEngine { return { mapping: mappings[0] as VerbMapping }; } if (mappings.length > 1) { - throw new Error("Multiple mappings found for verb, please specify one."); + throw new Error('Multiple mappings found for verb, please specify one.'); } if (args.noun) { throw new Error( `Mapping between noun ${ args.noun as string - } and verb ${verbId} not found.` + } and verb ${verbId} not found.`, ); } if (args.account) { throw new Error( `Mapping between account ${ args.account as string - } and verb ${verbId} not found.` + } and verb ${verbId} not found.`, ); } throw new Error(`No mapping found.`); @@ -571,7 +571,7 @@ export class SKLEngine { mapping: Mapping, args: JSONObject, verbConfig?: VerbConfig, - account?: Entity + account?: Entity, ): Promise> { args = await this.addPreProcessingMappingToArgs(mapping, args, verbConfig); let returnValue: OrArray; @@ -579,46 +579,46 @@ export class SKLEngine { const verbId = await this.performVerbMappingWithArgs( args, mapping, - verbConfig + verbConfig, ); const mappedArgs = await this.performParameterMappingOnArgsIfDefined( { ...args, verbId }, mapping as MappingWithParameterMapping, - verbConfig + verbConfig, ); - Logger.getInstance().log("Mapped args", mappedArgs); + Logger.getInstance().log('Mapped args', mappedArgs); returnValue = await this.executeVerbMapping( mapping, args, mappedArgs, - verbConfig + verbConfig, ); } else { const mappedArgs = await this.performParameterMappingOnArgsIfDefined( args, mapping as MappingWithParameterMapping, - verbConfig + verbConfig, ); - Logger.getInstance().log("Mapped args", mappedArgs); + Logger.getInstance().log('Mapped args', mappedArgs); if (SKL.operationId in mapping || SKL.operationMapping in mapping) { returnValue = (await this.executeOperationMapping( mapping, mappedArgs, args, account!, - verbConfig + verbConfig, )) as NodeObject; } else if (SKL.series in mapping) { returnValue = await this.executeSeriesMapping( mapping as MappingWithSeries, mappedArgs, - verbConfig + verbConfig, ); } else if (SKL.parallel in mapping) { returnValue = await this.executeParallelMapping( mapping as MappingWithParallel, mappedArgs, - verbConfig + verbConfig, ); } else { returnValue = mappedArgs; @@ -627,7 +627,7 @@ export class SKLEngine { return await this.performReturnValueMappingWithFrameIfDefined( returnValue as JSONValue, mapping as MappingWithReturnValueMapping, - verbConfig + verbConfig, ); } @@ -642,29 +642,29 @@ export class SKLEngine { mappedArgs: JSONObject, originalArgs: JSONObject, account: Entity, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const operationInfo = await this.performOperationMappingWithArgs( originalArgs, mapping, - verbConfig + verbConfig, ); const response = await this.performOperation( operationInfo, mappedArgs, originalArgs, account, - verbConfig + verbConfig, ); - Logger.getInstance().log("Original response", JSON.stringify(response)); + Logger.getInstance().log('Original response', JSON.stringify(response)); return response; } private async executeSeriesMapping( mapping: MappingWithSeries, args: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const seriesVerbMappingsList = this.rdfListToArray(mapping[SKL.series]!); const seriesVerbArgs = { @@ -674,42 +674,42 @@ export class SKLEngine { return await this.executeSeriesFromList( seriesVerbMappingsList, seriesVerbArgs, - verbConfig + verbConfig, ); } private rdfListToArray( - list: { "@list": VerbMapping[] } | RdfList + list: { '@list': VerbMapping[] } | RdfList, ): VerbMapping[] { - if (!("@list" in list)) { + if (!('@list' in list)) { return [ list[RDF.first], - ...(getIdFromNodeObjectIfDefined( - list[RDF.rest] as ReferenceNodeObject + ...getIdFromNodeObjectIfDefined( + list[RDF.rest] as ReferenceNodeObject, ) === RDF.nil ? [] - : this.rdfListToArray(list[RDF.rest] as RdfList)), + : this.rdfListToArray(list[RDF.rest] as RdfList), ]; } - return list["@list"]; + return list['@list']; } private async executeSeriesFromList( list: Mapping[], args: SeriesVerbArgs, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const nextVerbMapping = list[0]; const returnValue = await this.executeMapping( nextVerbMapping, args, - verbConfig + verbConfig, ); if (list.length > 1) { return await this.executeSeriesFromList( list.slice(1), { ...args, previousVerbReturnValue: returnValue as JSONObject }, - verbConfig + verbConfig, ); } return returnValue; @@ -719,12 +719,12 @@ export class SKLEngine { verbMapping: Mapping, originalArgs: JSONObject, mappedArgs: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const verbId = await this.performVerbMappingWithArgs( originalArgs, verbMapping, - verbConfig + verbConfig, ); if (verbId) { if (verbId === SKL_ENGINE.update) { @@ -757,14 +757,14 @@ export class SKLEngine { private async addPreProcessingMappingToArgs( verbMapping: Mapping, args: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { if (SKL.preProcessingMapping in verbMapping) { const preMappingArgs = await this.performMapping( args, verbMapping[SKL.preProcessingMapping] as NodeObject, getValueIfDefined(verbMapping[SKL.preProcessingMappingFrame]), - verbConfig + verbConfig, ); return { ...args, preProcessedParameters: preMappingArgs as JSONObject }; } @@ -772,43 +772,43 @@ export class SKLEngine { } private async updateEntityFromVerbArgs( - args: Record + args: Record, ): Promise { await this.update(args.id ?? args.ids, args.attributes); } private async saveEntityOrEntitiesFromVerbArgs( - args: Record + args: Record, ): Promise> { return await this.save(args.entity ?? args.entities); } private async destroyEntityOrEntitiesFromVerbArgs( - args: Record + args: Record, ): Promise> { return await this.destroy(args.entity ?? args.entities); } private async countAndWrapValueFromVerbArgs( - args: Record + args: Record, ): Promise { const count = await this.count(args); return { [SKL_ENGINE.countResult]: { - "@value": count, - "@type": XSD.integer, + '@value': count, + '@type': XSD.integer, }, }; } private async existsAndWrapValueFromVerbArgs( - args: Record + args: Record, ): Promise { const exists = await this.exists(args); return { [SKL_ENGINE.existsResult]: { - "@value": exists, - "@type": XSD.boolean, + '@value': exists, + '@type': XSD.boolean, }, }; } @@ -816,7 +816,7 @@ export class SKLEngine { private async findAndExecuteVerb( verbId: string, args: Record, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const verb = (await this.findBy({ id: verbId })) as Verb; return await this.executeVerb(verb, args, verbConfig); @@ -825,23 +825,23 @@ export class SKLEngine { private async executeParallelMapping( mapping: MappingWithParallel, args: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const parallelVerbMappings = ensureArray( - mapping[SKL.parallel] as unknown as OrArray + mapping[SKL.parallel] as unknown as OrArray, ); const nestedReturnValues = await Promise.all>>( parallelVerbMappings.map( (verbMapping): Promise> => - this.executeMapping(verbMapping, args, verbConfig) - ) + this.executeMapping(verbMapping, args, verbConfig), + ), ); return nestedReturnValues.flat(); } private async findVerbIntegrationMapping( verbId: string, - integrationId: string + integrationId: string, ): Promise { return (await this.findByIfExists({ type: SKL.VerbIntegrationMapping, @@ -853,7 +853,7 @@ export class SKLEngine { private async performOperationMappingWithArgs( args: JSONValue, mapping: Mapping, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { if (mapping[SKL.operationId]) { return { [SKL.operationId]: mapping[SKL.operationId] }; @@ -865,7 +865,7 @@ export class SKLEngine { args, mapping[SKL.operationMapping] as OrArray, undefined, - verbConfig + verbConfig, ); } @@ -875,43 +875,43 @@ export class SKLEngine { originalArgs: JSONObject, account: Entity, verbConfig?: VerbConfig, - securityCredentials?: Entity + securityCredentials?: Entity, ): Promise { if (operationInfo[SKL.schemeName]) { return await this.performOauthSecuritySchemeStageWithCredentials( operationInfo, operationArgs, account, - securityCredentials + securityCredentials, ); } if (operationInfo[SKL.dataSource]) { return await this.getDataFromDataSource( getIdFromNodeObjectIfDefined( - operationInfo[SKL.dataSource] as string | ReferenceNodeObject + operationInfo[SKL.dataSource] as string | ReferenceNodeObject, )!, - verbConfig + verbConfig, ); } if (operationInfo[SKL.operationId]) { const response = await this.performOpenapiOperationWithCredentials( getValueIfDefined(operationInfo[SKL.operationId])!, operationArgs, - account + account, ); return this.axiosResponseAndParamsToOperationResponse( response, operationArgs, - originalArgs + originalArgs, ); } - throw new Error("Operation not supported."); + throw new Error('Operation not supported.'); } private axiosResponseAndParamsToOperationResponse( response: AxiosResponse, operationParameters: JSONObject, - originalArgs: JSONObject + originalArgs: JSONObject, ): OperationResponse { const responseMapping = { operationParameters, @@ -933,14 +933,14 @@ export class SKLEngine { private async performReturnValueMappingWithFrameIfDefined( returnValue: JSONValue, mapping: MappingWithReturnValueMapping, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { if (SKL.returnValueMapping in mapping) { return await this.performMapping( returnValue, mapping[SKL.returnValueMapping], getValueIfDefined(mapping[SKL.returnValueFrame]), - verbConfig + verbConfig, ); } return returnValue as NodeObject; @@ -949,14 +949,14 @@ export class SKLEngine { private async performParameterMappingOnArgsIfDefined( args: JSONObject, mapping: - | Partial - | Partial, + | Partial + | Partial, verbConfig?: VerbConfig, - convertToJsonDeep = false + convertToJsonDeep = false, ): Promise> { if (SKL.parameterReference in mapping) { const reference = getValueIfDefined( - mapping[SKL.parameterReference] + mapping[SKL.parameterReference], )!; return this.getDataAtReference(reference, args); } @@ -965,7 +965,7 @@ export class SKLEngine { args, (mapping as MappingWithParameterMapping)[SKL.parameterMapping]!, getValueIfDefined(mapping[SKL.parameterMappingFrame]), - verbConfig + verbConfig, ); return toJSON(mappedData, convertToJsonDeep); } @@ -976,26 +976,26 @@ export class SKLEngine { const results = JSONPath({ path: reference, json: data, - resultType: "value", + resultType: 'value', }); const isArrayOfLengthOne = Array.isArray(results) && results.length === 1; return isArrayOfLengthOne ? results[0] : results; } private async getOpenApiDescriptionForIntegration( - integrationId: string + integrationId: string, ): Promise { const openApiDescriptionSchema = await this.findBy({ type: SKL.OpenApiDescription, [SKL.integration]: integrationId, }); return getValueIfDefined( - openApiDescriptionSchema[SKL.openApiDescription] + openApiDescriptionSchema[SKL.openApiDescription], )!; } private async findSecurityCredentialsForAccountIfDefined( - accountId: string + accountId: string, ): Promise { return await this.findByIfExists({ type: SKL.SecurityCredentials, @@ -1004,7 +1004,7 @@ export class SKLEngine { } private async createOpenApiOperationExecutorWithSpec( - openApiDescription: OpenApi + openApiDescription: OpenApi, ): Promise { const executor = new OpenApiOperationExecutor(); await executor.setOpenapiSpec(openApiDescription); @@ -1013,7 +1013,7 @@ export class SKLEngine { private async findVerbNounMapping( verbId: string, - noun: string + noun: string, ): Promise { return (await this.findByIfExists({ type: SKL.VerbNounMapping, @@ -1028,7 +1028,7 @@ export class SKLEngine { private async performVerbMappingWithArgs( args: JSONValue, mapping: Mapping, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { if (mapping[SKL.verbId]) { return getValueIfDefined(mapping[SKL.verbId])!; @@ -1037,42 +1037,42 @@ export class SKLEngine { args, mapping[SKL.verbMapping] as NodeObject, undefined, - verbConfig + verbConfig, ); return getValueIfDefined(verbInfoJsonLd[SKL.verbId])!; } private async assertVerbParamsMatchParameterSchemas( verbParams: any, - verb: Verb + verb: Verb, ): Promise { let parametersSchemaObject = verb[SKL.parameters]; if ( - parametersSchemaObject?.["@id"] && + parametersSchemaObject?.['@id'] && Object.keys(parametersSchemaObject).length === 1 ) { parametersSchemaObject = await this.findBy({ - id: parametersSchemaObject["@id"], + id: parametersSchemaObject['@id'], }); } if (verbParams && parametersSchemaObject) { const verbParamsAsJsonLd = { - "@context": getValueIfDefined( - verb[SKL.parametersContext] + '@context': getValueIfDefined( + verb[SKL.parametersContext], ), - "@type": SKL.Parameters, + '@type': SKL.Parameters, ...verbParams, }; const report = await this.convertToQuadsAndValidateAgainstShape( verbParamsAsJsonLd, - parametersSchemaObject + parametersSchemaObject, ); if (!report.conforms) { this.throwValidationReportError( report, `${getValueIfDefined( - verb[RDFS.label] - )} parameters do not conform to the schema` + verb[RDFS.label], + )} parameters do not conform to the schema`, ); } } @@ -1081,52 +1081,52 @@ export class SKLEngine { private async performOpenapiOperationWithCredentials( operationId: string, operationArgs: JSONObject, - account: Entity + account: Entity, ): Promise { const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ - "@id" + '@id' ]; const openApiDescription = await this.getOpenApiDescriptionForIntegration( - integrationId + integrationId, ); const openApiExecutor = await this.createOpenApiOperationExecutorWithSpec( - openApiDescription + openApiDescription, ); const securityCredentials = - await this.findSecurityCredentialsForAccountIfDefined(account["@id"]); + await this.findSecurityCredentialsForAccountIfDefined(account['@id']); - Logger.getInstance().log("Security Credentials", securityCredentials); + Logger.getInstance().log('Security Credentials', securityCredentials); const configuration = { accessToken: getValueIfDefined( - securityCredentials?.[SKL.accessToken] + securityCredentials?.[SKL.accessToken], ), bearerToken: getValueIfDefined( - securityCredentials?.[SKL.bearerToken] + securityCredentials?.[SKL.bearerToken], ), apiKey: getValueIfDefined(securityCredentials?.[SKL.apiKey]), basePath: getValueIfDefined(account[SKL.overrideBasePath]), username: getValueIfDefined(securityCredentials?.[SKL.clientId]), password: getValueIfDefined( - securityCredentials?.[SKL.clientSecret] + securityCredentials?.[SKL.clientSecret], ), }; const response = await openApiExecutor .executeOperation(operationId, configuration, operationArgs) - .catch(async (error: Error | AxiosError): Promise => { + .catch(async(error: Error | AxiosError): Promise => { if ( axios.isAxiosError(error) && - (await this.isInvalidTokenError(error, integrationId)) && + await this.isInvalidTokenError(error, integrationId) && securityCredentials ) { const refreshedConfiguration = await this.refreshSecurityCredentials( securityCredentials, integrationId, - account + account, ); return await openApiExecutor.executeOperation( operationId, refreshedConfiguration, - operationArgs + operationArgs, ); } throw error; @@ -1136,7 +1136,7 @@ export class SKLEngine { private async isInvalidTokenError( error: AxiosError, - integrationId: string + integrationId: string, ): Promise { const integration = await this.findBy({ id: integrationId }); const errorMatcher = integration[ @@ -1145,12 +1145,12 @@ export class SKLEngine { const errorMatcherStatus = errorMatcher && getValueIfDefined( - errorMatcher[SKL.invalidTokenErrorMatcherStatus] + errorMatcher[SKL.invalidTokenErrorMatcherStatus], ); const errorMatcherRegex = errorMatcher && getValueIfDefined( - errorMatcher[SKL.invalidTokenErrorMatcherMessageRegex] + errorMatcher[SKL.invalidTokenErrorMatcherMessageRegex], )!; if (errorMatcher && error.response?.status === errorMatcherStatus) { if (!errorMatcherRegex) { @@ -1158,7 +1158,7 @@ export class SKLEngine { } if ( error.response?.statusText && - new RegExp(errorMatcherRegex, "u").test(error.response?.statusText) + new RegExp(errorMatcherRegex, 'u').test(error.response?.statusText) ) { return true; } @@ -1171,39 +1171,39 @@ export class SKLEngine { securityCredentials: Entity, integrationId: string, account: Entity, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const getOauthTokenVerb = (await this.findBy({ type: SKL.Verb, - [RDFS.label]: "getOauthTokens", + [RDFS.label]: 'getOauthTokens', })) as Verb; const mapping = await this.findVerbIntegrationMapping( - getOauthTokenVerb["@id"], - integrationId + getOauthTokenVerb['@id'], + integrationId, ); if (!mapping) { throw new Error( - `No mapping found for verb ${getOauthTokenVerb["@id"]} and integration ${integrationId}` + `No mapping found for verb ${getOauthTokenVerb['@id']} and integration ${integrationId}`, ); } const args = { refreshToken: getValueIfDefined( - securityCredentials[SKL.refreshToken] + securityCredentials[SKL.refreshToken], )!, jwtBearerOptions: getValueIfDefined( - securityCredentials[SKL.jwtBearerOptions] + securityCredentials[SKL.jwtBearerOptions], )!, }; const operationArgs = await this.performParameterMappingOnArgsIfDefined( args, mapping, verbConfig, - true + true, ); const operationInfoJsonLd = await this.performOperationMappingWithArgs( {}, mapping, - verbConfig + verbConfig, ); const rawReturnValue = await this.performOperation( operationInfoJsonLd, @@ -1211,26 +1211,26 @@ export class SKLEngine { args, account, verbConfig, - securityCredentials + securityCredentials, ); const mappedReturnValue = await this.performReturnValueMappingWithFrameIfDefined( rawReturnValue, mapping as MappingWithReturnValueMapping, - verbConfig + verbConfig, ); await this.assertVerbReturnValueMatchesReturnTypeSchema( mappedReturnValue, - getOauthTokenVerb + getOauthTokenVerb, ); const bearerToken = getValueIfDefined( - mappedReturnValue[SKL.bearerToken] + mappedReturnValue[SKL.bearerToken], ); const accessToken = getValueIfDefined( - mappedReturnValue[SKL.accessToken] + mappedReturnValue[SKL.accessToken], ); const refreshToken = getValueIfDefined( - mappedReturnValue[SKL.refreshToken] + mappedReturnValue[SKL.refreshToken], ); if (bearerToken) { securityCredentials[SKL.bearerToken] = bearerToken; @@ -1246,66 +1246,66 @@ export class SKLEngine { } private getOauthConfigurationFromSecurityCredentials( - securityCredentialsSchema: Entity + securityCredentialsSchema: Entity, ): OpenApiClientConfiguration { const username = getValueIfDefined( - securityCredentialsSchema[SKL.clientId] + securityCredentialsSchema[SKL.clientId], ); const password = getValueIfDefined( - securityCredentialsSchema[SKL.clientSecret] + securityCredentialsSchema[SKL.clientSecret], ); const accessToken = getValueIfDefined( - securityCredentialsSchema[SKL.accessToken] + securityCredentialsSchema[SKL.accessToken], ); return { username, password, accessToken }; } private async assertVerbReturnValueMatchesReturnTypeSchema( returnValue: OrArray, - verb: Verb + verb: Verb, ): Promise { let returnTypeSchemaObject = verb[SKL.returnValue]; if ( - returnTypeSchemaObject?.["@id"] && + returnTypeSchemaObject?.['@id'] && Object.keys(returnTypeSchemaObject).length === 1 ) { returnTypeSchemaObject = await this.findBy({ - id: returnTypeSchemaObject["@id"], + id: returnTypeSchemaObject['@id'], }); } let report: ValidationReport | undefined; if (returnValue && returnTypeSchemaObject) { if (Array.isArray(returnValue)) { - if (returnValue.some((valueItem): boolean => "@id" in valueItem)) { + if (returnValue.some((valueItem): boolean => '@id' in valueItem)) { returnTypeSchemaObject[SHACL.targetNode] = returnValue.reduce( ( nodes: ReferenceNodeObject[], - returnValueItem + returnValueItem, ): ReferenceNodeObject[] => { - if (returnValueItem["@id"]) { - nodes.push({ "@id": returnValueItem["@id"] }); + if (returnValueItem['@id']) { + nodes.push({ '@id': returnValueItem['@id'] }); } return nodes; }, - [] + [], ); } else { const targetClasses = returnValue.reduce( ( nodes: ReferenceNodeObject[], - returnValueItem + returnValueItem, ): ReferenceNodeObject[] => { - if (returnValueItem["@type"]) { - const type = Array.isArray(returnValueItem["@type"]) - ? returnValueItem["@type"][0] - : returnValueItem["@type"]; - if (!nodes.includes({ "@id": type })) { - nodes.push({ "@id": type }); + if (returnValueItem['@type']) { + const type = Array.isArray(returnValueItem['@type']) + ? returnValueItem['@type'][0] + : returnValueItem['@type']; + if (!nodes.includes({ '@id': type })) { + nodes.push({ '@id': type }); } } return nodes; }, - [] + [], ); if (targetClasses.length > 0) { returnTypeSchemaObject[SHACL.targetClass] = targetClasses; @@ -1313,23 +1313,23 @@ export class SKLEngine { } report = await this.convertToQuadsAndValidateAgainstShape( returnValue, - returnTypeSchemaObject + returnTypeSchemaObject, ); } else if (Object.keys(returnValue).length > 0) { - if (returnValue["@id"]) { + if (returnValue['@id']) { returnTypeSchemaObject[SHACL.targetNode] = { - "@id": returnValue["@id"], + '@id': returnValue['@id'], }; - } else if (returnValue["@type"]) { + } else if (returnValue['@type']) { returnTypeSchemaObject[SHACL.targetClass] = { - "@id": Array.isArray(returnValue["@type"]) - ? returnValue["@type"][0] - : returnValue["@type"]!, + '@id': Array.isArray(returnValue['@type']) + ? returnValue['@type'][0] + : returnValue['@type']!, }; } report = await this.convertToQuadsAndValidateAgainstShape( returnValue, - returnTypeSchemaObject + returnTypeSchemaObject, ); } } @@ -1337,18 +1337,18 @@ export class SKLEngine { if (report && !report?.conforms) { throw new Error( `Return value ${ - Array.isArray(returnValue) ? "array" : returnValue["@id"] - } does not conform to the schema` + Array.isArray(returnValue) ? 'array' : returnValue['@id'] + } does not conform to the schema`, ); } } private async convertToQuadsAndValidateAgainstShape( value: OrArray, - shape: NodeObject + shape: NodeObject, ): Promise { const valueAsQuads = await convertJsonLdToQuads( - Array.isArray(value) ? value : [value] + Array.isArray(value) ? value : [ value ], ); const shapeQuads = await convertJsonLdToQuads(shape); const validator = new SHACLValidator(shapeQuads); @@ -1359,37 +1359,37 @@ export class SKLEngine { operationInfo: NodeObject, operationParameters: JSONObject, account: Entity, - securityCredentials?: Entity + securityCredentials?: Entity, ): Promise { const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ - "@id" + '@id' ]; const openApiDescription = await this.getOpenApiDescriptionForIntegration( - integrationId + integrationId, ); securityCredentials ||= - await this.findSecurityCredentialsForAccountIfDefined(account["@id"]); + await this.findSecurityCredentialsForAccountIfDefined(account['@id']); let configuration: OpenApiClientConfiguration; if (securityCredentials) { configuration = this.getOauthConfigurationFromSecurityCredentials(securityCredentials); operationParameters.client_id = getValueIfDefined( - securityCredentials[SKL.clientId] + securityCredentials[SKL.clientId], )!; } else { configuration = {}; } const openApiExecutor = await this.createOpenApiOperationExecutorWithSpec( - openApiDescription + openApiDescription, ); const response = await openApiExecutor.executeSecuritySchemeStage( getValueIfDefined(operationInfo[SKL.schemeName])!, getValueIfDefined(operationInfo[SKL.oauthFlow])!, getValueIfDefined(operationInfo[SKL.stage])!, configuration, - operationParameters + operationParameters, ); - if ("codeVerifier" in response && "authorizationUrl" in response) { + if ('codeVerifier' in response && 'authorizationUrl' in response) { return { data: response as unknown as JSONObject, operationParameters, @@ -1398,25 +1398,25 @@ export class SKLEngine { return this.axiosResponseAndParamsToOperationResponse( response, operationParameters, - operationParameters + operationParameters, ); } private async getDataFromDataSource( dataSourceId: string, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const dataSource = await this.findBy({ id: dataSourceId }); - if (dataSource["@type"] === SKL.JsonDataSource) { + if (dataSource['@type'] === SKL.JsonDataSource) { const data = this.getDataFromJsonDataSource(dataSource, verbConfig); - return { data, operationParameters: {} }; + return { data, operationParameters: {}}; } - throw new Error(`DataSource type ${dataSource["@type"]} is not supported.`); + throw new Error(`DataSource type ${dataSource['@type']} is not supported.`); } private getDataFromJsonDataSource( dataSource: NodeObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): JSONObject { if (dataSource[SKL.source]) { const sourceValue = getValueIfDefined(dataSource[SKL.source])!; @@ -1427,7 +1427,7 @@ export class SKLEngine { private getJsonDataFromSource( source: string, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): JSONObject { const inputFiles = { ...this.inputFiles, @@ -1435,7 +1435,7 @@ export class SKLEngine { }; if (source in inputFiles) { const file = inputFiles[source]; - if (typeof file === "string") { + if (typeof file === 'string') { return JSON.parse(file); } return file; @@ -1447,10 +1447,10 @@ export class SKLEngine { private throwValidationReportError( report: ValidationReport, - errorMessage: string + errorMessage: string, ): void { const reportMessages = this.validationReportToMessages(report); - throw new Error(`${errorMessage}\n\n${reportMessages.join("\n")}`); + throw new Error(`${errorMessage}\n\n${reportMessages.join('\n')}`); } private validationReportToMessages(report: ValidationReport): string[] { @@ -1463,7 +1463,7 @@ export class SKLEngine { } else { const resultMessages = result.message .map((message): string => `${message.value}`) - .join(", "); + .join(', '); const message = `${pathValue}: ${resultMessages}`; reportMessages.push(message); } diff --git a/src/index.ts b/src/index.ts index 5c89bbc..ba52e45 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ export * from './storage/operator/Exists'; export * from './storage/operator/GreaterThan'; export * from './storage/operator/GreaterThanOrEqual'; export * from './storage/operator/In'; +export * from './storage/operator/Contains'; export * from './storage/operator/Inverse'; export * from './storage/operator/InversePath'; export * from './storage/operator/InverseRelation'; diff --git a/src/storage/FindOperator.ts b/src/storage/FindOperator.ts index 484ce5a..641ca54 100644 --- a/src/storage/FindOperator.ts +++ b/src/storage/FindOperator.ts @@ -13,7 +13,8 @@ export type FindOperatorType = | 'sequencePath' | 'zeroOrMorePath' | 'inversePath' -| 'oneOrMorePath'; +| 'oneOrMorePath' +| 'contains'; export interface FindOperatorArgs { operator: TType; diff --git a/src/storage/FindOptionsTypes.ts b/src/storage/FindOptionsTypes.ts index 0881fae..c99fc07 100644 --- a/src/storage/FindOptionsTypes.ts +++ b/src/storage/FindOptionsTypes.ts @@ -60,11 +60,11 @@ export type FindOptionsWhereField = export type IdFindOptionsWhereField = | string -| FindOperator; +| FindOperator; export type TypeFindOptionsWhereField = | string -| FindOperator; +| FindOperator; export interface FindOptionsWhere { type?: TypeFindOptionsWhereField; diff --git a/src/storage/operator/Contains.ts b/src/storage/operator/Contains.ts new file mode 100644 index 0000000..5b24582 --- /dev/null +++ b/src/storage/operator/Contains.ts @@ -0,0 +1,11 @@ +import { FindOperator } from '../FindOperator'; + +// Definition for the Contains function +// eslint-disable-next-line @typescript-eslint/naming-convention +export function Contains(value: string): FindOperator { + return new FindOperator({ + operator: 'contains', + value, + }); +} + diff --git a/src/storage/query-adapter/sparql/SparqlQueryBuilder.ts b/src/storage/query-adapter/sparql/SparqlQueryBuilder.ts index 2fb4ce0..db02299 100644 --- a/src/storage/query-adapter/sparql/SparqlQueryBuilder.ts +++ b/src/storage/query-adapter/sparql/SparqlQueryBuilder.ts @@ -40,6 +40,8 @@ import { createSparqlZeroOrMorePredicate, createSparqlOneOrMorePredicate, createSparqlExistsOperation, + createSparqlContainsOperation, + createSparqlLcaseOperation, } from '../../../util/SparqlUtil'; import { valueToLiteral, @@ -222,6 +224,7 @@ export class SparqlQueryBuilder { filters: [ ...obj.filters, ...whereQueryDataForField.filters ], }; }, { values: [], triples: [], filters: []}); + return { ...whereQueryData, graphValues: [], @@ -536,6 +539,18 @@ export class SparqlQueryBuilder { tripleInFilter: true, }; } + + if (operator.operator === 'contains') { + const searchString = this.resolveValueToExpression(operator.value) as Literal; + const filter = createSparqlContainsOperation( + // Directly use the variable as an expression + createSparqlLcaseOperation(DataFactory.variable(leftSide.value)), + createSparqlLcaseOperation(DataFactory.literal(searchString.value.toLowerCase())), + ); + return { + filter, + }; + } const resolvedExpression = this.resolveValueToExpression(operator.value) as Expression; switch (operator.operator) { case 'equal': diff --git a/src/util/SparqlUtil.ts b/src/util/SparqlUtil.ts index cbd798b..dfe9b58 100644 --- a/src/util/SparqlUtil.ts +++ b/src/util/SparqlUtil.ts @@ -267,6 +267,14 @@ export function createFilterPatternFromFilters(filters: Expression[]): FilterPat return createSparqlFilterWithExpression(filters[0]); } +export function createSparqlLcaseOperation(expression: Expression): OperationExpression { + return { + type: 'operation', + operator: 'lcase', + args: [ expression ], + }; +} + export function createSparqlEqualOperation(leftSide: Expression, rightSide: Expression): OperationExpression { return { type: 'operation', @@ -323,6 +331,14 @@ export function createSparqlInOperation(leftSide: Expression, rightSide: Express }; } +export function createSparqlContainsOperation(leftSide: Expression, rightSide: Expression): OperationExpression { + return { + type: 'operation', + operator: 'contains', + args: [ leftSide, rightSide ], + }; +} + export function createSparqlNotInOperation(leftSide: Expression, rightSide: Expression): OperationExpression { return { type: 'operation', From c1dff4be568f24b778d15e037e311a3d14de20a0 Mon Sep 17 00:00:00 2001 From: Avneesh Raghav Date: Tue, 4 Jun 2024 21:05:19 +0530 Subject: [PATCH 4/4] Formatting restored --- package.json | 2 +- src/SklEngine.ts | 528 ++++++++++++++++++++-------------------- src/SklEngineOptions.ts | 4 +- src/logger.ts | 3 +- src/mapping/Mapper.ts | 32 +-- src/util/Util.ts | 52 ++-- 6 files changed, 311 insertions(+), 310 deletions(-) diff --git a/package.json b/package.json index 069acef..cfec810 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "test:integration": "jest --coverageReporters text-summary -- test/integration", "test:unit": "jest --config=./jest.coverage.config.js test/unit", "test:package": "chmod +x test/deploy/validate-package.sh && test/deploy/validate-package.sh", - "prepare": "npm run build" + "prepare": "husky && npm run build" }, "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/src/SklEngine.ts b/src/SklEngine.ts index 728fa74..78b0281 100644 --- a/src/SklEngine.ts +++ b/src/SklEngine.ts @@ -2,39 +2,40 @@ import type { OpenApi, OpenApiClientConfiguration, -} from "@comake/openapi-operation-executor"; -import { OpenApiOperationExecutor } from "@comake/openapi-operation-executor"; +} from '@comake/openapi-operation-executor'; +import { OpenApiOperationExecutor } from '@comake/openapi-operation-executor'; import { getIdFromNodeObjectIfDefined, type ReferenceNodeObject, -} from "@comake/rmlmapper-js"; -import axios from "axios"; -import type { AxiosError, AxiosResponse } from "axios"; -import type { ContextDefinition, GraphObject, NodeObject } from "jsonld"; -import type { Frame } from "jsonld/jsonld-spec"; -import { JSONPath } from "jsonpath-plus"; -import SHACLValidator from "rdf-validate-shacl"; -import type ValidationReport from "rdf-validate-shacl/src/validation-report"; -import { Mapper } from "./mapping/Mapper"; -import type { SklEngineOptions } from "./SklEngineOptions"; -import type { FindOperator } from "./storage/FindOperator"; +} from '@comake/rmlmapper-js'; +import axios from 'axios'; +import type { AxiosError, AxiosResponse } from 'axios'; +import type { ContextDefinition, GraphObject, NodeObject } from 'jsonld'; +import type { Frame } from 'jsonld/jsonld-spec'; +import { JSONPath } from 'jsonpath-plus'; +import SHACLValidator from 'rdf-validate-shacl'; +import type ValidationReport from 'rdf-validate-shacl/src/validation-report'; +import { Logger } from './logger'; +import { Mapper } from './mapping/Mapper'; +import type { SklEngineOptions } from './SklEngineOptions'; +import type { FindOperator } from './storage/FindOperator'; import type { FindAllOptions, FindOneOptions, FindOptionsWhere, -} from "./storage/FindOptionsTypes"; -import { Exists } from "./storage/operator/Exists"; -import { In } from "./storage/operator/In"; -import { InversePath } from "./storage/operator/InversePath"; -import { Not } from "./storage/operator/Not"; -import { OneOrMorePath } from "./storage/operator/OneOrMorePath"; -import { SequencePath } from "./storage/operator/SequencePath"; -import { ZeroOrMorePath } from "./storage/operator/ZeroOrMorePath"; +} from './storage/FindOptionsTypes'; +import { Exists } from './storage/operator/Exists'; +import { In } from './storage/operator/In'; +import { InversePath } from './storage/operator/InversePath'; +import { Not } from './storage/operator/Not'; +import { OneOrMorePath } from './storage/operator/OneOrMorePath'; +import { SequencePath } from './storage/operator/SequencePath'; +import { ZeroOrMorePath } from './storage/operator/ZeroOrMorePath'; import type { QueryAdapter, RawQueryResult, -} from "./storage/query-adapter/QueryAdapter"; -import { SparqlQueryAdapter } from "./storage/query-adapter/sparql/SparqlQueryAdapter"; +} from './storage/query-adapter/QueryAdapter'; +import { SparqlQueryAdapter } from './storage/query-adapter/sparql/SparqlQueryAdapter'; import type { Callbacks, OrArray, @@ -54,15 +55,14 @@ import type { MappingWithSeries, MappingWithParallel, JSONValue, -} from "./util/Types"; +} from './util/Types'; import { convertJsonLdToQuads, toJSON, getValueIfDefined, ensureArray, -} from "./util/Util"; -import { SKL, SHACL, RDFS, SKL_ENGINE, XSD, RDF } from "./util/Vocabularies"; -import { Logger } from "./logger"; +} from './util/Util'; +import { SKL, SHACL, RDFS, SKL_ENGINE, XSD, RDF } from './util/Vocabularies'; export type VerbHandler = = OrArray>( params: JSONObject, @@ -95,16 +95,16 @@ export class SKLEngine { // eslint-disable-next-line func-style const getVerbHandler = (getTarget: VerbInterface, property: string): VerbHandler => - async = OrArray>( - verbArgs: JSONObject, - verbConfig?: VerbConfig - ): Promise => - this.executeVerbByName(property, verbArgs, verbConfig) as Promise; + async = OrArray>( + verbArgs: JSONObject, + verbConfig?: VerbConfig, + ): Promise => + this.executeVerbByName(property, verbArgs, verbConfig) as Promise; this.verb = new Proxy({} as VerbInterface, { get: getVerbHandler }); } public async executeRawQuery( - query: string + query: string, ): Promise { return await this.queryAdapter.executeRawQuery(query); } @@ -115,7 +115,7 @@ export class SKLEngine { public async executeRawConstructQuery( query: string, - frame?: Frame + frame?: Frame, ): Promise { return await this.queryAdapter.executeRawConstructQuery(query, frame); } @@ -126,13 +126,13 @@ export class SKLEngine { return entity; } throw new Error( - `No schema found with fields matching ${JSON.stringify(options)}` + `No schema found with fields matching ${JSON.stringify(options)}`, ); } public async findBy( where: FindOptionsWhere, - notFoundErrorMessage?: string + notFoundErrorMessage?: string, ): Promise { const entity = await this.queryAdapter.findBy(where); if (entity) { @@ -140,12 +140,12 @@ export class SKLEngine { } throw new Error( notFoundErrorMessage ?? - `No schema found with fields matching ${JSON.stringify(where)}` + `No schema found with fields matching ${JSON.stringify(where)}`, ); } public async findByIfExists( - options: FindOptionsWhere + options: FindOptionsWhere, ): Promise { try { const entity = await this.findBy(options); @@ -174,7 +174,7 @@ export class SKLEngine { public async save(entity: Entity): Promise; public async save(entities: Entity[]): Promise; public async save( - entityOrEntities: Entity | Entity[] + entityOrEntities: Entity | Entity[], ): Promise { if (Array.isArray(entityOrEntities)) { await this.validateEntitiesConformToNounSchema(entityOrEntities); @@ -192,46 +192,46 @@ export class SKLEngine { public async update( idOrIds: string | string[], - attributes: Partial + attributes: Partial, ): Promise { if (Array.isArray(idOrIds)) { await this.validateEntitiesWithIdsConformsToNounSchemaForAttributes( idOrIds, - attributes + attributes, ); return await this.queryAdapter.update(idOrIds, attributes); } await this.validateEntityWithIdConformsToNounSchemaForAttributes( idOrIds, - attributes + attributes, ); return await this.queryAdapter.update(idOrIds, attributes); } private async validateEntitiesConformToNounSchema( - entities: Entity[] + entities: Entity[], ): Promise { const entitiesByType = this.groupEntitiesByType(entities); for (const type of Object.keys(entitiesByType)) { const noun = await this.findByIfExists({ id: type }); if (noun) { const parentNouns = await this.getSuperClassesOfNoun(type); - for (const currentNoun of [noun, ...parentNouns]) { + for (const currentNoun of [ noun, ...parentNouns ]) { const entitiesOfType = entitiesByType[type]; const nounSchemaWithTarget = { ...currentNoun, [SHACL.targetNode]: entitiesOfType.map( - (entity): ReferenceNodeObject => ({ "@id": entity["@id"] }) + (entity): ReferenceNodeObject => ({ '@id': entity['@id'] }), ), }; const report = await this.convertToQuadsAndValidateAgainstShape( entitiesOfType, - nounSchemaWithTarget + nounSchemaWithTarget, ); if (!report.conforms) { this.throwValidationReportError( report, - `An entity does not conform to the ${currentNoun["@id"]} schema.` + `An entity does not conform to the ${currentNoun['@id']} schema.`, ); } } @@ -243,11 +243,11 @@ export class SKLEngine { return entities.reduce( ( groupedEntities: Record, - entity + entity, ): Record => { - const entityTypes = Array.isArray(entity["@type"]) - ? entity["@type"] - : [entity["@type"]]; + const entityTypes = Array.isArray(entity['@type']) + ? entity['@type'] + : [ entity['@type'] ]; for (const type of entityTypes) { if (!groupedEntities[type]) { groupedEntities[type] = []; @@ -256,7 +256,7 @@ export class SKLEngine { } return groupedEntities; }, - {} + {}, ); } @@ -269,7 +269,7 @@ export class SKLEngine { } private async getParentsOfSelector( - selector: string | FindOperator + selector: string | FindOperator, ): Promise { return await this.findAll({ where: { @@ -282,28 +282,28 @@ export class SKLEngine { } private async validateEntityConformsToNounSchema( - entity: Entity + entity: Entity, ): Promise { - const nounIds = Array.isArray(entity["@type"]) - ? entity["@type"] - : [entity["@type"]]; + const nounIds = Array.isArray(entity['@type']) + ? entity['@type'] + : [ entity['@type'] ]; const directNouns = await this.findAllBy({ id: In(nounIds) }); if (directNouns.length > 0) { - const existingNounIds = directNouns.map((noun): string => noun["@id"]); + const existingNounIds = directNouns.map((noun): string => noun['@id']); const parentNouns = await this.getSuperClassesOfNouns(existingNounIds); - for (const currentNoun of [...directNouns, ...parentNouns]) { + for (const currentNoun of [ ...directNouns, ...parentNouns ]) { const nounSchemaWithTarget = { ...currentNoun, - [SHACL.targetNode]: { "@id": entity["@id"] }, + [SHACL.targetNode]: { '@id': entity['@id'] }, }; const report = await this.convertToQuadsAndValidateAgainstShape( entity, - nounSchemaWithTarget + nounSchemaWithTarget, ); if (!report.conforms) { this.throwValidationReportError( report, - `Entity ${entity["@id"]} does not conform to the ${currentNoun["@id"]} schema.` + `Entity ${entity['@id']} does not conform to the ${currentNoun['@id']} schema.`, ); } } @@ -312,12 +312,12 @@ export class SKLEngine { private async validateEntitiesWithIdsConformsToNounSchemaForAttributes( ids: string[], - attributes: Partial + attributes: Partial, ): Promise { for (const id of ids) { await this.validateEntityWithIdConformsToNounSchemaForAttributes( id, - attributes + attributes, ); } } @@ -338,22 +338,22 @@ export class SKLEngine { private async validateEntityWithIdConformsToNounSchemaForAttributes( id: string, - attributes: Partial + attributes: Partial, ): Promise { const nouns = await this.getNounsAndParentNounsOfEntity(id); for (const currentNoun of nouns) { if (SHACL.property in currentNoun) { const nounProperties = ensureArray( - currentNoun[SHACL.property] as OrArray + currentNoun[SHACL.property] as OrArray, ).filter((property): boolean => { const path = property[SHACL.path]; - if (typeof path === "string" && path in attributes) { + if (typeof path === 'string' && path in attributes) { return true; } if ( - typeof path === "object" && - "@id" in path! && - (path["@id"] as string) in attributes + typeof path === 'object' && + '@id' in path! && + (path['@id'] as string) in attributes ) { return true; } @@ -361,19 +361,19 @@ export class SKLEngine { }); if (nounProperties.length > 0) { const nounSchemaWithTarget = { - "@type": SHACL.NodeShape, - [SHACL.targetNode]: { "@id": id }, + '@type': SHACL.NodeShape, + [SHACL.targetNode]: { '@id': id }, [SHACL.property]: nounProperties, }; - const attributesWithId = { ...attributes, "@id": id }; + const attributesWithId = { ...attributes, '@id': id }; const report = await this.convertToQuadsAndValidateAgainstShape( attributesWithId, - nounSchemaWithTarget + nounSchemaWithTarget, ); if (!report.conforms) { this.throwValidationReportError( report, - `Entity ${id} does not conform to the ${currentNoun["@id"]} schema.` + `Entity ${id} does not conform to the ${currentNoun['@id']} schema.`, ); } } @@ -393,7 +393,7 @@ export class SKLEngine { public async destroy(entity: Entity): Promise; public async destroy(entities: Entity[]): Promise; public async destroy( - entityOrEntities: Entity | Entity[] + entityOrEntities: Entity | Entity[], ): Promise { if (Array.isArray(entityOrEntities)) { return await this.queryAdapter.destroy(entityOrEntities); @@ -409,7 +409,7 @@ export class SKLEngine { args: JSONValue, mapping: OrArray, frame?: Record, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const functions = { ...this.functions, @@ -421,16 +421,16 @@ export class SKLEngine { public async executeTrigger( integration: string, - payload: any + payload: any, ): Promise { const triggerToVerbMapping = await this.findTriggerVerbMapping(integration); const verbArgs = await this.performParameterMappingOnArgsIfDefined( payload, - triggerToVerbMapping + triggerToVerbMapping, ); const verbId = await this.performVerbMappingWithArgs( payload, - triggerToVerbMapping + triggerToVerbMapping, ); if (verbId) { const mappedVerb = (await this.findBy({ id: verbId })) as Verb; @@ -439,21 +439,21 @@ export class SKLEngine { } private async findTriggerVerbMapping( - integration: string + integration: string, ): Promise { return (await this.findBy( { type: SKL.TriggerVerbMapping, [SKL.integration]: integration, }, - `Failed to find a Trigger Verb mapping for integration ${integration}` + `Failed to find a Trigger Verb mapping for integration ${integration}`, )) as TriggerMapping; } private async executeVerbByName( verbName: string, verbArgs: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const verb = await this.findVerbWithName(verbName); return await this.executeVerb(verb, verbArgs, verbConfig); @@ -462,25 +462,25 @@ export class SKLEngine { private async findVerbWithName(verbName: string): Promise { return (await this.findBy( { type: SKL.Verb, [RDFS.label]: verbName }, - `Failed to find the verb ${verbName} in the schema.` + `Failed to find the verb ${verbName} in the schema.`, )) as Verb; } private async executeVerb( verb: Verb, verbArgs: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { - this.globalCallbacks?.onVerbStart?.(verb["@id"], verbArgs); + this.globalCallbacks?.onVerbStart?.(verb['@id'], verbArgs); if (verbConfig?.callbacks?.onVerbStart) { - Logger.getInstance().log("Verb arguments", verbArgs); - verbConfig.callbacks.onVerbStart(verb["@id"], verbArgs); + Logger.getInstance().log('Verb arguments', verbArgs); + verbConfig.callbacks.onVerbStart(verb['@id'], verbArgs); } const { mapping, account } = await this.findMappingForVerbContextually( - verb["@id"], - verbArgs + verb['@id'], + verbArgs, ); - Logger.getInstance().log("Mapping", JSON.stringify(mapping)); + Logger.getInstance().log('Mapping', JSON.stringify(mapping)); const shouldValidate = this.shouldValidate(verbConfig); if (shouldValidate) { await this.assertVerbParamsMatchParameterSchemas(verbArgs, verb); @@ -489,24 +489,24 @@ export class SKLEngine { mapping, verbArgs, verbConfig, - account + account, ); if (shouldValidate) { await this.assertVerbReturnValueMatchesReturnTypeSchema( verbReturnValue, - verb + verb, ); } - this.globalCallbacks?.onVerbEnd?.(verb["@id"], verbReturnValue); + this.globalCallbacks?.onVerbEnd?.(verb['@id'], verbReturnValue); if (verbConfig?.callbacks?.onVerbEnd) { - verbConfig.callbacks.onVerbEnd(verb["@id"], verbReturnValue); + verbConfig.callbacks.onVerbEnd(verb['@id'], verbReturnValue); } return verbReturnValue; } private async findMappingForVerbContextually( verbId: string, - args: JSONObject + args: JSONObject, ): Promise<{ mapping: VerbMapping; account?: Entity }> { if (args.mapping) { const mapping = await this.findByIfExists({ id: args.mapping as string }); @@ -518,7 +518,7 @@ export class SKLEngine { if (args.noun) { const mapping = await this.findVerbNounMapping( verbId, - args.noun as string + args.noun as string, ); if (mapping) { return { mapping }; @@ -527,11 +527,11 @@ export class SKLEngine { if (args.account) { const account = await this.findBy({ id: args.account as string }); const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ - "@id" + '@id' ]; const mapping = await this.findVerbIntegrationMapping( verbId, - integrationId + integrationId, ); if (mapping) { return { mapping, account }; @@ -548,20 +548,20 @@ export class SKLEngine { return { mapping: mappings[0] as VerbMapping }; } if (mappings.length > 1) { - throw new Error("Multiple mappings found for verb, please specify one."); + throw new Error('Multiple mappings found for verb, please specify one.'); } if (args.noun) { throw new Error( `Mapping between noun ${ args.noun as string - } and verb ${verbId} not found.` + } and verb ${verbId} not found.`, ); } if (args.account) { throw new Error( `Mapping between account ${ args.account as string - } and verb ${verbId} not found.` + } and verb ${verbId} not found.`, ); } throw new Error(`No mapping found.`); @@ -571,7 +571,7 @@ export class SKLEngine { mapping: Mapping, args: JSONObject, verbConfig?: VerbConfig, - account?: Entity + account?: Entity, ): Promise> { args = await this.addPreProcessingMappingToArgs(mapping, args, verbConfig); let returnValue: OrArray; @@ -579,46 +579,46 @@ export class SKLEngine { const verbId = await this.performVerbMappingWithArgs( args, mapping, - verbConfig + verbConfig, ); const mappedArgs = await this.performParameterMappingOnArgsIfDefined( { ...args, verbId }, mapping as MappingWithParameterMapping, - verbConfig + verbConfig, ); - Logger.getInstance().log("Mapped args", mappedArgs); + Logger.getInstance().log('Mapped args', mappedArgs); returnValue = await this.executeVerbMapping( mapping, args, mappedArgs, - verbConfig + verbConfig, ); } else { const mappedArgs = await this.performParameterMappingOnArgsIfDefined( args, mapping as MappingWithParameterMapping, - verbConfig + verbConfig, ); - Logger.getInstance().log("Mapped args", mappedArgs); + Logger.getInstance().log('Mapped args', mappedArgs); if (SKL.operationId in mapping || SKL.operationMapping in mapping) { returnValue = (await this.executeOperationMapping( mapping, mappedArgs, args, account!, - verbConfig + verbConfig, )) as NodeObject; } else if (SKL.series in mapping) { returnValue = await this.executeSeriesMapping( mapping as MappingWithSeries, mappedArgs, - verbConfig + verbConfig, ); } else if (SKL.parallel in mapping) { returnValue = await this.executeParallelMapping( mapping as MappingWithParallel, mappedArgs, - verbConfig + verbConfig, ); } else { returnValue = mappedArgs; @@ -627,7 +627,7 @@ export class SKLEngine { return await this.performReturnValueMappingWithFrameIfDefined( returnValue as JSONValue, mapping as MappingWithReturnValueMapping, - verbConfig + verbConfig, ); } @@ -642,29 +642,29 @@ export class SKLEngine { mappedArgs: JSONObject, originalArgs: JSONObject, account: Entity, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const operationInfo = await this.performOperationMappingWithArgs( originalArgs, mapping, - verbConfig + verbConfig, ); const response = await this.performOperation( operationInfo, mappedArgs, originalArgs, account, - verbConfig + verbConfig, ); - Logger.getInstance().log("Original response", JSON.stringify(response)); + Logger.getInstance().log('Original response', JSON.stringify(response)); return response; } private async executeSeriesMapping( mapping: MappingWithSeries, args: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const seriesVerbMappingsList = this.rdfListToArray(mapping[SKL.series]!); const seriesVerbArgs = { @@ -674,42 +674,42 @@ export class SKLEngine { return await this.executeSeriesFromList( seriesVerbMappingsList, seriesVerbArgs, - verbConfig + verbConfig, ); } private rdfListToArray( - list: { "@list": VerbMapping[] } | RdfList + list: { '@list': VerbMapping[] } | RdfList, ): VerbMapping[] { - if (!("@list" in list)) { + if (!('@list' in list)) { return [ list[RDF.first], - ...(getIdFromNodeObjectIfDefined( - list[RDF.rest] as ReferenceNodeObject + ...getIdFromNodeObjectIfDefined( + list[RDF.rest] as ReferenceNodeObject, ) === RDF.nil ? [] - : this.rdfListToArray(list[RDF.rest] as RdfList)), + : this.rdfListToArray(list[RDF.rest] as RdfList), ]; } - return list["@list"]; + return list['@list']; } private async executeSeriesFromList( list: Mapping[], args: SeriesVerbArgs, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const nextVerbMapping = list[0]; const returnValue = await this.executeMapping( nextVerbMapping, args, - verbConfig + verbConfig, ); if (list.length > 1) { return await this.executeSeriesFromList( list.slice(1), { ...args, previousVerbReturnValue: returnValue as JSONObject }, - verbConfig + verbConfig, ); } return returnValue; @@ -719,12 +719,12 @@ export class SKLEngine { verbMapping: Mapping, originalArgs: JSONObject, mappedArgs: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const verbId = await this.performVerbMappingWithArgs( originalArgs, verbMapping, - verbConfig + verbConfig, ); if (verbId) { if (verbId === SKL_ENGINE.update) { @@ -757,14 +757,14 @@ export class SKLEngine { private async addPreProcessingMappingToArgs( verbMapping: Mapping, args: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { if (SKL.preProcessingMapping in verbMapping) { const preMappingArgs = await this.performMapping( args, verbMapping[SKL.preProcessingMapping] as NodeObject, getValueIfDefined(verbMapping[SKL.preProcessingMappingFrame]), - verbConfig + verbConfig, ); return { ...args, preProcessedParameters: preMappingArgs as JSONObject }; } @@ -772,43 +772,43 @@ export class SKLEngine { } private async updateEntityFromVerbArgs( - args: Record + args: Record, ): Promise { await this.update(args.id ?? args.ids, args.attributes); } private async saveEntityOrEntitiesFromVerbArgs( - args: Record + args: Record, ): Promise> { return await this.save(args.entity ?? args.entities); } private async destroyEntityOrEntitiesFromVerbArgs( - args: Record + args: Record, ): Promise> { return await this.destroy(args.entity ?? args.entities); } private async countAndWrapValueFromVerbArgs( - args: Record + args: Record, ): Promise { const count = await this.count(args); return { [SKL_ENGINE.countResult]: { - "@value": count, - "@type": XSD.integer, + '@value': count, + '@type': XSD.integer, }, }; } private async existsAndWrapValueFromVerbArgs( - args: Record + args: Record, ): Promise { const exists = await this.exists(args); return { [SKL_ENGINE.existsResult]: { - "@value": exists, - "@type": XSD.boolean, + '@value': exists, + '@type': XSD.boolean, }, }; } @@ -816,7 +816,7 @@ export class SKLEngine { private async findAndExecuteVerb( verbId: string, args: Record, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise> { const verb = (await this.findBy({ id: verbId })) as Verb; return await this.executeVerb(verb, args, verbConfig); @@ -825,23 +825,23 @@ export class SKLEngine { private async executeParallelMapping( mapping: MappingWithParallel, args: JSONObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const parallelVerbMappings = ensureArray( - mapping[SKL.parallel] as unknown as OrArray + mapping[SKL.parallel] as unknown as OrArray, ); const nestedReturnValues = await Promise.all>>( parallelVerbMappings.map( (verbMapping): Promise> => - this.executeMapping(verbMapping, args, verbConfig) - ) + this.executeMapping(verbMapping, args, verbConfig), + ), ); return nestedReturnValues.flat(); } private async findVerbIntegrationMapping( verbId: string, - integrationId: string + integrationId: string, ): Promise { return (await this.findByIfExists({ type: SKL.VerbIntegrationMapping, @@ -853,7 +853,7 @@ export class SKLEngine { private async performOperationMappingWithArgs( args: JSONValue, mapping: Mapping, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { if (mapping[SKL.operationId]) { return { [SKL.operationId]: mapping[SKL.operationId] }; @@ -865,7 +865,7 @@ export class SKLEngine { args, mapping[SKL.operationMapping] as OrArray, undefined, - verbConfig + verbConfig, ); } @@ -875,43 +875,43 @@ export class SKLEngine { originalArgs: JSONObject, account: Entity, verbConfig?: VerbConfig, - securityCredentials?: Entity + securityCredentials?: Entity, ): Promise { if (operationInfo[SKL.schemeName]) { return await this.performOauthSecuritySchemeStageWithCredentials( operationInfo, operationArgs, account, - securityCredentials + securityCredentials, ); } if (operationInfo[SKL.dataSource]) { return await this.getDataFromDataSource( getIdFromNodeObjectIfDefined( - operationInfo[SKL.dataSource] as string | ReferenceNodeObject + operationInfo[SKL.dataSource] as string | ReferenceNodeObject, )!, - verbConfig + verbConfig, ); } if (operationInfo[SKL.operationId]) { const response = await this.performOpenapiOperationWithCredentials( getValueIfDefined(operationInfo[SKL.operationId])!, operationArgs, - account + account, ); return this.axiosResponseAndParamsToOperationResponse( response, operationArgs, - originalArgs + originalArgs, ); } - throw new Error("Operation not supported."); + throw new Error('Operation not supported.'); } private axiosResponseAndParamsToOperationResponse( response: AxiosResponse, operationParameters: JSONObject, - originalArgs: JSONObject + originalArgs: JSONObject, ): OperationResponse { const responseMapping = { operationParameters, @@ -933,14 +933,14 @@ export class SKLEngine { private async performReturnValueMappingWithFrameIfDefined( returnValue: JSONValue, mapping: MappingWithReturnValueMapping, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { if (SKL.returnValueMapping in mapping) { return await this.performMapping( returnValue, mapping[SKL.returnValueMapping], getValueIfDefined(mapping[SKL.returnValueFrame]), - verbConfig + verbConfig, ); } return returnValue as NodeObject; @@ -949,14 +949,14 @@ export class SKLEngine { private async performParameterMappingOnArgsIfDefined( args: JSONObject, mapping: - | Partial - | Partial, + | Partial + | Partial, verbConfig?: VerbConfig, - convertToJsonDeep = false + convertToJsonDeep = false, ): Promise> { if (SKL.parameterReference in mapping) { const reference = getValueIfDefined( - mapping[SKL.parameterReference] + mapping[SKL.parameterReference], )!; return this.getDataAtReference(reference, args); } @@ -965,7 +965,7 @@ export class SKLEngine { args, (mapping as MappingWithParameterMapping)[SKL.parameterMapping]!, getValueIfDefined(mapping[SKL.parameterMappingFrame]), - verbConfig + verbConfig, ); return toJSON(mappedData, convertToJsonDeep); } @@ -976,26 +976,26 @@ export class SKLEngine { const results = JSONPath({ path: reference, json: data, - resultType: "value", + resultType: 'value', }); const isArrayOfLengthOne = Array.isArray(results) && results.length === 1; return isArrayOfLengthOne ? results[0] : results; } private async getOpenApiDescriptionForIntegration( - integrationId: string + integrationId: string, ): Promise { const openApiDescriptionSchema = await this.findBy({ type: SKL.OpenApiDescription, [SKL.integration]: integrationId, }); return getValueIfDefined( - openApiDescriptionSchema[SKL.openApiDescription] + openApiDescriptionSchema[SKL.openApiDescription], )!; } private async findSecurityCredentialsForAccountIfDefined( - accountId: string + accountId: string, ): Promise { return await this.findByIfExists({ type: SKL.SecurityCredentials, @@ -1004,7 +1004,7 @@ export class SKLEngine { } private async createOpenApiOperationExecutorWithSpec( - openApiDescription: OpenApi + openApiDescription: OpenApi, ): Promise { const executor = new OpenApiOperationExecutor(); await executor.setOpenapiSpec(openApiDescription); @@ -1013,7 +1013,7 @@ export class SKLEngine { private async findVerbNounMapping( verbId: string, - noun: string + noun: string, ): Promise { return (await this.findByIfExists({ type: SKL.VerbNounMapping, @@ -1028,7 +1028,7 @@ export class SKLEngine { private async performVerbMappingWithArgs( args: JSONValue, mapping: Mapping, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { if (mapping[SKL.verbId]) { return getValueIfDefined(mapping[SKL.verbId])!; @@ -1037,42 +1037,42 @@ export class SKLEngine { args, mapping[SKL.verbMapping] as NodeObject, undefined, - verbConfig + verbConfig, ); return getValueIfDefined(verbInfoJsonLd[SKL.verbId])!; } private async assertVerbParamsMatchParameterSchemas( verbParams: any, - verb: Verb + verb: Verb, ): Promise { let parametersSchemaObject = verb[SKL.parameters]; if ( - parametersSchemaObject?.["@id"] && + parametersSchemaObject?.['@id'] && Object.keys(parametersSchemaObject).length === 1 ) { parametersSchemaObject = await this.findBy({ - id: parametersSchemaObject["@id"], + id: parametersSchemaObject['@id'], }); } if (verbParams && parametersSchemaObject) { const verbParamsAsJsonLd = { - "@context": getValueIfDefined( - verb[SKL.parametersContext] + '@context': getValueIfDefined( + verb[SKL.parametersContext], ), - "@type": SKL.Parameters, + '@type': SKL.Parameters, ...verbParams, }; const report = await this.convertToQuadsAndValidateAgainstShape( verbParamsAsJsonLd, - parametersSchemaObject + parametersSchemaObject, ); if (!report.conforms) { this.throwValidationReportError( report, `${getValueIfDefined( - verb[RDFS.label] - )} parameters do not conform to the schema` + verb[RDFS.label], + )} parameters do not conform to the schema`, ); } } @@ -1081,52 +1081,52 @@ export class SKLEngine { private async performOpenapiOperationWithCredentials( operationId: string, operationArgs: JSONObject, - account: Entity + account: Entity, ): Promise { const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ - "@id" + '@id' ]; const openApiDescription = await this.getOpenApiDescriptionForIntegration( - integrationId + integrationId, ); const openApiExecutor = await this.createOpenApiOperationExecutorWithSpec( - openApiDescription + openApiDescription, ); const securityCredentials = - await this.findSecurityCredentialsForAccountIfDefined(account["@id"]); + await this.findSecurityCredentialsForAccountIfDefined(account['@id']); - Logger.getInstance().log("Security Credentials", securityCredentials); + Logger.getInstance().log('Security Credentials', securityCredentials); const configuration = { accessToken: getValueIfDefined( - securityCredentials?.[SKL.accessToken] + securityCredentials?.[SKL.accessToken], ), bearerToken: getValueIfDefined( - securityCredentials?.[SKL.bearerToken] + securityCredentials?.[SKL.bearerToken], ), apiKey: getValueIfDefined(securityCredentials?.[SKL.apiKey]), basePath: getValueIfDefined(account[SKL.overrideBasePath]), username: getValueIfDefined(securityCredentials?.[SKL.clientId]), password: getValueIfDefined( - securityCredentials?.[SKL.clientSecret] + securityCredentials?.[SKL.clientSecret], ), }; const response = await openApiExecutor .executeOperation(operationId, configuration, operationArgs) - .catch(async (error: Error | AxiosError): Promise => { + .catch(async(error: Error | AxiosError): Promise => { if ( axios.isAxiosError(error) && - (await this.isInvalidTokenError(error, integrationId)) && + await this.isInvalidTokenError(error, integrationId) && securityCredentials ) { const refreshedConfiguration = await this.refreshSecurityCredentials( securityCredentials, integrationId, - account + account, ); return await openApiExecutor.executeOperation( operationId, refreshedConfiguration, - operationArgs + operationArgs, ); } throw error; @@ -1136,7 +1136,7 @@ export class SKLEngine { private async isInvalidTokenError( error: AxiosError, - integrationId: string + integrationId: string, ): Promise { const integration = await this.findBy({ id: integrationId }); const errorMatcher = integration[ @@ -1145,12 +1145,12 @@ export class SKLEngine { const errorMatcherStatus = errorMatcher && getValueIfDefined( - errorMatcher[SKL.invalidTokenErrorMatcherStatus] + errorMatcher[SKL.invalidTokenErrorMatcherStatus], ); const errorMatcherRegex = errorMatcher && getValueIfDefined( - errorMatcher[SKL.invalidTokenErrorMatcherMessageRegex] + errorMatcher[SKL.invalidTokenErrorMatcherMessageRegex], )!; if (errorMatcher && error.response?.status === errorMatcherStatus) { if (!errorMatcherRegex) { @@ -1158,7 +1158,7 @@ export class SKLEngine { } if ( error.response?.statusText && - new RegExp(errorMatcherRegex, "u").test(error.response?.statusText) + new RegExp(errorMatcherRegex, 'u').test(error.response?.statusText) ) { return true; } @@ -1171,39 +1171,39 @@ export class SKLEngine { securityCredentials: Entity, integrationId: string, account: Entity, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const getOauthTokenVerb = (await this.findBy({ type: SKL.Verb, - [RDFS.label]: "getOauthTokens", + [RDFS.label]: 'getOauthTokens', })) as Verb; const mapping = await this.findVerbIntegrationMapping( - getOauthTokenVerb["@id"], - integrationId + getOauthTokenVerb['@id'], + integrationId, ); if (!mapping) { throw new Error( - `No mapping found for verb ${getOauthTokenVerb["@id"]} and integration ${integrationId}` + `No mapping found for verb ${getOauthTokenVerb['@id']} and integration ${integrationId}`, ); } const args = { refreshToken: getValueIfDefined( - securityCredentials[SKL.refreshToken] + securityCredentials[SKL.refreshToken], )!, jwtBearerOptions: getValueIfDefined( - securityCredentials[SKL.jwtBearerOptions] + securityCredentials[SKL.jwtBearerOptions], )!, }; const operationArgs = await this.performParameterMappingOnArgsIfDefined( args, mapping, verbConfig, - true + true, ); const operationInfoJsonLd = await this.performOperationMappingWithArgs( {}, mapping, - verbConfig + verbConfig, ); const rawReturnValue = await this.performOperation( operationInfoJsonLd, @@ -1211,26 +1211,26 @@ export class SKLEngine { args, account, verbConfig, - securityCredentials + securityCredentials, ); const mappedReturnValue = await this.performReturnValueMappingWithFrameIfDefined( rawReturnValue, mapping as MappingWithReturnValueMapping, - verbConfig + verbConfig, ); await this.assertVerbReturnValueMatchesReturnTypeSchema( mappedReturnValue, - getOauthTokenVerb + getOauthTokenVerb, ); const bearerToken = getValueIfDefined( - mappedReturnValue[SKL.bearerToken] + mappedReturnValue[SKL.bearerToken], ); const accessToken = getValueIfDefined( - mappedReturnValue[SKL.accessToken] + mappedReturnValue[SKL.accessToken], ); const refreshToken = getValueIfDefined( - mappedReturnValue[SKL.refreshToken] + mappedReturnValue[SKL.refreshToken], ); if (bearerToken) { securityCredentials[SKL.bearerToken] = bearerToken; @@ -1246,66 +1246,66 @@ export class SKLEngine { } private getOauthConfigurationFromSecurityCredentials( - securityCredentialsSchema: Entity + securityCredentialsSchema: Entity, ): OpenApiClientConfiguration { const username = getValueIfDefined( - securityCredentialsSchema[SKL.clientId] + securityCredentialsSchema[SKL.clientId], ); const password = getValueIfDefined( - securityCredentialsSchema[SKL.clientSecret] + securityCredentialsSchema[SKL.clientSecret], ); const accessToken = getValueIfDefined( - securityCredentialsSchema[SKL.accessToken] + securityCredentialsSchema[SKL.accessToken], ); return { username, password, accessToken }; } private async assertVerbReturnValueMatchesReturnTypeSchema( returnValue: OrArray, - verb: Verb + verb: Verb, ): Promise { let returnTypeSchemaObject = verb[SKL.returnValue]; if ( - returnTypeSchemaObject?.["@id"] && + returnTypeSchemaObject?.['@id'] && Object.keys(returnTypeSchemaObject).length === 1 ) { returnTypeSchemaObject = await this.findBy({ - id: returnTypeSchemaObject["@id"], + id: returnTypeSchemaObject['@id'], }); } let report: ValidationReport | undefined; if (returnValue && returnTypeSchemaObject) { if (Array.isArray(returnValue)) { - if (returnValue.some((valueItem): boolean => "@id" in valueItem)) { + if (returnValue.some((valueItem): boolean => '@id' in valueItem)) { returnTypeSchemaObject[SHACL.targetNode] = returnValue.reduce( ( nodes: ReferenceNodeObject[], - returnValueItem + returnValueItem, ): ReferenceNodeObject[] => { - if (returnValueItem["@id"]) { - nodes.push({ "@id": returnValueItem["@id"] }); + if (returnValueItem['@id']) { + nodes.push({ '@id': returnValueItem['@id'] }); } return nodes; }, - [] + [], ); } else { const targetClasses = returnValue.reduce( ( nodes: ReferenceNodeObject[], - returnValueItem + returnValueItem, ): ReferenceNodeObject[] => { - if (returnValueItem["@type"]) { - const type = Array.isArray(returnValueItem["@type"]) - ? returnValueItem["@type"][0] - : returnValueItem["@type"]; - if (!nodes.includes({ "@id": type })) { - nodes.push({ "@id": type }); + if (returnValueItem['@type']) { + const type = Array.isArray(returnValueItem['@type']) + ? returnValueItem['@type'][0] + : returnValueItem['@type']; + if (!nodes.includes({ '@id': type })) { + nodes.push({ '@id': type }); } } return nodes; }, - [] + [], ); if (targetClasses.length > 0) { returnTypeSchemaObject[SHACL.targetClass] = targetClasses; @@ -1313,23 +1313,23 @@ export class SKLEngine { } report = await this.convertToQuadsAndValidateAgainstShape( returnValue, - returnTypeSchemaObject + returnTypeSchemaObject, ); } else if (Object.keys(returnValue).length > 0) { - if (returnValue["@id"]) { + if (returnValue['@id']) { returnTypeSchemaObject[SHACL.targetNode] = { - "@id": returnValue["@id"], + '@id': returnValue['@id'], }; - } else if (returnValue["@type"]) { + } else if (returnValue['@type']) { returnTypeSchemaObject[SHACL.targetClass] = { - "@id": Array.isArray(returnValue["@type"]) - ? returnValue["@type"][0] - : returnValue["@type"]!, + '@id': Array.isArray(returnValue['@type']) + ? returnValue['@type'][0] + : returnValue['@type']!, }; } report = await this.convertToQuadsAndValidateAgainstShape( returnValue, - returnTypeSchemaObject + returnTypeSchemaObject, ); } } @@ -1337,18 +1337,18 @@ export class SKLEngine { if (report && !report?.conforms) { throw new Error( `Return value ${ - Array.isArray(returnValue) ? "array" : returnValue["@id"] - } does not conform to the schema` + Array.isArray(returnValue) ? 'array' : returnValue['@id'] + } does not conform to the schema`, ); } } private async convertToQuadsAndValidateAgainstShape( value: OrArray, - shape: NodeObject + shape: NodeObject, ): Promise { const valueAsQuads = await convertJsonLdToQuads( - Array.isArray(value) ? value : [value] + Array.isArray(value) ? value : [ value ], ); const shapeQuads = await convertJsonLdToQuads(shape); const validator = new SHACLValidator(shapeQuads); @@ -1359,37 +1359,37 @@ export class SKLEngine { operationInfo: NodeObject, operationParameters: JSONObject, account: Entity, - securityCredentials?: Entity + securityCredentials?: Entity, ): Promise { const integrationId = (account[SKL.integration] as ReferenceNodeObject)[ - "@id" + '@id' ]; const openApiDescription = await this.getOpenApiDescriptionForIntegration( - integrationId + integrationId, ); securityCredentials ||= - await this.findSecurityCredentialsForAccountIfDefined(account["@id"]); + await this.findSecurityCredentialsForAccountIfDefined(account['@id']); let configuration: OpenApiClientConfiguration; if (securityCredentials) { configuration = this.getOauthConfigurationFromSecurityCredentials(securityCredentials); operationParameters.client_id = getValueIfDefined( - securityCredentials[SKL.clientId] + securityCredentials[SKL.clientId], )!; } else { configuration = {}; } const openApiExecutor = await this.createOpenApiOperationExecutorWithSpec( - openApiDescription + openApiDescription, ); const response = await openApiExecutor.executeSecuritySchemeStage( getValueIfDefined(operationInfo[SKL.schemeName])!, getValueIfDefined(operationInfo[SKL.oauthFlow])!, getValueIfDefined(operationInfo[SKL.stage])!, configuration, - operationParameters + operationParameters, ); - if ("codeVerifier" in response && "authorizationUrl" in response) { + if ('codeVerifier' in response && 'authorizationUrl' in response) { return { data: response as unknown as JSONObject, operationParameters, @@ -1398,25 +1398,25 @@ export class SKLEngine { return this.axiosResponseAndParamsToOperationResponse( response, operationParameters, - operationParameters + operationParameters, ); } private async getDataFromDataSource( dataSourceId: string, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): Promise { const dataSource = await this.findBy({ id: dataSourceId }); - if (dataSource["@type"] === SKL.JsonDataSource) { + if (dataSource['@type'] === SKL.JsonDataSource) { const data = this.getDataFromJsonDataSource(dataSource, verbConfig); - return { data, operationParameters: {} }; + return { data, operationParameters: {}}; } - throw new Error(`DataSource type ${dataSource["@type"]} is not supported.`); + throw new Error(`DataSource type ${dataSource['@type']} is not supported.`); } private getDataFromJsonDataSource( dataSource: NodeObject, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): JSONObject { if (dataSource[SKL.source]) { const sourceValue = getValueIfDefined(dataSource[SKL.source])!; @@ -1427,7 +1427,7 @@ export class SKLEngine { private getJsonDataFromSource( source: string, - verbConfig?: VerbConfig + verbConfig?: VerbConfig, ): JSONObject { const inputFiles = { ...this.inputFiles, @@ -1435,7 +1435,7 @@ export class SKLEngine { }; if (source in inputFiles) { const file = inputFiles[source]; - if (typeof file === "string") { + if (typeof file === 'string') { return JSON.parse(file); } return file; @@ -1447,10 +1447,10 @@ export class SKLEngine { private throwValidationReportError( report: ValidationReport, - errorMessage: string + errorMessage: string, ): void { const reportMessages = this.validationReportToMessages(report); - throw new Error(`${errorMessage}\n\n${reportMessages.join("\n")}`); + throw new Error(`${errorMessage}\n\n${reportMessages.join('\n')}`); } private validationReportToMessages(report: ValidationReport): string[] { @@ -1463,7 +1463,7 @@ export class SKLEngine { } else { const resultMessages = result.message .map((message): string => `${message.value}`) - .join(", "); + .join(', '); const message = `${pathValue}: ${resultMessages}`; reportMessages.push(message); } diff --git a/src/SklEngineOptions.ts b/src/SklEngineOptions.ts index 86c60a6..0ee8efb 100644 --- a/src/SklEngineOptions.ts +++ b/src/SklEngineOptions.ts @@ -1,5 +1,5 @@ -import type { SparqlQueryAdapterOptions } from "./storage/query-adapter/sparql/SparqlQueryAdapterOptions"; -import type { Callbacks } from "./util/Types"; +import type { SparqlQueryAdapterOptions } from './storage/query-adapter/sparql/SparqlQueryAdapterOptions'; +import type { Callbacks } from './util/Types'; export type SklEngineOptions = SparqlQueryAdapterOptions & { /** diff --git a/src/logger.ts b/src/logger.ts index e49ff51..9856321 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -1,6 +1,6 @@ export class Logger { private static instance: Logger; - private isDebug: boolean; + private readonly isDebug: boolean; private constructor(isDebug: boolean) { this.isDebug = isDebug; @@ -15,6 +15,7 @@ export class Logger { public log(...args: any[]): void { if (this.isDebug) { + // eslint-disable-next-line no-console console.log(...args); } } diff --git a/src/mapping/Mapper.ts b/src/mapping/Mapper.ts index 5237c7e..4641645 100644 --- a/src/mapping/Mapper.ts +++ b/src/mapping/Mapper.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import * as RmlParser from "@comake/rmlmapper-js"; -import type { NodeObject } from "jsonld"; -import jsonld from "jsonld"; -import type { OrArray, JSONValue } from "../util/Types"; -import { Logger } from "../logger"; +import * as RmlParser from '@comake/rmlmapper-js'; +import type { NodeObject } from 'jsonld'; +import jsonld from 'jsonld'; +import { Logger } from '../logger'; +import type { OrArray, JSONValue } from '../util/Types'; export interface MapperArgs { functions?: Record any>; @@ -19,28 +19,28 @@ export class Mapper { public async apply( data: JSONValue, mapping: OrArray, - frame: Record + frame: Record, ): Promise { const result = await this.doMapping(data, mapping); - Logger.getInstance().log("Mapping result", JSON.stringify(result)); + Logger.getInstance().log('Mapping result', JSON.stringify(result)); const frameResult = await this.frame(result, frame); - Logger.getInstance().log("Frame Result", frameResult); + Logger.getInstance().log('Frame Result', JSON.stringify(frameResult)); return frameResult; } private async doMapping( data: JSONValue, - mapping: OrArray + mapping: OrArray, ): Promise { - const sources = { "input.json": JSON.stringify(data) }; + const sources = { 'input.json': JSON.stringify(data) }; const options = { functions: this.functions }; const mappingNodeObject = Array.isArray(mapping) - ? { "@graph": mapping } + ? { '@graph': mapping } : mapping; const rmlResult = (await RmlParser.parseJsonLd( mappingNodeObject, sources, - options + options, )) as NodeObject[]; return rmlResult; @@ -48,16 +48,16 @@ export class Mapper { private async frame( jsonldDoc: any[], - overrideFrame: Record + overrideFrame: Record, ): Promise { let frame: Record = { - "@context": {}, - "@embed": "@always", + '@context': {}, + '@embed': '@always', }; frame = { ...frame, ...overrideFrame, - "@context": { ...frame["@context"], ...overrideFrame?.["@context"] }, + '@context': { ...frame['@context'], ...overrideFrame?.['@context'] }, }; return await jsonld.frame(jsonldDoc, frame); } diff --git a/src/util/Util.ts b/src/util/Util.ts index 61cbd23..ff46aa5 100644 --- a/src/util/Util.ts +++ b/src/util/Util.ts @@ -1,21 +1,21 @@ -import type { ReferenceNodeObject } from "@comake/rmlmapper-js"; -import { getIdFromNodeObjectIfDefined } from "@comake/rmlmapper-js"; -import * as jsonld from "jsonld"; -import type { NodeObject, ValueObject } from "jsonld"; -import { Parser, Store } from "n3"; +import type { ReferenceNodeObject } from '@comake/rmlmapper-js'; +import { getIdFromNodeObjectIfDefined } from '@comake/rmlmapper-js'; +import * as jsonld from 'jsonld'; +import type { NodeObject, ValueObject } from 'jsonld'; +import { Parser, Store } from 'n3'; import type { EntityFieldSingularValue, EntityFieldValue, JSONObject, RdfList, -} from "./Types"; -import { RDF } from "./Vocabularies"; +} from './Types'; +import { RDF } from './Vocabularies'; export async function convertJsonLdToQuads(jsonldDoc: any): Promise { const nquads = (await jsonld.toRDF(jsonldDoc, { - format: "application/n-quads", + format: 'application/n-quads', })) as unknown as string; - const turtleParser = new Parser({ format: "application/n-quads" }); + const turtleParser = new Parser({ format: 'application/n-quads' }); const store = new Store(); turtleParser.parse(nquads).forEach((quad): void => { store.addQuad(quad); @@ -25,9 +25,9 @@ export async function convertJsonLdToQuads(jsonldDoc: any): Promise { export function toJSON( jsonLd: NodeObject, - convertBeyondFirstLevel = true + convertBeyondFirstLevel = true, ): JSONObject { - ["@context", "@id", "@type"].forEach((key): void => { + [ '@context', '@id', '@type' ].forEach((key): void => { // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete jsonLd[key]; }); @@ -35,11 +35,11 @@ export function toJSON( Object.keys(jsonLd).forEach((key): void => { if (Array.isArray(jsonLd[key])) { (jsonLd[key] as any[])!.forEach((item, index): void => { - if (typeof item === "object") { + if (typeof item === 'object') { (jsonLd[key] as any[])[index] = toJSON(item); } }); - } else if (typeof jsonLd[key] === "object") { + } else if (typeof jsonLd[key] === 'object') { jsonLd[key] = toJSON(jsonLd[key] as NodeObject); } }); @@ -49,22 +49,22 @@ export function toJSON( export function ensureArray(arrayable: T | T[]): T[] { if (arrayable !== null && arrayable !== undefined) { - return Array.isArray(arrayable) ? arrayable : [arrayable]; + return Array.isArray(arrayable) ? arrayable : [ arrayable ]; } return []; } export function getValueIfDefined( - fieldValue?: EntityFieldValue + fieldValue?: EntityFieldValue, ): T | undefined { if (fieldValue && Array.isArray(fieldValue)) { return fieldValue.map( (valueItem): EntityFieldSingularValue => - getValueIfDefined(valueItem)! + getValueIfDefined(valueItem)!, ) as unknown as T; } - if (fieldValue && typeof fieldValue === "object") { - return (fieldValue as ValueObject)["@value"] as unknown as T; + if (fieldValue && typeof fieldValue === 'object') { + return (fieldValue as ValueObject)['@value'] as unknown as T; } if (fieldValue !== undefined && fieldValue !== null) { return fieldValue as unknown as T; @@ -72,7 +72,7 @@ export function getValueIfDefined( } export function isUrl(value: any): boolean { - if (typeof value !== "string") { + if (typeof value !== 'string') { return false; } try { @@ -84,19 +84,19 @@ export function isUrl(value: any): boolean { } } -// eslint-disable-next-line @typescript-eslint/naming-convention export function rdfListToArray( - list: { "@list": T[] } | RdfList + // eslint-disable-next-line @typescript-eslint/naming-convention + list: { '@list': T[] } | RdfList, ): T[] { - if (!("@list" in list)) { + if (!('@list' in list)) { return [ list[RDF.first], - ...(getIdFromNodeObjectIfDefined( - list[RDF.rest] as ReferenceNodeObject + ...getIdFromNodeObjectIfDefined( + list[RDF.rest] as ReferenceNodeObject, ) === RDF.nil ? [] - : rdfListToArray(list[RDF.rest] as RdfList)), + : rdfListToArray(list[RDF.rest] as RdfList), ]; } - return list["@list"]; + return list['@list']; }