diff --git a/package-lock.json b/package-lock.json index 3ef746a..365313a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@babel/eslint-parser": "^7.16.3", "@exabyte-io/eslint-config": "2025.5.13-0", "@mat3ra/code": "2025.8.7-0", - "@mat3ra/esse": "2025.8.14-0", + "@mat3ra/esse": "2025.11.26-0", "@mat3ra/made": "2025.7.15-0", "@mat3ra/standata": "2025.10.1-0", "@mat3ra/tsconfig": "2024.6.3-0", @@ -72,6 +72,24 @@ "node": ">=6.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "11.9.3", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.9.3.tgz", + "integrity": "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, "node_modules/@babel/cli": { "version": "7.28.3", "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.28.3.tgz", @@ -2268,24 +2286,6 @@ "node": ">=6.9.0" } }, - "node_modules/@bcherny/json-schema-ref-parser": { - "version": "10.0.5-fork", - "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", - "integrity": "sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==", - "dev": true, - "dependencies": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.6", - "call-me-maybe": "^1.0.1", - "js-yaml": "^4.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" - } - }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -3000,7 +3000,8 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@mat3ra/code": { "version": "2025.8.7-0", @@ -3021,55 +3022,553 @@ "underscore.string": "^3.3.6", "uuid": "8.3.2" }, - "engines": { - "node": ">=12.0.0" + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@mat3ra/esse": "*" + } + }, + "node_modules/@mat3ra/code/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@mat3ra/esse": { + "version": "2025.11.26-0", + "resolved": "https://registry.npmjs.org/@mat3ra/esse/-/esse-2025.11.26-0.tgz", + "integrity": "sha512-m0KZ3E8n+RvJR7cWeGstcJCXt7qxO0eCiZ97ojbBg5H2smTKLBfh4g5UF5ylJnk5PaArcPcRtLYwHcOxuPZHuA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/cli": "^7.27.0", + "@babel/core": "^7.26.10", + "@babel/eslint-parser": "^7.27.0", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/preset-env": "^7.26.9", + "@babel/preset-react": "^7.26.3", + "@babel/preset-typescript": "^7.27.0", + "@babel/register": "^7.25.9", + "@babel/runtime-corejs3": "^7.27.0", + "@mat3ra/utils": "^2025.11.20-0", + "@types/chai": "^4.3.20", + "@types/js-yaml": "^4.0.9", + "@types/json-schema-merge-allof": "^0.6.5", + "@types/mocha": "^10.0.10", + "ajv": "^8.17.1", + "ajv-formats": "^2.1.1", + "js-yaml": "^4.1.0", + "json-schema": "^0.4.0", + "json-schema-deref-sync": "0.14.0", + "json-schema-merge-allof": "^0.8.1", + "json-schema-to-typescript": "^15.0.4", + "lodash": "4.17.21" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", + "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@babel/preset-modules": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz", + "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils": { + "version": "2025.11.20-0", + "resolved": "https://registry.npmjs.org/@mat3ra/utils/-/utils-2025.11.20-0.tgz", + "integrity": "sha512-igkswFIPrvIsOKiGdLE6ifgKGa3nruepjq2pPs9us+gHRn4tCaFNsBJqHw3ysw1dLgCtoYhHyYbMdpQu46+FCw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@babel/cli": "7.16.0", + "@babel/core": "7.24.1", + "@babel/eslint-parser": "7.16.3", + "@babel/plugin-proposal-class-properties": "7.16.0", + "@babel/preset-env": "7.16.4", + "@babel/preset-react": "7.16.7", + "@babel/preset-typescript": "^7.22.5", + "@babel/register": "^7.16.0", + "@babel/runtime-corejs3": "7.16.8", + "crypto-js": "^4.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "mathjs": "12.4.1", + "semver": "^7.5.3", + "ts-node": "^10.9.1", + "typescript": "^4.5.5", + "underscore": "^1.13.3", + "underscore.string": "^3.3.4", + "uuid": "8.3.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/cli": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.16.0.tgz", + "integrity": "sha512-WLrM42vKX/4atIoQB+eb0ovUof53UUvecb4qGjU2PDDWRiZr50ZpiV8NpcLo7iSxeGYrRG0Mqembsa+UrTAV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/cli/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/core": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.1.tgz", + "integrity": "sha512-F82udohVyIgGAY2VVj/g34TpFUG606rumIHjTfVbssPg2zTR7PuuEpZcX8JA6sgBfIYmJrFtWgPvHQuJamVqZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.1", + "@babel/parser": "^7.24.1", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/eslint-parser": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.16.3.tgz", + "integrity": "sha512-iB4ElZT0jAt7PKVaeVulOECdGe6UnmA/O0P9jlF5g5GBOwDVbna8AXhHRu4s27xQf6OkveyA8iTDv1jHdDejgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz", + "integrity": "sha512-mCF3HcuZSY9Fcx56Lbn+CGdT44ioBMMvjNVldpKtj8tpniETdLjnxdHI1+sDWXIM1nNt+EanJOZ3IG9lzVjs7A==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/preset-env": { + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.4.tgz", + "integrity": "sha512-v0QtNd81v/xKj4gNKeuAerQ/azeNn/G1B1qMLeXOcV8+4TWlD2j3NV1u8q29SDFBXx/NBq5kyEAO+0mpRgacjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-async-generator-functions": "^7.16.4", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-class-static-block": "^7.16.0", + "@babel/plugin-proposal-dynamic-import": "^7.16.0", + "@babel/plugin-proposal-export-namespace-from": "^7.16.0", + "@babel/plugin-proposal-json-strings": "^7.16.0", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-object-rest-spread": "^7.16.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-proposal-private-property-in-object": "^7.16.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.16.0", + "@babel/plugin-transform-async-to-generator": "^7.16.0", + "@babel/plugin-transform-block-scoped-functions": "^7.16.0", + "@babel/plugin-transform-block-scoping": "^7.16.0", + "@babel/plugin-transform-classes": "^7.16.0", + "@babel/plugin-transform-computed-properties": "^7.16.0", + "@babel/plugin-transform-destructuring": "^7.16.0", + "@babel/plugin-transform-dotall-regex": "^7.16.0", + "@babel/plugin-transform-duplicate-keys": "^7.16.0", + "@babel/plugin-transform-exponentiation-operator": "^7.16.0", + "@babel/plugin-transform-for-of": "^7.16.0", + "@babel/plugin-transform-function-name": "^7.16.0", + "@babel/plugin-transform-literals": "^7.16.0", + "@babel/plugin-transform-member-expression-literals": "^7.16.0", + "@babel/plugin-transform-modules-amd": "^7.16.0", + "@babel/plugin-transform-modules-commonjs": "^7.16.0", + "@babel/plugin-transform-modules-systemjs": "^7.16.0", + "@babel/plugin-transform-modules-umd": "^7.16.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.0", + "@babel/plugin-transform-new-target": "^7.16.0", + "@babel/plugin-transform-object-super": "^7.16.0", + "@babel/plugin-transform-parameters": "^7.16.3", + "@babel/plugin-transform-property-literals": "^7.16.0", + "@babel/plugin-transform-regenerator": "^7.16.0", + "@babel/plugin-transform-reserved-words": "^7.16.0", + "@babel/plugin-transform-shorthand-properties": "^7.16.0", + "@babel/plugin-transform-spread": "^7.16.0", + "@babel/plugin-transform-sticky-regex": "^7.16.0", + "@babel/plugin-transform-template-literals": "^7.16.0", + "@babel/plugin-transform-typeof-symbol": "^7.16.0", + "@babel/plugin-transform-unicode-escapes": "^7.16.0", + "@babel/plugin-transform-unicode-regex": "^7.16.0", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.16.0", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.19.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/preset-react": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.7.tgz", + "integrity": "sha512-fWpyI8UM/HE6DfPBzD8LnhQ/OcH8AgTaqcqP2nGOXEUV+VKBR5JRN9hCk9ai+zQQ57vtm9oWeXguBCPNUjytgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-transform-react-display-name": "^7.16.7", + "@babel/plugin-transform-react-jsx": "^7.16.7", + "@babel/plugin-transform-react-jsx-development": "^7.16.7", + "@babel/plugin-transform-react-pure-annotations": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/@babel/runtime-corejs3": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.16.8.tgz", + "integrity": "sha512-3fKhuICS1lMz0plI5ktOE/yEtBRMVxplzRkdn6mJQ197XiY0JnrzYV0+Mxozq3JZ8SBV9Ecurmw1XsGbwOf+Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.20.2", + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@mat3ra/esse/node_modules/@mat3ra/utils/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@mat3ra/esse/node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", + "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.0", + "core-js-compat": "^3.18.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", + "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@mat3ra/esse/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@mat3ra/esse/node_modules/complex.js": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.3.tgz", + "integrity": "sha512-UrQVSUur14tNX6tiP4y8T4w4FeJAX3bi2cIv0pu/DTLFNxoq7z2Yh83Vfzztj6Px3X/lubqQ9IrPp7Bpn6p4MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/@mat3ra/esse/node_modules/fraction.js": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", + "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/@mat3ra/esse/node_modules/mathjs": { + "version": "12.4.1", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.1.tgz", + "integrity": "sha512-welnW3khgwYjPYvECFHO+xkCxAx9IKIIPDDWPi8B5rKAvmgoEHnQX9slEmHKZTNaJiE+OS4qrJJcB4sfDn/4sw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.24.0", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "4.3.4", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.1.1" + }, + "bin": { + "mathjs": "bin/cli.js" }, - "peerDependencies": { - "@mat3ra/esse": "*" + "engines": { + "node": ">= 18" } }, - "node_modules/@mat3ra/code/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "node_modules/@mat3ra/esse/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, - "bin": { - "semver": "bin/semver.js" - }, + "license": "BSD-3-Clause", "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/@mat3ra/esse": { - "version": "2025.8.14-0", - "resolved": "https://registry.npmjs.org/@mat3ra/esse/-/esse-2025.8.14-0.tgz", - "integrity": "sha512-p8Fijembng3eiXEwXXRNp34eVqUq8BueCGqA20aKFJTNROoJCws7ODZoHrGeYn91LXkEJ+lfsg4wa96GxYNZyg==", + "node_modules/@mat3ra/esse/node_modules/typed-function": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.2.tgz", + "integrity": "sha512-VwaXim9Gp1bngi/q3do8hgttYn2uC3MoT/gfuMWylnj1IeZBUAyPddHZlo1K05BDoj8DYPpMdiHqH1dDYdJf2A==", "dev": true, - "dependencies": { - "@babel/cli": "^7.27.0", - "@babel/core": "^7.26.10", - "@babel/eslint-parser": "^7.27.0", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/preset-env": "^7.26.9", - "@babel/preset-react": "^7.26.3", - "@babel/preset-typescript": "^7.27.0", - "@babel/register": "^7.25.9", - "@babel/runtime-corejs3": "^7.27.0", - "@types/chai": "^4.3.20", - "@types/js-yaml": "^4.0.9", - "@types/json-schema-merge-allof": "^0.6.5", - "@types/mocha": "^10.0.10", - "ajv": "^8.17.1", - "ajv-formats": "^2.1.1", - "js-yaml": "^4.1.0", - "json-schema": "^0.4.0", - "json-schema-deref-sync": "0.14.0", - "json-schema-merge-allof": "^0.8.1", - "json-schema-to-typescript": "^13.1.2", - "lodash": "4.17.21" + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@mat3ra/esse/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=14.0.0" + "node": ">=4.2.0" } }, "node_modules/@mat3ra/made": { @@ -4132,16 +4631,6 @@ "@types/chai": "*" } }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, "node_modules/@types/js-yaml": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", @@ -4169,10 +4658,11 @@ "dev": true }, "node_modules/@types/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", - "dev": true + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==", + "dev": true, + "license": "MIT" }, "node_modules/@types/mathjs": { "version": "5.0.1", @@ -4183,16 +4673,6 @@ "decimal.js": "^10.0.0" } }, - "node_modules/@types/minimatch": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-6.0.0.tgz", - "integrity": "sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==", - "deprecated": "This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "minimatch": "*" - } - }, "node_modules/@types/mocha": { "version": "10.0.10", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", @@ -4204,6 +4684,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.6.0.tgz", "integrity": "sha512-F1CBxgqwOMc4GKJ7eY22hWhBVQuMYTtqI8L0FcszYcpYX0fzfDGpez22Xau8Mgm7O9fI+zA/TYIdq3tGWfweBA==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~7.13.0" } @@ -4214,12 +4695,6 @@ "integrity": "sha512-pHiGtf83na1nCzliuAdq8GowYiXvH5l931xZ0YEHaLMNFgynpEqx+IPStlu7UaDkehfvl01e4x/9Tpwhy7Ue3w==", "dev": true }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true - }, "node_modules/@types/react": { "version": "19.1.15", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.15.tgz", @@ -4668,12 +5143,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -5187,12 +5656,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5319,22 +5782,6 @@ "node": ">=6" } }, - "node_modules/cli-color": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", - "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.64", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.15", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -5607,19 +6054,6 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, - "node_modules/d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", - "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.64", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/dag-map": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/dag-map/-/dag-map-1.0.2.tgz", @@ -6035,64 +6469,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es5-ext": { - "version": "0.10.64", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", - "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", - "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", - "dev": true, - "dependencies": { - "d": "^1.0.2", - "ext": "^1.7.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6794,21 +7176,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/esniff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", - "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -6887,16 +7254,6 @@ "node": ">=0.10.0" } }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -6920,15 +7277,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "dependencies": { - "type": "^2.7.2" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7287,18 +7635,6 @@ "node": ">= 0.4" } }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -7361,25 +7697,6 @@ "node": ">= 6" } }, - "node_modules/glob-promise": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", - "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.3" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/ahmadnassri" - }, - "peerDependencies": { - "glob": "^7.1.6" - } - }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -8013,12 +8330,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -8476,31 +8787,43 @@ } }, "node_modules/json-schema-to-typescript": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-13.1.2.tgz", - "integrity": "sha512-17G+mjx4nunvOpkPvcz7fdwUwYCEwyH8vR3Ym3rFiQ8uzAL3go+c1306Kk7iGRk8HuXBXqy+JJJmpYl0cvOllw==", + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-15.0.4.tgz", + "integrity": "sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ==", "dev": true, + "license": "MIT", "dependencies": { - "@bcherny/json-schema-ref-parser": "10.0.5-fork", - "@types/json-schema": "^7.0.11", - "@types/lodash": "^4.14.182", - "@types/prettier": "^2.6.1", - "cli-color": "^2.0.2", - "get-stdin": "^8.0.0", - "glob": "^7.1.6", - "glob-promise": "^4.2.2", + "@apidevtools/json-schema-ref-parser": "^11.5.5", + "@types/json-schema": "^7.0.15", + "@types/lodash": "^4.17.7", "is-glob": "^4.0.3", + "js-yaml": "^4.1.0", "lodash": "^4.17.21", - "minimist": "^1.2.6", - "mkdirp": "^1.0.4", - "mz": "^2.7.0", - "prettier": "^2.6.2" + "minimist": "^1.2.8", + "prettier": "^3.2.5", + "tinyglobby": "^0.2.9" }, "bin": { "json2ts": "dist/src/cli.js" }, "engines": { - "node": ">=12.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/json-schema-to-typescript/node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/json-schema-traverse": { @@ -8981,15 +9304,6 @@ "yallist": "^3.0.2" } }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.2" - } - }, "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -9066,25 +9380,6 @@ "is-buffer": "~1.1.1" } }, - "node_modules/memoizee": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", - "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", - "dev": true, - "dependencies": { - "d": "^1.0.2", - "es5-ext": "^0.10.64", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/memory-cache": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", @@ -9155,18 +9450,6 @@ "integrity": "sha512-DQsf/liljH/9e+94jR+xfK8vlKceeKdOM9H9UEXLwGuvEEpO6debNtJ9yt1ZKzPKPrwqGxzMdu0BR1fnQb6i4A==", "dev": true }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/mocha": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", @@ -9335,17 +9618,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "node_modules/nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", @@ -9370,12 +9642,6 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -11343,51 +11609,65 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "node_modules/timers-ext": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", - "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, + "license": "MIT", "dependencies": { - "es5-ext": "^0.10.64", - "next-tick": "^1.1.0" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { - "node": ">=0.12" + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -11542,12 +11822,6 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/type": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", - "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -11749,7 +12023,8 @@ "version": "7.13.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.13.0.tgz", "integrity": "sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", diff --git a/package.json b/package.json index 7afbd83..395482a 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "test:coverage:view": "node scripts/view-coverage.js", "lint": "eslint src/js tests/js && prettier --write src/js tests/js", "lint:fix": "eslint --fix --cache src/js tests/js && prettier --write src/js tests/js", - "transpile": "tsc -p tsconfig-transpile.json", + "transpile": "tsc -p tsconfig.json", "prettier": "prettier --check src/js tests/js", "prepare": "husky install" }, @@ -25,6 +25,16 @@ ".babelrc", "tsconfig.json" ], + "exports": { + ".": { + "types": "./dist/js/index.d.ts", + "default": "./dist/js/index.js" + }, + "./types": { + "types": "./dist/js/types.d.ts", + "default": "./dist/js/types.js" + } + }, "author": "Exabyte Inc.", "bugs": { "url": "https://github.com/Exabyte-io/ade/issues" @@ -42,7 +52,7 @@ "@exabyte-io/eslint-config": "2025.5.13-0", "@mat3ra/utils": "2025.9.20-0", "@mat3ra/code": "2025.8.7-0", - "@mat3ra/esse": "2025.8.14-0", + "@mat3ra/esse": "2025.11.26-0", "@mat3ra/made": "2025.7.15-0", "@mat3ra/standata": "2025.10.1-0", "@mat3ra/tsconfig": "2024.6.3-0", diff --git a/src/js/context/ContextProvider.ts b/src/js/context/ContextProvider.ts index ac70bda..3bd6c87 100644 --- a/src/js/context/ContextProvider.ts +++ b/src/js/context/ContextProvider.ts @@ -9,64 +9,26 @@ * to next one, for example data about material to track when it is changed. * @notes Should hold static data only (see `setData` method), no classes or functions */ +import { ContextProviderSchema, Name as ContextProviderNameEnum } from "@mat3ra/esse/dist/js/types"; import { Utils } from "@mat3ra/utils"; import lodash from "lodash"; export interface ContextProviderInstance { constructor: typeof ContextProvider; - config: ContextProviderConfig; -} - -export interface ContextProviderConfig { - name: ContextProviderName | `${ContextProviderName}`; - domain?: string; - entityName?: string; - data?: object; - extraData?: object; - isEdited?: boolean; - context?: object; -} - -// TODO: separate application-specific CPs -export enum ContextProviderName { - PlanewaveCutoffDataManager = "PlanewaveCutoffDataManager", - KGridFormDataManager = "KGridFormDataManager", - QGridFormDataManager = "QGridFormDataManager", - IGridFormDataManager = "IGridFormDataManager", - QPathFormDataManager = "QPathFormDataManager", - IPathFormDataManager = "IPathFormDataManager", - KPathFormDataManager = "KPathFormDataManager", - ExplicitKPathFormDataManager = "ExplicitKPathFormDataManager", - ExplicitKPath2PIBAFormDataManager = "ExplicitKPath2PIBAFormDataManager", - HubbardJContextManager = "HubbardJContextManager", - HubbardUContextManager = "HubbardUContextManager", - HubbardVContextManager = "HubbardVContextManager", - HubbardContextManagerLegacy = "HubbardContextManagerLegacy", - NEBFormDataManager = "NEBFormDataManager", - BoundaryConditionsFormDataManager = "BoundaryConditionsFormDataManager", - MLSettingsDataManager = "MLSettingsDataManager", - MLTrainTestSplitDataManager = "MLTrainTestSplitDataManager", - IonDynamicsContextProvider = "IonDynamicsContextProvider", - CollinearMagnetizationDataManager = "CollinearMagnetizationDataManager", - NonCollinearMagnetizationDataManager = "NonCollinearMagnetizationDataManager", - QEPWXInputDataManager = "QEPWXInputDataManager", - QENEBInputDataManager = "QENEBInputDataManager", - VASPInputDataManager = "VASPInputDataManager", - VASPNEBInputDataManager = "VASPNEBInputDataManager", - NWChemInputDataManager = "NWChemInputDataManager", + config: ContextProviderSchema; } export interface ContextProviderStatic { - getConstructorConfig: (config: ContextProviderConfig) => ContextProviderInstance; - createConfigFromContext: (config: ContextProviderConfig) => ContextProviderConfig; + getConstructorConfig: (config: ContextProviderSchema) => ContextProviderInstance; + createConfigFromContext: (config: ContextProviderSchema) => ContextProviderSchema; getExtraDataKeyByName: (name: string) => string; getIsEditedKeyByName: (name: string) => string; } -export default class ContextProvider { - config: ContextProviderConfig; +export default class ContextProvider implements ContextProviderSchema { + config: ContextProviderSchema; - name: `${ContextProviderName}`; + name: ContextProviderNameEnum; domain?: string; @@ -78,7 +40,11 @@ export default class ContextProvider { isEdited?: boolean; - constructor(config: ContextProviderConfig) { + context?: object; + + [k: string]: unknown; + + constructor(config: ContextProviderSchema) { this.config = config; this.name = config.name; // property name, ie. "kpath" this.domain = config.domain || "default"; @@ -99,14 +65,14 @@ export default class ContextProvider { this.yieldData = this.yieldData.bind(this); } - static getConstructorConfig(config: ContextProviderConfig): ContextProviderInstance { + static getConstructorConfig(config: ContextProviderSchema): ContextProviderInstance { return { constructor: this.prototype.constructor as typeof ContextProvider, config, }; } - static createConfigFromContext(config: ContextProviderConfig) { + static createConfigFromContext(config: ContextProviderSchema) { const data = lodash.get(config.context, config.name); const isEdited = lodash.get(config.context, this.getIsEditedKeyByName(config.name)); const extraData = lodash.get(config.context, this.getExtraDataKeyByName(config.name)); diff --git a/src/js/context/JSONSchemaDataProvider.ts b/src/js/context/JSONSchemaDataProvider.ts new file mode 100644 index 0000000..2159395 --- /dev/null +++ b/src/js/context/JSONSchemaDataProvider.ts @@ -0,0 +1,11 @@ +/* eslint-disable class-methods-use-this */ +import JinjaContextProvider from "./JinjaContextProvider"; + +/** + * @summary Provides jsonSchema only. + */ +export default class JSONSchemaDataProvider extends JinjaContextProvider { + get jsonSchema() { + throw new Error("Not implemented."); + } +} diff --git a/src/js/context/JSONSchemaFormDataProvider.ts b/src/js/context/JSONSchemaFormDataProvider.ts index 0dae843..05c97cc 100644 --- a/src/js/context/JSONSchemaFormDataProvider.ts +++ b/src/js/context/JSONSchemaFormDataProvider.ts @@ -1,11 +1,7 @@ /* eslint-disable class-methods-use-this */ import type { UiSchema } from "react-jsonschema-form"; -import ContextProvider, { type ContextProviderConfig } from "./ContextProvider"; - -interface JSONSchemaFormDataProviderConfig extends ContextProviderConfig { - isUsingJinjaVariables?: boolean; -} +import JSONSchemaDataProvider from "./JSONSchemaDataProvider"; /** * @summary Provides jsonSchema and uiSchema for generating react-jsonschema-form @@ -17,18 +13,8 @@ interface JSONSchemaFormDataProviderConfig extends ContextProviderConfig { * formData={provider.getData(unit.important)} /> * ``` */ -export default class JSONSchemaFormDataProvider extends ContextProvider { - isUsingJinjaVariables: boolean; - - constructor(config: JSONSchemaFormDataProviderConfig) { - super(config); - this.isUsingJinjaVariables = Boolean(config?.isUsingJinjaVariables); - } - - get jsonSchema() { - throw new Error("Not implemented."); - } - +// TODO: MOVE to WebApp/ave or wove +export default class JSONSchemaFormDataProvider extends JSONSchemaDataProvider { get uiSchema(): UiSchema { throw new Error("Not implemented."); } diff --git a/src/js/context/JinjaContextProvider.ts b/src/js/context/JinjaContextProvider.ts new file mode 100644 index 0000000..cdceb65 --- /dev/null +++ b/src/js/context/JinjaContextProvider.ts @@ -0,0 +1,16 @@ +import { ContextProviderSchema } from "@mat3ra/esse/dist/js/types"; + +import ContextProvider from "./ContextProvider"; + +interface JSONSchemaDataProviderConfig extends ContextProviderSchema { + isUsingJinjaVariables?: boolean; +} + +export default class JinjaContextProvider extends ContextProvider { + isUsingJinjaVariables: boolean; + + constructor(config: JSONSchemaDataProviderConfig) { + super(config); + this.isUsingJinjaVariables = Boolean(config.isUsingJinjaVariables); + } +} diff --git a/src/js/index.ts b/src/js/index.ts index 6e734a3..aa149a7 100644 --- a/src/js/index.ts +++ b/src/js/index.ts @@ -1,6 +1,32 @@ import Application from "./application"; +import { applicationMixin, applicationStaticMixin } from "./applicationMixin"; +import ApplicationRegistry from "./ApplicationRegistry"; +import ContextProvider from "./context/ContextProvider"; +import JSONSchemaFormDataProvider from "./context/JSONSchemaFormDataProvider"; import Executable from "./executable"; +import { executableMixin } from "./executableMixin"; import Flavor from "./flavor"; +import { flavorMixin } from "./flavorMixin"; import Template from "./template"; +import { templateMixin, templateStaticMixin } from "./templateMixin"; -export { Application, Executable, Flavor, Template }; +const allApplications = ApplicationRegistry.getUniqueAvailableApplicationNames(); + +export { + Application, + Executable, + Flavor, + Template, + ApplicationRegistry, + ContextProvider, + JSONSchemaFormDataProvider, + executableMixin, + flavorMixin, + applicationMixin, + applicationStaticMixin, + templateMixin, + templateStaticMixin, + allApplications, +}; + +export type * from "./types"; diff --git a/src/js/templateMixin.ts b/src/js/templateMixin.ts index 4d74880..c1e8f92 100644 --- a/src/js/templateMixin.ts +++ b/src/js/templateMixin.ts @@ -1,16 +1,17 @@ import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; import type { NamedInMemoryEntity } from "@mat3ra/code/dist/js/entity/mixins/NamedEntityMixin"; -import { Utils } from "@mat3ra/utils"; import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; import JSONSchemasInterface from "@mat3ra/esse/dist/js/esse/JSONSchemasInterface"; import type { AnyObject } from "@mat3ra/esse/dist/js/esse/types"; -import type { TemplateSchema } from "@mat3ra/esse/dist/js/types"; +import type { + ContextProviderNameEnum, + ContextProviderSchema, + TemplateSchema, +} from "@mat3ra/esse/dist/js/types"; +import { Utils } from "@mat3ra/utils"; import nunjucks from "nunjucks"; -import ContextProvider, { - type ContextProviderConfig, - type ContextProviderName, -} from "./context/ContextProvider"; +import ContextProvider from "./context/ContextProvider"; import ContextProviderRegistryContainer from "./context/ContextProviderRegistryContainer"; export type TemplateBase = InMemoryEntity & NamedInMemoryEntity; @@ -200,11 +201,11 @@ export function templateMixin(item: TemplateBase) { export type ContextProviderConfigMapEntry = { providerCls: typeof ContextProvider; - config: ContextProviderConfig; + config: ContextProviderSchema; }; export type ContextProviderConfigMap = Partial< - Record + Record >; export type TemplateStaticMixin = { diff --git a/src/js/types.ts b/src/js/types.ts new file mode 100644 index 0000000..22cac20 --- /dev/null +++ b/src/js/types.ts @@ -0,0 +1,15 @@ +import type { ApplicationMixin, ApplicationStaticMixin } from "./applicationMixin"; +import type { CreateApplicationConfig } from "./ApplicationRegistry"; +import type { ExecutableMixin } from "./executableMixin"; +import type { FlavorMixin } from "./flavorMixin"; +import type { TemplateMixin, TemplateStaticMixin } from "./templateMixin"; + +export type { + FlavorMixin, + ExecutableMixin, + ApplicationMixin, + ApplicationStaticMixin, + CreateApplicationConfig, + TemplateMixin, + TemplateStaticMixin, +}; diff --git a/src/py/mat3ra/ade/__init__.py b/src/py/mat3ra/ade/__init__.py index bfac587..258f381 100644 --- a/src/py/mat3ra/ade/__init__.py +++ b/src/py/mat3ra/ade/__init__.py @@ -3,6 +3,24 @@ from mat3ra.ade.application import Application from mat3ra.ade.executable import Executable from mat3ra.ade.flavor import Flavor, FlavorInput -from mat3ra.ade.template import ContextProvider, Template +from mat3ra.ade.template import ( + ContextProvider, + ContextProviderName, + JinjaContextProvider, + JSONSchemaDataProvider, + JSONSchemaFormDataProvider, + Template, +) -__all__ = ["Application", "Executable", "Flavor", "FlavorInput", "Template", "ContextProvider"] +__all__ = [ + "Application", + "Executable", + "Flavor", + "FlavorInput", + "Template", + "ContextProvider", + "ContextProviderName", + "JinjaContextProvider", + "JSONSchemaDataProvider", + "JSONSchemaFormDataProvider", +] diff --git a/src/py/mat3ra/ade/template.py b/src/py/mat3ra/ade/template.py index 5fdcd27..177dc2b 100644 --- a/src/py/mat3ra/ade/template.py +++ b/src/py/mat3ra/ade/template.py @@ -1,14 +1,135 @@ """Template class definition.""" -from typing import List, Optional +from enum import Enum +from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field +class ContextProviderName(str, Enum): + """Enum for context provider names matching ESSE schema.""" + + PlanewaveCutoffDataManager = "PlanewaveCutoffDataManager" + KGridFormDataManager = "KGridFormDataManager" + QGridFormDataManager = "QGridFormDataManager" + IGridFormDataManager = "IGridFormDataManager" + QPathFormDataManager = "QPathFormDataManager" + IPathFormDataManager = "IPathFormDataManager" + KPathFormDataManager = "KPathFormDataManager" + ExplicitKPathFormDataManager = "ExplicitKPathFormDataManager" + ExplicitKPath2PIBAFormDataManager = "ExplicitKPath2PIBAFormDataManager" + HubbardJContextManager = "HubbardJContextManager" + HubbardUContextManager = "HubbardUContextManager" + HubbardVContextManager = "HubbardVContextManager" + HubbardContextManagerLegacy = "HubbardContextManagerLegacy" + NEBFormDataManager = "NEBFormDataManager" + BoundaryConditionsFormDataManager = "BoundaryConditionsFormDataManager" + MLSettingsDataManager = "MLSettingsDataManager" + MLTrainTestSplitDataManager = "MLTrainTestSplitDataManager" + IonDynamicsContextProvider = "IonDynamicsContextProvider" + CollinearMagnetizationDataManager = "CollinearMagnetizationDataManager" + NonCollinearMagnetizationDataManager = "NonCollinearMagnetizationDataManager" + QEPWXInputDataManager = "QEPWXInputDataManager" + QENEBInputDataManager = "QENEBInputDataManager" + VASPInputDataManager = "VASPInputDataManager" + VASPNEBInputDataManager = "VASPNEBInputDataManager" + NWChemInputDataManager = "NWChemInputDataManager" + + class ContextProvider(BaseModel): - """Context provider for a template.""" + """ + Context provider for a template. + + This is a standalone class that contains "data" for a property with "name". + Helps facilitate UI logic. Can be initialized from context when user edits are present: + - user edits the corresponding property, eg. "kpath" + - isKpathEdited is set to True + - context property is updated for the parent entity (eg. Unit) in a way that persists in Redux state + - new entity inherits the "data" through "context" field in config + - extraData field is used to store any other data that should be passed from one instance of provider + to next one, for example data about material to track when it is changed. + + Attributes: + name: The name of this item (required) + domain: Domain of the context provider + entity_name: Entity name associated with the context provider + data: Data object for the context provider + extra_data: Additional data object for the context provider + is_edited: Flag indicating if the context provider has been edited + context: Context object for the context provider + """ name: str = Field(..., description="The name of this item. e.g. scf_accuracy") + domain: Optional[str] = Field(default="default", description="Domain of the context provider") + entity_name: Optional[str] = Field( + default="unit", description="Entity name associated with the context provider, eg. 'unit', 'subworkflow'" + ) + data: Optional[Dict[str, Any]] = Field(default=None, description="Data object for the context provider") + extra_data: Optional[Dict[str, Any]] = Field( + default=None, description="Additional data object for the context provider" + ) + is_edited: Optional[bool] = Field( + default=None, description="Flag indicating if the context provider has been edited" + ) + context: Optional[Dict[str, Any]] = Field(default=None, description="Context object for the context provider") + + model_config = ConfigDict(validate_assignment=True, extra="allow") + + @property + def extra_data_key(self) -> str: + """Get the key for extra data.""" + return f"{self.name}ExtraData" + + @property + def is_edited_key(self) -> str: + """Get the key for isEdited flag.""" + return f"is{self.name.capitalize()}Edited" + + @property + def is_unit_context_provider(self) -> bool: + """Check if this is a unit context provider.""" + return self.entity_name == "unit" + + @property + def is_subworkflow_context_provider(self) -> bool: + """Check if this is a subworkflow context provider.""" + return self.entity_name == "subworkflow" + + +class JinjaContextProvider(ContextProvider): + """ + Context provider with Jinja variable support. + + Extends ContextProvider with isUsingJinjaVariables flag. + """ + + is_using_jinja_variables: bool = Field( + default=False, description="Whether this provider uses Jinja variables" + ) + + +class JSONSchemaDataProvider(JinjaContextProvider): + """ + Provides jsonSchema only. + + Extends JinjaContextProvider with jsonSchema property. + """ + + json_schema: Optional[Dict[str, Any]] = Field(default=None, description="JSON schema for this provider") + + +class JSONSchemaFormDataProvider(JSONSchemaDataProvider): + """ + Provides jsonSchema and uiSchema for generating react-jsonschema-form. + + See https://github.com/mozilla-services/react-jsonschema-form for Form UI. + """ + + ui_schema: Optional[Dict[str, Any]] = Field(default=None, description="UI schema for form rendering") + fields: Optional[Dict[str, Any]] = Field(default_factory=dict, description="Custom fields") + default_field_styles: Optional[Dict[str, Any]] = Field( + default_factory=dict, description="Default styles for form fields" + ) class Template(BaseModel): diff --git a/tests/js/ApplicationRegistry.test.ts b/tests/js/ApplicationRegistry.test.ts index 0fd4a63..3088509 100644 --- a/tests/js/ApplicationRegistry.test.ts +++ b/tests/js/ApplicationRegistry.test.ts @@ -1,4 +1,5 @@ /* eslint-disable no-unused-expressions */ +import { Name as ContextProviderNameEnum } from "@mat3ra/esse/dist/js/types"; import { expect } from "chai"; import type { ContextProviderConfigMapEntry } from "src/js/templateMixin"; @@ -25,14 +26,14 @@ describe("ApplicationRegistry", () => { const mockConfig: ContextProviderConfigMapEntry = { providerCls: MockContextProvider, - config: { name: "QGridFormDataManager" }, + config: { name: ContextProviderNameEnum.QGridFormDataManager }, }; Template.setContextProvidersConfig({ - QGridFormDataManager: mockConfig, - PlanewaveCutoffDataManager: mockConfig, - KGridFormDataManager: mockConfig, - QEPWXInputDataManager: mockConfig, + [ContextProviderNameEnum.QGridFormDataManager]: mockConfig, + [ContextProviderNameEnum.PlanewaveCutoffDataManager]: mockConfig, + [ContextProviderNameEnum.KGridFormDataManager]: mockConfig, + [ContextProviderNameEnum.QEPWXInputDataManager]: mockConfig, }); }); diff --git a/tests/js/ContextProviderRegistryContainer.test.ts b/tests/js/ContextProviderRegistryContainer.test.ts index e50cf3a..63507d3 100644 --- a/tests/js/ContextProviderRegistryContainer.test.ts +++ b/tests/js/ContextProviderRegistryContainer.test.ts @@ -1,9 +1,9 @@ /* eslint-disable no-unused-expressions */ +import { Name as ContextProviderNameEnum } from "@mat3ra/esse/dist/js/types"; import { expect } from "chai"; import ContextProvider, { type ContextProviderInstance, - ContextProviderName, } from "../../src/js/context/ContextProvider"; import ContextProviderRegistryContainer from "../../src/js/context/ContextProviderRegistryContainer"; @@ -23,7 +23,7 @@ describe("ContextProviderRegistryContainer", () => { container = new ContextProviderRegistryContainer(); mockProviderInstance = { constructor: MockContextProvider, - config: { name: ContextProviderName.QGridFormDataManager }, + config: { name: ContextProviderNameEnum.QGridFormDataManager }, }; }); @@ -51,12 +51,12 @@ describe("ContextProviderRegistryContainer", () => { describe("addProvider", () => { it("should add a provider to the registry", () => { container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); expect(container.providers).to.have.length(1); expect(container.providers[0]).to.deep.equal({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); }); @@ -64,22 +64,22 @@ describe("ContextProviderRegistryContainer", () => { it("should add multiple providers", () => { const provider2 = { constructor: MockContextProvider, - config: { name: ContextProviderName.PlanewaveCutoffDataManager }, + config: { name: ContextProviderNameEnum.PlanewaveCutoffDataManager }, }; container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); container.addProvider({ - name: ContextProviderName.PlanewaveCutoffDataManager, + name: ContextProviderNameEnum.PlanewaveCutoffDataManager, instance: provider2, }); expect(container.providers).to.have.length(2); - expect(container.providers[0].name).to.equal(ContextProviderName.QGridFormDataManager); + expect(container.providers[0].name).to.equal(ContextProviderNameEnum.QGridFormDataManager); expect(container.providers[1].name).to.equal( - ContextProviderName.PlanewaveCutoffDataManager, + ContextProviderNameEnum.PlanewaveCutoffDataManager, ); }); }); @@ -87,19 +87,19 @@ describe("ContextProviderRegistryContainer", () => { describe("findProviderInstanceByName", () => { it("should find provider instance by name", () => { container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); const found = container.findProviderInstanceByName( - ContextProviderName.QGridFormDataManager, + ContextProviderNameEnum.QGridFormDataManager, ); expect(found).to.equal(mockProviderInstance); }); it("should return undefined for non-existent provider", () => { const found = container.findProviderInstanceByName( - ContextProviderName.KGridFormDataManager, + ContextProviderNameEnum.KGridFormDataManager, ); expect(found).to.be.undefined; }); @@ -107,20 +107,20 @@ describe("ContextProviderRegistryContainer", () => { it("should find provider when multiple providers exist", () => { const provider2 = { constructor: MockContextProvider, - config: { name: ContextProviderName.PlanewaveCutoffDataManager }, + config: { name: ContextProviderNameEnum.PlanewaveCutoffDataManager }, }; container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); container.addProvider({ - name: ContextProviderName.PlanewaveCutoffDataManager, + name: ContextProviderNameEnum.PlanewaveCutoffDataManager, instance: provider2, }); const found = container.findProviderInstanceByName( - ContextProviderName.PlanewaveCutoffDataManager, + ContextProviderNameEnum.PlanewaveCutoffDataManager, ); expect(found).to.equal(provider2); }); @@ -129,12 +129,12 @@ describe("ContextProviderRegistryContainer", () => { describe("removeProvider", () => { it("should remove provider by ContextProvider instance", () => { container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); const providerInstance = new MockContextProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, }); container.removeProvider(providerInstance); @@ -145,38 +145,38 @@ describe("ContextProviderRegistryContainer", () => { it("should remove only the matching provider", () => { const provider2 = { constructor: MockContextProvider, - config: { name: ContextProviderName.PlanewaveCutoffDataManager }, + config: { name: ContextProviderNameEnum.PlanewaveCutoffDataManager }, }; container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); container.addProvider({ - name: ContextProviderName.PlanewaveCutoffDataManager, + name: ContextProviderNameEnum.PlanewaveCutoffDataManager, instance: provider2, }); const providerInstance = new MockContextProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, }); container.removeProvider(providerInstance); // The removeProvider method should remove the matching provider expect(container.providers).to.have.length(1); expect(container.providers[0].name).to.equal( - ContextProviderName.PlanewaveCutoffDataManager, + ContextProviderNameEnum.PlanewaveCutoffDataManager, ); }); it("should not remove anything if provider not found", () => { container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); const nonExistentProvider = new MockContextProvider({ - name: ContextProviderName.KGridFormDataManager, + name: ContextProviderNameEnum.KGridFormDataManager, }); container.removeProvider(nonExistentProvider); @@ -187,13 +187,13 @@ describe("ContextProviderRegistryContainer", () => { describe("removeProviderByName", () => { it("should remove provider by name", () => { container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); expect(container.providers).to.have.length(1); - container.removeProviderByName(ContextProviderName.QGridFormDataManager); + container.removeProviderByName(ContextProviderNameEnum.QGridFormDataManager); expect(container.providers).to.have.length(0); }); @@ -201,33 +201,33 @@ describe("ContextProviderRegistryContainer", () => { it("should remove only the matching provider by name", () => { const provider2 = { constructor: MockContextProvider, - config: { name: ContextProviderName.PlanewaveCutoffDataManager }, + config: { name: ContextProviderNameEnum.PlanewaveCutoffDataManager }, }; container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); container.addProvider({ - name: ContextProviderName.PlanewaveCutoffDataManager, + name: ContextProviderNameEnum.PlanewaveCutoffDataManager, instance: provider2, }); - container.removeProviderByName(ContextProviderName.QGridFormDataManager); + container.removeProviderByName(ContextProviderNameEnum.QGridFormDataManager); expect(container.providers).to.have.length(1); expect(container.providers[0].name).to.equal( - ContextProviderName.PlanewaveCutoffDataManager, + ContextProviderNameEnum.PlanewaveCutoffDataManager, ); }); it("should not remove anything if provider name not found", () => { container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); - container.removeProviderByName(ContextProviderName.KGridFormDataManager); + container.removeProviderByName(ContextProviderNameEnum.KGridFormDataManager); expect(container.providers).to.have.length(1); }); @@ -237,33 +237,33 @@ describe("ContextProviderRegistryContainer", () => { it("should handle full lifecycle: add, find, remove", () => { // Add providers container.addProvider({ - name: ContextProviderName.QGridFormDataManager, + name: ContextProviderNameEnum.QGridFormDataManager, instance: mockProviderInstance, }); container.addProvider({ - name: ContextProviderName.PlanewaveCutoffDataManager, + name: ContextProviderNameEnum.PlanewaveCutoffDataManager, instance: mockProviderInstance, }); // Verify they exist expect( - container.findProviderInstanceByName(ContextProviderName.QGridFormDataManager), + container.findProviderInstanceByName(ContextProviderNameEnum.QGridFormDataManager), ).to.equal(mockProviderInstance); expect( container.findProviderInstanceByName( - ContextProviderName.PlanewaveCutoffDataManager, + ContextProviderNameEnum.PlanewaveCutoffDataManager, ), ).to.equal(mockProviderInstance); // Remove one - container.removeProviderByName(ContextProviderName.QGridFormDataManager); + container.removeProviderByName(ContextProviderNameEnum.QGridFormDataManager); // Verify state - expect(container.findProviderInstanceByName(ContextProviderName.QGridFormDataManager)) + expect(container.findProviderInstanceByName(ContextProviderNameEnum.QGridFormDataManager)) .to.be.undefined; expect( container.findProviderInstanceByName( - ContextProviderName.PlanewaveCutoffDataManager, + ContextProviderNameEnum.PlanewaveCutoffDataManager, ), ).to.equal(mockProviderInstance); expect(container.providers).to.have.length(1); diff --git a/tests/js/provider.tests.ts b/tests/js/provider.tests.ts index 419773b..18873cb 100644 --- a/tests/js/provider.tests.ts +++ b/tests/js/provider.tests.ts @@ -1,9 +1,10 @@ +import { Name as ContextProviderNameEnum } from "@mat3ra/esse/dist/js/types"; import { expect } from "chai"; -import ContextProvider, { ContextProviderName } from "../../src/js/context/ContextProvider"; +import ContextProvider from "../../src/js/context/ContextProvider"; describe("ContextProvider", () => { - const minimal = { name: ContextProviderName.KGridFormDataManager }; + const minimal = { name: ContextProviderNameEnum.KGridFormDataManager }; const data = { a: "test" }; it("can be created", () => { diff --git a/tests/js/template.test.ts b/tests/js/template.test.ts index 33bdb61..68ba295 100644 --- a/tests/js/template.test.ts +++ b/tests/js/template.test.ts @@ -1,4 +1,5 @@ /* eslint-disable no-unused-expressions */ +import { Name as ContextProviderNameEnum } from "@mat3ra/esse/dist/js/types"; import { expect } from "chai"; import ContextProvider from "../../src/js/context/ContextProvider"; @@ -19,35 +20,35 @@ class MockContextProvider extends ContextProvider { // Set up the static context provider registry before tests const mockConfig: ContextProviderConfigMapEntry = { providerCls: MockContextProvider, - config: { name: "QGridFormDataManager" }, + config: { name: ContextProviderNameEnum.QGridFormDataManager }, }; const providersConfig: ContextProviderConfigMap = { - QGridFormDataManager: mockConfig, - PlanewaveCutoffDataManager: mockConfig, - KGridFormDataManager: mockConfig, - IGridFormDataManager: mockConfig, - QPathFormDataManager: mockConfig, - IPathFormDataManager: mockConfig, - KPathFormDataManager: mockConfig, - ExplicitKPathFormDataManager: mockConfig, - ExplicitKPath2PIBAFormDataManager: mockConfig, - HubbardJContextManager: mockConfig, - HubbardUContextManager: mockConfig, - HubbardVContextManager: mockConfig, - HubbardContextManagerLegacy: mockConfig, - NEBFormDataManager: mockConfig, - BoundaryConditionsFormDataManager: mockConfig, - MLSettingsDataManager: mockConfig, - MLTrainTestSplitDataManager: mockConfig, - IonDynamicsContextProvider: mockConfig, - CollinearMagnetizationDataManager: mockConfig, - NonCollinearMagnetizationDataManager: mockConfig, - QEPWXInputDataManager: mockConfig, - QENEBInputDataManager: mockConfig, - VASPInputDataManager: mockConfig, - VASPNEBInputDataManager: mockConfig, - NWChemInputDataManager: mockConfig, + [ContextProviderNameEnum.QGridFormDataManager]: mockConfig, + [ContextProviderNameEnum.PlanewaveCutoffDataManager]: mockConfig, + [ContextProviderNameEnum.KGridFormDataManager]: mockConfig, + [ContextProviderNameEnum.IGridFormDataManager]: mockConfig, + [ContextProviderNameEnum.QPathFormDataManager]: mockConfig, + [ContextProviderNameEnum.IPathFormDataManager]: mockConfig, + [ContextProviderNameEnum.KPathFormDataManager]: mockConfig, + [ContextProviderNameEnum.ExplicitKPathFormDataManager]: mockConfig, + [ContextProviderNameEnum.ExplicitKPath2PIBAFormDataManager]: mockConfig, + [ContextProviderNameEnum.HubbardJContextManager]: mockConfig, + [ContextProviderNameEnum.HubbardUContextManager]: mockConfig, + [ContextProviderNameEnum.HubbardVContextManager]: mockConfig, + [ContextProviderNameEnum.HubbardContextManagerLegacy]: mockConfig, + [ContextProviderNameEnum.NEBFormDataManager]: mockConfig, + [ContextProviderNameEnum.BoundaryConditionsFormDataManager]: mockConfig, + [ContextProviderNameEnum.MLSettingsDataManager]: mockConfig, + [ContextProviderNameEnum.MLTrainTestSplitDataManager]: mockConfig, + [ContextProviderNameEnum.IonDynamicsContextProvider]: mockConfig, + [ContextProviderNameEnum.CollinearMagnetizationDataManager]: mockConfig, + [ContextProviderNameEnum.NonCollinearMagnetizationDataManager]: mockConfig, + [ContextProviderNameEnum.QEPWXInputDataManager]: mockConfig, + [ContextProviderNameEnum.QENEBInputDataManager]: mockConfig, + [ContextProviderNameEnum.VASPInputDataManager]: mockConfig, + [ContextProviderNameEnum.VASPNEBInputDataManager]: mockConfig, + [ContextProviderNameEnum.NWChemInputDataManager]: mockConfig, }; before(() => { @@ -203,7 +204,7 @@ describe("Template", () => { describe("addContextProvider method", () => { it("should add a context provider", () => { const provider = new MockContextProvider({ - name: "QGridFormDataManager", + name: ContextProviderNameEnum.QGridFormDataManager, domain: "test", }); const initialLength = template.contextProviders.length; @@ -216,11 +217,11 @@ describe("Template", () => { describe("removeContextProvider method", () => { it("should remove a context provider by name and domain", () => { const provider1 = new MockContextProvider({ - name: "QGridFormDataManager", + name: ContextProviderNameEnum.QGridFormDataManager, domain: "domain1", }); const provider2 = new MockContextProvider({ - name: "PlanewaveCutoffDataManager", + name: ContextProviderNameEnum.PlanewaveCutoffDataManager, domain: "domain2", }); template.setProp("contextProviders", [provider1, provider2]); @@ -316,11 +317,11 @@ describe("Template", () => { // Added with LLM to help with coverage it("should handle getDataFromProvidersForPersistentContext with edited providers", () => { - const editedProvider = new MockContextProvider({ name: "QGridFormDataManager", domain: "test" }); + const editedProvider = new MockContextProvider({ name: ContextProviderNameEnum.QGridFormDataManager, domain: "test" }); editedProvider.isEdited = true; editedProvider.yieldData = () => ({ data: { value: 1 } }); - const nonEditedProvider = new MockContextProvider({ name: "PlanewaveCutoffDataManager", domain: "test" }); + const nonEditedProvider = new MockContextProvider({ name: ContextProviderNameEnum.PlanewaveCutoffDataManager, domain: "test" }); nonEditedProvider.isEdited = false; nonEditedProvider.yieldData = () => ({ data: { value: 2 } }); diff --git a/tests/py/test_integration.py b/tests/py/test_integration.py index 7545c18..0d0705b 100644 --- a/tests/py/test_integration.py +++ b/tests/py/test_integration.py @@ -110,9 +110,13 @@ def test_import_all_from_package(self): from mat3ra.ade import ( Application, ContextProvider, + ContextProviderName, Executable, Flavor, FlavorInput, + JinjaContextProvider, + JSONSchemaDataProvider, + JSONSchemaFormDataProvider, Template, ) @@ -123,3 +127,7 @@ def test_import_all_from_package(self): assert FlavorInput is not None assert Template is not None assert ContextProvider is not None + assert ContextProviderName is not None + assert JinjaContextProvider is not None + assert JSONSchemaDataProvider is not None + assert JSONSchemaFormDataProvider is not None diff --git a/tests/py/test_template.py b/tests/py/test_template.py index d00ec8a..b5a58d8 100644 --- a/tests/py/test_template.py +++ b/tests/py/test_template.py @@ -1,7 +1,27 @@ """Tests for Template class.""" import pytest -from mat3ra.ade import ContextProvider, Template +from mat3ra.ade import ( + ContextProvider, + ContextProviderName, + JinjaContextProvider, + JSONSchemaDataProvider, + JSONSchemaFormDataProvider, + Template, +) + + +class TestContextProviderName: + """Test suite for ContextProviderName enum.""" + + def test_context_provider_name_enum_values(self): + """Test that ContextProviderName enum has expected values.""" + assert ContextProviderName.PlanewaveCutoffDataManager == "PlanewaveCutoffDataManager" + assert ContextProviderName.KGridFormDataManager == "KGridFormDataManager" + assert ContextProviderName.QGridFormDataManager == "QGridFormDataManager" + assert ContextProviderName.IonDynamicsContextProvider == "IonDynamicsContextProvider" + assert ContextProviderName.VASPInputDataManager == "VASPInputDataManager" + assert ContextProviderName.NWChemInputDataManager == "NWChemInputDataManager" class TestContextProvider: @@ -17,6 +37,160 @@ def test_context_provider_validation(self): with pytest.raises(Exception): ContextProvider() # Should raise validation error for missing name + def test_context_provider_full_creation(self): + """Test ContextProvider creation with all fields.""" + provider = ContextProvider( + name="KGridFormDataManager", + domain="test_domain", + entity_name="subworkflow", + data={"key": "value"}, + extra_data={"extra_key": "extra_value"}, + is_edited=True, + context={"context_key": "context_value"}, + ) + assert provider.name == "KGridFormDataManager" + assert provider.domain == "test_domain" + assert provider.entity_name == "subworkflow" + assert provider.data == {"key": "value"} + assert provider.extra_data == {"extra_key": "extra_value"} + assert provider.is_edited is True + assert provider.context == {"context_key": "context_value"} + + def test_context_provider_default_values(self): + """Test ContextProvider default values.""" + provider = ContextProvider(name="test") + assert provider.domain == "default" + assert provider.entity_name == "unit" + assert provider.data is None + assert provider.extra_data is None + assert provider.is_edited is None + assert provider.context is None + + def test_context_provider_extra_data_key(self): + """Test extra_data_key property.""" + provider = ContextProvider(name="kpath") + assert provider.extra_data_key == "kpathExtraData" + + def test_context_provider_is_edited_key(self): + """Test is_edited_key property.""" + provider = ContextProvider(name="kpath") + assert provider.is_edited_key == "isKpathEdited" + + def test_context_provider_is_unit_context_provider(self): + """Test is_unit_context_provider property.""" + unit_provider = ContextProvider(name="test", entity_name="unit") + assert unit_provider.is_unit_context_provider is True + subworkflow_provider = ContextProvider(name="test", entity_name="subworkflow") + assert subworkflow_provider.is_unit_context_provider is False + + def test_context_provider_is_subworkflow_context_provider(self): + """Test is_subworkflow_context_provider property.""" + unit_provider = ContextProvider(name="test", entity_name="unit") + assert unit_provider.is_subworkflow_context_provider is False + subworkflow_provider = ContextProvider(name="test", entity_name="subworkflow") + assert subworkflow_provider.is_subworkflow_context_provider is True + + +class TestJinjaContextProvider: + """Test suite for JinjaContextProvider class.""" + + def test_jinja_context_provider_creation(self): + """Test JinjaContextProvider creation.""" + provider = JinjaContextProvider(name="test") + assert provider.name == "test" + assert provider.is_using_jinja_variables is False + + def test_jinja_context_provider_with_jinja_variables(self): + """Test JinjaContextProvider with is_using_jinja_variables set.""" + provider = JinjaContextProvider(name="test", is_using_jinja_variables=True) + assert provider.is_using_jinja_variables is True + + def test_jinja_context_provider_inherits_context_provider(self): + """Test that JinjaContextProvider inherits from ContextProvider.""" + provider = JinjaContextProvider( + name="test", + domain="custom", + entity_name="subworkflow", + is_using_jinja_variables=True, + ) + assert provider.domain == "custom" + assert provider.entity_name == "subworkflow" + assert provider.is_using_jinja_variables is True + assert provider.is_subworkflow_context_provider is True + + +class TestJSONSchemaDataProvider: + """Test suite for JSONSchemaDataProvider class.""" + + def test_json_schema_data_provider_creation(self): + """Test JSONSchemaDataProvider creation.""" + provider = JSONSchemaDataProvider(name="test") + assert provider.name == "test" + assert provider.json_schema is None + + def test_json_schema_data_provider_with_schema(self): + """Test JSONSchemaDataProvider with json_schema set.""" + schema = {"type": "object", "properties": {"value": {"type": "number"}}} + provider = JSONSchemaDataProvider(name="test", json_schema=schema) + assert provider.json_schema == schema + + def test_json_schema_data_provider_inherits_jinja(self): + """Test that JSONSchemaDataProvider inherits from JinjaContextProvider.""" + provider = JSONSchemaDataProvider( + name="test", + is_using_jinja_variables=True, + json_schema={"type": "object"}, + ) + assert provider.is_using_jinja_variables is True + assert provider.json_schema == {"type": "object"} + + +class TestJSONSchemaFormDataProvider: + """Test suite for JSONSchemaFormDataProvider class.""" + + def test_json_schema_form_data_provider_creation(self): + """Test JSONSchemaFormDataProvider creation.""" + provider = JSONSchemaFormDataProvider(name="test") + assert provider.name == "test" + assert provider.ui_schema is None + assert provider.fields == {} + assert provider.default_field_styles == {} + + def test_json_schema_form_data_provider_with_all_fields(self): + """Test JSONSchemaFormDataProvider with all fields.""" + provider = JSONSchemaFormDataProvider( + name="test", + json_schema={"type": "object"}, + ui_schema={"ui:widget": "textarea"}, + fields={"custom": "field"}, + default_field_styles={"margin": "10px"}, + ) + assert provider.json_schema == {"type": "object"} + assert provider.ui_schema == {"ui:widget": "textarea"} + assert provider.fields == {"custom": "field"} + assert provider.default_field_styles == {"margin": "10px"} + + def test_json_schema_form_data_provider_inherits_hierarchy(self): + """Test that JSONSchemaFormDataProvider inherits full hierarchy.""" + provider = JSONSchemaFormDataProvider( + name="test", + domain="custom", + entity_name="unit", + is_using_jinja_variables=True, + json_schema={"type": "object"}, + ui_schema={"ui:widget": "select"}, + ) + # From ContextProvider + assert provider.domain == "custom" + assert provider.entity_name == "unit" + assert provider.is_unit_context_provider is True + # From JinjaContextProvider + assert provider.is_using_jinja_variables is True + # From JSONSchemaDataProvider + assert provider.json_schema == {"type": "object"} + # From JSONSchemaFormDataProvider + assert provider.ui_schema == {"ui:widget": "select"} + class TestTemplate: """Test suite for Template class."""