diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 19e9da319..a6195ce26 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,30 +1,26 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: // https://github.com/microsoft/vscode-dev-containers/tree/v0.191.1/containers/javascript-node { - "name": "Node.js", - "build": { - "dockerfile": "Dockerfile", - // Update 'VARIANT' to pick a Node version: 14, 16 - "args": { - "VARIANT": "14" - } - }, - // Set *default* container specific settings.json values on container create. - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "esbenp.prettier-vscode", - "ms-vscode.vscode-typescript-tslint-plugin", - "vue.volar" - ], - "settings": { - "editor.formatOnSave": false, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "prettier.jsxSingleQuote": true, - "prettier.singleQuote": true - }, - - // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "npm ci && npm run init && npm run build", - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "node" -} \ No newline at end of file + "name": "Node.js", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick a Node version: 14, 16 + "args": { + "VARIANT": "14" + } + }, + // Set *default* container specific settings.json values on container create. + // Add the IDs of extensions you want installed when the container is created. + "customizations": { + "extensions": [ + "DavidAnson.vscode-markdownlint", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "vue.volar" + ] + }, + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "npm ci && npm run init && npm run build", + // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "node" +} diff --git a/.github/config/changelog.json b/.github/config/changelog.json index 586fc7c7c..04256b89c 100644 --- a/.github/config/changelog.json +++ b/.github/config/changelog.json @@ -2,7 +2,5 @@ "sort": "DESC", "pr_template": "- [${{LABELS}}] ${{TITLE}} (#${{NUMBER}})", "template": "${{UNCATEGORIZED}}", - "ignore_labels": [ - "dependencies" - ] + "ignore_labels": ["dependencies"] } diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7a5d0a379..5ab0439a8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,29 +15,32 @@ jobs: - windows-latest name: Run on ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - name: Setup node - uses: actions/setup-node@v2 - with: - node-version: 14 - - name: Build - run: | - npm ci - npm run init - npm run build - npm run bundle - - name: Test - if: matrix.os == 'windows-latest' - run: | - npm run test - - name: Test & Coverage - if: matrix.os == 'ubuntu-latest' - run: | - npm run test-cov - npm run check-format - npm run merge-report && cat coverage/lcov.info - - name: Upload Coveralls Report - if: success() && matrix.os == 'ubuntu-latest' - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 14 + - name: Build + run: | + npm ci + npm run init + npm run build + npm run bundle + - name: Lint + if: matrix.os == 'ubuntu-latest' + run: npm run lint + - name: Test + if: matrix.os == 'windows-latest' + run: | + npm run test + - name: Test & Coverage + if: matrix.os == 'ubuntu-latest' + run: | + npm run test-cov + npm run check-format + npm run merge-report && cat coverage/lcov.info + - name: Upload Coveralls Report + if: success() && matrix.os == 'ubuntu-latest' + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a23551150..8a001f488 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -6,7 +6,7 @@ on: jobs: release: - if: | + if: | startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 93fff0417..000000000 --- a/.prettierrc +++ /dev/null @@ -1,2 +0,0 @@ -singleQuote: true -jsxSingleQuote: true \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..2c26853c4 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + $schema: 'http://json.schemastore.org/prettierrc', + singleQuote: true, + jsxSingleQuote: true, + endOfLine: 'auto', +}; diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 6bc77f479..460ca3db3 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,13 +1,12 @@ { // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp - // List of extensions which should be recommended for users of this workspace. "recommendations": [ + "DavidAnson.vscode-markdownlint", + "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", - "ms-vscode.vscode-typescript-tslint-plugin", "ms-vscode-remote.remote-containers" - ], // List of extensions recommended by VS Code that should not be recommended for users of this workspace. "unwantedRecommendations": [] diff --git a/.vscode/settings.json b/.vscode/settings.json index 34caaf616..9c94fbac5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,49 @@ { - "editor.formatOnSave": false, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue" + ], + "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", - "prettier.jsxSingleQuote": true, - "prettier.singleQuote": true -} \ No newline at end of file + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } + }, + "[javascriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } + }, + "[vue]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } + }, + "search.exclude": { + "**/docs": true, + "**/node_modules": true, + "**/lib": true + } +} diff --git a/MIGRATION.md b/MIGRATION.md index 909c8b287..9458c2f80 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -24,8 +24,16 @@ interface TesterContext { config: any; } -type Tester = (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => boolean; -type RankedTester = (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => number; +type Tester = ( + uischema: UISchemaElement, + schema: JsonSchema, + context: TesterContext +) => boolean; +type RankedTester = ( + uischema: UISchemaElement, + schema: JsonSchema, + context: TesterContext +) => number; ``` This allows the testers to resolve any `$ref` they might encounter in their handed over `schema` by using the context's `rootSchema`. @@ -50,7 +58,10 @@ To restore the old behavior, you can use `json-schema-ref-parser` or other libra ```ts import React, { useState } from 'react'; import { JsonForms } from '@jsonforms/react'; -import { materialCells, materialRenderers } from '@jsonforms/material-renderers'; +import { + materialCells, + materialRenderers, +} from '@jsonforms/material-renderers'; import $RefParser from '@apidevtools/json-schema-ref-parser'; import JsonRefs from 'json-refs'; @@ -58,22 +69,26 @@ import mySchemaWithReferences from 'myschema.json'; const refParserOptions = { dereference: { - circular: false - } -} + circular: false, + }, +}; function App() { const [data, setData] = useState(initialData); const [resolvedSchema, setSchema] = useState(); useEffect(() => { - $RefParser.dereference(mySchemaWithReferences).then(res => setSchema(res.$schema)); + $RefParser + .dereference(mySchemaWithReferences) + .then((res) => setSchema(res.$schema)); // or - JsonRefs.resolveRefs(mySchemaWithReferences).then(res => setSchema(res.resolved)); - },[]); + JsonRefs.resolveRefs(mySchemaWithReferences).then((res) => + setSchema(res.resolved) + ); + }, []); - if(resolvedSchema === undefined) { - return
Loading...
+ if (resolvedSchema === undefined) { + return
Loading...
; } return ( @@ -143,12 +158,12 @@ export const schema = { type: 'object', properties: { name: { - type: 'string' - } + type: 'string', + }, }, - required: ['name'] + required: ['name'], }; -export const data = {name: 'Send email to Adrian'}; +export const data = { name: 'Send email to Adrian' }; @Component({ selector: 'app-root', @@ -160,7 +175,7 @@ export const data = {name: 'Send email to Adrian'}; [renderers]="renderers" (dataChange)="onDataChange($event)" > - ` + `, }) export class AppComponent { readonly renderers = angularMaterialRenderers; @@ -201,15 +216,12 @@ All current Redux functionally can also be achieved with the standalone version. Previously the store was initialized like this: ```ts -const store = createStore( - combineReducers({ jsonforms: jsonformsReducer() }), - { - jsonforms: { - cells: materialCells, - renderers: materialRenderers - } - } -); +const store = createStore(combineReducers({ jsonforms: jsonformsReducer() }), { + jsonforms: { + cells: materialCells, + renderers: materialRenderers, + }, +}); store.dispatch(Actions.init(data, schema, uischema)); return ( @@ -250,7 +262,7 @@ Within the standalone version, the renderer can just be provided to the ` ( @@ -259,7 +271,6 @@ const MyApp = () => ( renderers={renderers} /> ); - ``` ##### Example 3: Listen to data and validation changes @@ -286,7 +297,10 @@ If you want to keep using the Redux variant of JSON Forms for now (which is not The new imports are available at `@jsonforms/react/lib/redux`, i.e. ```ts -import { jsonformsReducer, JsonFormsReduxProvider } from '@jsonforms/react/lib/redux'; +import { + jsonformsReducer, + JsonFormsReduxProvider, +} from '@jsonforms/react/lib/redux'; ``` ## Migrating from JSON Forms 1.x (AngularJS 1.x) @@ -298,8 +312,8 @@ The complexity of the migration of an existing JSON Forms 1.x application, which There are two big changes between JSON Forms 1 and JSON Forms 2 you need to understand when migrating your existing application. 1. JSON Forms 2.x does not rely on any specific UI framework [or library]. - The `2.0.0` initial release featured renderers based on [React](https://reactjs.org). - An [Angular](https://angular.io) based renderer set was released with `2.1.0`. + The `2.0.0` initial release featured renderers based on [React](https://reactjs.org). + An [Angular](https://angular.io) based renderer set was released with `2.1.0`. 2. Since JSON Forms 2.x maintains its internal state via [redux](https://redux.js.org/), you will need to add it as a dependency to your application. @@ -314,20 +328,20 @@ Instead of: ```ts const uischema = { - type: 'Control', - scope: { - $ref: '#/properties/name' - } -} + type: 'Control', + scope: { + $ref: '#/properties/name', + }, +}; ``` simply write: ```ts const uischema = { - type: 'Control', - scope: '#/properties/name' -} + type: 'Control', + scope: '#/properties/name', +}; ``` Otherwise the UI schema remains unchanged and works like in JSON Forms 1.x. diff --git a/README.md b/README.md index 36cb2cb4e..6923a41de 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # JSON Forms - More Forms. Less Code -*Complex forms in the blink of an eye* +_Complex forms in the blink of an eye_ ## Documentation @@ -32,28 +32,28 @@ In addition, EclipseSource also offers [professional support](https://jsonforms. ### First time setup -* Install [node.js](https://nodejs.org/) (only Node 14 and npm 6 is currently supported) -* Clone this repository -* Install dependencies: `npm ci` -* Hook up dependencies between packages: `npm run init` +- Install [node.js](https://nodejs.org/) (only Node 14 and npm 6 is currently supported) +- Clone this repository +- Install dependencies: `npm ci` +- Hook up dependencies between packages: `npm run init` ### VS Code dev container As an alternative to the first time setup, you can use the provided [VS Code dev container](https://code.visualstudio.com/docs/remote/containers) configured in [devcontainer.json](.devcontainer/devcontainer.json). -* Execute command: `Remote Containers: Reopen in container` -* Wait until the container is built and loaded -* First time setup and an initial build of all packages has been executed in the container +- Execute command: `Remote Containers: Reopen in container` +- Wait until the container is built and loaded +- First time setup and an initial build of all packages has been executed in the container ### Build & Testing -* Build (all packages): `npm run build` -* Test (all packages): `npm run test` -* Clean (delete `dist` folder of all packages): `npm run clean` -* Run React Vanilla examples: `cd packages/vanilla && npm run dev` -* Run React Material examples: `cd packages/material && npm run dev` -* Run Angular Material examples: `cd packages/angular-material && npm run dev` -* Run Vue Vanilla dev setup: `cd packages/vue/vue-vanilla && npm run serve` +- Build (all packages): `npm run build` +- Test (all packages): `npm run test` +- Clean (delete `dist` folder of all packages): `npm run clean` +- Run React Vanilla examples: `cd packages/vanilla && npm run dev` +- Run React Material examples: `cd packages/material && npm run dev` +- Run Angular Material examples: `cd packages/angular-material && npm run dev` +- Run Vue Vanilla dev setup: `cd packages/vue/vue-vanilla && npm run serve` ### Dependency & Release management diff --git a/ROADMAP.md b/ROADMAP.md index 916d7eccc..f58e51c5b 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,8 +3,10 @@ This roadmap defines our current view on how we will continue with the development of JSON Forms on a very coarse-grained level and is subject to change at any time: H1/2023 - * Improve developer tooling - * Improve release process to allow for more and less effort releases + +- Improve developer tooling +- Improve release process to allow for more and less effort releases H2/2023 - * Improve adopter experience + +- Improve adopter experience diff --git a/lerna.json b/lerna.json index b30a9f999..506e14a72 100644 --- a/lerna.json +++ b/lerna.json @@ -4,7 +4,7 @@ "packages/vue/*", "packages/vue2/*" ], - "version": "3.1.0-alpha.1", + "version": "3.1.0-alpha.2", "nohoist": [ "core-js", "vue", diff --git a/package-lock.json b/package-lock.json index 1554df93e..a5944fb51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,92 @@ } } }, + "@angular-eslint/bundled-angular-compiler": { + "version": "12.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-12.7.0.tgz", + "integrity": "sha512-n7nUSIK+bl2DQXIPRyts/xVTw94Mk0rRNd2WBCL9ni27XKOhKtTdP7tLpD+nAiuY4BTTJr7/yTzPWCCRDQgWZg==" + }, + "@angular-eslint/eslint-plugin": { + "version": "12.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-12.7.0.tgz", + "integrity": "sha512-TTTimCddON6TdGw3NDglgWqnrP2VLFiAA+FJAg/iiCKKVI+XOddtpDXmeHmas8cHIJXJH1WNxrae394DpThiOA==", + "requires": { + "@angular-eslint/utils": "12.7.0", + "@typescript-eslint/experimental-utils": "4.28.2" + } + }, + "@angular-eslint/eslint-plugin-template": { + "version": "12.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-12.7.0.tgz", + "integrity": "sha512-G/UIifRNZuk0Vc3Q2bjAvRa2MMMCSuSzW3E9QAvSr0n4QkhIJwDJvyR/KV1ubswgHB0RRkYcfGQ8d6VKA5Vqjw==", + "requires": { + "@angular-eslint/bundled-angular-compiler": "12.7.0", + "@typescript-eslint/experimental-utils": "4.28.2", + "aria-query": "^4.2.2", + "axobject-query": "^2.2.0" + } + }, + "@angular-eslint/schematics": { + "version": "12.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-12.7.0.tgz", + "integrity": "sha512-qt5OiCk5kTr+l8XG+WJxLhwvZMT5MWPBCK/rknCpIEd4z2HkOK24Cttuj3jdOYJ3abQ0ha4SiIne5LkrEZBoLw==", + "requires": { + "@angular-eslint/eslint-plugin": "12.7.0", + "@angular-eslint/eslint-plugin-template": "12.7.0", + "ignore": "5.1.9", + "strip-json-comments": "3.1.1", + "tmp": "0.2.1" + }, + "dependencies": { + "ignore": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==" + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + } + } + }, + "@angular-eslint/template-parser": { + "version": "12.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-12.7.0.tgz", + "integrity": "sha512-bTGRZ/2m2Z/MCoazWnpbPWLSBK8AsnHCuCXAgiiveYql0GD+PySP1EkBuiWesIyxCsYdzf4aQciJSVuQRo9jEQ==", + "requires": { + "@angular-eslint/bundled-angular-compiler": "12.7.0", + "eslint-scope": "^5.1.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + } + } + }, + "@angular-eslint/utils": { + "version": "12.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-12.7.0.tgz", + "integrity": "sha512-1yyRxtxXg6VoyU8wUDcaZEdN7oDE0pRRCUZsQBGungPSv5PQt4nlv+9ZnjJ93rVMEoGztHD2CBWeoRtNlqvg4A==", + "requires": { + "@angular-eslint/bundled-angular-compiler": "12.7.0", + "@typescript-eslint/experimental-utils": "4.28.2" + } + }, "@angular/animations": { "version": "12.2.17", "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-12.2.17.tgz", @@ -111,9 +197,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "requires": { "lru-cache": "^6.0.0" } @@ -137,9 +223,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -316,17 +402,54 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", - "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz", + "integrity": "sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/helper-split-export-declaration": "^7.18.6" + }, + "dependencies": { + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-create-regexp-features-plugin": { @@ -382,11 +505,23 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", + "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.21.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-module-imports": { @@ -437,15 +572,90 @@ } }, "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", + "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.20.7", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "dependencies": { + "@babel/generator": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", + "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "requires": { + "@babel/types": "^7.21.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", + "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "requires": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "requires": { + "@babel/highlight": "^7.18.6" + } + } + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-simple-access": { @@ -532,19 +742,32 @@ } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", + "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.7" + }, + "dependencies": { + "@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + } } }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.20.1", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", + "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-plugin-utils": "^7.19.0", @@ -562,25 +785,25 @@ } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-decorators": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz", - "integrity": "sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz", + "integrity": "sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/plugin-syntax-decorators": "^7.19.0" + "@babel/plugin-syntax-decorators": "^7.21.0" } }, "@babel/plugin-proposal-dynamic-import": { @@ -611,11 +834,11 @@ } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, @@ -638,15 +861,54 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" + "@babel/plugin-transform-parameters": "^7.20.7" + }, + "dependencies": { + "@babel/helper-compilation-targets": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", + "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "requires": { + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "dependencies": { + "@babel/compat-data": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", + "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==" + } + } + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==" + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -662,6 +924,7 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", @@ -678,12 +941,12 @@ } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", - "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", + "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.20.5", + "@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" } @@ -730,11 +993,11 @@ } }, "@babel/plugin-syntax-decorators": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", - "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz", + "integrity": "sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-syntax-dynamic-import": { @@ -778,11 +1041,11 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", + "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -850,29 +1113,29 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", + "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", + "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", "requires": { "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9" } }, "@babel/plugin-transform-block-scoped-functions": { @@ -884,41 +1147,140 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", - "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", + "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", "requires": { "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", + "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" + }, + "dependencies": { + "@babel/compat-data": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", + "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==" + }, + "@babel/helper-compilation-targets": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", + "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "requires": { + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + } + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==" + }, + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } } }, "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", + "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7" + }, + "dependencies": { + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", + "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", "requires": { "@babel/helper-plugin-utils": "^7.20.2" } @@ -950,11 +1312,11 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", + "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-function-name": { @@ -984,12 +1346,101 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", + "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2" + }, + "dependencies": { + "@babel/generator": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", + "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "requires": { + "@babel/types": "^7.21.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + } + }, + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", + "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "requires": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "requires": { + "@babel/highlight": "^7.18.6" + } + } + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-modules-commonjs": { @@ -1003,14 +1454,103 @@ } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", + "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", "requires": { "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-identifier": "^7.19.1" + }, + "dependencies": { + "@babel/generator": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", + "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "requires": { + "@babel/types": "^7.21.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + } + }, + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", + "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "requires": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "requires": { + "@babel/highlight": "^7.18.6" + } + } + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-modules-umd": { @@ -1049,9 +1589,9 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", - "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", + "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", "requires": { "@babel/helper-plugin-utils": "^7.20.2" } @@ -1082,17 +1622,37 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz", + "integrity": "sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA==", "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-plugin-utils": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", "semver": "^6.3.0" - } + }, + "dependencies": { + "@babel/helper-module-imports": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", + "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "requires": { + "@babel/types": "^7.21.4" + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } + } }, "@babel/plugin-transform-shorthand-properties": { "version": "7.18.6", @@ -1103,12 +1663,12 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", + "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" } }, "@babel/plugin-transform-sticky-regex": { @@ -1136,11 +1696,12 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", - "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz", + "integrity": "sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.2", + "@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-typescript": "^7.20.0" } @@ -1163,30 +1724,30 @@ } }, "@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", + "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/compat-data": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", + "@babel/helper-validator-option": "^7.21.0", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", + "@babel/plugin-proposal-async-generator-functions": "^7.20.7", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.21.0", "@babel/plugin-proposal-dynamic-import": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.21.0", "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.21.0", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -1203,45 +1764,200 @@ "@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.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.20.7", + "@babel/plugin-transform-async-to-generator": "^7.20.7", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-block-scoping": "^7.21.0", + "@babel/plugin-transform-classes": "^7.21.0", + "@babel/plugin-transform-computed-properties": "^7.20.7", + "@babel/plugin-transform-destructuring": "^7.21.3", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-for-of": "^7.21.0", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-amd": "^7.20.11", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-modules-systemjs": "^7.20.11", "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-parameters": "^7.21.3", "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.20.5", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-spread": "^7.20.7", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", + "@babel/types": "^7.21.4", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", "core-js-compat": "^3.25.1", "semver": "^6.3.0" + }, + "dependencies": { + "@babel/compat-data": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", + "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==" + }, + "@babel/generator": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", + "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "requires": { + "@babel/types": "^7.21.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", + "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "requires": { + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + } + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + } + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==" + }, + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", + "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", + "requires": { + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-simple-access": "^7.20.2" + } + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", + "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "requires": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "requires": { + "@babel/highlight": "^7.18.6" + } + } + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } } }, "@babel/preset-modules": { @@ -1257,27 +1973,133 @@ } }, "@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.4.tgz", + "integrity": "sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.21.0", + "@babel/plugin-syntax-jsx": "^7.21.4", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-typescript": "^7.21.3" + }, + "dependencies": { + "@babel/generator": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", + "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "requires": { + "@babel/types": "^7.21.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + } + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==" + }, + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", + "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", + "requires": { + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-simple-access": "^7.20.2" + } + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", + "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "requires": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "requires": { + "@babel/highlight": "^7.18.6" + } + } + } + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/runtime": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", - "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "requires": { "regenerator-runtime": "^0.13.11" } }, "@babel/runtime-corejs2": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.20.6.tgz", - "integrity": "sha512-6qz3LPkwPDBDEAOsf/fXdsX/c5u2GNy33QlY1caaR8qPVG2Q0tTkS0mKYMXRhT9wsDQAAEj4T7scykRB3nBjWA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.21.0.tgz", + "integrity": "sha512-hVFDLYkuthnvQwWoOniPSq+RWyQTiimVdMXQJujoiSX8maFh/62+qRImGkRpeRflsVXXSMFS4HgNe3X9fuw5ww==", "requires": { "core-js": "^2.6.12", "regenerator-runtime": "^0.13.11" @@ -1290,6 +2112,15 @@ } } }, + "@babel/runtime-corejs3": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.21.0.tgz", + "integrity": "sha512-TDD4UJzos3JJtM+tHX+w2Uc+KWj7GV+VKKFdMVd2Rx8sdA19hcc3P3AHFYd5LVOw+pYuSd5lICC3gm52B6Rwxw==", + "requires": { + "core-js-pure": "^3.25.1", + "regenerator-runtime": "^0.13.11" + } + }, "@babel/template": { "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", @@ -1438,12 +2269,11 @@ } }, "@emotion/babel-plugin": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", - "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", + "integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==", "requires": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -1464,9 +2294,9 @@ } }, "@emotion/cache": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", - "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "version": "11.10.7", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.7.tgz", + "integrity": "sha512-VLl1/2D6LOjH57Y8Vem1RoZ9haWF4jesHDGiHtKozDQuBIkJm2gimVo0I02sWCuzZtVACeixTVB4jeE8qvCBoQ==", "requires": { "@emotion/memoize": "^0.8.0", "@emotion/sheet": "^1.2.1", @@ -1494,12 +2324,12 @@ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "@emotion/react": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz", - "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz", + "integrity": "sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==", "requires": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", + "@emotion/babel-plugin": "^11.10.6", "@emotion/cache": "^11.10.5", "@emotion/serialize": "^1.1.1", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", @@ -1526,12 +2356,12 @@ "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" }, "@emotion/styled": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", - "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.6.tgz", + "integrity": "sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==", "requires": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", + "@emotion/babel-plugin": "^11.10.6", "@emotion/is-prop-valid": "^1.2.0", "@emotion/serialize": "^1.1.1", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", @@ -1558,6 +2388,117 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "requires": { + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==" + } + } + }, + "@eslint-community/regexpp": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", + "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==" + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "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": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "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==" + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + } + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "requires": { + "type-fest": "^0.20.2" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^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==" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + } + } + }, "@evocateur/libnpmaccess": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz", @@ -1772,6 +2713,21 @@ "@hapi/hoek": "^8.3.0" } }, + "@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==", + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, "@intervolga/optimize-cssnano-plugin": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz", @@ -2063,9 +3019,9 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "version": "15.0.15", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz", + "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==", "requires": { "@types/yargs-parser": "*" } @@ -4626,52 +5582,52 @@ } }, "@mui/private-theming": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.16.tgz", - "integrity": "sha512-0MArkJaOHRCKqL/GWjngGZmyOeRz+uxffhx82bKcewr8swqV7xx7EFP02pk0L/gLdfcvYdqwH4YTVjG/+TaKrg==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.12.0.tgz", + "integrity": "sha512-w5dwMen1CUm1puAtubqxY9BIzrBxbOThsg2iWMvRJmWyJAPdf3Z583fPXpqeA2lhTW79uH2jajk5Ka4FuGlTPg==", "requires": { - "@babel/runtime": "^7.20.1", - "@mui/utils": "^5.10.16", + "@babel/runtime": "^7.21.0", + "@mui/utils": "^5.12.0", "prop-types": "^15.8.1" } }, "@mui/styled-engine": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.16.tgz", - "integrity": "sha512-ZMSjXvtiGwGDKqrSlXhpxK2voUaF2/lpC/pSTfFmZvKH9j9a9h1/iwo3ybgjFVYGgbfNeW4h0xEchiRohu9xsw==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.12.0.tgz", + "integrity": "sha512-frh8L7CRnvD0RDmIqEv6jFeKQUIXqW90BaZ6OrxJ2j4kIsiVLu29Gss4SbBvvrWwwatR72sBmC3w1aG4fjp9mQ==", "requires": { - "@babel/runtime": "^7.20.1", - "@emotion/cache": "^11.10.5", - "csstype": "^3.1.1", + "@babel/runtime": "^7.21.0", + "@emotion/cache": "^11.10.7", + "csstype": "^3.1.2", "prop-types": "^15.8.1" } }, "@mui/system": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.16.tgz", - "integrity": "sha512-OqI9B1jZ9zQ/dmoqseku4CzdEs9DbLiiMOaWxC3WeAJxM1UavlCgXz0encqm93LIlmSL7TjuHN1/rW8BJCnU8A==", - "requires": { - "@babel/runtime": "^7.20.1", - "@mui/private-theming": "^5.10.16", - "@mui/styled-engine": "^5.10.16", - "@mui/types": "^7.2.2", - "@mui/utils": "^5.10.16", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.12.0.tgz", + "integrity": "sha512-Zi+WHuiJfK1ya+9+oeJQ1rLIBdY8CGDYT5oVlQg/6kIuyiCaE6SnN9PVzxBxfY77wHuOPwz4kxcPe9srdZc12Q==", + "requires": { + "@babel/runtime": "^7.21.0", + "@mui/private-theming": "^5.12.0", + "@mui/styled-engine": "^5.12.0", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.12.0", "clsx": "^1.2.1", - "csstype": "^3.1.1", + "csstype": "^3.1.2", "prop-types": "^15.8.1" } }, "@mui/types": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.2.tgz", - "integrity": "sha512-siex8cZDtWeC916cXOoUOnEQQejuMYmHtc4hM6VkKVYaBICz3VIiqyiAomRboTQHt2jchxQ5Q5ATlbcDekTxDA==" + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==" }, "@mui/utils": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.16.tgz", - "integrity": "sha512-3MB/SGsgiiu9Z55CFmAfiONUoR7AAue/H4F6w3mc2LnhFQCsoVvXhioDPcsiRpUMIQr34jDPzGXdCuqWooPCXQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.12.0.tgz", + "integrity": "sha512-RmQwgzF72p7Yr4+AAUO6j1v2uzt6wr7SWXn68KBsnfVpdOHyclCzH2lr/Xu6YOw9su4JRtdAIYfJFXsS6Cjkmw==", "requires": { - "@babel/runtime": "^7.20.1", + "@babel/runtime": "^7.21.0", "@types/prop-types": "^15.7.5", "@types/react-is": "^16.7.1 || ^17.0.0", "prop-types": "^15.8.1", @@ -4686,9 +5642,9 @@ } }, "@mui/x-date-pickers": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.9.tgz", - "integrity": "sha512-PM3RU8MiwDVi+dSDGJ7ylI0hCe79wSCDfrjghS8ApGGFn/n87S8pUZxsZ5czw3mVRN6VfS2C19peo4nM1Tx+nA==", + "version": "5.0.20", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.20.tgz", + "integrity": "sha512-ERukSeHIoNLbI1C2XRhF9wRhqfsr+Q4B1SAw2ZlU7CWgcG8UBOxgqRKDEOVAIoSWL+DWT6GRuQjOKvj6UXZceA==", "requires": { "@babel/runtime": "^7.18.9", "@date-io/core": "^2.15.0", @@ -4938,9 +5894,9 @@ } }, "@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" + "version": "2.11.7", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz", + "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==" }, "@rollup/plugin-alias": { "version": "3.1.9", @@ -4951,16 +5907,16 @@ } }, "@rollup/plugin-commonjs": { - "version": "23.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-23.0.3.tgz", - "integrity": "sha512-31HxrT5emGfTyIfAs1lDQHj6EfYxTXcwtX5pIIhq+B/xZBNIqQ179d/CkYxlpYmFCxT78AeU4M8aL8Iv/IBxFA==", + "version": "23.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-23.0.7.tgz", + "integrity": "sha512-hsSD5Qzyuat/swzrExGG5l7EuIlPhwTsT7KwKbSCQzIcJWjRxiimi/0tyMYY2bByitNb3i1p+6JWEDGa0NvT0Q==", "requires": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "glob": "^8.0.3", "is-reference": "1.2.1", - "magic-string": "^0.26.4" + "magic-string": "^0.27.0" }, "dependencies": { "brace-expansion": { @@ -4972,9 +5928,9 @@ } }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4984,17 +5940,17 @@ } }, "magic-string": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", - "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", "requires": { - "sourcemap-codec": "^1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.13" } }, "minimatch": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", - "integrity": "sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "requires": { "brace-expansion": "^2.0.1" } @@ -5010,33 +5966,33 @@ } }, "@rollup/plugin-node-resolve": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz", - "integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", + "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", "requires": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.0", + "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", "resolve": "^1.22.1" } }, "@rollup/plugin-replace": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.1.tgz", - "integrity": "sha512-Z3MfsJ4CK17BfGrZgvrcp/l6WXoKb0kokULO+zt/7bmcyayokDaQ2K3eDJcRLCTAlp5FPI4/gz9MHAsosz4Rag==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", + "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", "requires": { "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.26.4" + "magic-string": "^0.27.0" }, "dependencies": { "magic-string": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", - "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", "requires": { - "sourcemap-codec": "^1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.13" } } } @@ -5186,15 +6142,32 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" + }, + "dependencies": { + "@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + }, + "@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, "@types/babel__generator": { @@ -5276,20 +6249,20 @@ "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, "@types/express": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", - "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", "requires": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "@types/express-serve-static-core": { - "version": "4.17.31", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", - "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -5314,9 +6287,9 @@ } }, "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "requires": { "@types/node": "*" } @@ -5331,9 +6304,9 @@ } }, "@types/http-proxy": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", - "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "version": "1.17.10", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz", + "integrity": "sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==", "requires": { "@types/node": "*" } @@ -5373,6 +6346,11 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, "@types/lodash": { "version": "4.14.191", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", @@ -5420,9 +6398,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==" }, "@types/prop-types": { "version": "15.7.5", @@ -5445,9 +6423,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/react": { - "version": "17.0.52", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", - "integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", + "version": "17.0.57", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.57.tgz", + "integrity": "sha512-e4msYpu5QDxzNrXDHunU/VPyv2M1XemGG/p7kfCjUiPtlLDCWLGQfgAMng6YyisWYxZ09mYdQlmMnyS0NfZdEg==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -5455,9 +6433,9 @@ } }, "@types/react-dom": { - "version": "17.0.18", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.18.tgz", - "integrity": "sha512-rLVtIfbwyur2iFKykP2w0pl/1unw26b5td16d5xMgp7/yjTHomkyxPYChFoCr/FtEX1lN9wY6lFj1qvKdS5kDw==", + "version": "17.0.19", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.19.tgz", + "integrity": "sha512-PiYG40pnQRdPHnlf7tZnp0aQ6q9tspYr72vD61saO6zFCybLfMqwUCN0va1/P+86DXn18ZWeW30Bk7xlC5eEAQ==", "requires": { "@types/react": "^17" } @@ -5479,9 +6457,9 @@ } }, "@types/react-redux": { - "version": "7.1.24", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", - "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==", + "version": "7.1.25", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz", + "integrity": "sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg==", "requires": { "@types/hoist-non-react-statics": "^3.3.0", "@types/react": "*", @@ -5519,19 +6497,24 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" }, "@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" }, "@types/selenium-webdriver": { "version": "3.0.20", "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.20.tgz", "integrity": "sha512-6d8Q5fqS9DWOXEhMDiF6/2FjyHdmP/jSTAUyeQR7QwrFeNmYyzmvGxD5aLIHL445HjWgibs0eAig+KPnbaesXA==" }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" + }, "@types/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", "requires": { "@types/mime": "*", "@types/node": "*" @@ -5644,57 +6627,493 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, - "@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz", - "integrity": "sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==" - }, - "@vue/babel-helper-vue-transform-on": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", - "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==" - }, - "@vue/babel-plugin-jsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz", - "integrity": "sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==", + "@typescript-eslint/eslint-plugin": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.58.0.tgz", + "integrity": "sha512-vxHvLhH0qgBd3/tW6/VccptSfc8FxPQIkmNTVLWcCOVqSBvqpnKkBTYrhcGlXfSnd78azwe+PsjYFj0X34/njA==", "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "@vue/babel-helper-vue-transform-on": "^1.0.2", - "camelcase": "^6.0.0", - "html-tags": "^3.1.0", - "svg-tags": "^1.0.0" + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.58.0", + "@typescript-eslint/type-utils": "5.58.0", + "@typescript-eslint/utils": "5.58.0", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + "@typescript-eslint/scope-manager": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", + "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0" + } + }, + "@typescript-eslint/types": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", + "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==" + }, + "@typescript-eslint/visitor-keys": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", + "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, - "@vue/babel-plugin-transform-vue-jsx": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.4.0.tgz", - "integrity": "sha512-Fmastxw4MMx0vlgLS4XBX0XiBbUFzoMGeVXuMV08wyOfXdikAFqBTuYPR0tlk+XskL19EzHc39SgjrPGY23JnA==", + "@typescript-eslint/experimental-utils": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz", + "integrity": "sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ==", "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0", - "html-tags": "^2.0.0", - "lodash.kebabcase": "^4.1.1", - "svg-tags": "^1.0.0" + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" }, "dependencies": { - "html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==" - } + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz", + "integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==", + "requires": { + "@typescript-eslint/scope-manager": "5.58.0", + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/typescript-estree": "5.58.0", + "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", + "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0" + } + }, + "@typescript-eslint/types": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", + "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==" + }, + "@typescript-eslint/typescript-estree": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", + "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", + "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==" + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", + "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", + "requires": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.58.0.tgz", + "integrity": "sha512-FF5vP/SKAFJ+LmR9PENql7fQVVgGDOS+dq3j+cKl9iW/9VuZC/8CFmzIP0DLKXfWKpRHawJiG70rVH+xZZbp8w==", + "requires": { + "@typescript-eslint/typescript-estree": "5.58.0", + "@typescript-eslint/utils": "5.58.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", + "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==" + }, + "@typescript-eslint/typescript-estree": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", + "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", + "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==" + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "@typescript-eslint/types": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", + "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==" + }, + "@typescript-eslint/typescript-estree": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", + "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", + "requires": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "@typescript-eslint/utils": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.58.0.tgz", + "integrity": "sha512-gAmLOTFXMXOC+zP1fsqm3VceKSBQJNzV385Ok3+yzlavNHZoedajjS4UyS21gabJYcobuigQPs/z71A9MdJFqQ==", + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.58.0", + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/typescript-estree": "5.58.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", + "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0" + } + }, + "@typescript-eslint/types": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", + "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==" + }, + "@typescript-eslint/typescript-estree": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", + "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", + "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "requires": { + "@typescript-eslint/types": "5.58.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==" + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", + "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", + "requires": { + "@typescript-eslint/types": "4.28.2", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@vue/babel-helper-vue-jsx-merge-props": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz", + "integrity": "sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==" + }, + "@vue/babel-helper-vue-transform-on": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", + "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==" + }, + "@vue/babel-plugin-jsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz", + "integrity": "sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "@vue/babel-helper-vue-transform-on": "^1.0.2", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + } + } + }, + "@vue/babel-plugin-transform-vue-jsx": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.4.0.tgz", + "integrity": "sha512-Fmastxw4MMx0vlgLS4XBX0XiBbUFzoMGeVXuMV08wyOfXdikAFqBTuYPR0tlk+XskL19EzHc39SgjrPGY23JnA==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0", + "html-tags": "^2.0.0", + "lodash.kebabcase": "^4.1.1", + "svg-tags": "^1.0.0" + }, + "dependencies": { + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==" + } } }, "@vue/babel-preset-app": { @@ -6192,9 +7611,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "optional": true, "requires": { "lru-cache": "^6.0.0" @@ -7017,12 +8436,12 @@ } }, "@vue/compiler-core": { - "version": "3.2.45", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz", - "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", + "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==", "requires": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.45", + "@vue/shared": "3.2.47", "estree-walker": "^2.0.2", "source-map": "^0.6.1" }, @@ -7035,25 +8454,25 @@ } }, "@vue/compiler-dom": { - "version": "3.2.45", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", - "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz", + "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==", "requires": { - "@vue/compiler-core": "3.2.45", - "@vue/shared": "3.2.45" + "@vue/compiler-core": "3.2.47", + "@vue/shared": "3.2.47" } }, "@vue/compiler-sfc": { - "version": "3.2.45", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", - "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz", + "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.45", - "@vue/compiler-dom": "3.2.45", - "@vue/compiler-ssr": "3.2.45", - "@vue/reactivity-transform": "3.2.45", - "@vue/shared": "3.2.45", + "@vue/compiler-core": "3.2.47", + "@vue/compiler-dom": "3.2.47", + "@vue/compiler-ssr": "3.2.47", + "@vue/reactivity-transform": "3.2.47", + "@vue/shared": "3.2.47", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -7061,9 +8480,9 @@ }, "dependencies": { "postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -7078,12 +8497,12 @@ } }, "@vue/compiler-ssr": { - "version": "3.2.45", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", - "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz", + "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==", "requires": { - "@vue/compiler-dom": "3.2.45", - "@vue/shared": "3.2.45" + "@vue/compiler-dom": "3.2.47", + "@vue/shared": "3.2.47" } }, "@vue/component-compiler-utils": { @@ -7114,27 +8533,37 @@ } } }, + "@vue/eslint-config-typescript": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-11.0.2.tgz", + "integrity": "sha512-EiKud1NqlWmSapBFkeSrE994qpKx7/27uCGnhdqzllYDpQZroyX/O6bwjEpeuyKamvLbsGdO6PMR2faIf+zFnw==", + "requires": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "@typescript-eslint/parser": "^5.0.0", + "vue-eslint-parser": "^9.0.0" + } + }, "@vue/preload-webpack-plugin": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz", "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==" }, "@vue/reactivity-transform": { - "version": "3.2.45", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", - "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz", + "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.45", - "@vue/shared": "3.2.45", + "@vue/compiler-core": "3.2.47", + "@vue/shared": "3.2.47", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "@vue/shared": { - "version": "3.2.45", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz", - "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz", + "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" }, "@vue/web-component-wrapper": { "version": "1.3.0", @@ -7466,6 +8895,11 @@ } } }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + }, "acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", @@ -7473,14 +8907,14 @@ "dev": true }, "address": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", - "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==" }, "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" }, "after": { "version": "0.8.2", @@ -7518,7 +8952,6 @@ "version": "8.11.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -7703,6 +9136,15 @@ "sprintf-js": "~1.0.2" } }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -7745,6 +9187,18 @@ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", "dev": true }, + "array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + } + }, "array-slice": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", @@ -7789,6 +9243,17 @@ "es-shim-unscopables": "^1.0.0" } }, + "array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, "array.prototype.reduce": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", @@ -7801,7 +9266,19 @@ "is-string": "^1.0.7" } }, - "arraybuffer.slice": { + "array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" @@ -7890,8 +9367,7 @@ "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 + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" }, "async": { "version": "2.6.4", @@ -8091,6 +9567,11 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -9074,9 +10555,9 @@ "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" }, "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==" }, "builtin-status-codes": { "version": "3.0.0", @@ -9186,9 +10667,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -9478,14 +10959,14 @@ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" }, "htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "requires": { "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", + "domhandler": "^5.0.3", "domutils": "^3.0.1", - "entities": "^4.3.0" + "entities": "^4.4.0" } }, "parse5": { @@ -10403,9 +11884,9 @@ } }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" }, "conventional-changelog-angular": { "version": "5.0.13", @@ -11078,9 +12559,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" }, "copy-concurrently": { "version": "1.0.5", @@ -11229,9 +12710,9 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -11328,13 +12809,41 @@ "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==" }, "core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.0.tgz", + "integrity": "sha512-P5A2h/9mRYZFIAP+5Ab8ns6083IyVpSclU74UNvbGVQ8VM7n3n3/g2yF3AkKQ9NXz2O+ioxLbEWKnDtgsFamhg==", "requires": { - "browserslist": "^4.21.4" + "browserslist": "^4.21.5" + }, + "dependencies": { + "browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "requires": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + } + }, + "caniuse-lite": { + "version": "1.0.30001477", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001477.tgz", + "integrity": "sha512-lZim4iUHhGcy5p+Ri/G7m84hJwncj+Kz7S5aD4hoQfslKZJgt0tHc/hafVbqHC5bbhHb+mrW2JOUHkI5KH7toQ==" + }, + "node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" + } } }, + "core-js-pure": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.30.0.tgz", + "integrity": "sha512-+2KbMFGeBU0ln/csoPqTe0i/yfHbrd2EUhNMObsGtXMKS/RTtlkYyi+/3twLcevbgNR0yM/r0Psa3TEoQRpFMQ==" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -11921,9 +13430,9 @@ } }, "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "currently-unhandled": { "version": "0.4.1", @@ -12063,9 +13572,9 @@ } }, "decimal.js": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", - "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==" + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "decode-uri-component": { "version": "0.2.1", @@ -12088,9 +13597,9 @@ "dev": true }, "deep-eql": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", - "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "requires": { "type-detect": "^4.0.0" } @@ -12120,9 +13629,9 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" }, "default-gateway": { "version": "5.0.5", @@ -12484,6 +13993,14 @@ "buffer-indexof": "^1.0.0" } }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, "document-register-element": { "version": "1.14.10", "resolved": "https://registry.npmjs.org/document-register-element/-/document-register-element-1.14.10.tgz", @@ -12862,6 +14379,21 @@ "tapable": "^1.0.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "requires": { + "ansi-colors": "^4.1.1" + }, + "dependencies": { + "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==" + } + } + }, "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -13028,79 +14560,632 @@ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, - "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==", + "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==", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "requires": { + "es6-promise": "^4.0.3" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-templates": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", + "integrity": "sha512-sziUVwcvQ+lOsrTyUY0Q11ilAPj+dy7AQ1E1MgSaHTaaAFTffaa08QSlGNU61iyVaroyb6nYdBV6oD7nzn6i8w==", + "requires": { + "recast": "~0.11.12", + "through": "~2.3.6" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } + } + }, + "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==", + "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": { + "@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==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "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==" + } + } + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "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==" + } + } + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^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==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "eslint-config-prettier": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==" + }, + "eslint-import-resolver-node": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } } }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "eslint-plugin-import": { + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", "requires": { - "es6-promise": "^4.0.3" + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", + "has": "^1.0.3", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + } } }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" + "prettier-linter-helpers": "^1.0.0" } }, - "es6-templates": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", - "integrity": "sha512-sziUVwcvQ+lOsrTyUY0Q11ilAPj+dy7AQ1E1MgSaHTaaAFTffaa08QSlGNU61iyVaroyb6nYdBV6oD7nzn6i8w==", + "eslint-plugin-prettier-vue": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier-vue/-/eslint-plugin-prettier-vue-4.2.0.tgz", + "integrity": "sha512-DA2oNRx+pZ6RM/EIHIPME4FQZifnkEROa55OWtTTUFGHpj53tcHomuxVP/kS/2MM+ul46GEK+jymK69STWDWoA==", "requires": { - "recast": "~0.11.12", - "through": "~2.3.6" + "@vue/compiler-sfc": "^3.2.37", + "chalk": "^4.0.0", + "prettier": "^2.7.1", + "prettier-linter-helpers": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "eslint-plugin-react": { + "version": "7.32.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", + "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==", + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.8" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + } + } }, - "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "eslint-plugin-vue": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.10.0.tgz", + "integrity": "sha512-2MgP31OBf8YilUvtakdVMc8xVbcMp7z7/iQj8LHVpXrSXHPXSJRUIGSPFI6b6pyCx/buKaFJ45ycqfHvQRiW2g==", "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "@eslint-community/eslint-utils": "^4.3.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.0.1", + "postcss-selector-parser": "^6.0.9", + "semver": "^7.3.5", + "vue-eslint-parser": "^9.0.1", + "xml-name-validator": "^4.0.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -13113,6 +15198,19 @@ "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + }, + "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==" + }, "esm": { "version": "3.2.25", "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", @@ -13131,6 +15229,23 @@ "xtend": "^4.0.0" } }, + "espree": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", + "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==" + } + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -13153,6 +15268,21 @@ } } }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + } + } + }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -13573,8 +15703,7 @@ "fast-diff": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" }, "fast-glob": { "version": "3.2.12", @@ -13646,6 +15775,14 @@ "escape-string-regexp": "^1.0.5" } }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "requires": { + "flat-cache": "^3.0.4" + } + }, "file-loader": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz", @@ -13656,9 +15793,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -13905,10 +16042,19 @@ } } }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, "flush-write-stream": { "version": "1.1.1", @@ -14134,9 +16280,9 @@ }, "dependencies": { "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", + "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", "requires": { "side-channel": "^1.0.4" } @@ -14185,9 +16331,9 @@ } }, "fs-extra": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", - "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -14257,6 +16403,11 @@ "functions-have-names": "^1.2.2" } }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -14874,6 +17025,11 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, "graphlib": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", @@ -15274,9 +17430,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -15336,9 +17492,9 @@ } }, "html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==" }, "html-webpack-plugin": { "version": "3.2.0", @@ -16044,18 +18200,11 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-builtin-module": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", - "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "requires": { "builtin-modules": "^3.3.0" - }, - "dependencies": { - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==" - } } }, "is-callable": { @@ -16649,9 +18798,9 @@ "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -17065,9 +19214,9 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "version": "15.0.15", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz", + "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==", "requires": { "@types/yargs-parser": "*" } @@ -17730,9 +19879,9 @@ }, "dependencies": { "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "requires": { "lru-cache": "^6.0.0" } @@ -17846,9 +19995,9 @@ }, "dependencies": { "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "optional": true, "requires": { "lru-cache": "^6.0.0" @@ -19132,9 +21281,9 @@ } }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -19144,9 +21293,9 @@ } }, "minimatch": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", - "integrity": "sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "requires": { "brace-expansion": "^2.0.1" } @@ -19337,14 +21486,12 @@ "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "json-stringify-safe": { "version": "5.0.1", @@ -19382,6 +21529,15 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "requires": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + } + }, "jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -19524,6 +21680,11 @@ } } }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + }, "fsevents": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", @@ -19686,9 +21847,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -20094,8 +22255,7 @@ "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "lodash.set": { "version": "4.3.2", @@ -20132,6 +22292,11 @@ "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", "integrity": "sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==" }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -20412,9 +22577,9 @@ } }, "memfs": { - "version": "3.4.12", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", - "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.0.tgz", + "integrity": "sha512-yK6o8xVJlQerz57kvPROwTMgx5WtGwC2ZxDtOUsnGl49rHjYkfQoPNZPCKH73VdLE1BwBu/+Fx/NL8NYMUw2aA==", "optional": true, "requires": { "fs-monkey": "^1.0.3" @@ -20591,9 +22756,9 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -21309,9 +23474,9 @@ } }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -21560,9 +23725,9 @@ "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==" }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, "nanomatch": { "version": "1.2.13", @@ -21592,6 +23757,11 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" + }, "nearley": { "version": "2.20.1", "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", @@ -22059,9 +24229,9 @@ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==" }, "nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.3.tgz", + "integrity": "sha512-jscxIO4/VKScHlbmFBdV1Z6LXnLO+ZR4VMtypudUdfwtKxUN3TQcNFIHLwKtrUbDyHN4/GycY9+oRGZ2XMXYPw==" }, "nyc": { "version": "15.1.0", @@ -22332,6 +24502,15 @@ "es-abstract": "^1.20.4" } }, + "object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -23300,9 +25479,9 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -23736,9 +25915,17 @@ "dev": true }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==" + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "requires": { + "fast-diff": "^1.1.2" + } }, "pretty": { "version": "2.0.0", @@ -24155,11 +26342,11 @@ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==" }, "webdriver-manager": { - "version": "12.1.8", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.8.tgz", - "integrity": "sha512-qJR36SXG2VwKugPcdwhaqcLQOD7r8P2Xiv9sfNbfZrKBnX243iAkOueX1yAmeNgIKhJ3YAT/F2gq6IiEZzahsg==", + "version": "12.1.9", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.9.tgz", + "integrity": "sha512-Yl113uKm8z4m/KMUVWHq1Sjtla2uxEBtx2Ue3AmIlnlPAKloDn/Lvmy6pqWCUersVISpdMeVpAaGbNnvMuT2LQ==", "requires": { - "adm-zip": "^0.4.9", + "adm-zip": "^0.5.2", "chalk": "^1.1.1", "del": "^2.2.0", "glob": "^7.0.3", @@ -24773,9 +26960,9 @@ } }, "redux": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", - "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "requires": { "@babel/runtime": "^7.9.2" } @@ -24838,6 +27025,11 @@ "functions-have-names": "^1.2.2" } }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + }, "regexpu-core": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", @@ -25104,8 +27296,7 @@ "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-main-filename": { "version": "2.0.0", @@ -25340,9 +27531,9 @@ } }, "rollup-plugin-import-css": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-import-css/-/rollup-plugin-import-css-3.1.0.tgz", - "integrity": "sha512-+azurUk2QrUNWs1V5EzpuvV9bRQDEjG+aQDadM6ZEc5LbU6VvFiR3+MPIBnqKrg/miBNag/9H1TWhEUv4TH+jQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-import-css/-/rollup-plugin-import-css-3.2.1.tgz", + "integrity": "sha512-svr1JrBknT5ndEUM8nPaemTx/uF/5Tf4FAMQxvAYx2K9Sx7hL+JwB/rPuB1ZmUE1rjCnQHnz/fgik+noYM5+0w==", "requires": { "@rollup/pluginutils": "^5.0.2" } @@ -25382,11 +27573,12 @@ } }, "rollup-plugin-visualizer": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.8.3.tgz", - "integrity": "sha512-QGJk4Bqe4AOat5AjipOh8esZH1nck5X2KFpf4VytUdSUuuuSwvIQZjMGgjcxe/zXexltqaXp5Vx1V3LmnQH15Q==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.9.0.tgz", + "integrity": "sha512-bbDOv47+Bw4C/cgs0czZqfm8L82xOZssk4ayZjG40y9zbXclNk7YikrZTDao6p7+HDiGxrN0b65SgZiVm9k1Cg==", "requires": { "open": "^8.4.0", + "picomatch": "^2.3.1", "source-map": "^0.7.4", "yargs": "^17.5.1" }, @@ -25415,9 +27607,9 @@ } }, "open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "requires": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -25438,9 +27630,9 @@ } }, "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -26051,9 +28243,9 @@ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" }, "shell-quote": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", - "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==" + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" }, "shelljs": { "version": "0.8.5", @@ -26641,9 +28833,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -26896,6 +29088,21 @@ } } }, + "string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + } + }, "string.prototype.padend": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", @@ -27078,17 +29285,17 @@ } }, "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", + "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", "requires": { "side-channel": "^1.0.4" } }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -27096,9 +29303,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "requires": { "lru-cache": "^6.0.0" } @@ -27239,14 +29446,72 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "symlink-dir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/symlink-dir/-/symlink-dir-5.1.0.tgz", - "integrity": "sha512-nrwSDbmMYGwc+wu6gzmTdQIV9GzItMG/0LX4c9Co0bhtx2KK1WUKjNIyhjhAdIKaA5eIwVhB2tqFsn8ooUsRKA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/symlink-dir/-/symlink-dir-5.1.1.tgz", + "integrity": "sha512-kmVV2SfdoDksjJxStJ5N9u1ZZ5tQndCeUEG8St0tHI9BZe/ehZYbKB6eXPjo+AvFG1uRsDymUSGG0OLv2Ox8aQ==", "requires": { "better-path-resolve": "^1.0.0", "rename-overwrite": "^4.0.3" } }, + "table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -27480,6 +29745,11 @@ "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, "thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -27507,9 +29777,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -27756,9 +30026,9 @@ } }, "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "version": "15.0.15", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz", + "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==", "requires": { "@types/yargs-parser": "*" } @@ -27825,9 +30095,9 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "requires": { "lru-cache": "^6.0.0" } @@ -27921,10 +30191,31 @@ "strip-json-comments": "^2.0.0" } }, + "tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "requires": { + "minimist": "^1.2.0" + } + } + } + }, "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "tslint": { "version": "5.20.1", @@ -27946,6 +30237,11 @@ "tsutils": "^2.29.0" }, "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==" + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -27955,91 +30251,21 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "tslint-loader": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/tslint-loader/-/tslint-loader-3.5.4.tgz", - "integrity": "sha512-jBHNNppXut6SgZ7CsTBh+6oMwVum9n8azbmcYSeMlsABhWWoHwjq631vIFXef3VSd75cCdX3rc6kstsB7rSVVw==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.1", - "rimraf": "^2.4.4", - "semver": "^5.3.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-react": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/tslint-react/-/tslint-react-4.1.0.tgz", - "integrity": "sha512-Y7CbFn09X7Mpg6rc7t/WPbmjx9xPI8p1RsQyiGCLWgDR6sh3+IBSlT+bEkc0PSZcWwClOkqq2wPsID8Vep6szQ==", - "dev": true, - "requires": { - "tsutils": "^3.9.1" - }, - "dependencies": { "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "requires": { "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } } } } }, "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "requires": { "tslib": "^1.8.1" }, @@ -28498,9 +30724,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -28760,6 +30986,62 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==" }, + "vue-eslint-parser": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz", + "integrity": "sha512-C2aI/r85Q6tYcz4dpgvrs4wH/MqVrRAVIdpYedrxnATDHHkb+TroeRcDpKWGZCx/OcECMWfz7tVwQ8e+Opy6rA==", + "requires": { + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" + }, + "dependencies": { + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==" + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, "vue-hot-reload-api": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", @@ -28803,9 +31085,9 @@ "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -28837,9 +31119,9 @@ "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -29463,9 +31745,9 @@ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } diff --git a/package.json b/package.json index 77695bc34..faef6dc4e 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "clean": "lerna run clean", "test": "lerna run test", "test-cov": "lerna run test-cov", - "lint": "tslint 'packages/**/*.{ts,tsx}' -c ./tslint.json", + "lint": "lerna run --no-bail lint", + "lint:fix": "lerna run --no-bail lint:fix", "build:examples-app": "lerna run build:examples-app && node packages/examples-app/prepare-examples-app.js" }, "devDependencies": { @@ -33,15 +34,12 @@ "lerna": "^3.19.0", "nan": "^2.14.2", "nyc": "^15.1.0", - "prettier": "^1.19.1", + "prettier": "^2.8.4", "source-map-loader": "^0.2.4", "source-map-support": "0.5.16", "style-loader": "^1.0.1", "ts-loader": "^6.2.1", "ts-node": "^10.4.0", - "tslint": "^5.20.1", - "tslint-loader": "^3.5.4", - "tslint-react": "^4.1.0", "typedoc": "^0.19.2", "typescript": "4.2.3", "webpack": "^4.41.2", diff --git a/packages/angular-material/.eslintrc.js b/packages/angular-material/.eslintrc.js new file mode 100644 index 000000000..0bf60144d --- /dev/null +++ b/packages/angular-material/.eslintrc.js @@ -0,0 +1,38 @@ +/* eslint-env node */ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + parserOptions: { + /* Reset project because @angular-eslint/recommended sets this to an incompatible value */ + project: null, + }, + // There is no file include in ESLint. Thus, ignore all and include files via negative ignore (!) + ignorePatterns: ['/*', '!/src', '!/test', '!/example', '/example/dist'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:@angular-eslint/recommended', + 'plugin:@angular-eslint/template/process-inline-templates', + 'plugin:prettier/recommended', + ], + rules: { + '@angular-eslint/component-class-suffix': 'off', + '@angular-eslint/directive-class-suffix': 'off', + '@angular-eslint/no-conflicting-lifecycle': 'warn', + '@typescript-eslint/no-explicit-any': 'off', + 'no-prototype-builtins': 'off', + // Base rule must be disabled to avoid incorrect errors + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', // or "error" + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, +}; diff --git a/packages/angular-material/.prettierrc.js b/packages/angular-material/.prettierrc.js new file mode 100644 index 000000000..2c26853c4 --- /dev/null +++ b/packages/angular-material/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + $schema: 'http://json.schemastore.org/prettierrc', + singleQuote: true, + jsxSingleQuote: true, + endOfLine: 'auto', +}; diff --git a/packages/angular-material/README.md b/packages/angular-material/README.md index 817807d30..c8ab6e12a 100644 --- a/packages/angular-material/README.md +++ b/packages/angular-material/README.md @@ -1,6 +1,6 @@ # JSON Forms - More Forms. Less Code -*Complex forms in the blink of an eye* +_Complex forms in the blink of an eye_ JSON Forms eliminates the tedious task of writing fully-featured forms by hand by leveraging the capabilities of JSON, JSON Schema and Javascript. @@ -25,11 +25,11 @@ Use the `json-forms` component for each form you want to render and hand over th Example component file `app.component.ts`: ```ts -import { Component } from "@angular/core"; -import { angularMaterialRenderers } from "@jsonforms/angular-material"; +import { Component } from '@angular/core'; +import { angularMaterialRenderers } from '@jsonforms/angular-material'; @Component({ - selector: "app-root", + selector: 'app-root', template: ` { if (schemaPath === '#/properties/warehouseitems/items') { @@ -85,7 +89,7 @@ const itemTester: UISchemaTester = (_schema, schemaPath, _path) => { [readonly]="readonly" [config]="config" > - ` + `, }) export class AppComponent { readonly renderers = angularMaterialRenderers; @@ -95,8 +99,8 @@ export class AppComponent { private dateAdapter; private readonly = false; data: any; - uischemas: { tester: UISchemaTester; uischema: UISchemaElement; }[] = [ - { tester: itemTester, uischema: uiSchema } + uischemas: { tester: UISchemaTester; uischema: UISchemaElement }[] = [ + { tester: itemTester, uischema: uiSchema }, ]; constructor(dateAdapter: DateAdapter) { @@ -107,7 +111,9 @@ export class AppComponent { } onChange(ev: any) { - this.selectedExample = this.examples.find(e => e.name === ev.target.value); + this.selectedExample = this.examples.find( + (e) => e.name === ev.target.value + ); this.i18n = this.selectedExample.i18n ?? defaultI18n; } diff --git a/packages/angular-material/example/app/app.module.ts b/packages/angular-material/example/app/app.module.ts index 08d79c7e2..25cb82bf9 100644 --- a/packages/angular-material/example/app/app.module.ts +++ b/packages/angular-material/example/app/app.module.ts @@ -33,10 +33,9 @@ import { JsonFormsAngularMaterialModule } from '../../src/module'; imports: [ BrowserModule, BrowserAnimationsModule, - JsonFormsAngularMaterialModule + JsonFormsAngularMaterialModule, ], bootstrap: [AppComponent], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) -export class AppModule { -} +export class AppModule {} diff --git a/packages/angular-material/example/index.bundled.html b/packages/angular-material/example/index.bundled.html index 3c6ae29cf..52c0b9b0b 100644 --- a/packages/angular-material/example/index.bundled.html +++ b/packages/angular-material/example/index.bundled.html @@ -1,22 +1,30 @@ - + - - - JSON Forms Angular Material RendererSet - - - - - - - - - - + + + JSON Forms Angular Material RendererSet + + + + + + + + + + \ No newline at end of file +--> diff --git a/packages/angular-material/example/index.html b/packages/angular-material/example/index.html index 780779fd7..7eb9fa2b8 100644 --- a/packages/angular-material/example/index.html +++ b/packages/angular-material/example/index.html @@ -1,25 +1,31 @@ - + - - - Tour of Heroes - + + + Tour of Heroes + - - - - - - - - - - + + + + + + + + + + \ No newline at end of file +--> diff --git a/packages/angular-material/package-lock.json b/packages/angular-material/package-lock.json index b3829ad3d..a5c2d542e 100644 --- a/packages/angular-material/package-lock.json +++ b/packages/angular-material/package-lock.json @@ -1,6 +1,6 @@ { "name": "@jsonforms/angular-material", - "version": "3.1.0-alpha.1", + "version": "3.1.0-alpha.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/angular-material/package.json b/packages/angular-material/package.json index 49fbb188e..ffc6fd0f4 100644 --- a/packages/angular-material/package.json +++ b/packages/angular-material/package.json @@ -1,6 +1,6 @@ { "name": "@jsonforms/angular-material", - "version": "3.1.0-alpha.1", + "version": "3.1.0-alpha.2", "description": "Material Renderer Set for Angular module of JSON Forms", "repository": "https://github.com/eclipsesource/jsonforms", "bugs": "https://github.com/eclipsesource/jsonforms/issues", @@ -42,7 +42,8 @@ "build:examples-app": "rollup -c rollup.example.config.js", "dev": "webpack --config webpack/webpack.dev.js && webpack-dev-server --config webpack/webpack.dev.js --env=dev --inline", "clean": "rimraf lib coverage dist .nyc_output 2> /dev/null", - "lint": "tslint --project tsconfig.json --exclude src/models/jsonSchema.ts", + "lint": "eslint .", + "lint:fix": "eslint --fix .", "report": "nyc report --reporter=html", "doc": "typedoc --name 'JSON Forms Angular Material Renderers' --mode file --out docs src", "test": "karma start ./test-config/karma.conf.js --single-run", @@ -68,8 +69,8 @@ "@angular/material": "^12.0.0 || ^13.0.0 || ^14.0.0", "@angular/platform-browser": "^12.0.0 || ^13.0.0 || ^14.0.0", "@angular/router": "^12.0.0 || ^13.0.0 || ^14.0.0", - "@jsonforms/angular": "3.1.0-alpha.1", - "@jsonforms/core": "3.1.0-alpha.1", + "@jsonforms/angular": "3.1.0-alpha.2", + "@jsonforms/core": "3.1.0-alpha.2", "core-js": "^2.5.3", "rxjs": "^6.5.3 || ^7.4.0" }, @@ -77,6 +78,10 @@ "hammerjs": "2.0.8" }, "devDependencies": { + "@angular-eslint/eslint-plugin": "^12.0.0", + "@angular-eslint/eslint-plugin-template": "^12.0.0", + "@angular-eslint/schematics": "^12.0.0", + "@angular-eslint/template-parser": "^12.0.0", "@angular/animations": "^12.0.0", "@angular/cdk": "^12.0.0", "@angular/common": "^12.0.0", @@ -89,18 +94,24 @@ "@angular/platform-browser": "^12.0.0", "@angular/platform-browser-dynamic": "^12.0.0", "@angular/router": "^12.0.0", - "@jsonforms/angular": "^3.1.0-alpha.1", - "@jsonforms/angular-test": "^3.1.0-alpha.1", - "@jsonforms/core": "^3.1.0-alpha.1", - "@jsonforms/examples": "^3.1.0-alpha.1", + "@jsonforms/angular": "^3.1.0-alpha.2", + "@jsonforms/angular-test": "^3.1.0-alpha.2", + "@jsonforms/core": "^3.1.0-alpha.2", + "@jsonforms/examples": "^3.1.0-alpha.2", "@rollup/plugin-commonjs": "^23.0.3", "@rollup/plugin-json": "^5.0.2", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-replace": "^5.0.1", "@types/node": "^10.10.0", + "@typescript-eslint/eslint-plugin": "^5.54.1", + "@typescript-eslint/parser": "^5.54.1", "angular2-template-loader": "^0.6.2", "copy-webpack-plugin": "^5.0.5", "core-js": "^2.5.3", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.7.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", "html-loader": "^0.5.5", "istanbul-instrumenter-loader": "^3.0.1", "jasmine": "^3.2.0", @@ -114,6 +125,7 @@ "karma-webpack": "^3.0.5", "null-loader": "^0.1.1", "nyc": "^15.1.0", + "prettier": "^2.8.4", "protractor": "^5.4.1", "request": "^2.88.0", "rimraf": "^3.0.2", @@ -125,7 +137,6 @@ "rollup-plugin-visualizer": "^5.4.1", "rxjs": "^6.5.3", "ts-loader": "^6.2.1", - "tslint": "^5.20.1", "typedoc": "^0.19.2", "webpack": "^4.41.2", "webpack-cli": "^3.2.1", diff --git a/packages/angular-material/rollup.example.config.js b/packages/angular-material/rollup.example.config.js index 8869b27b6..7d0495919 100644 --- a/packages/angular-material/rollup.example.config.js +++ b/packages/angular-material/rollup.example.config.js @@ -8,13 +8,13 @@ import typescript from 'rollup-plugin-typescript2'; /** * @type {import('rollup').RollupOptions} -*/ + */ const config = { input: 'example/main.ts', output: { file: 'example/dist/bundle.js', format: 'iife', - sourcemap: true + sourcemap: true, }, plugins: [ replace({ @@ -30,23 +30,24 @@ const config = { tsconfigOverride: { compilerOptions: { // Do not emit typescript declarations for our bundled example app - declaration: false - } - }}), + declaration: false, + }, + }, + }), copy({ targets: [ { src: '../../node_modules/@angular/material/prebuilt-themes/indigo-pink.css', - dest: 'example/dist' + dest: 'example/dist', }, { src: 'example/index.bundled.html', dest: 'example/dist', - rename: () => 'index.html' - } - ] + rename: () => 'index.html', + }, + ], }), - ] -} + ], +}; -export default config; \ No newline at end of file +export default config; diff --git a/packages/angular-material/src/controls/autocomplete.renderer.ts b/packages/angular-material/src/controls/autocomplete.renderer.ts index e326d86bf..3af32412a 100644 --- a/packages/angular-material/src/controls/autocomplete.renderer.ts +++ b/packages/angular-material/src/controls/autocomplete.renderer.ts @@ -22,7 +22,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + Input, + OnInit, +} from '@angular/core'; import type { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { @@ -32,11 +37,10 @@ import { isEnumControl, OwnPropsOfControl, RankedTester, - rankWith + rankWith, } from '@jsonforms/core'; import type { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { startWith } from 'rxjs/operators'; +import { map, startWith } from 'rxjs/operators'; /** * To use this component you will need to add your own tester: @@ -74,7 +78,7 @@ import { startWith } from 'rxjs/operators'; [formControl]="form" [matAutocomplete]="auto" (keydown)="updateFilter($event)" - (focus)="focused = true" + (focus)="focused = true" (focusout)="focused = false" /> - {{ description }} + {{ + description + }} {{ error }} `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class AutocompleteControlRenderer extends JsonFormsControl { +export class AutocompleteControlRenderer + extends JsonFormsControl + implements OnInit +{ @Input() options: string[]; filteredOptions: Observable; shouldFilter: boolean; @@ -110,7 +119,7 @@ export class AutocompleteControlRenderer extends JsonFormsControl { this.shouldFilter = false; this.filteredOptions = this.form.valueChanges.pipe( startWith(''), - map(val => this.filter(val)) + map((val) => this.filter(val)) ); } @@ -126,13 +135,15 @@ export class AutocompleteControlRenderer extends JsonFormsControl { onSelect(ev: MatAutocompleteSelectedEvent) { const path = composeWithUi(this.uischema as ControlElement, this.path); this.shouldFilter = false; - this.jsonFormsService.updateCore(Actions.update(path, () => ev.option.value)); + this.jsonFormsService.updateCore( + Actions.update(path, () => ev.option.value) + ); this.triggerValidation(); } filter(val: string): string[] { return (this.options || this.scopedSchema.enum || []).filter( - option => + (option) => !this.shouldFilter || !val || option.toLowerCase().indexOf(val.toLowerCase()) === 0 @@ -141,7 +152,7 @@ export class AutocompleteControlRenderer extends JsonFormsControl { protected getOwnProps(): OwnPropsOfAutoComplete { return { ...super.getOwnProps(), - options: this.options + options: this.options, }; } } diff --git a/packages/angular-material/src/controls/boolean.renderer.ts b/packages/angular-material/src/controls/boolean.renderer.ts index 06d9807d5..da81a68b2 100644 --- a/packages/angular-material/src/controls/boolean.renderer.ts +++ b/packages/angular-material/src/controls/boolean.renderer.ts @@ -22,7 +22,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewRef} from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ViewRef, +} from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { isBooleanControl, RankedTester, rankWith } from '@jsonforms/core'; @@ -43,14 +48,19 @@ import { isBooleanControl, RankedTester, rankWith } from '@jsonforms/core'; > {{ label }} - {{ description }} + {{ + description + }} {{ error }} `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class BooleanControlRenderer extends JsonFormsControl { - constructor(jsonformsService: JsonFormsAngularService, private changeDetectionRef: ChangeDetectorRef) { + constructor( + jsonformsService: JsonFormsAngularService, + private changeDetectionRef: ChangeDetectorRef + ) { super(jsonformsService); } isChecked = () => this.data || false; diff --git a/packages/angular-material/src/controls/date.renderer.ts b/packages/angular-material/src/controls/date.renderer.ts index e937f0a88..5d628a171 100644 --- a/packages/angular-material/src/controls/date.renderer.ts +++ b/packages/angular-material/src/controls/date.renderer.ts @@ -23,11 +23,7 @@ THE SOFTWARE. */ import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { - isDateControl, - RankedTester, - rankWith -} from '@jsonforms/core'; +import { isDateControl, RankedTester, rankWith } from '@jsonforms/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; @Component({ @@ -41,7 +37,7 @@ import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; [id]="id" [formControl]="form" [matDatepicker]="datepicker" - (focus)="focused = true" + (focus)="focused = true" (focusout)="focused = false" /> - {{ description }} + {{ + description + }} {{ error }} `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class DateControlRenderer extends JsonFormsControl { - constructor( - jsonformsService: JsonFormsAngularService, - ) { + constructor(jsonformsService: JsonFormsAngularService) { super(jsonformsService); } diff --git a/packages/angular-material/src/controls/number.renderer.ts b/packages/angular-material/src/controls/number.renderer.ts index ce0a8e2d5..3907eab3c 100644 --- a/packages/angular-material/src/controls/number.renderer.ts +++ b/packages/angular-material/src/controls/number.renderer.ts @@ -30,7 +30,7 @@ import { or, RankedTester, rankWith, - StatePropsOfControl + StatePropsOfControl, } from '@jsonforms/core'; import merge from 'lodash/merge'; @@ -48,14 +48,16 @@ import merge from 'lodash/merge'; [min]="min" [max]="max" [step]="multipleOf" - (focus)="focused = true" + (focus)="focused = true" (focusout)="focused = false" /> - {{ description }} + {{ + description + }} {{ error }} `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class NumberControlRenderer extends JsonFormsControl { private readonly MAXIMUM_FRACTIONAL_DIGITS = 20; @@ -126,25 +128,33 @@ export class NumberControlRenderer extends JsonFormsControl { return ''; }; - mapAdditionalProps(props:StatePropsOfControl) { + mapAdditionalProps(props: StatePropsOfControl) { if (this.scopedSchema) { const testerContext = { rootSchema: this.rootSchema, - config: props.config - } - const defaultStep = isNumberControl(this.uischema, this.rootSchema, testerContext) + config: props.config, + }; + const defaultStep = isNumberControl( + this.uischema, + this.rootSchema, + testerContext + ) ? 0.1 : 1; this.min = this.scopedSchema.minimum; this.max = this.scopedSchema.maximum; this.multipleOf = this.scopedSchema.multipleOf || defaultStep; - const appliedUiSchemaOptions = merge({}, props.config, this.uischema.options); + const appliedUiSchemaOptions = merge( + {}, + props.config, + this.uischema.options + ); const currentLocale = this.jsonFormsService.getLocale(); if (this.locale === undefined || this.locale !== currentLocale) { this.locale = currentLocale; this.numberFormat = new Intl.NumberFormat(this.locale, { useGrouping: appliedUiSchemaOptions.useGrouping, - maximumFractionDigits: this.MAXIMUM_FRACTIONAL_DIGITS + maximumFractionDigits: this.MAXIMUM_FRACTIONAL_DIGITS, }); this.determineDecimalSeparator(); this.oldValue = this.getValue(); diff --git a/packages/angular-material/src/controls/range.renderer.ts b/packages/angular-material/src/controls/range.renderer.ts index 1effc3f7f..49a397978 100644 --- a/packages/angular-material/src/controls/range.renderer.ts +++ b/packages/angular-material/src/controls/range.renderer.ts @@ -22,7 +22,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { ChangeDetectionStrategy, Component, ChangeDetectorRef } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + ChangeDetectorRef, +} from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { isRangeControl, RankedTester, rankWith } from '@jsonforms/core'; @@ -44,18 +48,23 @@ import { isRangeControl, RankedTester, rankWith } from '@jsonforms/core'; tickInterval="auto" [id]="id" > - {{ description }} + {{ + description + }} {{ error }} `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class RangeControlRenderer extends JsonFormsControl { min: number; max: number; multipleOf: number; - constructor(jsonformsService: JsonFormsAngularService, private changeDetectorRef: ChangeDetectorRef) { + constructor( + jsonformsService: JsonFormsAngularService, + private changeDetectorRef: ChangeDetectorRef + ) { super(jsonformsService); } getEventValue = (event: any) => Number(event.value); diff --git a/packages/angular-material/src/controls/text.renderer.ts b/packages/angular-material/src/controls/text.renderer.ts index 6e7d1f7c7..8659a6497 100644 --- a/packages/angular-material/src/controls/text.renderer.ts +++ b/packages/angular-material/src/controls/text.renderer.ts @@ -37,14 +37,16 @@ import { isStringControl, RankedTester, rankWith } from '@jsonforms/core'; (input)="onChange($event)" [id]="id" [formControl]="form" - (focus)="focused = true" + (focus)="focused = true" (focusout)="focused = false" /> - {{ description }} + {{ + description + }} {{ error }} `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class TextControlRenderer extends JsonFormsControl { constructor(jsonformsService: JsonFormsAngularService) { diff --git a/packages/angular-material/src/controls/textarea.renderer.ts b/packages/angular-material/src/controls/textarea.renderer.ts index a40c0ca16..073b1b3fe 100644 --- a/packages/angular-material/src/controls/textarea.renderer.ts +++ b/packages/angular-material/src/controls/textarea.renderer.ts @@ -36,14 +36,16 @@ import { isMultiLineControl, RankedTester, rankWith } from '@jsonforms/core'; (input)="onChange($event)" [id]="id" [formControl]="form" - (focus)="focused = true" + (focus)="focused = true" (focusout)="focused = false" > - {{ description }} + {{ + description + }} {{ error }} `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class TextAreaRenderer extends JsonFormsControl { constructor(jsonformsService: JsonFormsAngularService) { diff --git a/packages/angular-material/src/controls/toggle.renderer.ts b/packages/angular-material/src/controls/toggle.renderer.ts index a0586f910..0404da0fe 100644 --- a/packages/angular-material/src/controls/toggle.renderer.ts +++ b/packages/angular-material/src/controls/toggle.renderer.ts @@ -22,14 +22,18 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { ChangeDetectionStrategy, Component, ChangeDetectorRef } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + ChangeDetectorRef, +} from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { and, isBooleanControl, optionIs, RankedTester, - rankWith + rankWith, } from '@jsonforms/core'; @Component({ @@ -44,14 +48,19 @@ import { > {{ label }} - {{ description }} + {{ + description + }} {{ error }} `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class ToggleControlRenderer extends JsonFormsControl { - constructor(jsonformsService: JsonFormsAngularService, private changeDetectorRef: ChangeDetectorRef) { + constructor( + jsonformsService: JsonFormsAngularService, + private changeDetectorRef: ChangeDetectorRef + ) { super(jsonformsService); } isChecked = () => this.data || false; diff --git a/packages/angular-material/src/index.ts b/packages/angular-material/src/index.ts index 67819e6d8..64c286e7d 100644 --- a/packages/angular-material/src/index.ts +++ b/packages/angular-material/src/index.ts @@ -27,67 +27,67 @@ import { RankedTester } from '@jsonforms/core'; export * from './module'; import { BooleanControlRenderer, - booleanControlTester + booleanControlTester, } from './controls/boolean.renderer'; import { TextControlRenderer, - TextControlRendererTester + TextControlRendererTester, } from './controls/text.renderer'; import { TextAreaRenderer, - TextAreaRendererTester + TextAreaRendererTester, } from './controls/textarea.renderer'; import { NumberControlRenderer, - NumberControlRendererTester + NumberControlRendererTester, } from './controls/number.renderer'; import { RangeControlRenderer, - RangeControlRendererTester + RangeControlRendererTester, } from './controls/range.renderer'; import { DateControlRenderer, - DateControlRendererTester + DateControlRendererTester, } from './controls/date.renderer'; import { ToggleControlRenderer, - ToggleControlRendererTester + ToggleControlRendererTester, } from './controls/toggle.renderer'; import { AutocompleteControlRenderer, - enumControlTester + enumControlTester, } from './controls/autocomplete.renderer'; import { ObjectControlRenderer, - ObjectControlRendererTester + ObjectControlRendererTester, } from './other/object.renderer'; import { VerticalLayoutRenderer, - verticalLayoutTester + verticalLayoutTester, } from './layouts/vertical-layout.renderer'; import { HorizontalLayoutRenderer, - horizontalLayoutTester + horizontalLayoutTester, } from './layouts/horizontal-layout.renderer'; import { CategorizationTabLayoutRenderer, - categorizationTester + categorizationTester, } from './layouts/categorization-layout.renderer'; import { LabelRenderer, LabelRendererTester } from './other/label.renderer'; import { masterDetailTester, - MasterListComponent + MasterListComponent, } from './other/master-detail/master'; import { GroupLayoutRenderer, - groupLayoutTester + groupLayoutTester, } from './layouts/group-layout.renderer'; import { TableRenderer, TableRendererTester } from './other/table.renderer'; import { ArrayLayoutRenderer, - ArrayLayoutRendererTester + ArrayLayoutRendererTester, } from './layouts/array-layout.renderer'; export * from './controls'; @@ -117,5 +117,5 @@ export const angularMaterialRenderers: { { tester: ArrayLayoutRendererTester, renderer: ArrayLayoutRenderer }, // other { tester: masterDetailTester, renderer: MasterListComponent }, - { tester: TableRendererTester, renderer: TableRenderer } + { tester: TableRendererTester, renderer: TableRenderer }, ]; diff --git a/packages/angular-material/src/layouts/array-layout.renderer.ts b/packages/angular-material/src/layouts/array-layout.renderer.ts index ce966145f..eb1b3c1b6 100644 --- a/packages/angular-material/src/layouts/array-layout.renderer.ts +++ b/packages/angular-material/src/layouts/array-layout.renderer.ts @@ -26,11 +26,15 @@ import { ChangeDetectionStrategy, Component, OnDestroy, - OnInit + OnInit, } from '@angular/core'; -import { JsonFormsAngularService, JsonFormsAbstractControl } from '@jsonforms/angular'; +import { + JsonFormsAngularService, + JsonFormsAbstractControl, +} from '@jsonforms/angular'; import { ArrayLayoutProps, + ArrayTranslations, createDefaultValue, findUISchema, isObjectArrayWithNesting, @@ -45,7 +49,7 @@ import { StatePropsOfArrayLayout, UISchemaElement, UISchemaTester, - unsetReadonly + unsetReadonly, } from '@jsonforms/core'; @Component({ @@ -58,25 +62,30 @@ import { - error_outline + > + error_outline -

{{ this.noDataMessage }}

+

{{ translations.noDataMessage }}

-
`, styles: [ - `.array-layout-toolbar { - display: flex; - align-items: center; + ` + .array-layout-toolbar { + display: flex; + align-items: center; } .array-layout-title { margin: 0; @@ -141,23 +151,16 @@ import { ::ng-deep .error-message-tooltip { white-space: pre-line; } - ` + `, ], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class ArrayLayoutRenderer extends JsonFormsAbstractControl - implements OnInit, OnDestroy { - addTooltip: string; - addAriaLabel: string; - noDataMessage: string; - removeTooltip: string; - removeAriaLabel: string; - upTooltip: string; - upAriaLabel: string; - downTooltip: string; - downAriaLabel:string; + implements OnInit, OnDestroy +{ noData: boolean; + translations: ArrayTranslations; addItem: (path: string, value: any) => () => void; moveItemUp: (path: string, index: number) => () => void; moveItemDown: (path: string, index: number) => () => void; @@ -187,24 +190,19 @@ export class ArrayLayoutRenderer } ngOnInit() { super.ngOnInit(); - const { addItem, removeItems, moveUp, moveDown } = mapDispatchToArrayControlProps( - this.jsonFormsService.updateCore.bind(this.jsonFormsService) - ); + const { addItem, removeItems, moveUp, moveDown } = + mapDispatchToArrayControlProps( + this.jsonFormsService.updateCore.bind(this.jsonFormsService) + ); this.addItem = addItem; this.moveItemUp = moveUp; this.moveItemDown = moveDown; this.removeItems = removeItems; } mapAdditionalProps(props: ArrayLayoutProps) { + this.translations = props.translations; this.noData = !props.data || props.data === 0; this.uischemas = props.uischemas; - this.addTooltip = `Add to ${this.label}`; - this.addAriaLabel = `Add to ${this.label} button`; - this.upAriaLabel = `Move ${this.label} up`; - this.downAriaLabel = `Move ${this.label} down`; - this.removeTooltip = `Delete`; - this.removeAriaLabel = `Delete button`; - this.noDataMessage = `No data`; } getProps(index: number): OwnPropsOfRenderer { const uischema = findUISchema( @@ -224,7 +222,7 @@ export class ArrayLayoutRenderer return { schema: this.scopedSchema, path: Paths.compose(this.propsPath, `${index}`), - uischema + uischema, }; } trackByFn(index: number) { diff --git a/packages/angular-material/src/layouts/categorization-layout.renderer.ts b/packages/angular-material/src/layouts/categorization-layout.renderer.ts index f5526eec0..b594693ac 100644 --- a/packages/angular-material/src/layouts/categorization-layout.renderer.ts +++ b/packages/angular-material/src/layouts/categorization-layout.renderer.ts @@ -36,12 +36,12 @@ import { mapStateToLayoutProps, RankedTester, rankWith, - uiTypeIs + uiTypeIs, } from '@jsonforms/core'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { JsonFormsAngularService, - JsonFormsBaseRenderer + JsonFormsBaseRenderer, } from '@jsonforms/angular'; import { Subscription } from 'rxjs'; @@ -54,15 +54,20 @@ import { Subscription } from 'rxjs'; [label]="categoryLabels[i]" >
- +
- ` + `, }) export class CategorizationTabLayoutRenderer extends JsonFormsBaseRenderer - implements OnInit, OnDestroy { + implements OnInit, OnDestroy +{ hidden: boolean; visibleCategories: (Category | Categorization)[]; private subscription: Subscription; @@ -77,12 +82,18 @@ export class CategorizationTabLayoutRenderer next: (state: JsonFormsState) => { const props = mapStateToLayoutProps(state, this.getOwnProps()); this.hidden = !props.visible; - this.visibleCategories = this.uischema.elements.filter((category: Category | Categorization) => - isVisible(category, props.data, undefined, getAjv(state))); - this.categoryLabels = this.visibleCategories.map( - element => deriveLabelForUISchemaElement(element as Labelable, - state.jsonforms.i18n?.translate ?? defaultJsonFormsI18nState.translate)); - } + this.visibleCategories = this.uischema.elements.filter( + (category: Category | Categorization) => + isVisible(category, props.data, undefined, getAjv(state)) + ); + this.categoryLabels = this.visibleCategories.map((element) => + deriveLabelForUISchemaElement( + element as Labelable, + state.jsonforms.i18n?.translate ?? + defaultJsonFormsI18nState.translate + ) + ); + }, }); } diff --git a/packages/angular-material/src/layouts/group-layout.renderer.ts b/packages/angular-material/src/layouts/group-layout.renderer.ts index e18b52d99..291d5e814 100644 --- a/packages/angular-material/src/layouts/group-layout.renderer.ts +++ b/packages/angular-material/src/layouts/group-layout.renderer.ts @@ -22,7 +22,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, +} from '@angular/core'; import { GroupLayout, RankedTester, rankWith, uiTypeIs } from '@jsonforms/core'; import { LayoutRenderer } from './layout.renderer'; import { JsonFormsAngularService } from '@jsonforms/angular'; @@ -32,15 +36,24 @@ import { JsonFormsAngularService } from '@jsonforms/angular'; template: ` {{ label }} -
+
`, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class GroupLayoutRenderer extends LayoutRenderer { - constructor(jsonFormsService: JsonFormsAngularService, changeDetectionRef: ChangeDetectorRef) { + constructor( + jsonFormsService: JsonFormsAngularService, + changeDetectionRef: ChangeDetectorRef + ) { super(jsonFormsService, changeDetectionRef); } } diff --git a/packages/angular-material/src/layouts/horizontal-layout.renderer.ts b/packages/angular-material/src/layouts/horizontal-layout.renderer.ts index 9a541e440..b4c450b93 100644 --- a/packages/angular-material/src/layouts/horizontal-layout.renderer.ts +++ b/packages/angular-material/src/layouts/horizontal-layout.renderer.ts @@ -22,12 +22,16 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, +} from '@angular/core'; import { HorizontalLayout, RankedTester, rankWith, - uiTypeIs + uiTypeIs, } from '@jsonforms/core'; import { LayoutRenderer } from './layout.renderer'; import { JsonFormsAngularService } from '@jsonforms/angular'; @@ -41,15 +45,24 @@ import { JsonFormsAngularService } from '@jsonforms/angular'; [fxHide]="hidden" fxLayoutAlign="center start" > -
+
`, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class HorizontalLayoutRenderer extends LayoutRenderer { - constructor(jsonFormsService: JsonFormsAngularService, changeDetectionRef: ChangeDetectorRef) { + constructor( + jsonFormsService: JsonFormsAngularService, + changeDetectionRef: ChangeDetectorRef + ) { super(jsonFormsService, changeDetectionRef); } } diff --git a/packages/angular-material/src/layouts/layout.renderer.ts b/packages/angular-material/src/layouts/layout.renderer.ts index d8e81f4cb..35b795814 100644 --- a/packages/angular-material/src/layouts/layout.renderer.ts +++ b/packages/angular-material/src/layouts/layout.renderer.ts @@ -22,10 +22,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { OnDestroy, OnInit, ChangeDetectorRef, Component, PipeTransform, Pipe } from '@angular/core'; +import { + OnDestroy, + OnInit, + ChangeDetectorRef, + Component, + PipeTransform, + Pipe, +} from '@angular/core'; import { JsonFormsAngularService, - JsonFormsBaseRenderer + JsonFormsBaseRenderer, } from '@jsonforms/angular'; import { JsonFormsState, @@ -33,20 +40,25 @@ import { mapStateToLayoutProps, OwnPropsOfRenderer, UISchemaElement, - JsonSchema + JsonSchema, } from '@jsonforms/core'; import type { Subscription } from 'rxjs'; @Component({ - template: '' + template: '', }) -export class LayoutRenderer extends JsonFormsBaseRenderer - implements OnInit, OnDestroy { +export class LayoutRenderer + extends JsonFormsBaseRenderer + implements OnInit, OnDestroy +{ hidden: boolean; label: string | undefined; private subscription: Subscription; - constructor(private jsonFormsService: JsonFormsAngularService, protected changeDetectionRef: ChangeDetectorRef) { + constructor( + private jsonFormsService: JsonFormsAngularService, + protected changeDetectionRef: ChangeDetectorRef + ) { super(); } @@ -57,7 +69,7 @@ export class LayoutRenderer extends JsonFormsBaseRenderer this.label = props.label; this.hidden = !props.visible; this.changeDetectionRef.markForCheck(); - } + }, }); } @@ -76,15 +88,16 @@ export class LayoutRenderer extends JsonFormsBaseRenderer @Pipe({ name: 'layoutChildrenRenderProps' }) export class LayoutChildrenRenderPropsPipe implements PipeTransform { - transform(uischema: Layout, schema: JsonSchema, path: string): OwnPropsOfRenderer[] { - const elements = (uischema.elements || []).map( - (el: UISchemaElement) => ({ - uischema: el, - schema: schema, - path: path - }) - ); + transform( + uischema: Layout, + schema: JsonSchema, + path: string + ): OwnPropsOfRenderer[] { + const elements = (uischema.elements || []).map((el: UISchemaElement) => ({ + uischema: el, + schema: schema, + path: path, + })); return elements; } - } diff --git a/packages/angular-material/src/layouts/vertical-layout.renderer.ts b/packages/angular-material/src/layouts/vertical-layout.renderer.ts index 7d285476b..f7c879394 100644 --- a/packages/angular-material/src/layouts/vertical-layout.renderer.ts +++ b/packages/angular-material/src/layouts/vertical-layout.renderer.ts @@ -22,12 +22,16 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, +} from '@angular/core'; import { RankedTester, rankWith, uiTypeIs, - VerticalLayout + VerticalLayout, } from '@jsonforms/core'; import { LayoutRenderer } from './layout.renderer'; import { JsonFormsAngularService } from '@jsonforms/angular'; @@ -36,15 +40,24 @@ import { JsonFormsAngularService } from '@jsonforms/angular'; selector: 'VerticalLayoutRenderer', template: `
-
+
`, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class VerticalLayoutRenderer extends LayoutRenderer { - constructor(jsonFormsService: JsonFormsAngularService, changeDetectionRef: ChangeDetectorRef) { + constructor( + jsonFormsService: JsonFormsAngularService, + changeDetectionRef: ChangeDetectorRef + ) { super(jsonFormsService, changeDetectionRef); } } diff --git a/packages/angular-material/src/module.ts b/packages/angular-material/src/module.ts index 9ce00c79f..7dc23720e 100644 --- a/packages/angular-material/src/module.ts +++ b/packages/angular-material/src/module.ts @@ -25,9 +25,7 @@ import { CommonModule } from '@angular/common'; import { FlexLayoutModule } from '@angular/flex-layout'; import { ReactiveFormsModule } from '@angular/forms'; -import { - MatAutocompleteModule -} from '@angular/material/autocomplete'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; import { MatBadgeModule } from '@angular/material/badge'; import { MatCardModule } from '@angular/material/card'; @@ -92,7 +90,7 @@ import { LayoutChildrenRenderPropsPipe } from './layouts'; MatTableModule, MatToolbarModule, MatTooltipModule, - MatBadgeModule + MatBadgeModule, ], declarations: [ BooleanControlRenderer, @@ -113,7 +111,7 @@ import { LayoutChildrenRenderPropsPipe } from './layouts'; AutocompleteControlRenderer, TableRenderer, ArrayLayoutRenderer, - LayoutChildrenRenderPropsPipe + LayoutChildrenRenderPropsPipe, ], entryComponents: [ BooleanControlRenderer, @@ -133,7 +131,7 @@ import { LayoutChildrenRenderPropsPipe } from './layouts'; ObjectControlRenderer, AutocompleteControlRenderer, TableRenderer, - ArrayLayoutRenderer + ArrayLayoutRenderer, ], exports: [ CommonModule, @@ -154,9 +152,9 @@ import { LayoutChildrenRenderPropsPipe } from './layouts'; MatSelectModule, MatButtonModule, MatIconModule, - MatAutocompleteModule + MatAutocompleteModule, ], schemas: [CUSTOM_ELEMENTS_SCHEMA], - providers: [] + providers: [], }) -export class JsonFormsAngularMaterialModule { } +export class JsonFormsAngularMaterialModule {} diff --git a/packages/angular-material/src/other/label.renderer.ts b/packages/angular-material/src/other/label.renderer.ts index 341c0ea4c..e5ff352b3 100644 --- a/packages/angular-material/src/other/label.renderer.ts +++ b/packages/angular-material/src/other/label.renderer.ts @@ -22,10 +22,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { Component } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { JsonFormsAngularService, - JsonFormsBaseRenderer + JsonFormsBaseRenderer, } from '@jsonforms/angular'; import { JsonFormsState, @@ -40,11 +40,12 @@ import { Subscription } from 'rxjs'; @Component({ selector: 'LabelRenderer', - template: ` - - ` + template: ` `, }) -export class LabelRenderer extends JsonFormsBaseRenderer { +export class LabelRenderer + extends JsonFormsBaseRenderer + implements OnDestroy, OnInit +{ label: string; visible: boolean; @@ -56,10 +57,13 @@ export class LabelRenderer extends JsonFormsBaseRenderer { ngOnInit() { this.subscription = this.jsonFormsService.$state.subscribe({ next: (state: JsonFormsState) => { - const props = mapStateToLabelProps(state, this.getOwnProps() as OwnPropsOfLabel); + const props = mapStateToLabelProps( + state, + this.getOwnProps() as OwnPropsOfLabel + ); this.visible = props.visible; - this.label = props.text - } + this.label = props.text; + }, }); } diff --git a/packages/angular-material/src/other/master-detail/detail.ts b/packages/angular-material/src/other/master-detail/detail.ts index 66ac06734..9076a6667 100644 --- a/packages/angular-material/src/other/master-detail/detail.ts +++ b/packages/angular-material/src/other/master-detail/detail.ts @@ -30,14 +30,14 @@ import { Component, Input } from '@angular/core';
- ` + `, }) export class JsonFormsDetailComponent { _item: any; _schema: any; initialized = false; - @Input('item') + @Input() set item(item: any) { if (item) { this._item = item; diff --git a/packages/angular-material/src/other/master-detail/master.ts b/packages/angular-material/src/other/master-detail/master.ts index eb99b90e1..8b8f58b3d 100644 --- a/packages/angular-material/src/other/master-detail/master.ts +++ b/packages/angular-material/src/other/master-detail/master.ts @@ -24,13 +24,19 @@ */ import some from 'lodash/some'; import get from 'lodash/get'; -import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnInit, +} from '@angular/core'; import { JsonFormsAngularService, - JsonFormsArrayControl + JsonFormsArrayControl, } from '@jsonforms/angular'; import { ArrayControlProps, + ArrayTranslations, ControlElement, createDefaultValue, decode, @@ -43,7 +49,7 @@ import { rankWith, setReadonly, StatePropsOfArrayControl, - uiTypeIs + uiTypeIs, } from '@jsonforms/core'; const keywords = ['#', 'properties', 'items']; @@ -52,7 +58,7 @@ export const removeSchemaKeywords = (path: string) => { return decode( path .split('/') - .filter(s => !some(keywords, key => key === s)) + .filter((s) => !some(keywords, (key) => key === s)) .join('.') ); }; @@ -63,9 +69,9 @@ export const removeSchemaKeywords = (path: string) => { - No items + {{ + translations.noDataMessage + }} - add + add @@ -137,11 +143,14 @@ export const removeSchemaKeywords = (path: string) => { mat-sidenav { width: 20%; } - ` + `, ], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MasterListComponent extends JsonFormsArrayControl { +export class MasterListComponent + extends JsonFormsArrayControl + implements OnInit +{ masterItems: any[]; selectedItem: any; selectedItemIdx: number; @@ -149,8 +158,12 @@ export class MasterListComponent extends JsonFormsArrayControl { removeItems: (path: string, toDelete: number[]) => () => void; propsPath: string; highlightedIdx: number; + translations: ArrayTranslations; - constructor(jsonformsService: JsonFormsAngularService, private changeDetectorRef: ChangeDetectorRef) { + constructor( + jsonformsService: JsonFormsAngularService, + private changeDetectorRef: ChangeDetectorRef + ) { super(jsonformsService); } @@ -164,7 +177,9 @@ export class MasterListComponent extends JsonFormsArrayControl { ngOnInit() { super.ngOnInit(); - const dispatch = this.jsonFormsService.updateCore.bind(this.jsonFormsService); + const dispatch = this.jsonFormsService.updateCore.bind( + this.jsonFormsService + ); const { addItem, removeItems } = mapDispatchToArrayControlProps(dispatch); this.addItem = addItem; this.removeItems = removeItems; @@ -175,30 +190,34 @@ export class MasterListComponent extends JsonFormsArrayControl { const controlElement = uischema as ControlElement; this.propsPath = props.path; const detailUISchema = findUISchema( - props.uischemas, - schema, - `${controlElement.scope}/items`, - props.path, - 'VerticalLayout', - controlElement, - props.rootSchema - ); + props.uischemas, + schema, + `${controlElement.scope}/items`, + props.path, + 'VerticalLayout', + controlElement, + props.rootSchema + ); if (!this.isEnabled()) { setReadonly(detailUISchema); } + this.translations = props.translations; + const masterItems = (data || []).map((d: any, index: number) => { - const labelRefInstancePath = controlElement.options?.labelRef && removeSchemaKeywords( - controlElement.options.labelRef - ); + const labelRefInstancePath = + controlElement.options?.labelRef && + removeSchemaKeywords(controlElement.options.labelRef); const isPrimitive = d !== undefined && typeof d !== 'object'; const masterItem = { - label: isPrimitive ? d.toString() : get(d, labelRefInstancePath ?? getFirstPrimitiveProp(schema)), + label: isPrimitive + ? d.toString() + : get(d, labelRefInstancePath ?? getFirstPrimitiveProp(schema)), data: d, path: `${path}.${index}`, schema, - uischema: detailUISchema + uischema: detailUISchema, }; return masterItem; }); diff --git a/packages/angular-material/src/other/object.renderer.ts b/packages/angular-material/src/other/object.renderer.ts index 1bf86a755..8e7e5a10f 100644 --- a/packages/angular-material/src/other/object.renderer.ts +++ b/packages/angular-material/src/other/object.renderer.ts @@ -27,7 +27,7 @@ import startCase from 'lodash/startCase'; import { ChangeDetectionStrategy, Component } from '@angular/core'; import { JsonFormsAngularService, - JsonFormsControlWithDetail + JsonFormsControlWithDetail, } from '@jsonforms/angular'; import { ControlWithDetailProps, @@ -37,7 +37,7 @@ import { RankedTester, rankWith, setReadonly, - UISchemaElement + UISchemaElement, } from '@jsonforms/core'; @Component({ @@ -52,7 +52,7 @@ import { `, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class ObjectControlRenderer extends JsonFormsControlWithDetail { detailUiSchema: UISchemaElement; diff --git a/packages/angular-material/src/other/table.renderer.ts b/packages/angular-material/src/other/table.renderer.ts index 62c2542ef..7cdcdb991 100644 --- a/packages/angular-material/src/other/table.renderer.ts +++ b/packages/angular-material/src/other/table.renderer.ts @@ -23,26 +23,29 @@ THE SOFTWARE. */ import startCase from 'lodash/startCase'; -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { JsonFormsAngularService, - JsonFormsArrayControl + JsonFormsArrayControl, } from '@jsonforms/angular'; import { ArrayControlProps, - ControlElement, createDefaultValue, + ArrayTranslations, + ControlElement, + createDefaultValue, deriveTypes, encode, isObjectArrayControl, isPrimitiveArrayControl, - JsonSchema, mapDispatchToArrayControlProps, + JsonSchema, + mapDispatchToArrayControlProps, or, OwnPropsOfRenderer, Paths, RankedTester, rankWith, setReadonly, - UISchemaElement + UISchemaElement, } from '@jsonforms/core'; @Component({ @@ -57,20 +60,36 @@ import { - + - - - - + + + + `, - styles: [ - 'table {width: 100%;}', - '.cdk-column-action { width: 15%}'] + styles: ['table {width: 100%;}', '.cdk-column-action { width: 15%}'], }) -export class TableRenderer extends JsonFormsArrayControl { +export class TableRenderer extends JsonFormsArrayControl implements OnInit { detailUiSchema: UISchemaElement; displayedColumns: string[]; items: ColumnDescription[]; @@ -126,6 +146,7 @@ export class TableRenderer extends JsonFormsArrayControl { moveItemUp: (path: string, index: number) => () => void; moveItemDown: (path: string, index: number) => () => void; removeItems: (path: string, toDelete: number[]) => () => void; + translations: ArrayTranslations; constructor(jsonformsService: JsonFormsAngularService) { super(jsonformsService); @@ -135,17 +156,18 @@ export class TableRenderer extends JsonFormsArrayControl { } mapAdditionalProps(props: ArrayControlProps) { this.items = this.generateCells(props.schema, props.path); - this.displayedColumns = this.items.map(item => item.property); + this.displayedColumns = this.items.map((item) => item.property); if (this.isEnabled()) { this.displayedColumns.push('action'); } + this.translations = props.translations; } getProps(index: number, props: OwnPropsOfRenderer): OwnPropsOfRenderer { const rowPath = Paths.compose(props.path, `${index}`); return { schema: props.schema, uischema: props.uischema, - path: rowPath + path: rowPath, }; } @@ -164,9 +186,10 @@ export class TableRenderer extends JsonFormsArrayControl { ngOnInit() { super.ngOnInit(); - const { addItem, removeItems, moveUp, moveDown } = mapDispatchToArrayControlProps( + const { addItem, removeItems, moveUp, moveDown } = + mapDispatchToArrayControlProps( this.jsonFormsService.updateCore.bind(this.jsonFormsService) - ); + ); this.addItem = addItem; this.moveItemUp = moveUp; this.moveItemDown = moveDown; @@ -178,7 +201,7 @@ export class TableRenderer extends JsonFormsArrayControl { rowPath: string ): ColumnDescription[] => { if (schema.type === 'object') { - return this.getValidColumnProps(schema).map(prop => { + return this.getValidColumnProps(schema).map((prop) => { const encProp = encode(prop); const uischema = controlWithoutLabel(`#/properties/${encProp}`); if (!this.isEnabled()) { @@ -190,8 +213,8 @@ export class TableRenderer extends JsonFormsArrayControl { props: { schema: schema, uischema, - path: rowPath - } + path: rowPath, + }, }; }); } @@ -203,15 +226,15 @@ export class TableRenderer extends JsonFormsArrayControl { props: { schema: schema, uischema: controlWithoutLabel(`#`), - path: rowPath - } - } + path: rowPath, + }, + }, ]; }; getValidColumnProps = (scopedSchema: JsonSchema) => { if (scopedSchema.type === 'object') { - return Object.keys(scopedSchema.properties).filter(prop => { + return Object.keys(scopedSchema.properties).filter((prop) => { const types = deriveTypes(scopedSchema.properties[prop]); if (types.length > 1) { return false; @@ -237,5 +260,5 @@ interface ColumnDescription { export const controlWithoutLabel = (scope: string): ControlElement => ({ type: 'Control', scope: scope, - label: false + label: false, }); diff --git a/packages/angular-material/src/other/util.ts b/packages/angular-material/src/other/util.ts index 2abdcc178..767200287 100644 --- a/packages/angular-material/src/other/util.ts +++ b/packages/angular-material/src/other/util.ts @@ -22,12 +22,19 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { ControlElement, getAjv, getData, isVisible, JsonFormsState, OwnPropsOfRenderer } from '@jsonforms/core'; +import { + ControlElement, + getAjv, + getData, + isVisible, + JsonFormsState, + OwnPropsOfRenderer, +} from '@jsonforms/core'; export const controlWithoutLabel = (scope: string): ControlElement => ({ type: 'Control', scope: scope, - label: false + label: false, }); export const mapStateToVisible = ( @@ -40,6 +47,6 @@ export const mapStateToVisible = ( : isVisible(ownProps.uischema, getData(state), undefined, getAjv(state)); return { - visible + visible, }; }; diff --git a/packages/angular-material/test-config/karma-test-shim.js b/packages/angular-material/test-config/karma-test-shim.js index cb0112587..de240f3e5 100755 --- a/packages/angular-material/test-config/karma-test-shim.js +++ b/packages/angular-material/test-config/karma-test-shim.js @@ -18,4 +18,7 @@ appContext.keys().forEach(appContext); var testing = require('@angular/core/testing'); var browser = require('@angular/platform-browser-dynamic/testing'); -testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting()); +testing.TestBed.initTestEnvironment( + browser.BrowserDynamicTestingModule, + browser.platformBrowserDynamicTesting() +); diff --git a/packages/angular-material/test-config/karma.conf.js b/packages/angular-material/test-config/karma.conf.js index 7ef05799f..7cecf6925 100755 --- a/packages/angular-material/test-config/karma.conf.js +++ b/packages/angular-material/test-config/karma.conf.js @@ -1,6 +1,6 @@ var webpackConfig = require('./webpack.test.js'); -module.exports = function(config) { +module.exports = function (config) { var _config = { basePath: '../', @@ -9,36 +9,38 @@ module.exports = function(config) { files: [ { pattern: './test-config/karma-test-shim.js', - watched: true - } + watched: true, + }, ], preprocessors: { - './test-config/karma-test-shim.js': ['webpack', 'sourcemap'] + './test-config/karma-test-shim.js': ['webpack', 'sourcemap'], }, webpack: webpackConfig, webpackMiddleware: { - stats: 'errors-only' + stats: 'errors-only', }, webpackServer: { - noInfo: true + noInfo: true, }, browserConsoleLogOptions: { level: 'log', format: '%b %T: %m', - terminal: true + terminal: true, }, coverageIstanbulReporter: { - reports: [ 'html', 'lcovonly' ], - fixWebpackSourcePaths: true + reports: ['html', 'lcovonly'], + fixWebpackSourcePaths: true, }, - reporters: config.coverage ? ['kjhtml', 'dots', 'coverage-istanbul'] : ['kjhtml', 'dots'], + reporters: config.coverage + ? ['kjhtml', 'dots', 'coverage-istanbul'] + : ['kjhtml', 'dots'], port: 9876, colors: true, @@ -48,10 +50,10 @@ module.exports = function(config) { customLaunchers: { ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', - flags: ['--no-sandbox'] - } + flags: ['--no-sandbox'], + }, }, - singleRun: false + singleRun: false, }; config.set(_config); diff --git a/packages/angular-material/test-config/protractor.conf.js b/packages/angular-material/test-config/protractor.conf.js index 8a0a7fc2f..9f0daec9a 100644 --- a/packages/angular-material/test-config/protractor.conf.js +++ b/packages/angular-material/test-config/protractor.conf.js @@ -5,11 +5,9 @@ const { SpecReporter } = require('jasmine-spec-reporter'); exports.config = { allScriptsTimeout: 11000, - specs: [ - '../e2e/**/*.e2e-spec.ts' - ], + specs: ['../e2e/**/*.e2e-spec.ts'], capabilities: { - 'browserName': 'chrome' + browserName: 'chrome', }, directConnect: true, baseUrl: 'http://localhost:8100/', @@ -17,12 +15,14 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: 'e2e/tsconfig.e2e.json' + project: 'e2e/tsconfig.e2e.json', }); - jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); - } + jasmine + .getEnv() + .addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + }, }; diff --git a/packages/angular-material/test-config/webpack.test.js b/packages/angular-material/test-config/webpack.test.js index 2ab5a0645..431c39eb7 100755 --- a/packages/angular-material/test-config/webpack.test.js +++ b/packages/angular-material/test-config/webpack.test.js @@ -5,7 +5,7 @@ module.exports = { devtool: 'inline-source-map', resolve: { - extensions: ['.ts', '.js'] + extensions: ['.ts', '.js'], }, module: { @@ -16,19 +16,19 @@ module.exports = { options: { plugins: [ '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-nullish-coalescing-operator' - ] + '@babel/plugin-proposal-nullish-coalescing-operator', + ], }, - exclude: /node_modules/ + exclude: /node_modules/, }, { test: /\.ts$/, loaders: [ { - loader: 'ts-loader' + loader: 'ts-loader', }, - 'angular2-template-loader' - ] + 'angular2-template-loader', + ], }, { test: /.+\.ts$/, @@ -36,18 +36,18 @@ module.exports = { loader: 'istanbul-instrumenter-loader', enforce: 'post', query: { - esModules: true - } + esModules: true, + }, }, { test: /\.html$/, - loader: 'html-loader?attrs=false' + loader: 'html-loader?attrs=false', }, { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, - loader: 'null-loader' - } - ] + loader: 'null-loader', + }, + ], }, plugins: [ @@ -56,8 +56,8 @@ module.exports = { /(angular(\\|\/)core(\\|\/)@angular)/, root('./src'), // location of your src {} // a map of your routes - ) - ] + ), + ], }; function root(localPath) { diff --git a/packages/angular-material/test/autocomplete-control.spec.ts b/packages/angular-material/test/autocomplete-control.spec.ts index 777613ef4..d014878d0 100644 --- a/packages/angular-material/test/autocomplete-control.spec.ts +++ b/packages/angular-material/test/autocomplete-control.spec.ts @@ -22,7 +22,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; +import { + MatAutocompleteModule, + MatAutocompleteSelectedEvent, +} from '@angular/material/autocomplete'; import { MatError, MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { OverlayContainer } from '@angular/cdk/overlay'; @@ -32,12 +35,16 @@ import { fakeAsync, inject, TestBed, - tick + tick, } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ErrorTestExpectation, setupMockStore, getJsonFormsService } from '@jsonforms/angular-test'; +import { + ErrorTestExpectation, + setupMockStore, + getJsonFormsService, +} from '@jsonforms/angular-test'; import { ControlElement, JsonSchema, Actions } from '@jsonforms/core'; import { AutocompleteControlRenderer } from '../src'; import { JsonFormsAngularService } from '@jsonforms/angular'; @@ -50,13 +57,13 @@ const schema: JsonSchema = { properties: { foo: { type: 'string', - enum: ['A', 'B', 'C'] - } - } + enum: ['A', 'B', 'C'], + }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const imports = [ @@ -65,14 +72,14 @@ const imports = [ MatFormFieldModule, NoopAnimationsModule, ReactiveFormsModule, - FlexLayoutModule + FlexLayoutModule, ]; const providers = [JsonFormsAngularService]; const componentUT: any = AutocompleteControlRenderer; const errorTest: ErrorTestExpectation = { errorInstance: MatError, numberOfElements: 1, - indexOfElement: 0 + indexOfElement: 0, }; describe('Autocomplete control Base Tests', () => { @@ -83,9 +90,8 @@ describe('Autocomplete control Base Tests', () => { TestBed.configureTestingModule({ declarations: [componentUT], imports: imports, - providers: providers + providers: providers, }).compileComponents(); - }); beforeEach(() => { fixture = TestBed.createComponent(componentUT); @@ -96,7 +102,9 @@ describe('Autocomplete control Base Tests', () => { it('should render', fakeAsync(() => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); tick(); @@ -107,7 +115,9 @@ describe('Autocomplete control Base Tests', () => { it('should support updating the state', fakeAsync(() => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); tick(); @@ -120,29 +130,39 @@ describe('Autocomplete control Base Tests', () => { it('should update with undefined value', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); - getJsonFormsService(component).updateCore(Actions.update('foo', () => undefined)); + getJsonFormsService(component).updateCore( + Actions.update('foo', () => undefined) + ); fixture.detectChanges(); expect(component.data).toBe(undefined); expect(inputElement.value).toBe(''); }); it('should update with null value', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); fixture.detectChanges(); component.ngOnInit(); - getJsonFormsService(component).updateCore(Actions.update('foo', () => null)); + getJsonFormsService(component).updateCore( + Actions.update('foo', () => null) + ); fixture.detectChanges(); expect(component.data).toBe(null); expect(inputElement.value).toBe(''); }); it('should not update with wrong ref', fakeAsync(() => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); tick(); @@ -156,7 +176,9 @@ describe('Autocomplete control Base Tests', () => { // store needed as we evaluate the calculated enabled value to disable/enable the control it('can be disabled', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.disabled = true; component.ngOnInit(); fixture.detectChanges(); @@ -164,7 +186,9 @@ describe('Autocomplete control Base Tests', () => { }); it('can be hidden', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.visible = false; component.ngOnInit(); fixture.detectChanges(); @@ -177,7 +201,9 @@ describe('Autocomplete control Base Tests', () => { it('id should be present in output', () => { setupMockStore(fixture, { uischema, schema, data }); component.id = 'myId'; - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); fixture.detectChanges(); component.ngOnInit(); @@ -195,9 +221,7 @@ describe('AutoComplete control Input Event Tests', () => { TestBed.configureTestingModule({ declarations: [componentUT], imports: imports, - providers: [ - ...providers, - ] + providers: [...providers], }).compileComponents(); inject([OverlayContainer], (oc: OverlayContainer) => { @@ -208,8 +232,8 @@ describe('AutoComplete control Input Event Tests', () => { beforeEach(() => { fixture = TestBed.createComponent(componentUT); component = fixture.componentInstance; - zone = TestBed.inject(NgZone); - spyOn(zone, 'runOutsideAngular').and.callFake((fn: Function) => fn()); + zone = TestBed.inject(NgZone); + spyOn(zone, 'runOutsideAngular').and.callFake((fn: () => any) => fn()); inputElement = fixture.debugElement.query(By.css('input')).nativeElement; }); @@ -224,7 +248,9 @@ describe('AutoComplete control Input Event Tests', () => { )); it('should update via input event', fakeAsync(() => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); @@ -250,7 +276,9 @@ describe('AutoComplete control Input Event Tests', () => { })); it('options should prefer own props', fakeAsync(() => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.options = ['X', 'Y', 'Z']; component.ngOnInit(); @@ -282,9 +310,8 @@ describe('AutoComplete control Error Tests', () => { TestBed.configureTestingModule({ declarations: [componentUT], imports: imports, - providers: providers + providers: providers, }).compileComponents(); - }); beforeEach(() => { fixture = TestBed.createComponent(componentUT); @@ -297,13 +324,13 @@ describe('AutoComplete control Error Tests', () => { message: 'Hi, this is me, test error!', params: {}, keyword: '', - schemaPath: '' - } + schemaPath: '', + }, ]; setupMockStore(fixture, { uischema, schema, - data + data, }); const formsService = getJsonFormsService(component); formsService.updateCore(Actions.updateErrors(errors)); diff --git a/packages/angular-material/test/boolean-control.spec.ts b/packages/angular-material/test/boolean-control.spec.ts index b1bfbfca1..dac35861d 100644 --- a/packages/angular-material/test/boolean-control.spec.ts +++ b/packages/angular-material/test/boolean-control.spec.ts @@ -28,7 +28,7 @@ import { booleanBaseTest, booleanErrorTest, booleanInputEventTest, - ErrorTestExpectation + ErrorTestExpectation, } from '@jsonforms/angular-test'; import { BooleanControlRenderer, booleanControlTester } from '../src'; import { FlexLayoutModule } from '@angular/flex-layout'; @@ -37,19 +37,23 @@ import { JsonFormsAngularService } from '@jsonforms/angular'; describe('Material boolean field tester', () => { const uischema = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; it('should succeed', () => { expect( - booleanControlTester(uischema, { - type: 'object', - properties: { - foo: { - type: 'boolean' - } - } - }, undefined) + booleanControlTester( + uischema, + { + type: 'object', + properties: { + foo: { + type: 'boolean', + }, + }, + }, + undefined + ) ).toBe(2); }); }); @@ -59,7 +63,7 @@ const componentUT: any = BooleanControlRenderer; const errorTest: ErrorTestExpectation = { errorInstance: MatError, numberOfElements: 1, - indexOfElement: 0 + indexOfElement: 0, }; const testConfig = { imports, providers, componentUT }; describe( diff --git a/packages/angular-material/test/categorization-tab-layout.spec.ts b/packages/angular-material/test/categorization-tab-layout.spec.ts index ca945fd30..c6271693e 100644 --- a/packages/angular-material/test/categorization-tab-layout.spec.ts +++ b/packages/angular-material/test/categorization-tab-layout.spec.ts @@ -28,17 +28,21 @@ import { MatTab, MatTabBody, MatTabGroup, - MatTabsModule + MatTabsModule, } from '@angular/material/tabs'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { JsonFormsAngularService, JsonFormsModule, - JsonFormsOutlet + JsonFormsOutlet, } from '@jsonforms/angular'; import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; -import { CategorizationTabLayoutRenderer, TextControlRenderer, TextControlRendererTester } from '../src'; +import { + CategorizationTabLayoutRenderer, + TextControlRenderer, + TextControlRendererTester, +} from '../src'; import { FlexLayoutModule } from '@angular/flex-layout'; import { setupMockStore, getJsonFormsService } from '@jsonforms/angular-test'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -59,27 +63,33 @@ describe('Categorization tab layout', () => { type: 'object', properties: { foo: { - type: 'string' + type: 'string', }, bar: { - type: 'string' - } - } + type: 'string', + }, + }, }; beforeEach(() => { TestBed.configureTestingModule({ - declarations: [ - CategorizationTabLayoutRenderer, - TextControlRenderer + declarations: [CategorizationTabLayoutRenderer, TextControlRenderer], + imports: [ + CommonModule, + MatTabsModule, + FlexLayoutModule, + NoopAnimationsModule, + JsonFormsModule, + MatFormFieldModule, + MatInputModule, + ReactiveFormsModule, ], - imports: [CommonModule, MatTabsModule, FlexLayoutModule, NoopAnimationsModule, JsonFormsModule,MatFormFieldModule,MatInputModule,ReactiveFormsModule,], - providers: [JsonFormsAngularService] + providers: [JsonFormsAngularService], }) .overrideModule(BrowserDynamicTestingModule, { set: { - entryComponents: [TextControlRenderer] - } + entryComponents: [TextControlRenderer], + }, }) .compileComponents(); @@ -97,13 +107,13 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }, { type: 'Control', - scope: '#/properties/bar' - } - ] + scope: '#/properties/bar', + }, + ], }, { type: 'Category', @@ -111,11 +121,11 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/bar' - } - ] - } - ] + scope: '#/properties/bar', + }, + ], + }, + ], }; setupMockStore(fixture, { uischema, schema, data }); @@ -162,25 +172,23 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }, - ] - } - ] + ], + }, + ], }; setupMockStore(fixture, { uischema, schema, data }); component.path = 'aa'; - const subSchema = {type: 'string'}; + const subSchema = { type: 'string' }; component.schema = subSchema; getJsonFormsService(component).init({ - renderers: renderers, core: { data: {}, schema: schema, - uischema: undefined - } - + uischema: undefined, + }, }); fixture.detectChanges(); @@ -206,13 +214,13 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }, { type: 'Control', - scope: '#/properties/bar' - } - ] + scope: '#/properties/bar', + }, + ], }, { type: 'Category', @@ -220,11 +228,11 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/bar' - } - ] - } - ] + scope: '#/properties/bar', + }, + ], + }, + ], }; setupMockStore(fixture, { uischema, schema, data }); fixture.detectChanges(); @@ -245,9 +253,9 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/foo' - } - ] + scope: '#/properties/foo', + }, + ], }, { type: 'Category', @@ -255,9 +263,9 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/bar' - } - ] + scope: '#/properties/bar', + }, + ], }, { type: 'Category', @@ -265,11 +273,11 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/bar' - } - ] - } - ] + scope: '#/properties/bar', + }, + ], + }, + ], }; component.uischema = newUischema; fixture.detectChanges(); @@ -300,13 +308,13 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }, { type: 'Control', - scope: '#/properties/bar' - } - ] + scope: '#/properties/bar', + }, + ], }, { type: 'Category', @@ -314,11 +322,11 @@ describe('Categorization tab layout', () => { elements: [ { type: 'Control', - scope: '#/properties/bar' - } - ] - } - ] + scope: '#/properties/bar', + }, + ], + }, + ], }; setupMockStore(fixture, { uischema, schema, data }); component.visible = false; diff --git a/packages/angular-material/test/date-control.spec.ts b/packages/angular-material/test/date-control.spec.ts index 006b4ba55..04e7b2758 100644 --- a/packages/angular-material/test/date-control.spec.ts +++ b/packages/angular-material/test/date-control.spec.ts @@ -27,16 +27,23 @@ import { ComponentFixture, fakeAsync, flush, - TestBed + TestBed, } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; -import { MatNativeDateModule } from '@angular/material/core' -import { MatDatepicker, MatDatepickerModule } from '@angular/material/datepicker'; +import { MatNativeDateModule } from '@angular/material/core'; +import { + MatDatepicker, + MatDatepickerModule, +} from '@angular/material/datepicker'; import { MatError, MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ErrorTestExpectation, getJsonFormsService, setupMockStore } from '@jsonforms/angular-test'; +import { + ErrorTestExpectation, + getJsonFormsService, + setupMockStore, +} from '@jsonforms/angular-test'; import { Actions, ControlElement, JsonSchema } from '@jsonforms/core'; import { DateControlRenderer, DateControlRendererTester } from '../src'; import { FlexLayoutModule } from '@angular/flex-layout'; @@ -49,18 +56,20 @@ const schema: JsonSchema = { properties: { foo: { type: 'string', - format: 'date' - } - } + format: 'date', + }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; describe('Material boolean field tester', () => { it('should succeed', () => { - expect(DateControlRendererTester(uischema, schema, createTesterContext(schema))).toBe(2); + expect( + DateControlRendererTester(uischema, schema, createTesterContext(schema)) + ).toBe(2); }); }); const imports = [ @@ -70,14 +79,14 @@ const imports = [ MatFormFieldModule, NoopAnimationsModule, ReactiveFormsModule, - FlexLayoutModule + FlexLayoutModule, ]; const providers = [JsonFormsAngularService]; const componentUT: any = DateControlRenderer; const errorTest: ErrorTestExpectation = { errorInstance: MatError, numberOfElements: 1, - indexOfElement: 0 + indexOfElement: 0, }; describe('Date control Base Tests', () => { @@ -88,9 +97,8 @@ describe('Date control Base Tests', () => { TestBed.configureTestingModule({ declarations: [componentUT], imports: imports, - providers: providers + providers: providers, }).compileComponents(); - }); beforeEach(() => { fixture = TestBed.createComponent(componentUT); @@ -101,7 +109,9 @@ describe('Date control Base Tests', () => { it('should render', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); expect(component.data).toBe('2018-01-01'); @@ -114,45 +124,63 @@ describe('Date control Base Tests', () => { it('should support updating the state', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); - getJsonFormsService(component).updateCore(Actions.update('foo', () => '2018-03-03')); + getJsonFormsService(component).updateCore( + Actions.update('foo', () => '2018-03-03') + ); fixture.detectChanges(); expect(component.data).toBe('2018-03-03'); expect(inputElement.value).toBe('3/3/2018'); }); it('should update with undefined value', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); - getJsonFormsService(component).updateCore(Actions.update('foo', () => undefined)); + getJsonFormsService(component).updateCore( + Actions.update('foo', () => undefined) + ); fixture.detectChanges(); expect(component.data).toBe(undefined); expect(inputElement.value).toBe(''); }); it('should update with null value', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); - getJsonFormsService(component).updateCore(Actions.update('foo', () => null)); + getJsonFormsService(component).updateCore( + Actions.update('foo', () => null) + ); fixture.detectChanges(); expect(component.data).toBe(null); expect(inputElement.value).toBe(''); }); it('should not update with wrong ref', () => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); - getJsonFormsService(component).updateCore(Actions.update('foo', () => '2018-01-01')); - getJsonFormsService(component).updateCore(Actions.update('bar', () => '2018-03-03')); + getJsonFormsService(component).updateCore( + Actions.update('foo', () => '2018-01-01') + ); + getJsonFormsService(component).updateCore( + Actions.update('bar', () => '2018-03-03') + ); fixture.detectChanges(); expect(component.data).toBe('2018-01-01'); expect(inputElement.value).toBe('1/1/2018'); @@ -161,7 +189,9 @@ describe('Date control Base Tests', () => { it('can be disabled', () => { setupMockStore(fixture, { uischema, schema, data }); component.disabled = true; - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); @@ -171,7 +201,9 @@ describe('Date control Base Tests', () => { it('can be hidden', () => { setupMockStore(fixture, { uischema, schema, data }); component.visible = false; - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); @@ -181,9 +213,9 @@ describe('Date control Base Tests', () => { it('id should be present in output', () => { component.uischema = uischema; component.id = 'myId'; - getJsonFormsService(component).init( - {core: {data: data, schema: schema, uischema: uischema}} - ); + getJsonFormsService(component).init({ + core: { data: data, schema: schema, uischema: uischema }, + }); component.ngOnInit(); fixture.detectChanges(); @@ -198,7 +230,7 @@ describe('Date control Input Event Tests', () => { TestBed.configureTestingModule({ declarations: [componentUT], imports: imports, - providers: providers + providers: providers, }).compileComponents(); }); beforeEach(() => { @@ -209,7 +241,9 @@ describe('Date control Input Event Tests', () => { }); it('should update via input event', fakeAsync(() => { setupMockStore(fixture, { uischema, schema, data }); - getJsonFormsService(component).updateCore(Actions.init(data, schema, uischema)); + getJsonFormsService(component).updateCore( + Actions.init(data, schema, uischema) + ); component.ngOnInit(); fixture.detectChanges(); @@ -241,9 +275,8 @@ describe('Date control Error Tests', () => { TestBed.configureTestingModule({ declarations: [componentUT], imports: imports, - providers: providers + providers: providers, }).compileComponents(); - }); beforeEach(() => { fixture = TestBed.createComponent(componentUT); @@ -253,18 +286,20 @@ describe('Date control Error Tests', () => { setupMockStore(fixture, { uischema, schema, - data + data, }); const formsService = getJsonFormsService(component); - formsService.updateCore(Actions.updateErrors([ - { - instancePath: '/foo', - message: 'Hi, this is me, test error!', - params: {}, - keyword: '', - schemaPath: '' - } - ])); + formsService.updateCore( + Actions.updateErrors([ + { + instancePath: '/foo', + message: 'Hi, this is me, test error!', + params: {}, + keyword: '', + schemaPath: '', + }, + ]) + ); formsService.refresh(); component.ngOnInit(); diff --git a/packages/angular-material/test/group-layout.spec.ts b/packages/angular-material/test/group-layout.spec.ts index a2e47c0a6..584e87807 100644 --- a/packages/angular-material/test/group-layout.spec.ts +++ b/packages/angular-material/test/group-layout.spec.ts @@ -27,15 +27,12 @@ import { GroupLayout, UISchemaElement } from '@jsonforms/core'; import { MatCard, MatCardTitle } from '@angular/material/card'; import { By } from '@angular/platform-browser'; import { DebugElement } from '@angular/core'; -import { - beforeEachLayoutTest, - setupMockStore -} from '@jsonforms/angular-test'; +import { beforeEachLayoutTest, setupMockStore } from '@jsonforms/angular-test'; import { FlexLayoutModule } from '@angular/flex-layout'; import { LayoutChildrenRenderPropsPipe } from '../src/layouts/layout.renderer'; import { GroupLayoutRenderer, - groupLayoutTester + groupLayoutTester, } from '../src/layouts/group-layout.renderer'; describe('Group layout tester', () => { @@ -49,13 +46,13 @@ describe('Group layout', () => { beforeEach(() => { fixture = beforeEachLayoutTest(GroupLayoutRenderer, { declarations: [LayoutChildrenRenderPropsPipe, MatCard, MatCardTitle], - imports: [FlexLayoutModule] + imports: [FlexLayoutModule], }); }); it('render with undefined elements', () => { const uischema: UISchemaElement = { - type: 'Group' + type: 'Group', }; setupMockStore(fixture, { data: {}, schema: {}, uischema }); fixture.componentInstance.ngOnInit(); @@ -70,7 +67,7 @@ describe('Group layout', () => { it('render with null elements', () => { const uischema: GroupLayout = { type: 'Group', - elements: null + elements: null, }; setupMockStore(fixture, { data: {}, schema: {}, uischema }); fixture.componentInstance.ngOnInit(); @@ -86,7 +83,7 @@ describe('Group layout', () => { const uischema: GroupLayout = { type: 'Group', label: 'foo', - elements: [{ type: 'Control' }, { type: 'Control' }] + elements: [{ type: 'Control' }, { type: 'Control' }], }; setupMockStore(fixture, { data: {}, schema: {}, uischema }); fixture.componentInstance.ngOnInit(); diff --git a/packages/angular-material/test/horizontal-layout.spec.ts b/packages/angular-material/test/horizontal-layout.spec.ts index 7726cec20..16cc72e68 100644 --- a/packages/angular-material/test/horizontal-layout.spec.ts +++ b/packages/angular-material/test/horizontal-layout.spec.ts @@ -28,7 +28,7 @@ import { beforeEachLayoutTest, setupMockStore } from '@jsonforms/angular-test'; import { FlexLayoutModule } from '@angular/flex-layout'; import { HorizontalLayoutRenderer, - horizontalLayoutTester + horizontalLayoutTester, } from '../src/layouts/horizontal-layout.renderer'; import { LayoutChildrenRenderPropsPipe } from '../src/layouts/layout.renderer'; @@ -45,18 +45,18 @@ describe('Horizontal layout', () => { beforeEach(() => { fixture = beforeEachLayoutTest(HorizontalLayoutRenderer, { declarations: [LayoutChildrenRenderPropsPipe], - imports: [FlexLayoutModule] + imports: [FlexLayoutModule], }); }); it('render with undefined elements', () => { const uischema: UISchemaElement = { - type: 'HorizontalLayout' + type: 'HorizontalLayout', }; setupMockStore(fixture, { data: {}, schema: {}, - uischema + uischema, }); fixture.componentInstance.ngOnInit(); fixture.detectChanges(); @@ -66,12 +66,12 @@ describe('Horizontal layout', () => { it('render with null elements', () => { const uischema: HorizontalLayout = { type: 'HorizontalLayout', - elements: null + elements: null, }; setupMockStore(fixture, { data: {}, schema: {}, - uischema + uischema, }); fixture.componentInstance.ngOnInit(); fixture.detectChanges(); @@ -81,12 +81,12 @@ describe('Horizontal layout', () => { it('render with children', () => { const uischema: HorizontalLayout = { type: 'HorizontalLayout', - elements: [{ type: 'Control' }, { type: 'Control' }] + elements: [{ type: 'Control' }, { type: 'Control' }], }; setupMockStore(fixture, { data: {}, schema: {}, - uischema + uischema, }); fixture.componentInstance.ngOnInit(); fixture.detectChanges(); diff --git a/packages/angular-material/test/label-renderer.spec.ts b/packages/angular-material/test/label-renderer.spec.ts index cbc4b7bf0..c7c264607 100644 --- a/packages/angular-material/test/label-renderer.spec.ts +++ b/packages/angular-material/test/label-renderer.spec.ts @@ -35,13 +35,13 @@ const schema: JsonSchema = { type: 'object', properties: { foo: { - type: 'string' - } - } + type: 'string', + }, + }, }; const uischema: LabelElement = { type: 'Label', - text: 'FooBar' + text: 'FooBar', }; describe('Material label field tester', () => { @@ -59,7 +59,7 @@ describe('Label Renderer Base Tests', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [componentUT], - providers: providers + providers: providers, }).compileComponents(); }); beforeEach(() => { diff --git a/packages/angular-material/test/master-detail.spec.ts b/packages/angular-material/test/master-detail.spec.ts index 70739fff8..d8f1ac337 100644 --- a/packages/angular-material/test/master-detail.spec.ts +++ b/packages/angular-material/test/master-detail.spec.ts @@ -33,7 +33,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { JsonFormsAngularService, JsonFormsOutlet, - UnknownRenderer + UnknownRenderer, } from '@jsonforms/angular'; import { FlexLayoutModule } from '@angular/flex-layout'; import { DebugElement } from '@angular/core'; @@ -41,6 +41,7 @@ import { MasterListComponent } from '../src/other/master-detail/master'; import { JsonFormsDetailComponent } from '../src/other/master-detail/detail'; import { getJsonFormsService, setupMockStore } from '@jsonforms/angular-test'; import { Actions } from '@jsonforms/core'; +import { MatTooltipModule } from '@angular/material/tooltip'; describe('Master detail', () => { let fixture: ComponentFixture; @@ -50,11 +51,11 @@ describe('Master detail', () => { orders: [ { customer: { - name: 'ACME' + name: 'ACME', }, - title: 'Carrots' - } - ] + title: 'Carrots', + }, + ], }; const schema = { definitions: { @@ -64,24 +65,24 @@ describe('Master detail', () => { customer: { type: 'object', properties: { - name: { type: 'string' } - } + name: { type: 'string' }, + }, }, title: { - type: 'string' - } - } - } + type: 'string', + }, + }, + }, }, type: 'object', properties: { orders: { type: 'array', items: { - $ref: '#/definitions/order' - } - } - } + $ref: '#/definitions/order', + }, + }, + }, }; const uischema = { type: 'ListWithDetail', @@ -93,11 +94,11 @@ describe('Master detail', () => { elements: [ { type: 'Control', - scope: '#/properties/customer/properties/name' - } - ] - } - } + scope: '#/properties/customer/properties/name', + }, + ], + }, + }, }; beforeEach(() => { @@ -106,7 +107,7 @@ describe('Master detail', () => { JsonFormsOutlet, MasterListComponent, UnknownRenderer, - JsonFormsDetailComponent + JsonFormsDetailComponent, ], imports: [ MatListModule, @@ -114,14 +115,15 @@ describe('Master detail', () => { MatIconModule, MatButtonModule, FlexLayoutModule, - NoopAnimationsModule + NoopAnimationsModule, + MatTooltipModule, ], - providers: [JsonFormsAngularService] + providers: [JsonFormsAngularService], }) .overrideModule(BrowserDynamicTestingModule, { set: { - entryComponents: [UnknownRenderer] - } + entryComponents: [UnknownRenderer], + }, }) .compileComponents(); @@ -194,23 +196,23 @@ describe('Master detail', () => { orders: [ { customer: { name: 'Carrot Chipmunk' }, - title: 'Carrots' + title: 'Carrots', }, { customer: { name: 'Banana Joe' }, - title: 'Bananas' + title: 'Bananas', }, { customer: { name: 'Fry' }, - title: 'Slurm' - } - ] + title: 'Slurm', + }, + ], }; setupMockStore(fixture, { uischema, schema, - data: moreData + data: moreData, }); getJsonFormsService(component).updateCore(Actions.init(moreData, schema)); component.ngOnInit(); @@ -226,7 +228,9 @@ describe('Master detail', () => { // delete 1st item spyOn(component, 'removeItems').and.callFake(() => () => { - getJsonFormsService(component).updateCore(Actions.update('orders', () => moreData.orders.slice(1))); + getJsonFormsService(component).updateCore( + Actions.update('orders', () => moreData.orders.slice(1)) + ); fixture.detectChanges(); }); const buttons: DebugElement[] = fixture.debugElement.queryAll( @@ -243,22 +247,22 @@ describe('Master detail', () => { orders: [ { customer: { name: 'Carrot Chipmunk' }, - title: 'Carrots' + title: 'Carrots', }, { customer: { name: 'Banana Joe' }, - title: 'Bananas' + title: 'Bananas', }, { customer: { name: 'Fry' }, - title: 'Slurm' - } - ] + title: 'Slurm', + }, + ], }; setupMockStore(fixture, { uischema, schema, - data: moreData + data: moreData, }); getJsonFormsService(component).updateCore(Actions.init(moreData, schema)); component.ngOnInit(); @@ -268,7 +272,9 @@ describe('Master detail', () => { spyOn(component, 'removeItems').and.callFake(() => () => { const copy = moreData.orders.slice(); copy.splice(1, 1); - getJsonFormsService(component).updateCore(Actions.update('orders', () => copy)); + getJsonFormsService(component).updateCore( + Actions.update('orders', () => copy) + ); fixture.detectChanges(); }); const buttons: DebugElement[] = fixture.debugElement.queryAll( @@ -285,22 +291,22 @@ describe('Master detail', () => { orders: [ { customer: { name: 'Carrot Chipmunk' }, - title: 'Carrots' + title: 'Carrots', }, { customer: { name: 'Banana Joe' }, - title: 'Bananas' + title: 'Bananas', }, { customer: { name: 'Fry' }, - title: 'Slurm' - } - ] + title: 'Slurm', + }, + ], }; setupMockStore(fixture, { uischema, schema, - data: moreData + data: moreData, }); getJsonFormsService(component).updateCore(Actions.init(moreData, schema)); component.ngOnInit(); @@ -308,7 +314,9 @@ describe('Master detail', () => { // delete 1st item spyOn(component, 'removeItems').and.callFake(() => () => { - getJsonFormsService(component).updateCore(Actions.update('orders', () => moreData.orders.slice(1))); + getJsonFormsService(component).updateCore( + Actions.update('orders', () => moreData.orders.slice(1)) + ); fixture.detectChanges(); }); const buttons: DebugElement[] = fixture.debugElement.queryAll( @@ -325,14 +333,14 @@ describe('Master detail', () => { orders: [ { customer: { name: 'Carrot Chipmunk' }, - title: 'Carrots' - } - ] + title: 'Carrots', + }, + ], }; setupMockStore(fixture, { uischema, schema, - data: moreData + data: moreData, }); getJsonFormsService(component).updateCore(Actions.init(moreData, schema)); component.ngOnInit(); @@ -340,7 +348,9 @@ describe('Master detail', () => { // delete item spyOn(component, 'removeItems').and.callFake(() => () => { - getJsonFormsService(component).updateCore(Actions.update('orders', () => [])); + getJsonFormsService(component).updateCore( + Actions.update('orders', () => []) + ); fixture.detectChanges(); }); const buttons: DebugElement[] = fixture.debugElement.queryAll( @@ -360,8 +370,9 @@ describe('Master detail', () => { fixture.detectChanges(); fixture.whenStable().then(() => { spyOn(component, 'onSelect'); - const select = fixture.debugElement.query(By.directive(MatListItem)) - .nativeElement; + const select = fixture.debugElement.query( + By.directive(MatListItem) + ).nativeElement; select.click(); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -375,7 +386,7 @@ describe('Master detail', () => { label: 'ACME', data: { customer: { name: 'ACME' }, - title: 'Carrots' + title: 'Carrots', }, path: 'orders.0', schema: schema.definitions.order, @@ -384,10 +395,10 @@ describe('Master detail', () => { elements: [ { type: 'Control', - scope: '#/properties/customer/properties/name' - } - ] - } + scope: '#/properties/customer/properties/name', + }, + ], + }, }, 0 ); diff --git a/packages/angular-material/test/number-control.spec.ts b/packages/angular-material/test/number-control.spec.ts index 6ab66d43a..5abd1c677 100644 --- a/packages/angular-material/test/number-control.spec.ts +++ b/packages/angular-material/test/number-control.spec.ts @@ -38,7 +38,7 @@ import { numberBaseTest, numberErrorTest, numberInputEventTest, - prepareComponent + prepareComponent, } from '@jsonforms/angular-test'; import { Actions, ControlElement, JsonFormsCore } from '@jsonforms/core'; import { NumberControlRenderer, NumberControlRendererTester } from '../src'; @@ -46,31 +46,39 @@ import { NumberControlRenderer, NumberControlRendererTester } from '../src'; describe('Material number field tester', () => { const uischema = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; it('should succeed with floats', () => { expect( - NumberControlRendererTester(uischema, { - type: 'object', - properties: { - foo: { - type: 'number' - } - } - }, undefined) + NumberControlRendererTester( + uischema, + { + type: 'object', + properties: { + foo: { + type: 'number', + }, + }, + }, + undefined + ) ).toBe(2); }); it('should succeed with integers', () => { expect( - NumberControlRendererTester(uischema, { - type: 'object', - properties: { - foo: { - type: 'integer' - } - } - }, undefined) + NumberControlRendererTester( + uischema, + { + type: 'object', + properties: { + foo: { + type: 'integer', + }, + }, + }, + undefined + ) ).toBe(2); }); }); @@ -80,14 +88,14 @@ const imports = [ MatInputModule, NoopAnimationsModule, ReactiveFormsModule, - FlexLayoutModule + FlexLayoutModule, ]; const providers = [JsonFormsAngularService]; const componentUT: any = NumberControlRenderer; const errorTest: ErrorTestExpectation = { errorInstance: MatError, numberOfElements: 1, - indexOfElement: 0 + indexOfElement: 0, }; const toSelect = (el: DebugElement) => el.nativeElement; const testConfig = { imports, providers, componentUT }; @@ -106,103 +114,105 @@ describe( numberAdditionalPropsTest(testConfig, 'input', toSelect) ); -describe( - 'Number control custom', () => { - let fixture: ComponentFixture; - let numberNativeElement: any; - let component: JsonFormsControl; - baseSetup(testConfig); - - const defaultSchema = { - type: 'object', - properties: { - foo: { type: 'number' } - } - }; - const defaultData = {foo:1000000}; - const defaultUischema: ControlElement = { - type: 'Control', - scope: '#/properties/foo' - }; +describe('Number control custom', () => { + let fixture: ComponentFixture; + let numberNativeElement: any; + let component: JsonFormsControl; + baseSetup(testConfig); - beforeEach(() => { - const preparedComponents = prepareComponent( - testConfig, 'input', toSelect); - fixture = preparedComponents.fixture; - numberNativeElement = preparedComponents.numberNativeElement; - component = preparedComponents.component; - }); + const defaultSchema = { + type: 'object', + properties: { + foo: { type: 'number' }, + }, + }; + const defaultData = { foo: 1000000 }; + const defaultUischema: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + }; - it('default grouping behavior', () => { - const uischema = Object.assign({},defaultUischema); - component.uischema = uischema; - const state:JsonFormsCore = { - data: defaultData, - schema: defaultSchema, - uischema: uischema - }; - getJsonFormsService(component).init({ - core: state, i18n: { - locale: 'en', - } - }); - getJsonFormsService(component).updateCore( - Actions.init(state.data, state.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig, 'input', toSelect); + fixture = preparedComponents.fixture; + numberNativeElement = preparedComponents.numberNativeElement; + component = preparedComponents.component; + }); - expect(numberNativeElement.value).toBe('1,000,000'); + it('default grouping behavior', () => { + const uischema = Object.assign({}, defaultUischema); + component.uischema = uischema; + const state: JsonFormsCore = { + data: defaultData, + schema: defaultSchema, + uischema: uischema, + }; + getJsonFormsService(component).init({ + core: state, + i18n: { + locale: 'en', + }, }); + getJsonFormsService(component).updateCore( + Actions.init(state.data, state.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); - it('should use config for grouping', () => { - const uischema = Object.assign({},defaultUischema); - component.uischema = uischema; - const state:JsonFormsCore = { - data: defaultData, - schema: defaultSchema, - uischema: uischema - }; - getJsonFormsService(component).init({ - core: state, i18n: { - locale: 'en', - },config: { - useGrouping: false - }, - }); - getJsonFormsService(component).updateCore( - Actions.init(state.data, state.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); + expect(numberNativeElement.value).toBe('1,000,000'); + }); - expect(numberNativeElement.value).toBe('1000000'); + it('should use config for grouping', () => { + const uischema = Object.assign({}, defaultUischema); + component.uischema = uischema; + const state: JsonFormsCore = { + data: defaultData, + schema: defaultSchema, + uischema: uischema, + }; + getJsonFormsService(component).init({ + core: state, + i18n: { + locale: 'en', + }, + config: { + useGrouping: false, + }, }); - it('should use uischema for grouping', () => { - const uischema = Object.assign({},defaultUischema); - uischema.options = { - useGrouping: false - } - component.uischema = uischema; - const state:JsonFormsCore = { - data: defaultData, - schema: defaultSchema, - uischema: uischema - }; - getJsonFormsService(component).init({ - core: state, i18n: { - locale: 'en', - },config: { - useGrouping: true - }, - }); - getJsonFormsService(component).updateCore( - Actions.init(state.data, state.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); + getJsonFormsService(component).updateCore( + Actions.init(state.data, state.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); - expect(numberNativeElement.value).toBe('1000000'); + expect(numberNativeElement.value).toBe('1000000'); + }); + it('should use uischema for grouping', () => { + const uischema = Object.assign({}, defaultUischema); + uischema.options = { + useGrouping: false, + }; + component.uischema = uischema; + const state: JsonFormsCore = { + data: defaultData, + schema: defaultSchema, + uischema: uischema, + }; + getJsonFormsService(component).init({ + core: state, + i18n: { + locale: 'en', + }, + config: { + useGrouping: true, + }, }); - } -); + getJsonFormsService(component).updateCore( + Actions.init(state.data, state.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); + + expect(numberNativeElement.value).toBe('1000000'); + }); +}); diff --git a/packages/angular-material/test/object-control.spec.ts b/packages/angular-material/test/object-control.spec.ts index 1a53b2062..d6dd2f72c 100644 --- a/packages/angular-material/test/object-control.spec.ts +++ b/packages/angular-material/test/object-control.spec.ts @@ -39,11 +39,11 @@ import { TextControlRenderer, TextControlRendererTester, VerticalLayoutRenderer, - verticalLayoutTester + verticalLayoutTester, } from '../src'; import { ObjectControlRenderer, - ObjectControlRendererTester + ObjectControlRendererTester, } from '../src/other/object.renderer'; import { getJsonFormsService } from '@jsonforms/angular-test'; import { LayoutChildrenRenderPropsPipe } from '../src/layouts/layout.renderer'; @@ -51,13 +51,13 @@ import { LayoutChildrenRenderPropsPipe } from '../src/layouts/layout.renderer'; const uischema1: ControlElement = { type: 'Control', scope: '#' }; const uischema2: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const schema1 = { type: 'object', properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const schema2 = { type: 'object', @@ -65,22 +65,22 @@ const schema2 = { foo: { type: 'object', properties: { - foo_1: { type: 'string' } - } + foo_1: { type: 'string' }, + }, }, bar: { type: 'object', properties: { - bar_1: { type: 'string' } - } - } - } + bar_1: { type: 'string' }, + }, + }, + }, }; const renderers = [ { tester: TextControlRendererTester, renderer: TextControlRenderer }, { tester: verticalLayoutTester, renderer: VerticalLayoutRenderer }, { tester: groupLayoutTester, renderer: GroupLayoutRenderer }, - { tester: ObjectControlRendererTester, renderer: ObjectControlRenderer } + { tester: ObjectControlRendererTester, renderer: ObjectControlRenderer }, ]; describe('Object Control tester', () => { @@ -100,7 +100,7 @@ describe('Object Control', () => { TextControlRenderer, VerticalLayoutRenderer, GroupLayoutRenderer, - LayoutChildrenRenderPropsPipe + LayoutChildrenRenderPropsPipe, ], imports: [ CommonModule, @@ -110,9 +110,9 @@ describe('Object Control', () => { MatFormFieldModule, MatInputModule, ReactiveFormsModule, - FlexLayoutModule + FlexLayoutModule, ], - providers: [JsonFormsAngularService] + providers: [JsonFormsAngularService], }) .overrideModule(BrowserDynamicTestingModule, { set: { @@ -120,9 +120,9 @@ describe('Object Control', () => { TextControlRenderer, VerticalLayoutRenderer, GroupLayoutRenderer, - ObjectControlRenderer - ] - } + ObjectControlRenderer, + ], + }, }) .compileComponents(); @@ -135,14 +135,12 @@ describe('Object Control', () => { component.schema = schema2; getJsonFormsService(component).init({ - renderers: renderers, core: { data: {}, schema: schema2, - uischema: undefined - } - + uischema: undefined, + }, }); fixture.detectChanges(); component.ngOnInit(); @@ -156,19 +154,15 @@ describe('Object Control', () => { })); it('render all elements', async(() => { - component.uischema = uischema1; component.schema = schema2; getJsonFormsService(component).init({ - - core: { data: {}, schema: schema2, - uischema: undefined - } - + uischema: undefined, + }, }); getJsonFormsService(component).registerRenderers(renderers); @@ -184,14 +178,11 @@ describe('Object Control', () => { component.schema = schema2; getJsonFormsService(component).init({ - - core: { data: {}, schema: schema2, - uischema: undefined - } - + uischema: undefined, + }, }); getJsonFormsService(component).registerRenderers(renderers); fixture.detectChanges(); @@ -202,19 +193,16 @@ describe('Object Control', () => { })); xit('can be disabled', async(() => { - component.uischema = uischema1; component.schema = schema1; component.disabled = true; getJsonFormsService(component).init({ - core: { data: {}, schema: schema1, - uischema: undefined - } - + uischema: undefined, + }, }); getJsonFormsService(component).registerRenderers(renderers); fixture.detectChanges(); @@ -224,7 +212,6 @@ describe('Object Control', () => { }); })); xit('should be enabled by default', async(() => { - component.uischema = uischema1; component.schema = schema1; @@ -232,9 +219,8 @@ describe('Object Control', () => { core: { data: {}, schema: schema1, - uischema: undefined - } - + uischema: undefined, + }, }); getJsonFormsService(component).registerRenderers(renderers); component.ngOnInit(); diff --git a/packages/angular-material/test/range-control.spec.ts b/packages/angular-material/test/range-control.spec.ts index 6082e2f4e..31213f623 100644 --- a/packages/angular-material/test/range-control.spec.ts +++ b/packages/angular-material/test/range-control.spec.ts @@ -30,7 +30,7 @@ import { ErrorTestExpectation, rangeBaseTest, rangeErrorTest, - rangeInputEventTest + rangeInputEventTest, } from '@jsonforms/angular-test'; import { RangeControlRenderer, RangeControlRendererTester } from '../src'; import { FlexLayoutModule } from '@angular/flex-layout'; @@ -40,37 +40,45 @@ describe('Material number field tester', () => { const uischema = { type: 'Control', scope: '#/properties/foo', - options: { slider: true } + options: { slider: true }, }; it('should succeed with floats', () => { expect( - RangeControlRendererTester(uischema, { - type: 'object', - properties: { - foo: { - type: 'number', - minimum: -42.42, - maximum: 42.42, - default: 0.42 - } - } - }, undefined) + RangeControlRendererTester( + uischema, + { + type: 'object', + properties: { + foo: { + type: 'number', + minimum: -42.42, + maximum: 42.42, + default: 0.42, + }, + }, + }, + undefined + ) ).toBe(4); }); it('should succeed with integers', () => { expect( - RangeControlRendererTester(uischema, { - type: 'object', - properties: { - foo: { - type: 'integer', - minimum: -42, - maximum: 42, - default: 1 - } - } - }, undefined) + RangeControlRendererTester( + uischema, + { + type: 'object', + properties: { + foo: { + type: 'integer', + minimum: -42, + maximum: 42, + default: 1, + }, + }, + }, + undefined + ) ).toBe(4); }); }); @@ -79,14 +87,14 @@ const imports = [ MatSliderModule, MatFormFieldModule, ReactiveFormsModule, - FlexLayoutModule + FlexLayoutModule, ]; const providers = [JsonFormsAngularService]; const componentUT: any = RangeControlRenderer; const errorTest: ErrorTestExpectation = { errorInstance: MatError, numberOfElements: 1, - indexOfElement: 0 + indexOfElement: 0, }; const defaultTestConfig = { imports, providers, componentUT }; diff --git a/packages/angular-material/test/table-control.spec.ts b/packages/angular-material/test/table-control.spec.ts index 2481e1c38..cdbf8a058 100644 --- a/packages/angular-material/test/table-control.spec.ts +++ b/packages/angular-material/test/table-control.spec.ts @@ -37,23 +37,24 @@ import { ControlElement } from '@jsonforms/core'; import { TextControlRenderer, TextControlRendererTester } from '../src'; import { TableRenderer, - TableRendererTester + TableRendererTester, } from '../src/other/table.renderer'; import { FlexLayoutModule } from '@angular/flex-layout'; import { setupMockStore } from '@jsonforms/angular-test'; import { createTesterContext } from './util'; +import { MatTooltipModule } from '@angular/material/tooltip'; const uischema1: ControlElement = { type: 'Control', scope: '#' }; const uischema2: ControlElement = { type: 'Control', - scope: '#/properties/my' + scope: '#/properties/my', }; const uischemaWithSorting: ControlElement = { type: 'Control', scope: '#', options: { - showSortButtons: true - } + showSortButtons: true, + }, }; const schema_object1 = { type: 'array', @@ -61,9 +62,9 @@ const schema_object1 = { type: 'object', properties: { foo: { type: 'string' }, - bar: { type: 'string' } - } - } + bar: { type: 'string' }, + }, + }, }; const schema_object2 = { type: 'object', @@ -74,17 +75,17 @@ const schema_object2 = { type: 'object', properties: { foo: { type: 'string' }, - bar: { type: 'string' } - } - } - } - } + bar: { type: 'string' }, + }, + }, + }, + }, }; const schema_simple1 = { type: 'array', items: { - type: 'string' - } + type: 'string', + }, }; const schema_simple2 = { type: 'object', @@ -92,22 +93,46 @@ const schema_simple2 = { my: { type: 'array', items: { - type: 'string' - } - } - } + type: 'string', + }, + }, + }, }; const renderers = [ { tester: TextControlRendererTester, renderer: TextControlRenderer }, - { tester: TableRendererTester, renderer: TableRenderer } + { tester: TableRendererTester, renderer: TableRenderer }, ]; describe('Table tester', () => { it('should succeed', () => { - expect(TableRendererTester(uischema1, schema_object1, createTesterContext(schema_object1))).toBe(3); - expect(TableRendererTester(uischema1, schema_simple1, createTesterContext(schema_simple1))).toBe(3); - expect(TableRendererTester(uischema2, schema_object2, createTesterContext(schema_object2))).toBe(3); - expect(TableRendererTester(uischema2, schema_simple2, createTesterContext(schema_simple2))).toBe(3); + expect( + TableRendererTester( + uischema1, + schema_object1, + createTesterContext(schema_object1) + ) + ).toBe(3); + expect( + TableRendererTester( + uischema1, + schema_simple1, + createTesterContext(schema_simple1) + ) + ).toBe(3); + expect( + TableRendererTester( + uischema2, + schema_object2, + createTesterContext(schema_object2) + ) + ).toBe(3); + expect( + TableRendererTester( + uischema2, + schema_simple2, + createTesterContext(schema_simple2) + ) + ).toBe(3); }); }); describe('Table', () => { @@ -127,14 +152,15 @@ describe('Table', () => { MatInputModule, ReactiveFormsModule, FlexLayoutModule, - MatTableModule + MatTableModule, + MatTooltipModule, ], - providers: [JsonFormsAngularService] + providers: [JsonFormsAngularService], }) .overrideModule(BrowserDynamicTestingModule, { set: { - entryComponents: [TextControlRenderer] - } + entryComponents: [TextControlRenderer], + }, }) .compileComponents(); @@ -148,9 +174,9 @@ describe('Table', () => { schema: schema_object1, data: [ { foo: 'foo_1', bar: 'bar_1' }, - { foo: 'foo_2', bar: 'bar_2' } + { foo: 'foo_2', bar: 'bar_2' }, ], - renderers + renderers, }); fixture.detectChanges(); component.ngOnInit(); @@ -170,10 +196,10 @@ describe('Table', () => { data: { my: [ { foo: 'foo_1', bar: 'bar_1' }, - { foo: 'foo_2', bar: 'bar_2' } - ] + { foo: 'foo_2', bar: 'bar_2' }, + ], }, - renderers + renderers, }); fixture.detectChanges(); @@ -193,7 +219,7 @@ describe('Table', () => { uischema: uischema1, schema: schema_simple1, data: ['foo', 'bar'], - renderers + renderers, }); fixture.detectChanges(); component.ngOnInit(); @@ -211,7 +237,7 @@ describe('Table', () => { uischema: uischema2, schema: schema_simple2, data: { my: ['foo', 'bar'] }, - renderers + renderers, }); fixture.detectChanges(); component.ngOnInit(); @@ -230,7 +256,7 @@ describe('Table', () => { uischema: uischema1, schema: schema_object1, data: [{ foo: 'foo_1', bar: 'bar_1' }], - renderers + renderers, }); component.disabled = true; fixture.detectChanges(); @@ -250,7 +276,7 @@ describe('Table', () => { uischema: uischema1, schema: schema_object1, data: [{ foo: 'foo_1', bar: 'bar_1' }], - renderers + renderers, }); fixture.detectChanges(); component.ngOnInit(); @@ -267,9 +293,9 @@ describe('Table', () => { schema: schema_object1, data: [ { foo: 'foo_1', bar: 'bar_1' }, - { foo: 'foo_2', bar: 'bar_2' } + { foo: 'foo_2', bar: 'bar_2' }, ], - renderers + renderers, }); fixture.detectChanges(); @@ -279,7 +305,6 @@ describe('Table', () => { fixture.detectChanges(); fixture.whenStable().then(() => { - // 1 row expect(fixture.nativeElement.querySelectorAll('tr').length).toBe(1 + 0); }); @@ -291,9 +316,9 @@ describe('Table', () => { schema: schema_object1, data: [ { foo: 'foo_1', bar: 'bar_1' }, - { foo: 'foo_2', bar: 'bar_2' } + { foo: 'foo_2', bar: 'bar_2' }, ], - renderers + renderers, }); fixture.detectChanges(); @@ -306,7 +331,6 @@ describe('Table', () => { fixture.whenStable().then(() => { // 3 row expect(fixture.nativeElement.querySelectorAll('tr').length).toBe(1 + 4); - }); })); @@ -316,9 +340,9 @@ describe('Table', () => { schema: schema_object1, data: [ { foo: 'foo_1', bar: 'bar_1' }, - { foo: 'foo_2', bar: 'bar_2' } + { foo: 'foo_2', bar: 'bar_2' }, ], - renderers + renderers, }); component.disabled = true; fixture.detectChanges(); @@ -338,7 +362,7 @@ describe('Table', () => { uischema: uischemaWithSorting, schema: schema_simple1, data: ['foo', 'bar'], - renderers + renderers, }); component.disabled = false; fixture.detectChanges(); @@ -346,7 +370,9 @@ describe('Table', () => { component.ngOnInit(); fixture.whenStable().then(() => { expect(fixture.nativeElement.querySelectorAll('.item-up').length).toBe(2); - expect(fixture.nativeElement.querySelectorAll('.item-down').length).toBe(2); + expect(fixture.nativeElement.querySelectorAll('.item-down').length).toBe( + 2 + ); }); })); it('when options.showSortButtons is False, it should NOT render sort buttons', async(() => { @@ -354,7 +380,7 @@ describe('Table', () => { uischema: uischema1, schema: schema_simple1, data: ['foo', 'bar'], - renderers + renderers, }); component.disabled = false; fixture.detectChanges(); @@ -362,8 +388,9 @@ describe('Table', () => { component.ngOnInit(); fixture.whenStable().then(() => { expect(fixture.nativeElement.querySelectorAll('.item-up').length).toBe(0); - expect(fixture.nativeElement.querySelectorAll('.item-down').length).toBe(0); + expect(fixture.nativeElement.querySelectorAll('.item-down').length).toBe( + 0 + ); }); })); - }); diff --git a/packages/angular-material/test/text-area.spec.ts b/packages/angular-material/test/text-area.spec.ts index 6841460a9..4c19c025a 100644 --- a/packages/angular-material/test/text-area.spec.ts +++ b/packages/angular-material/test/text-area.spec.ts @@ -32,7 +32,7 @@ import { TestData, textBaseTest, textErrorTest, - textInputEventTest + textInputEventTest, } from '@jsonforms/angular-test'; import { TextAreaRenderer, TextAreaRendererTester } from '../src'; import { ControlElement, JsonSchema } from '@jsonforms/core'; @@ -43,19 +43,23 @@ describe('Material text field tester', () => { const uischema = { type: 'Control', scope: '#/properties/foo', - options: { multi: true } + options: { multi: true }, }; it('should succeed', () => { expect( - TextAreaRendererTester(uischema, { - type: 'object', - properties: { - foo: { - type: 'string' - } - } - }, undefined) + TextAreaRendererTester( + uischema, + { + type: 'object', + properties: { + foo: { + type: 'string', + }, + }, + }, + undefined + ) ).toBe(2); }); }); @@ -64,14 +68,14 @@ const imports = [ MatInputModule, NoopAnimationsModule, ReactiveFormsModule, - FlexLayoutModule + FlexLayoutModule, ]; const providers = [JsonFormsAngularService]; const componentUT: any = TextAreaRenderer; const errorTest: ErrorTestExpectation = { errorInstance: MatError, numberOfElements: 1, - indexOfElement: 0 + indexOfElement: 0, }; const toSelect = (el: DebugElement) => el.nativeElement; const testConfig = { imports, providers, componentUT }; @@ -80,19 +84,19 @@ const defaultSchema: JsonSchema = { type: 'object', properties: { foo: { - type: 'string' - } - } + type: 'string', + }, + }, }; const defaultUischema: ControlElement = { type: 'Control', scope: '#/properties/foo', - options: { multi: true } + options: { multi: true }, }; const defaultTestData: TestData = { data: defaultData, schema: defaultSchema, - uischema: defaultUischema + uischema: defaultUischema, }; describe( 'Text control Base Tests', diff --git a/packages/angular-material/test/text-control.spec.ts b/packages/angular-material/test/text-control.spec.ts index 064c9badb..5a3afc47d 100644 --- a/packages/angular-material/test/text-control.spec.ts +++ b/packages/angular-material/test/text-control.spec.ts @@ -32,7 +32,7 @@ import { textBaseTest, textErrorTest, textInputEventTest, - textTypeTest + textTypeTest, } from '@jsonforms/angular-test'; import { TextControlRenderer, TextControlRendererTester } from '../src'; import { FlexLayoutModule } from '@angular/flex-layout'; @@ -41,19 +41,23 @@ import { JsonFormsAngularService } from '@jsonforms/angular'; describe('Material text field tester', () => { const uischema = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; it('should succeed', () => { expect( - TextControlRendererTester(uischema, { - type: 'object', - properties: { - foo: { - type: 'string' - } - } - }, undefined) + TextControlRendererTester( + uischema, + { + type: 'object', + properties: { + foo: { + type: 'string', + }, + }, + }, + undefined + ) ).toBe(1); }); }); @@ -62,14 +66,14 @@ const imports = [ MatInputModule, NoopAnimationsModule, ReactiveFormsModule, - FlexLayoutModule + FlexLayoutModule, ]; const providers = [JsonFormsAngularService]; const componentUT: any = TextControlRenderer; const errorTest: ErrorTestExpectation = { errorInstance: MatError, numberOfElements: 1, - indexOfElement: 0 + indexOfElement: 0, }; const toSelect = (el: DebugElement) => el.nativeElement; const testConfig = { imports, providers, componentUT }; diff --git a/packages/angular-material/test/toggle-control.spec.ts b/packages/angular-material/test/toggle-control.spec.ts index f3769758d..7f1e3140d 100644 --- a/packages/angular-material/test/toggle-control.spec.ts +++ b/packages/angular-material/test/toggle-control.spec.ts @@ -23,12 +23,15 @@ THE SOFTWARE. */ import { MatError, MatFormFieldModule } from '@angular/material/form-field'; -import { MatSlideToggle, MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { + MatSlideToggle, + MatSlideToggleModule, +} from '@angular/material/slide-toggle'; import { booleanBaseTest, booleanErrorTest, booleanInputEventTest, - ErrorTestExpectation + ErrorTestExpectation, } from '@jsonforms/angular-test'; import { ToggleControlRenderer, ToggleControlRendererTester } from '../src'; import { FlexLayoutModule } from '@angular/flex-layout'; @@ -38,19 +41,23 @@ describe('Material boolean field tester', () => { const uischema = { type: 'Control', scope: '#/properties/foo', - options: { toggle: true } + options: { toggle: true }, }; it('should succeed', () => { expect( - ToggleControlRendererTester(uischema, { - type: 'object', - properties: { - foo: { - type: 'boolean' - } - } - }, undefined) + ToggleControlRendererTester( + uischema, + { + type: 'object', + properties: { + foo: { + type: 'boolean', + }, + }, + }, + undefined + ) ).toBe(3); }); }); @@ -60,7 +67,7 @@ const componentUT: any = ToggleControlRenderer; const errorTest: ErrorTestExpectation = { errorInstance: MatError, numberOfElements: 1, - indexOfElement: 0 + indexOfElement: 0, }; const testConfig = { imports, providers, componentUT }; describe( diff --git a/packages/angular-material/test/tsconfig.test.json b/packages/angular-material/test/tsconfig.test.json index 46da1c60a..8b6cff6dc 100644 --- a/packages/angular-material/test/tsconfig.test.json +++ b/packages/angular-material/test/tsconfig.test.json @@ -5,14 +5,7 @@ "target": "es6", "inlineSourceMap": true }, - "include": [ - "**/*.ts", - "**/*.tsx" - ], - "exclude":[ - "node_modules" - ], - "files": [ - "../src/index.ts" - ] + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"], + "files": ["../src/index.ts"] } diff --git a/packages/angular-material/test/util.ts b/packages/angular-material/test/util.ts index f8aae2282..c0bd9b744 100644 --- a/packages/angular-material/test/util.ts +++ b/packages/angular-material/test/util.ts @@ -24,5 +24,7 @@ */ import { JsonSchema, TesterContext } from '@jsonforms/core'; -export const createTesterContext = - (rootSchema: JsonSchema, config?: any): TesterContext => ({ rootSchema, config }); +export const createTesterContext = ( + rootSchema: JsonSchema, + config?: any +): TesterContext => ({ rootSchema, config }); diff --git a/packages/angular-material/test/vertical-layout.spec.ts b/packages/angular-material/test/vertical-layout.spec.ts index ead39fd27..f1cdc54a3 100644 --- a/packages/angular-material/test/vertical-layout.spec.ts +++ b/packages/angular-material/test/vertical-layout.spec.ts @@ -28,13 +28,15 @@ import { beforeEachLayoutTest, setupMockStore } from '@jsonforms/angular-test'; import { FlexLayoutModule } from '@angular/flex-layout'; import { VerticalLayoutRenderer, - verticalLayoutTester + verticalLayoutTester, } from '../src/layouts/vertical-layout.renderer'; import { LayoutChildrenRenderPropsPipe } from '../src/layouts/layout.renderer'; describe('Vertical layout tester', () => { it('should succeed', () => { - expect(verticalLayoutTester({ type: 'VerticalLayout' }, undefined, undefined)).toBe(1); + expect( + verticalLayoutTester({ type: 'VerticalLayout' }, undefined, undefined) + ).toBe(1); }); }); describe('Vertical layout', () => { @@ -44,19 +46,19 @@ describe('Vertical layout', () => { beforeEach(() => { fixture = beforeEachLayoutTest(VerticalLayoutRenderer, { declarations: [LayoutChildrenRenderPropsPipe], - imports: [FlexLayoutModule] + imports: [FlexLayoutModule], }); component = fixture.componentInstance; }); it('render with undefined elements', () => { const uischema: UISchemaElement = { - type: 'VerticalLayout' + type: 'VerticalLayout', }; setupMockStore(fixture, { data: {}, schema: {}, - uischema + uischema, }); fixture.componentInstance.ngOnInit(); fixture.detectChanges(); @@ -68,13 +70,13 @@ describe('Vertical layout', () => { it('render with null elements', () => { const uischema: VerticalLayout = { type: 'VerticalLayout', - elements: null + elements: null, }; setupMockStore(fixture, { data: {}, schema: {}, - uischema + uischema, }); fixture.componentInstance.ngOnInit(); fixture.detectChanges(); @@ -84,12 +86,12 @@ describe('Vertical layout', () => { it('render with children', () => { const uischema: VerticalLayout = { type: 'VerticalLayout', - elements: [{ type: 'Control' }, { type: 'Control' }] + elements: [{ type: 'Control' }, { type: 'Control' }], }; setupMockStore(fixture, { data: {}, schema: {}, - uischema + uischema, }); fixture.componentInstance.ngOnInit(); fixture.detectChanges(); @@ -101,13 +103,13 @@ describe('Vertical layout', () => { xit('can be hidden', () => { const uischema: VerticalLayout = { type: 'VerticalLayout', - elements: [{ type: 'Control' }, { type: 'Control' }] + elements: [{ type: 'Control' }, { type: 'Control' }], }; component.visible = false; setupMockStore(fixture, { data: {}, schema: {}, - uischema + uischema, }); component.ngOnInit(); expect(fixture.nativeElement.children[0].style.display).toBe('none'); diff --git a/packages/angular-material/tsconfig.cjs.json b/packages/angular-material/tsconfig.cjs.json index b04d624eb..b0c215c3d 100644 --- a/packages/angular-material/tsconfig.cjs.json +++ b/packages/angular-material/tsconfig.cjs.json @@ -5,5 +5,5 @@ "sourceMap": true, "target": "es5", "module": "commonjs" - }, + } } diff --git a/packages/angular-material/webpack/webpack.build.js b/packages/angular-material/webpack/webpack.build.js index 062808dcb..3a676b9a7 100644 --- a/packages/angular-material/webpack/webpack.build.js +++ b/packages/angular-material/webpack/webpack.build.js @@ -2,12 +2,12 @@ const merge = require('webpack-merge'); const baseConfig = require('../../../webpack/webpack.build.base.js'); module.exports = merge(baseConfig, { - output: { - filename: "jsonforms-angular-material.js", - library: "JSONFormsAngularMaterial" - }, - externals: { - '@jsonforms/core': 'JSONFormsCore', - '@jsonforms/angular': 'JSONFormsAngular' - }, -}); \ No newline at end of file + output: { + filename: 'jsonforms-angular-material.js', + library: 'JSONFormsAngularMaterial', + }, + externals: { + '@jsonforms/core': 'JSONFormsCore', + '@jsonforms/angular': 'JSONFormsAngular', + }, +}); diff --git a/packages/angular-material/webpack/webpack.dev.js b/packages/angular-material/webpack/webpack.dev.js index b0d25d9bd..6189cdcc7 100644 --- a/packages/angular-material/webpack/webpack.dev.js +++ b/packages/angular-material/webpack/webpack.dev.js @@ -1,37 +1,45 @@ var webpack = require('webpack'); -const path = require("path"); +const path = require('path'); const merge = require('webpack-merge'); -var copyWebpackPlugin = require("copy-webpack-plugin"); +var copyWebpackPlugin = require('copy-webpack-plugin'); const baseConfig = require('../../../webpack/webpack.base.js'); module.exports = merge(baseConfig, { - entry: [ - 'webpack-dev-server/client?http://localhost:8080', - 'webpack/hot/dev-server', - './example/main.ts' - ], - output: { - publicPath: "/assets/", - filename: "bundle.js" - }, + entry: [ + 'webpack-dev-server/client?http://localhost:8080', + 'webpack/hot/dev-server', + './example/main.ts', + ], + output: { + publicPath: '/assets/', + filename: 'bundle.js', + }, - devServer: { - contentBase: './example' - }, - plugins: [ - new webpack.HotModuleReplacementPlugin(), - new copyWebpackPlugin([ - { from: '../../node_modules/@angular/material/prebuilt-themes/indigo-pink.css' } - ]) - + devServer: { + contentBase: './example', + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new copyWebpackPlugin([ + { + from: '../../node_modules/@angular/material/prebuilt-themes/indigo-pink.css', + }, + ]), + ], + module: { + rules: [ + { + test: /\.html$/, + exclude: /node_modules/, + loader: 'html-loader?exportAsEs6Default', + }, + ], + }, + resolve: { + // manually link to angular path in case of dev + modules: [ + path.resolve(__dirname, '../../angular/node_modules'), + 'node_modules', ], - module: { - rules: [ - { test: /\.html$/, exclude: /node_modules/, loader: 'html-loader?exportAsEs6Default'} - ] - }, - resolve: { - // manually link to angular path in case of dev - modules: [path.resolve(__dirname, "../../angular/node_modules"), "node_modules"] - } -}); \ No newline at end of file + }, +}); diff --git a/packages/angular-test/.eslintrc.js b/packages/angular-test/.eslintrc.js new file mode 100644 index 000000000..28449d281 --- /dev/null +++ b/packages/angular-test/.eslintrc.js @@ -0,0 +1,38 @@ +/* eslint-env node */ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + parserOptions: { + /* Reset project because @angular-eslint/recommended sets this to an incompatible value */ + project: null, + }, + // There is no file include in ESLint. Thus, ignore all and include files via negative ignore (!) + ignorePatterns: ['/*', '!/src'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:@angular-eslint/recommended', + 'plugin:@angular-eslint/template/process-inline-templates', + 'plugin:prettier/recommended', + ], + rules: { + '@angular-eslint/component-class-suffix': 'off', + '@angular-eslint/directive-class-suffix': 'off', + '@angular-eslint/no-conflicting-lifecycle': 'warn', + '@typescript-eslint/no-explicit-any': 'off', + 'no-prototype-builtins': 'off', + // Base rule must be disabled to avoid incorrect errors + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', // or "error" + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, +}; diff --git a/packages/angular-test/.prettierrc.js b/packages/angular-test/.prettierrc.js new file mode 100644 index 000000000..2c26853c4 --- /dev/null +++ b/packages/angular-test/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + $schema: 'http://json.schemastore.org/prettierrc', + singleQuote: true, + jsxSingleQuote: true, + endOfLine: 'auto', +}; diff --git a/packages/angular-test/package.json b/packages/angular-test/package.json index dbe22f76c..caa85930b 100644 --- a/packages/angular-test/package.json +++ b/packages/angular-test/package.json @@ -1,13 +1,21 @@ { "name": "@jsonforms/angular-test", - "version": "3.1.0-alpha.1", + "version": "3.1.0-alpha.2", "private": true, "main": "./lib/index.js", "dependencies": { - "@jsonforms/angular": "^3.1.0-alpha.1", - "@jsonforms/core": "^3.1.0-alpha.1" + "@jsonforms/angular": "^3.1.0-alpha.2", + "@jsonforms/core": "^3.1.0-alpha.2" }, "devDependencies": { + "@angular-eslint/eslint-plugin": "^12.0.0", + "@angular-eslint/eslint-plugin-template": "^12.0.0", + "@angular-eslint/schematics": "^12.0.0", + "@angular-eslint/template-parser": "^12.0.0", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.7.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", "jasmine": "^3.2.0", "jasmine-spec-reporter": "^4.2.1", "karma": "^3.1.1", @@ -16,10 +24,13 @@ "karma-jasmine": "^2.0.1", "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^3.0.5", + "prettier": "^2.8.4", "typescript": "4.2.3" }, "scripts": { "build": "tsc", + "lint": "eslint .", + "lint:fix": "eslint --fix .", "test": "echo 'Nothing to do'" } } diff --git a/packages/angular-test/src/boolean.ts b/packages/angular-test/src/boolean.ts index f18a928ed..6f845fdc4 100644 --- a/packages/angular-test/src/boolean.ts +++ b/packages/angular-test/src/boolean.ts @@ -31,7 +31,7 @@ import { baseSetup, ErrorTestExpectation, TestConfig, - getJsonFormsService + getJsonFormsService, } from './util'; const prepareComponent = ( @@ -54,250 +54,295 @@ export const defaultBooleanTestSchema: JsonSchema = { type: 'object', properties: { foo: { - type: 'boolean' - } - } + type: 'boolean', + }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; export const defaultBooleanTestData = { data, schema: defaultBooleanTestSchema, - uischema + uischema, }; -export const booleanBaseTest = ( - testConfig: TestConfig, - instance: Type -) => () => { - let fixture: ComponentFixture; - let checkboxNativeElement: HTMLElement; - let checkboxInstance: any; - let component: C; +export const booleanBaseTest = + ( + testConfig: TestConfig, + instance: Type + ) => + () => { + let fixture: ComponentFixture; + let checkboxNativeElement: HTMLElement; + let checkboxInstance: any; + let component: C; - baseSetup(testConfig); + baseSetup(testConfig); - beforeEach(() => { - const preparedComponents = prepareComponent(testConfig, instance); - fixture = preparedComponents.fixture; - checkboxNativeElement = preparedComponents.checkboxNativeElement; - checkboxInstance = preparedComponents.checkboxInstance; - component = preparedComponents.component; - }); + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig, instance); + fixture = preparedComponents.fixture; + checkboxNativeElement = preparedComponents.checkboxNativeElement; + checkboxInstance = preparedComponents.checkboxInstance; + component = preparedComponents.component; + }); - it('should render', () => { - component.uischema = uischema; + it('should render', () => { + component.uischema = uischema; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(component.data).toBe(true); - expect(checkboxInstance.checked).toBe(true); - expect(checkboxInstance.disabled).toBe(false); - // the component is wrapped in a div - const hasDisplayNone = - 'none' === fixture.nativeElement.children[0].style.display; - const hasHidden = fixture.nativeElement.children[0].hidden; - expect(hasDisplayNone || hasHidden).toBeFalsy(); - }); - it('should support updating the state', () => { - component.uischema = uischema; + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(component.data).toBe(true); + expect(checkboxInstance.checked).toBe(true); + expect(checkboxInstance.disabled).toBe(false); + // the component is wrapped in a div + const hasDisplayNone = + 'none' === fixture.nativeElement.children[0].style.display; + const hasHidden = fixture.nativeElement.children[0].hidden; + expect(hasDisplayNone || hasHidden).toBeFalsy(); + }); + it('should support updating the state', () => { + component.uischema = uischema; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); - getJsonFormsService(component).updateCore( - Actions.update('foo', () => false) - ); - fixture.detectChanges(); - expect(component.data).toBe(false); - expect(checkboxInstance.checked).toBe(false); - }); - it('should update with undefined value', () => { - component.uischema = uischema; + getJsonFormsService(component).updateCore( + Actions.update('foo', () => false) + ); + fixture.detectChanges(); + expect(component.data).toBe(false); + expect(checkboxInstance.checked).toBe(false); + }); + it('should update with undefined value', () => { + component.uischema = uischema; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); - getJsonFormsService(component).updateCore( - Actions.update('foo', () => undefined) - ); - fixture.detectChanges(); - expect(component.data).toBe(undefined); - expect(checkboxInstance.checked).toBe(false); - }); - it('should update with null value', () => { - component.uischema = uischema; + getJsonFormsService(component).updateCore( + Actions.update('foo', () => undefined) + ); + fixture.detectChanges(); + expect(component.data).toBe(undefined); + expect(checkboxInstance.checked).toBe(false); + }); + it('should update with null value', () => { + component.uischema = uischema; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); - getJsonFormsService(component).updateCore( - Actions.update('foo', () => null) - ); - fixture.detectChanges(); - expect(component.data).toBe(null); - expect(checkboxInstance.checked).toBe(false); - }); - it('should not update with wrong ref', () => { - component.uischema = uischema; + getJsonFormsService(component).updateCore( + Actions.update('foo', () => null) + ); + fixture.detectChanges(); + expect(component.data).toBe(null); + expect(checkboxInstance.checked).toBe(false); + }); + it('should not update with wrong ref', () => { + component.uischema = uischema; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); - getJsonFormsService(component).updateCore( - Actions.update('foo', () => true) - ); - getJsonFormsService(component).updateCore( - Actions.update('bar', () => false) - ); - fixture.detectChanges(); - expect(component.data).toBe(true); - expect(checkboxInstance.checked).toBe(true); - }); - // store needed as we evaluate the calculated enabled value to disable/enable the control - it('can be disabled', () => { - component.uischema = uischema; - component.disabled = true; + getJsonFormsService(component).updateCore( + Actions.update('foo', () => true) + ); + getJsonFormsService(component).updateCore( + Actions.update('bar', () => false) + ); + fixture.detectChanges(); + expect(component.data).toBe(true); + expect(checkboxInstance.checked).toBe(true); + }); + // store needed as we evaluate the calculated enabled value to disable/enable the control + it('can be disabled', () => { + component.uischema = uischema; + component.disabled = true; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(checkboxInstance.disabled).toBe(true); - }); - // store needed as we evaluate the calculated enabled value to disable/enable the control - it('can be hidden', () => { - component.uischema = uischema; - component.visible = false; + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(checkboxInstance.disabled).toBe(true); + }); + // store needed as we evaluate the calculated enabled value to disable/enable the control + it('can be hidden', () => { + component.uischema = uischema; + component.visible = false; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - // the component is wrapped in a div - const hasDisplayNone = - 'none' === fixture.nativeElement.children[0].style.display; - const hasHidden = fixture.nativeElement.children[0].hidden; - expect(hasDisplayNone || hasHidden).toBeTruthy(); - }); + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + // the component is wrapped in a div + const hasDisplayNone = + 'none' === fixture.nativeElement.children[0].style.display; + const hasHidden = fixture.nativeElement.children[0].hidden; + expect(hasDisplayNone || hasHidden).toBeTruthy(); + }); - it('id should be present in output', () => { - component.uischema = uischema; - component.id = 'myId'; + it('id should be present in output', () => { + component.uischema = uischema; + component.id = 'myId'; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(checkboxNativeElement.id).toBe('myId'); - }); -}; -export const booleanInputEventTest = ( - testConfig: TestConfig, - instance: Type, - selectorForClick: string -) => () => { - let fixture: ComponentFixture; - let checkboxNativeElement: HTMLElement; - let checkboxInstance: any; - let component: C; - let elementToClick: any; - - baseSetup(testConfig); + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(checkboxNativeElement.id).toBe('myId'); + }); + }; +export const booleanInputEventTest = + ( + testConfig: TestConfig, + instance: Type, + selectorForClick: string + ) => + () => { + let fixture: ComponentFixture; + let checkboxNativeElement: HTMLElement; + let checkboxInstance: any; + let component: C; + let elementToClick: any; - beforeEach(() => { - const preparedComponents = prepareComponent(testConfig, instance); - fixture = preparedComponents.fixture; - checkboxNativeElement = preparedComponents.checkboxNativeElement; - checkboxInstance = preparedComponents.checkboxInstance; - component = preparedComponents.component; + baseSetup(testConfig); - elementToClick = checkboxNativeElement.querySelector(selectorForClick); - }); + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig, instance); + fixture = preparedComponents.fixture; + checkboxNativeElement = preparedComponents.checkboxNativeElement; + checkboxInstance = preparedComponents.checkboxInstance; + component = preparedComponents.component; - it('should update via input event', () => { - component.uischema = uischema; - getJsonFormsService(component).init( - {core: {data: data, schema: defaultBooleanTestSchema, uischema: uischema}} - ); - fixture.detectChanges(); - component.ngOnInit(); + elementToClick = checkboxNativeElement.querySelector(selectorForClick); + }); - const spy = spyOn(component, 'onChange'); - elementToClick.click(); - // trigger change detection - fixture.detectChanges(); + it('should update via input event', () => { + component.uischema = uischema; + getJsonFormsService(component).init({ + core: { + data: data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + fixture.detectChanges(); + component.ngOnInit(); - expect(spy).toHaveBeenCalled(); - expect(checkboxInstance.checked).toBe(false); - }); -}; + const spy = spyOn(component, 'onChange'); + elementToClick.click(); + // trigger change detection + fixture.detectChanges(); -export const booleanErrorTest = ( - testConfig: TestConfig, - instance: Type, - errorTestInformation: ErrorTestExpectation -) => () => { - let fixture: ComponentFixture; - let component: C; + expect(spy).toHaveBeenCalled(); + expect(checkboxInstance.checked).toBe(false); + }); + }; - baseSetup(testConfig); +export const booleanErrorTest = + ( + testConfig: TestConfig, + instance: Type, + errorTestInformation: ErrorTestExpectation + ) => + () => { + let fixture: ComponentFixture; + let component: C; - beforeEach(() => { - const preparedComponents = prepareComponent(testConfig, instance); - fixture = preparedComponents.fixture; - component = preparedComponents.component; - }); - it('should display errors', () => { - component.uischema = uischema; + baseSetup(testConfig); - const formsService = getJsonFormsService(component); - formsService.init({ - core: { - data, - schema: defaultBooleanTestSchema, - uischema: uischema - } + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig, instance); + fixture = preparedComponents.fixture; + component = preparedComponents.component; }); - formsService.updateCore(Actions.updateErrors([ - { - instancePath: '/foo', - message: 'Hi, this is me, test error!', - keyword: '', - schemaPath: '', - params: {} - } - ])); - formsService.refresh(); + it('should display errors', () => { + component.uischema = uischema; - component.ngOnInit(); - fixture.detectChanges(); - const debugErrors: DebugElement[] = fixture.debugElement.queryAll( - By.directive(errorTestInformation.errorInstance) - ); - expect(debugErrors.length).toBe(errorTestInformation.numberOfElements); - expect( - debugErrors[errorTestInformation.indexOfElement].nativeElement.textContent - ).toBe('Hi, this is me, test error!'); - }); -}; + const formsService = getJsonFormsService(component); + formsService.init({ + core: { + data, + schema: defaultBooleanTestSchema, + uischema: uischema, + }, + }); + formsService.updateCore( + Actions.updateErrors([ + { + instancePath: '/foo', + message: 'Hi, this is me, test error!', + keyword: '', + schemaPath: '', + params: {}, + }, + ]) + ); + formsService.refresh(); + + component.ngOnInit(); + fixture.detectChanges(); + const debugErrors: DebugElement[] = fixture.debugElement.queryAll( + By.directive(errorTestInformation.errorInstance) + ); + expect(debugErrors.length).toBe(errorTestInformation.numberOfElements); + expect( + debugErrors[errorTestInformation.indexOfElement].nativeElement + .textContent + ).toBe('Hi, this is me, test error!'); + }); + }; diff --git a/packages/angular-test/src/layout.ts b/packages/angular-test/src/layout.ts index 21d393088..bea797779 100644 --- a/packages/angular-test/src/layout.ts +++ b/packages/angular-test/src/layout.ts @@ -25,7 +25,7 @@ import { JsonFormsAngularService, JsonFormsOutlet, - UnknownRenderer + UnknownRenderer, } from '@jsonforms/angular'; import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; @@ -37,12 +37,12 @@ export const beforeEachLayoutTest = ( TestBed.configureTestingModule({ declarations: [Renderer, UnknownRenderer, JsonFormsOutlet, ...declarations], imports, - providers: [JsonFormsAngularService, ...providers] + providers: [JsonFormsAngularService, ...providers], }) .overrideModule(BrowserDynamicTestingModule, { set: { - entryComponents: [UnknownRenderer] - } + entryComponents: [UnknownRenderer], + }, }) .compileComponents(); return TestBed.createComponent(Renderer); diff --git a/packages/angular-test/src/number.ts b/packages/angular-test/src/number.ts index 6d3007f11..e4947a5f0 100644 --- a/packages/angular-test/src/number.ts +++ b/packages/angular-test/src/number.ts @@ -33,7 +33,7 @@ import { getJsonFormsService, setupMockStore, TestConfig, - TestData + TestData, } from './util'; interface ComponentResult { @@ -65,18 +65,18 @@ const defaultSchema: JsonSchema = { type: 'object', properties: { foo: { - type: 'number' - } - } + type: 'number', + }, + }, }; const defaultUischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; export const defaultNumberTestData: TestData = { data: defaultData, schema: defaultSchema, - uischema: defaultUischema + uischema: defaultUischema, }; export const updateWithSiblingNumberValue = ( fixture: ComponentFixture, @@ -88,283 +88,304 @@ export const updateWithSiblingNumberValue = ( core: { data: { foo: 123.123, bar: 456.456 }, schema: testData.schema, - uischema: undefined - } + uischema: undefined, + }, }); fixture.componentInstance.ngOnInit(); fixture.detectChanges(); expectations(); }; -export const numberBaseTest = ( - testConfig: TestConfig, - instance: string, - elementToUse: (element: DebugElement) => any, - testData: TestData = defaultNumberTestData -) => () => { - let fixture: ComponentFixture; - let numberElement: DebugElement; - let numberNativeElement: any; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent( - testConfig, - instance, - elementToUse - ); - fixture = preparedComponents.fixture; - numberNativeElement = preparedComponents.numberNativeElement; - numberElement = preparedComponents.numberElement; - component = preparedComponents.component; - }); - - it('should render floats', () => { - component.uischema = testData.uischema; - getJsonFormsService(component).init({ core: testData }); - getJsonFormsService(component).updateCore( - Actions.init(testData.data, testData.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(component.data).toBe(123.123); - expect(numberNativeElement.value).toBe('123.123'); - // step is of type string - expect(numberNativeElement.step).toBe('0.1'); - expect(numberNativeElement.disabled).toBe(false); - // the component is wrapped in a div - expect(fixture.nativeElement.children[0].style.display).not.toBe('none'); - }); +export const numberBaseTest = + ( + testConfig: TestConfig, + instance: string, + elementToUse: (element: DebugElement) => any, + testData: TestData = defaultNumberTestData + ) => + () => { + let fixture: ComponentFixture; + let numberElement: DebugElement; + let numberNativeElement: any; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent( + testConfig, + instance, + elementToUse + ); + fixture = preparedComponents.fixture; + numberNativeElement = preparedComponents.numberNativeElement; + numberElement = preparedComponents.numberElement; + component = preparedComponents.component; + }); - it('should render integers', () => { - const state = { - data: { foo: 123 }, - schema: { - type: 'object', - properties: { - foo: { type: 'integer' } - } - }, - uischema: testData.uischema - }; - component.uischema = testData.uischema; - getJsonFormsService(component).init({ core: state }); - getJsonFormsService(component).updateCore( - Actions.init(state.data, state.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); - - expect(component.data).toBe(123); - expect(numberNativeElement.value).toBe('123'); - // step is of type string - expect(numberNativeElement.step).toBe('1'); - expect(numberNativeElement.disabled).toBe(false); - // the component is wrapped in a div - expect(fixture.nativeElement.children[0].style.display).not.toBe('none'); - }); + it('should render floats', () => { + component.uischema = testData.uischema; + getJsonFormsService(component).init({ core: testData }); + getJsonFormsService(component).updateCore( + Actions.init(testData.data, testData.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); + expect(component.data).toBe(123.123); + expect(numberNativeElement.value).toBe('123.123'); + // step is of type string + expect(numberNativeElement.step).toBe('0.1'); + expect(numberNativeElement.disabled).toBe(false); + // the component is wrapped in a div + expect(fixture.nativeElement.children[0].style.display).not.toBe('none'); + }); - it('should support updating the state', () => { - component.uischema = testData.uischema; - getJsonFormsService(component).init({ core: testData }); - getJsonFormsService(component).updateCore( - Actions.init(testData.data, testData.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); - getJsonFormsService(fixture.componentInstance).updateCore( - Actions.update('foo', () => 456.456) - ); - fixture.detectChanges(); - expect(component.data).toBe(456.456); - expect(Number(numberNativeElement.value)).toBe(456.456); - }); + it('should render integers', () => { + const state = { + data: { foo: 123 }, + schema: { + type: 'object', + properties: { + foo: { type: 'integer' }, + }, + }, + uischema: testData.uischema, + }; + component.uischema = testData.uischema; + getJsonFormsService(component).init({ core: state }); + getJsonFormsService(component).updateCore( + Actions.init(state.data, state.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); + + expect(component.data).toBe(123); + expect(numberNativeElement.value).toBe('123'); + // step is of type string + expect(numberNativeElement.step).toBe('1'); + expect(numberNativeElement.disabled).toBe(false); + // the component is wrapped in a div + expect(fixture.nativeElement.children[0].style.display).not.toBe('none'); + }); - it('should update with undefined value', () => { - component.uischema = testData.uischema; - getJsonFormsService(component).init({ core: testData }); - getJsonFormsService(component).updateCore( - Actions.init(testData.data, testData.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); - getJsonFormsService(fixture.componentInstance).updateCore( - Actions.update('foo', () => undefined) - ); - fixture.detectChanges(); - - expect(component.data).toBe(undefined); - expect(numberNativeElement.value).toBe(''); - }); + it('should support updating the state', () => { + component.uischema = testData.uischema; + getJsonFormsService(component).init({ core: testData }); + getJsonFormsService(component).updateCore( + Actions.init(testData.data, testData.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); + getJsonFormsService(fixture.componentInstance).updateCore( + Actions.update('foo', () => 456.456) + ); + fixture.detectChanges(); + expect(component.data).toBe(456.456); + expect(Number(numberNativeElement.value)).toBe(456.456); + }); - it('should update with null value', () => { - component.uischema = testData.uischema; - getJsonFormsService(component).init({ core: testData }); - getJsonFormsService(component).updateCore( - Actions.init(testData.data, testData.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); - getJsonFormsService(fixture.componentInstance).updateCore( - Actions.update('foo', () => null) - ); - fixture.detectChanges(); - expect(component.data).toBe(null); - expect(numberNativeElement.value).toBe(''); - }); + it('should update with undefined value', () => { + component.uischema = testData.uischema; + getJsonFormsService(component).init({ core: testData }); + getJsonFormsService(component).updateCore( + Actions.init(testData.data, testData.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); + getJsonFormsService(fixture.componentInstance).updateCore( + Actions.update('foo', () => undefined) + ); + fixture.detectChanges(); + + expect(component.data).toBe(undefined); + expect(numberNativeElement.value).toBe(''); + }); - it('should not update with wrong ref', () => { - component.uischema = testData.uischema; - getJsonFormsService(component).init({ core: testData }); - getJsonFormsService(component).updateCore( - Actions.init(testData.data, testData.schema) - ); - component.ngOnInit(); - fixture.detectChanges(); - getJsonFormsService(fixture.componentInstance).updateCore( - Actions.update('bar', () => 456.456) - ); - fixture.detectChanges(); - expect(component.data).toBe(123.123); - expect(Number(numberNativeElement.value)).toBe(123.123); - }); + it('should update with null value', () => { + component.uischema = testData.uischema; + getJsonFormsService(component).init({ core: testData }); + getJsonFormsService(component).updateCore( + Actions.init(testData.data, testData.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); + getJsonFormsService(fixture.componentInstance).updateCore( + Actions.update('foo', () => null) + ); + fixture.detectChanges(); + expect(component.data).toBe(null); + expect(numberNativeElement.value).toBe(''); + }); - // store needed as we evaluate the calculated enabled value to disable/enable the control - it('can be disabled', () => { - component.uischema = testData.uischema; - component.disabled = true; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(numberNativeElement.disabled).toBe(true); - }); - // store needed as we evaluate the calculated enabled value to disable/enable the control - it('can be hidden', () => { - component.uischema = testData.uischema; - component.visible = false; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - const hasDisplayNone = - 'none' === fixture.nativeElement.children[0].style.display; - const hasHidden = fixture.nativeElement.children[0].hidden; - expect(hasDisplayNone || hasHidden).toBeTruthy(); - }); + it('should not update with wrong ref', () => { + component.uischema = testData.uischema; + getJsonFormsService(component).init({ core: testData }); + getJsonFormsService(component).updateCore( + Actions.init(testData.data, testData.schema) + ); + component.ngOnInit(); + fixture.detectChanges(); + getJsonFormsService(fixture.componentInstance).updateCore( + Actions.update('bar', () => 456.456) + ); + fixture.detectChanges(); + expect(component.data).toBe(123.123); + expect(Number(numberNativeElement.value)).toBe(123.123); + }); - it('id should be present in output', () => { - component.uischema = testData.uischema; - component.id = 'myId'; - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(numberElement.nativeElement.id).toBe('myId'); - }); -}; -export const numberInputEventTest = ( - testConfig: TestConfig, - instance: string, - elementToUse: (element: DebugElement) => any, - testData: TestData = defaultNumberTestData -) => () => { - let fixture: ComponentFixture; - let numberNativeElement: any; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent( - testConfig, - instance, - elementToUse - ); - fixture = preparedComponents.fixture; - numberNativeElement = preparedComponents.numberNativeElement; - component = preparedComponents.component; - }); + // store needed as we evaluate the calculated enabled value to disable/enable the control + it('can be disabled', () => { + component.uischema = testData.uischema; + component.disabled = true; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(numberNativeElement.disabled).toBe(true); + }); + // store needed as we evaluate the calculated enabled value to disable/enable the control + it('can be hidden', () => { + component.uischema = testData.uischema; + component.visible = false; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + const hasDisplayNone = + 'none' === fixture.nativeElement.children[0].style.display; + const hasHidden = fixture.nativeElement.children[0].hidden; + expect(hasDisplayNone || hasHidden).toBeTruthy(); + }); - it('should update via input event', () => { - component.uischema = testData.uischema as ControlElement; + it('id should be present in output', () => { + component.uischema = testData.uischema; + component.id = 'myId'; + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(numberElement.nativeElement.id).toBe('myId'); + }); + }; +export const numberInputEventTest = + ( + testConfig: TestConfig, + instance: string, + elementToUse: (element: DebugElement) => any, + testData: TestData = defaultNumberTestData + ) => + () => { + let fixture: ComponentFixture; + let numberNativeElement: any; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent( + testConfig, + instance, + elementToUse + ); + fixture = preparedComponents.fixture; + numberNativeElement = preparedComponents.numberNativeElement; + component = preparedComponents.component; + }); - getJsonFormsService(component).init({ - core: { - data: testData.data, - schema: testData.schema, - uischema: undefined + it('should update via input event', () => { + component.uischema = testData.uischema as ControlElement; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: undefined, + }, + }); + fixture.detectChanges(); + component.ngOnInit(); + + const spy = spyOn(component, 'onChange'); + numberNativeElement.value = 456.456; + if (numberNativeElement.dispatchEvent) { + numberNativeElement.dispatchEvent(new Event('input')); } + // trigger change detection + fixture.detectChanges(); + expect(spy).toHaveBeenCalled(); + expect(Number(numberNativeElement.value)).toBe(456.456); + }); + }; +export const numberErrorTest = + ( + testConfig: TestConfig, + errorTestInformation: ErrorTestExpectation, + testData: TestData = defaultNumberTestData + ) => + () => { + let fixture: ComponentFixture; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig); + fixture = preparedComponents.fixture; + component = preparedComponents.component; }); - fixture.detectChanges(); - component.ngOnInit(); - - const spy = spyOn(component, 'onChange'); - numberNativeElement.value = 456.456; - if (numberNativeElement.dispatchEvent) { - numberNativeElement.dispatchEvent(new Event('input')); - } - // trigger change detection - fixture.detectChanges(); - expect(spy).toHaveBeenCalled(); - expect(Number(numberNativeElement.value)).toBe(456.456); - }); -}; -export const numberErrorTest = ( - testConfig: TestConfig, - errorTestInformation: ErrorTestExpectation, - testData: TestData = defaultNumberTestData -) => () => { - let fixture: ComponentFixture; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent(testConfig); - fixture = preparedComponents.fixture; - component = preparedComponents.component; - }); - - it('should display errors', () => { - component.uischema = testData.uischema; - const formsService = getJsonFormsService(component); - formsService.init({ - core: { - data: testData.data, - schema: testData.schema, - uischema: undefined - } + it('should display errors', () => { + component.uischema = testData.uischema; + + const formsService = getJsonFormsService(component); + formsService.init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: undefined, + }, + }); + formsService.updateCore( + Actions.updateErrors([ + { + instancePath: '/foo', + message: 'Hi, this is me, test error!', + keyword: '', + schemaPath: '', + params: {}, + }, + ]) + ); + formsService.refresh(); + component.ngOnInit(); + fixture.detectChanges(); + const debugErrors: DebugElement[] = fixture.debugElement.queryAll( + By.directive(errorTestInformation.errorInstance) + ); + expect(debugErrors.length).toBe(errorTestInformation.numberOfElements); + expect( + debugErrors[errorTestInformation.indexOfElement].nativeElement + .textContent + ).toBe('Hi, this is me, test error!'); }); - formsService.updateCore(Actions.updateErrors([ - { - instancePath: '/foo', - message: 'Hi, this is me, test error!', - keyword: '', - schemaPath: '', - params: {} - } - ])); - formsService.refresh(); - component.ngOnInit(); - fixture.detectChanges(); - const debugErrors: DebugElement[] = fixture.debugElement.queryAll( - By.directive(errorTestInformation.errorInstance) - ); - expect(debugErrors.length).toBe(errorTestInformation.numberOfElements); - expect( - debugErrors[errorTestInformation.indexOfElement].nativeElement.textContent - ).toBe('Hi, this is me, test error!'); - }); -}; + }; const additionalSchema: JsonSchema = { type: 'object', @@ -373,48 +394,50 @@ const additionalSchema: JsonSchema = { type: 'number', minimum: -42.42, maximum: 42, - multipleOf: 3 - } - } + multipleOf: 3, + }, + }, }; export const additionalTestData: TestData = { data: defaultData, schema: additionalSchema, - uischema: defaultUischema + uischema: defaultUischema, }; -export const numberAdditionalPropsTest = ( - testConfig: TestConfig, - instance: string, - elementToUse: (element: DebugElement) => any, - testData: TestData = additionalTestData -) => () => { - let fixture: ComponentFixture; - let numberNativeElement: any; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent( - testConfig, - instance, - elementToUse - ); - fixture = preparedComponents.fixture; - numberNativeElement = preparedComponents.numberNativeElement; - }); +export const numberAdditionalPropsTest = + ( + testConfig: TestConfig, + instance: string, + elementToUse: (element: DebugElement) => any, + testData: TestData = additionalTestData + ) => + () => { + let fixture: ComponentFixture; + let numberNativeElement: any; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent( + testConfig, + instance, + elementToUse + ); + fixture = preparedComponents.fixture; + numberNativeElement = preparedComponents.numberNativeElement; + }); - it('should respect min,max,multipleOf', () => { - setupMockStore(fixture, testData); - getJsonFormsService(fixture.componentInstance).updateCore( - Actions.init(testData.data, testData.schema) - ); - fixture.componentInstance.ngOnInit(); - fixture.detectChanges(); - - // step, min and max are of type string on an input control - expect(numberNativeElement.step).toBe('3'); - expect(numberNativeElement.min).toBe('-42.42'); - expect(numberNativeElement.max).toBe('42'); - }); -}; + it('should respect min,max,multipleOf', () => { + setupMockStore(fixture, testData); + getJsonFormsService(fixture.componentInstance).updateCore( + Actions.init(testData.data, testData.schema) + ); + fixture.componentInstance.ngOnInit(); + fixture.detectChanges(); + + // step, min and max are of type string on an input control + expect(numberNativeElement.step).toBe('3'); + expect(numberNativeElement.min).toBe('-42.42'); + expect(numberNativeElement.max).toBe('42'); + }); + }; diff --git a/packages/angular-test/src/range.ts b/packages/angular-test/src/range.ts index 579d3526e..a5e92ec60 100644 --- a/packages/angular-test/src/range.ts +++ b/packages/angular-test/src/range.ts @@ -33,7 +33,7 @@ import { setupMockStore, TestConfig, TestData, - getJsonFormsService + getJsonFormsService, } from './util'; import { ControlElement, JsonSchema, Actions } from '@jsonforms/core'; @@ -61,289 +61,335 @@ export const rangeDefaultSchema: JsonSchema = { type: 'number', minimum: -42.42, maximum: 42.42, - default: 0.42 - } - } + default: 0.42, + }, + }, }; export const rangeDefaultUischema: ControlElement = { type: 'Control', scope: '#/properties/foo', - options: { slider: true } + options: { slider: true }, }; export const rangeDefaultTestData: TestData = { data: rangeDefaultData, schema: rangeDefaultSchema, - uischema: rangeDefaultUischema + uischema: rangeDefaultUischema, }; -export const rangeBaseTest = ( - testConfig: TestConfig, - instance: Type -) => () => { - let fixture: ComponentFixture; - let rangeElement: DebugElement; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent(testConfig, instance); - fixture = preparedComponents.fixture; - rangeElement = preparedComponents.rangeElement; - component = preparedComponents.component; - }); - - it('should render floats', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(component.data).toBe(1.234); - expect(rangeElement.componentInstance.value).toBe(1.234); - // step is of type string - expect(rangeElement.componentInstance.step).toBe(1); - expect(rangeElement.componentInstance.min).toBe(-42.42); - expect(rangeElement.componentInstance.max).toBe(42.42); - expect(rangeElement.componentInstance.disabled).toBe(false); - expect(fixture.nativeElement.children[0].style.display).not.toBe('none'); - }); - - it('should render integer', () => { - component.uischema = rangeDefaultTestData.uischema; - const schema = JSON.parse(JSON.stringify(rangeDefaultTestData.schema)); - schema.properties.foo.type = 'integer'; - schema.properties.foo.minimum = -42; - schema.properties.foo.maximum = 42; - schema.properties.foo.default = 1; - setupMockStore(fixture, { - uischema: rangeDefaultTestData.uischema, - schema, - data: { foo: 12 } +export const rangeBaseTest = + ( + testConfig: TestConfig, + instance: Type + ) => + () => { + let fixture: ComponentFixture; + let rangeElement: DebugElement; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig, instance); + fixture = preparedComponents.fixture; + rangeElement = preparedComponents.rangeElement; + component = preparedComponents.component; }); - getJsonFormsService(component).updateCore( - Actions.init({ foo: 12 }, schema, rangeDefaultTestData.uischema) - ); - - fixture.componentInstance.ngOnInit(); - fixture.detectChanges(); - expect(component.data).toBe(12); - expect(rangeElement.componentInstance.value).toBe(12); - // step is of type string - expect(rangeElement.componentInstance.step).toBe(1); - expect(rangeElement.componentInstance.min).toBe(-42); - expect(rangeElement.componentInstance.max).toBe(42); - expect(rangeElement.componentInstance.disabled).toBe(false); - // the component is wrapped in a div - expect(fixture.nativeElement.children[0].style.display).not.toBe('none'); - }); - - it('should support updating the state', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - getJsonFormsService(component).updateCore( - Actions.update('foo', () => 4.56) - ); - fixture.detectChanges(); - expect(component.data).toBe(4.56); - expect(rangeElement.componentInstance.value).toBe(4.56); - }); - it('should update with undefined value', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - getJsonFormsService(component).updateCore( - Actions.update('foo', () => undefined) - ); - fixture.detectChanges(); - expect(component.data).toBe(undefined); - expect(rangeElement.componentInstance.value).toBe(0.42); - }); - it('should update with null value', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - getJsonFormsService(component).updateCore( - Actions.update('foo', () => null) - ); - fixture.detectChanges(); - expect(component.data).toBe(null); - expect(rangeElement.componentInstance.value).toBe(0.42); - }); - it('should not update with wrong ref', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - getJsonFormsService(component).updateCore( - Actions.update('foo', () => 1.234) - ); - getJsonFormsService(component).updateCore( - Actions.update('bar', () => 456.456) - ); - - fixture.detectChanges(); - expect(component.data).toBe(1.234); - expect(rangeElement.componentInstance.value).toBe(1.234); - }); - // store needed as we evaluate the calculated enabled value to disable/enable the control - it('can be disabled', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - component.disabled = true; - - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(rangeElement.componentInstance.disabled).toBe(true); - }); - it('can be hidden', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - component.visible = false; - - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - fixture.detectChanges(); - component.ngOnInit(); - expect(fixture.nativeElement.children[0].style.display).toBe('none'); - }); - it('id should be present in output', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - component.id = 'myId'; - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(rangeElement.nativeElement.id).toBe('myId'); - }); -}; -export const rangeInputEventTest = ( - testConfig: TestConfig, - instance: Type -) => () => { - let fixture: ComponentFixture; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent(testConfig, instance); - fixture = preparedComponents.fixture; - component = preparedComponents.component; - }); - - xit('should update via input event', async () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - - getJsonFormsService(component).init( - {core: {data: rangeDefaultTestData.data, schema: rangeDefaultTestData.schema, uischema: rangeDefaultTestData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - const spy = spyOn(component, 'onChange'); - - const sliderElement = fixture.debugElement.query(By.css('.mat-slider')) - .nativeElement; - - const trackElement = fixture.debugElement.query( - By.css('.mat-slider-wrapper') - ).nativeElement; - const dimensions = trackElement.getBoundingClientRect(); - const x = dimensions.left + dimensions.width * 0.2; - const y = dimensions.top + dimensions.height * 0.2; - - dispatchEvent(sliderElement, createMouseEvent('mousedown', x, y, 0)); - - // trigger change detection - fixture.detectChanges(); - await fixture.whenStable(); - expect(spy).toHaveBeenCalled(); - }); -}; -export const rangeErrorTest = ( - testConfig: TestConfig, - instance: Type, - errorTestInformation: ErrorTestExpectation -) => () => { - let fixture: ComponentFixture; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent(testConfig, instance); - fixture = preparedComponents.fixture; - component = preparedComponents.component; - }); - it('should display errors', () => { - component.uischema = rangeDefaultTestData.uischema; - component.schema = rangeDefaultTestData.schema; - - const formsService = getJsonFormsService(component); - formsService.init({ - core: { - data: rangeDefaultTestData.data, - schema: rangeDefaultTestData.schema, - uischema: undefined - } + + it('should render floats', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(component.data).toBe(1.234); + expect(rangeElement.componentInstance.value).toBe(1.234); + // step is of type string + expect(rangeElement.componentInstance.step).toBe(1); + expect(rangeElement.componentInstance.min).toBe(-42.42); + expect(rangeElement.componentInstance.max).toBe(42.42); + expect(rangeElement.componentInstance.disabled).toBe(false); + expect(fixture.nativeElement.children[0].style.display).not.toBe('none'); }); - formsService.updateCore(Actions.updateErrors([ - { - instancePath: '/foo', - message: 'Hi, this is me, test error!', - keyword: '', - schemaPath: '', - params: {} - } - ])); - formsService.refresh(); - - component.ngOnInit(); - fixture.detectChanges(); - const debugErrors: DebugElement[] = fixture.debugElement.queryAll( - By.directive(errorTestInformation.errorInstance) - ); - expect(debugErrors.length).toBe(errorTestInformation.numberOfElements); - expect( - debugErrors[errorTestInformation.indexOfElement].nativeElement.textContent - ).toBe('Hi, this is me, test error!'); - }); -}; + + it('should render integer', () => { + component.uischema = rangeDefaultTestData.uischema; + const schema = JSON.parse(JSON.stringify(rangeDefaultTestData.schema)); + schema.properties.foo.type = 'integer'; + schema.properties.foo.minimum = -42; + schema.properties.foo.maximum = 42; + schema.properties.foo.default = 1; + setupMockStore(fixture, { + uischema: rangeDefaultTestData.uischema, + schema, + data: { foo: 12 }, + }); + getJsonFormsService(component).updateCore( + Actions.init({ foo: 12 }, schema, rangeDefaultTestData.uischema) + ); + + fixture.componentInstance.ngOnInit(); + fixture.detectChanges(); + expect(component.data).toBe(12); + expect(rangeElement.componentInstance.value).toBe(12); + // step is of type string + expect(rangeElement.componentInstance.step).toBe(1); + expect(rangeElement.componentInstance.min).toBe(-42); + expect(rangeElement.componentInstance.max).toBe(42); + expect(rangeElement.componentInstance.disabled).toBe(false); + // the component is wrapped in a div + expect(fixture.nativeElement.children[0].style.display).not.toBe('none'); + }); + + it('should support updating the state', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + getJsonFormsService(component).updateCore( + Actions.update('foo', () => 4.56) + ); + fixture.detectChanges(); + expect(component.data).toBe(4.56); + expect(rangeElement.componentInstance.value).toBe(4.56); + }); + it('should update with undefined value', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + getJsonFormsService(component).updateCore( + Actions.update('foo', () => undefined) + ); + fixture.detectChanges(); + expect(component.data).toBe(undefined); + expect(rangeElement.componentInstance.value).toBe(0.42); + }); + it('should update with null value', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + getJsonFormsService(component).updateCore( + Actions.update('foo', () => null) + ); + fixture.detectChanges(); + expect(component.data).toBe(null); + expect(rangeElement.componentInstance.value).toBe(0.42); + }); + it('should not update with wrong ref', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + getJsonFormsService(component).updateCore( + Actions.update('foo', () => 1.234) + ); + getJsonFormsService(component).updateCore( + Actions.update('bar', () => 456.456) + ); + + fixture.detectChanges(); + expect(component.data).toBe(1.234); + expect(rangeElement.componentInstance.value).toBe(1.234); + }); + // store needed as we evaluate the calculated enabled value to disable/enable the control + it('can be disabled', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + component.disabled = true; + + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(rangeElement.componentInstance.disabled).toBe(true); + }); + it('can be hidden', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + component.visible = false; + + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + fixture.detectChanges(); + component.ngOnInit(); + expect(fixture.nativeElement.children[0].style.display).toBe('none'); + }); + it('id should be present in output', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + component.id = 'myId'; + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(rangeElement.nativeElement.id).toBe('myId'); + }); + }; +export const rangeInputEventTest = + ( + testConfig: TestConfig, + instance: Type + ) => + () => { + let fixture: ComponentFixture; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig, instance); + fixture = preparedComponents.fixture; + component = preparedComponents.component; + }); + + xit('should update via input event', async () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + + getJsonFormsService(component).init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: rangeDefaultTestData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + const spy = spyOn(component, 'onChange'); + + const sliderElement = fixture.debugElement.query( + By.css('.mat-slider') + ).nativeElement; + + const trackElement = fixture.debugElement.query( + By.css('.mat-slider-wrapper') + ).nativeElement; + const dimensions = trackElement.getBoundingClientRect(); + const x = dimensions.left + dimensions.width * 0.2; + const y = dimensions.top + dimensions.height * 0.2; + + dispatchEvent(sliderElement, createMouseEvent('mousedown', x, y, 0)); + + // trigger change detection + fixture.detectChanges(); + await fixture.whenStable(); + expect(spy).toHaveBeenCalled(); + }); + }; +export const rangeErrorTest = + ( + testConfig: TestConfig, + instance: Type, + errorTestInformation: ErrorTestExpectation + ) => + () => { + let fixture: ComponentFixture; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig, instance); + fixture = preparedComponents.fixture; + component = preparedComponents.component; + }); + it('should display errors', () => { + component.uischema = rangeDefaultTestData.uischema; + component.schema = rangeDefaultTestData.schema; + + const formsService = getJsonFormsService(component); + formsService.init({ + core: { + data: rangeDefaultTestData.data, + schema: rangeDefaultTestData.schema, + uischema: undefined, + }, + }); + formsService.updateCore( + Actions.updateErrors([ + { + instancePath: '/foo', + message: 'Hi, this is me, test error!', + keyword: '', + schemaPath: '', + params: {}, + }, + ]) + ); + formsService.refresh(); + + component.ngOnInit(); + fixture.detectChanges(); + const debugErrors: DebugElement[] = fixture.debugElement.queryAll( + By.directive(errorTestInformation.errorInstance) + ); + expect(debugErrors.length).toBe(errorTestInformation.numberOfElements); + expect( + debugErrors[errorTestInformation.indexOfElement].nativeElement + .textContent + ).toBe('Hi, this is me, test error!'); + }); + }; /** Creates a browser MouseEvent with the specified options. */ const createMouseEvent = (type: string, x = 0, y = 0, button = 0) => { diff --git a/packages/angular-test/src/text.ts b/packages/angular-test/src/text.ts index 706799830..c59cd1745 100644 --- a/packages/angular-test/src/text.ts +++ b/packages/angular-test/src/text.ts @@ -32,7 +32,7 @@ import { ErrorTestExpectation, getJsonFormsService, TestConfig, - TestData + TestData, } from './util'; interface ComponentResult { @@ -63,333 +63,392 @@ const defaultSchema: JsonSchema = { type: 'object', properties: { foo: { - type: 'string' - } - } + type: 'string', + }, + }, }; const defaultUischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; export const defaultTextTestData: TestData = { data: defaultData, schema: defaultSchema, - uischema: defaultUischema -}; -export const textBaseTest = ( - testConfig: TestConfig, - instance: string, - elementToUse: (element: DebugElement) => any, - testData: TestData = defaultTextTestData -) => () => { - let fixture: ComponentFixture; - let textElement: DebugElement; - let textNativeElement: any; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent( - testConfig, - instance, - elementToUse - ); - fixture = preparedComponents.fixture; - textNativeElement = preparedComponents.textNativeElement; - textElement = preparedComponents.textElement; - component = preparedComponents.component; - }); - - it('should render', () => { - component.uischema = testData.uischema; - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(component.data).toBe('foo'); - expect(textNativeElement.value).toBe('foo'); - expect(textNativeElement.disabled).toBe(false); - // the component is wrapped in a div - const hasDisplayNone = - 'none' === fixture.nativeElement.children[0].style.display; - const hasHidden = fixture.nativeElement.children[0].hidden; - expect(!hasDisplayNone && !hasHidden).toBeTruthy(); - }); - - it('should support updating the state', () => { - component.uischema = testData.uischema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - getJsonFormsService(component).updateCore( - Actions.update('foo', () => 'bar') - ); - fixture.detectChanges(); - expect(component.data).toBe('bar'); - expect(textNativeElement.value).toBe('bar'); - }); - it('should update with undefined value', () => { - component.uischema = testData.uischema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - getJsonFormsService(component).updateCore( - Actions.update('foo', () => undefined) - ); - fixture.detectChanges(); - expect(component.data).toBe(undefined); - expect(textNativeElement.value).toBe(''); - }); - it('should update with null value', () => { - component.uischema = testData.uischema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - getJsonFormsService(component).updateCore( - Actions.update('foo', () => null) - ); - fixture.detectChanges(); - expect(component.data).toBe(null); - expect(textNativeElement.value).toBe(''); - }); - it('should not update with wrong ref', () => { - component.uischema = testData.uischema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - getJsonFormsService(component).updateCore( - Actions.update('foo', () => 'foo') - ); - getJsonFormsService(component).updateCore( - Actions.update('bar', () => 'bar') - ); - fixture.detectChanges(); - expect(component.data).toBe('foo'); - expect(textNativeElement.value).toBe('foo'); - }); - // store needed as we evaluate the calculated enabled value to disable/enable the control - it('can be disabled', () => { - component.uischema = testData.uischema; - component.disabled = true; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(textNativeElement.disabled).toBe(true); - }); - it('can be hidden', () => { - component.uischema = testData.uischema; - component.visible = false; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - const hasDisplayNone = - 'none' === fixture.nativeElement.children[0].style.display; - const hasHidden = fixture.nativeElement.children[0].hidden; - expect(hasDisplayNone || hasHidden).toBeTruthy(); - }); - it('id should be present in output', () => { - component.uischema = testData.uischema; - component.id = 'myId'; - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(textElement.nativeElement.id).toBe('myId'); - }); -}; -export const textInputEventTest = ( - testConfig: TestConfig, - instance: string, - elementToUse: (element: DebugElement) => any, - testData: TestData = defaultTextTestData -) => () => { - let fixture: ComponentFixture; - let textNativeElement: any; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent( - testConfig, - instance, - elementToUse - ); - fixture = preparedComponents.fixture; - textNativeElement = preparedComponents.textNativeElement; - component = preparedComponents.component; - }); - - it('should update via input event', () => { - component.uischema = testData.uischema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: testData.schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - - const spy = spyOn(component, 'onChange'); - textNativeElement.value = 'bar'; - if (textNativeElement.dispatchEvent) { - textNativeElement.dispatchEvent(new Event('input')); - } - // trigger change detection - fixture.detectChanges(); - expect(spy).toHaveBeenCalled(); - expect(textNativeElement.value).toBe('bar'); - }); + uischema: defaultUischema, }; -export const textErrorTest = ( - testConfig: TestConfig, - errorTestInformation: ErrorTestExpectation, - testData: TestData = defaultTextTestData -) => () => { - let fixture: ComponentFixture; - let component: C; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent(testConfig); - fixture = preparedComponents.fixture; - component = preparedComponents.component; - }); - it('should display errors', () => { - component.uischema = testData.uischema; - - const formsService = getJsonFormsService(component); - formsService.init({ - core: { - data: testData.data, - schema: testData.schema, - uischema: undefined - } +export const textBaseTest = + ( + testConfig: TestConfig, + instance: string, + elementToUse: (element: DebugElement) => any, + testData: TestData = defaultTextTestData + ) => + () => { + let fixture: ComponentFixture; + let textElement: DebugElement; + let textNativeElement: any; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent( + testConfig, + instance, + elementToUse + ); + fixture = preparedComponents.fixture; + textNativeElement = preparedComponents.textNativeElement; + textElement = preparedComponents.textElement; + component = preparedComponents.component; + }); + + it('should render', () => { + component.uischema = testData.uischema; + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(component.data).toBe('foo'); + expect(textNativeElement.value).toBe('foo'); + expect(textNativeElement.disabled).toBe(false); + // the component is wrapped in a div + const hasDisplayNone = + 'none' === fixture.nativeElement.children[0].style.display; + const hasHidden = fixture.nativeElement.children[0].hidden; + expect(!hasDisplayNone && !hasHidden).toBeTruthy(); + }); + + it('should support updating the state', () => { + component.uischema = testData.uischema; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + getJsonFormsService(component).updateCore( + Actions.update('foo', () => 'bar') + ); + fixture.detectChanges(); + expect(component.data).toBe('bar'); + expect(textNativeElement.value).toBe('bar'); + }); + it('should update with undefined value', () => { + component.uischema = testData.uischema; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + getJsonFormsService(component).updateCore( + Actions.update('foo', () => undefined) + ); + fixture.detectChanges(); + expect(component.data).toBe(undefined); + expect(textNativeElement.value).toBe(''); + }); + it('should update with null value', () => { + component.uischema = testData.uischema; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + getJsonFormsService(component).updateCore( + Actions.update('foo', () => null) + ); + fixture.detectChanges(); + expect(component.data).toBe(null); + expect(textNativeElement.value).toBe(''); + }); + it('should not update with wrong ref', () => { + component.uischema = testData.uischema; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + getJsonFormsService(component).updateCore( + Actions.update('foo', () => 'foo') + ); + getJsonFormsService(component).updateCore( + Actions.update('bar', () => 'bar') + ); + fixture.detectChanges(); + expect(component.data).toBe('foo'); + expect(textNativeElement.value).toBe('foo'); + }); + // store needed as we evaluate the calculated enabled value to disable/enable the control + it('can be disabled', () => { + component.uischema = testData.uischema; + component.disabled = true; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(textNativeElement.disabled).toBe(true); }); - formsService.updateCore(Actions.updateErrors([ - { - instancePath: '/foo', - message: 'Hi, this is me, test error!', - keyword: '', - schemaPath: '', - params: {} + it('can be hidden', () => { + component.uischema = testData.uischema; + component.visible = false; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + const hasDisplayNone = + 'none' === fixture.nativeElement.children[0].style.display; + const hasHidden = fixture.nativeElement.children[0].hidden; + expect(hasDisplayNone || hasHidden).toBeTruthy(); + }); + it('id should be present in output', () => { + component.uischema = testData.uischema; + component.id = 'myId'; + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(textElement.nativeElement.id).toBe('myId'); + }); + }; +export const textInputEventTest = + ( + testConfig: TestConfig, + instance: string, + elementToUse: (element: DebugElement) => any, + testData: TestData = defaultTextTestData + ) => + () => { + let fixture: ComponentFixture; + let textNativeElement: any; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent( + testConfig, + instance, + elementToUse + ); + fixture = preparedComponents.fixture; + textNativeElement = preparedComponents.textNativeElement; + component = preparedComponents.component; + }); + + it('should update via input event', () => { + component.uischema = testData.uischema; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + + const spy = spyOn(component, 'onChange'); + textNativeElement.value = 'bar'; + if (textNativeElement.dispatchEvent) { + textNativeElement.dispatchEvent(new Event('input')); } - ])); - formsService.refresh(); - component.ngOnInit(); - fixture.detectChanges(); - const debugErrors: DebugElement[] = fixture.debugElement.queryAll( - By.directive(errorTestInformation.errorInstance) - ); - expect(debugErrors.length).toBe(errorTestInformation.numberOfElements); - expect( - debugErrors[errorTestInformation.indexOfElement].nativeElement.textContent - ).toBe('Hi, this is me, test error!'); - }); -}; -export const textTypeTest = ( - testConfig: TestConfig, - instance: string, - elementToUse: (element: DebugElement) => any, - testData: TestData = defaultTextTestData -) => () => { - let fixture: ComponentFixture; - let component: C; - let textNativeElement: any; - - baseSetup(testConfig); - - beforeEach(() => { - const preparedComponents = prepareComponent( - testConfig, - instance, - elementToUse - ); - fixture = preparedComponents.fixture; - component = preparedComponents.component; - textNativeElement = preparedComponents.textNativeElement; - }); - it('should show password independent of schema', () => { - const uischema = JSON.parse(JSON.stringify(testData.uischema)); - uischema.options = { format: 'password' }; - const schema = JSON.parse(JSON.stringify(testData.schema)); - schema.properties.foo.format = 'email'; - - component.uischema = uischema; - component.schema = schema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: schema, uischema: uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(textNativeElement.type).toBe('password'); - }); - it('should show email', () => { - const schema = JSON.parse(JSON.stringify(testData.schema)); - schema.properties.foo.format = 'email'; - - component.uischema = testData.uischema; - component.schema = schema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(textNativeElement.type).toBe('email'); - }); - xit('should show tel', () => { - const schema = JSON.parse(JSON.stringify(testData.schema)); - schema.properties.foo.format = 'tel'; - - component.uischema = testData.uischema; - component.schema = schema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(textNativeElement.type).toBe('tel'); - }); - xit('should fallback to text', () => { - const schema = JSON.parse(JSON.stringify(testData.schema)); - schema.properties.foo.format = 'foo'; - - component.uischema = testData.uischema; - component.schema = schema; - - getJsonFormsService(component).init( - {core: {data: testData.data, schema: schema, uischema: testData.uischema}} - ); - component.ngOnInit(); - fixture.detectChanges(); - expect(textNativeElement.type).toBe('text'); - }); -}; + // trigger change detection + fixture.detectChanges(); + expect(spy).toHaveBeenCalled(); + expect(textNativeElement.value).toBe('bar'); + }); + }; +export const textErrorTest = + ( + testConfig: TestConfig, + errorTestInformation: ErrorTestExpectation, + testData: TestData = defaultTextTestData + ) => + () => { + let fixture: ComponentFixture; + let component: C; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent(testConfig); + fixture = preparedComponents.fixture; + component = preparedComponents.component; + }); + it('should display errors', () => { + component.uischema = testData.uischema; + + const formsService = getJsonFormsService(component); + formsService.init({ + core: { + data: testData.data, + schema: testData.schema, + uischema: undefined, + }, + }); + formsService.updateCore( + Actions.updateErrors([ + { + instancePath: '/foo', + message: 'Hi, this is me, test error!', + keyword: '', + schemaPath: '', + params: {}, + }, + ]) + ); + formsService.refresh(); + component.ngOnInit(); + fixture.detectChanges(); + const debugErrors: DebugElement[] = fixture.debugElement.queryAll( + By.directive(errorTestInformation.errorInstance) + ); + expect(debugErrors.length).toBe(errorTestInformation.numberOfElements); + expect( + debugErrors[errorTestInformation.indexOfElement].nativeElement + .textContent + ).toBe('Hi, this is me, test error!'); + }); + }; +export const textTypeTest = + ( + testConfig: TestConfig, + instance: string, + elementToUse: (element: DebugElement) => any, + testData: TestData = defaultTextTestData + ) => + () => { + let fixture: ComponentFixture; + let component: C; + let textNativeElement: any; + + baseSetup(testConfig); + + beforeEach(() => { + const preparedComponents = prepareComponent( + testConfig, + instance, + elementToUse + ); + fixture = preparedComponents.fixture; + component = preparedComponents.component; + textNativeElement = preparedComponents.textNativeElement; + }); + it('should show password independent of schema', () => { + const uischema = JSON.parse(JSON.stringify(testData.uischema)); + uischema.options = { format: 'password' }; + const schema = JSON.parse(JSON.stringify(testData.schema)); + schema.properties.foo.format = 'email'; + + component.uischema = uischema; + component.schema = schema; + + getJsonFormsService(component).init({ + core: { data: testData.data, schema: schema, uischema: uischema }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(textNativeElement.type).toBe('password'); + }); + it('should show email', () => { + const schema = JSON.parse(JSON.stringify(testData.schema)); + schema.properties.foo.format = 'email'; + + component.uischema = testData.uischema; + component.schema = schema; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(textNativeElement.type).toBe('email'); + }); + xit('should show tel', () => { + const schema = JSON.parse(JSON.stringify(testData.schema)); + schema.properties.foo.format = 'tel'; + + component.uischema = testData.uischema; + component.schema = schema; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(textNativeElement.type).toBe('tel'); + }); + xit('should fallback to text', () => { + const schema = JSON.parse(JSON.stringify(testData.schema)); + schema.properties.foo.format = 'foo'; + + component.uischema = testData.uischema; + component.schema = schema; + + getJsonFormsService(component).init({ + core: { + data: testData.data, + schema: schema, + uischema: testData.uischema, + }, + }); + component.ngOnInit(); + fixture.detectChanges(); + expect(textNativeElement.type).toBe('text'); + }); + }; diff --git a/packages/angular-test/src/util.ts b/packages/angular-test/src/util.ts index da4c1803f..36afc4385 100644 --- a/packages/angular-test/src/util.ts +++ b/packages/angular-test/src/util.ts @@ -28,7 +28,7 @@ import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import type { JsonFormsRendererRegistryEntry, JsonSchema, - UISchemaElement + UISchemaElement, } from '@jsonforms/core'; import type { ErrorObject } from 'ajv'; @@ -50,7 +50,7 @@ export const baseSetup = ( TestBed.configureTestingModule({ declarations: [testConfig.componentUT], imports: testConfig.imports, - providers: [JsonFormsAngularService].concat(testConfig.providers) + providers: [JsonFormsAngularService].concat(testConfig.providers), }).compileComponents(); }); }; @@ -82,8 +82,8 @@ export const setupMockStore = ( data: testData.data, schema: testData.schema, errors: testData.errors, - uischema: testData.uischema - } + uischema: testData.uischema, + }, }); getJsonFormsService(component).registerRenderers(testData.renderers); }; diff --git a/packages/angular-test/tsconfig.json b/packages/angular-test/tsconfig.json index 5c9f3f825..9af7ef8c9 100644 --- a/packages/angular-test/tsconfig.json +++ b/packages/angular-test/tsconfig.json @@ -4,10 +4,6 @@ "outDir": "./lib", "sourceMap": true }, - "exclude":[ - "node_modules" - ], - "files": [ - "./src/index.ts" - ] + "exclude": ["node_modules"], + "files": ["./src/index.ts"] } diff --git a/packages/angular/.eslintrc.js b/packages/angular/.eslintrc.js new file mode 100644 index 000000000..d3d27d3a1 --- /dev/null +++ b/packages/angular/.eslintrc.js @@ -0,0 +1,38 @@ +/* eslint-env node */ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + parserOptions: { + /* Reset project because @angular-eslint/recommended sets this to an incompatible value */ + project: null, + }, + // There is no file include in ESLint. Thus, ignore all and include files via negative ignore (!) + ignorePatterns: ['/*', '!/src', '!/test'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:@angular-eslint/recommended', + 'plugin:@angular-eslint/template/process-inline-templates', + 'plugin:prettier/recommended', + ], + rules: { + '@angular-eslint/component-class-suffix': 'off', + '@angular-eslint/directive-class-suffix': 'off', + '@angular-eslint/no-conflicting-lifecycle': 'warn', + '@typescript-eslint/no-explicit-any': 'off', + 'no-prototype-builtins': 'off', + // Base rule must be disabled to avoid incorrect errors + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', // or "error" + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, +}; diff --git a/packages/angular/.prettierrc.js b/packages/angular/.prettierrc.js new file mode 100644 index 000000000..2c26853c4 --- /dev/null +++ b/packages/angular/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + $schema: 'http://json.schemastore.org/prettierrc', + singleQuote: true, + jsxSingleQuote: true, + endOfLine: 'auto', +}; diff --git a/packages/angular/README.md b/packages/angular/README.md index 1afb1bf33..c71fe53c9 100644 --- a/packages/angular/README.md +++ b/packages/angular/README.md @@ -1,6 +1,6 @@ # JSON Forms - More Forms. Less Code -*Complex forms in the blink of an eye* +_Complex forms in the blink of an eye_ JSON Forms eliminates the tedious task of writing fully-featured forms by hand by leveraging the capabilities of JSON, JSON Schema and Javascript. @@ -20,30 +20,30 @@ Use the `JsonForms` component to render a form for your data. Mandatory props: -* `data: any` - the data to show -* `renderers: JsonFormsRendererRegistryEntry[]` - the Angular renderer set to use +- `data: any` - the data to show +- `renderers: JsonFormsRendererRegistryEntry[]` - the Angular renderer set to use Optional props: -* `schema: JsonSchema` - the data schema for the given data. Will be generated when not given. -* `uischema: UISchemaElement` - the UI schema for the given data schema. Will be generated when not given. -* `config: any` - form-wide options. May contain default ui schema options. -* `readonly: boolean` - whether all controls shall be readonly. -* `uischemas: JsonFormsUiSchemaEntry[]` - registry for dynamic ui schema dispatching -* `validationMode: 'ValidateAndShow' | 'ValidateAndHide' | 'NoValidation'` - the validation mode for the form -* `ajv: AJV` - custom Ajv instance for the form -* `locale` - string, for example for formatting numbers -* `dataChange` - event emitter which is called on each data change, containing the updated data and the validation result. -* `errors` - event emitter which is called with all validations errors. +- `schema: JsonSchema` - the data schema for the given data. Will be generated when not given. +- `uischema: UISchemaElement` - the UI schema for the given data schema. Will be generated when not given. +- `config: any` - form-wide options. May contain default ui schema options. +- `readonly: boolean` - whether all controls shall be readonly. +- `uischemas: JsonFormsUiSchemaEntry[]` - registry for dynamic ui schema dispatching +- `validationMode: 'ValidateAndShow' | 'ValidateAndHide' | 'NoValidation'` - the validation mode for the form +- `ajv: AJV` - custom Ajv instance for the form +- `locale` - string, for example for formatting numbers +- `dataChange` - event emitter which is called on each data change, containing the updated data and the validation result. +- `errors` - event emitter which is called with all validations errors. Example component file `app.component.ts`: ```ts -import { Component } from "@angular/core"; -import { angularMaterialRenderers } from "@jsonforms/angular-material"; +import { Component } from '@angular/core'; +import { angularMaterialRenderers } from '@jsonforms/angular-material'; @Component({ - selector: "app-root", + selector: 'app-root', template: ` /dev/null", - "lint": "tslint --project tsconfig.json --exclude src/models/jsonSchema.ts", + "lint": "eslint .", + "lint:fix": "eslint --fix .", "report": "nyc report --reporter=html", "test": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} ava", "test-cov": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} nyc ava", @@ -67,22 +68,32 @@ "peerDependencies": { "@angular/core": "^12.0.0 || ^13.0.0 || ^14.0.0", "@angular/forms": "^12.0.0 || ^13.0.0 || ^14.0.0", - "@jsonforms/core": "3.1.0-alpha.1", + "@jsonforms/core": "3.1.0-alpha.2", "rxjs": "^6.5.3 || ^7.4.0" }, "devDependencies": { + "@angular-eslint/eslint-plugin": "^12.0.0", + "@angular-eslint/eslint-plugin-template": "^12.0.0", + "@angular-eslint/schematics": "^12.0.0", + "@angular-eslint/template-parser": "^12.0.0", "@angular/compiler": "^12.0.0", "@angular/compiler-cli": "^12.0.0", "@angular/core": "^12.0.0", "@angular/forms": "^12.0.0", - "@jsonforms/core": "^3.1.0-alpha.1", + "@jsonforms/core": "^3.1.0-alpha.2", + "@typescript-eslint/eslint-plugin": "^5.54.1", + "@typescript-eslint/parser": "^5.54.1", "ava": "~2.4.0", "copy-webpack-plugin": "^5.0.5", "cross-env": "^7.0.2", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.7.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", "nyc": "^15.1.0", + "prettier": "^2.8.4", "rimraf": "^3.0.2", "rxjs": "^6.5.3", - "tslint": "^5.20.1", "typedoc": "^0.19.2" } } diff --git a/packages/angular/src/abstract-control.ts b/packages/angular/src/abstract-control.ts index db8841d94..1052c21b8 100644 --- a/packages/angular/src/abstract-control.ts +++ b/packages/angular/src/abstract-control.ts @@ -29,14 +29,14 @@ import { JsonFormsState, JsonSchema, OwnPropsOfControl, - StatePropsOfControl + StatePropsOfControl, } from '@jsonforms/core'; import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormControl, ValidationErrors, - ValidatorFn + ValidatorFn, } from '@angular/forms'; import type { Subscription } from 'rxjs'; @@ -44,11 +44,14 @@ import { JsonFormsBaseRenderer } from './base.renderer'; import { JsonFormsAngularService } from './jsonforms.service'; import merge from 'lodash/merge'; @Component({ - template: '' + template: '', }) export abstract class JsonFormsAbstractControl< - Props extends StatePropsOfControl -> extends JsonFormsBaseRenderer implements OnInit, OnDestroy { + Props extends StatePropsOfControl + > + extends JsonFormsBaseRenderer + implements OnInit, OnDestroy +{ @Input() id: string; @Input() disabled: boolean; @Input() visible: boolean; @@ -70,11 +73,11 @@ export abstract class JsonFormsAbstractControl< this.form = new FormControl( { value: '', - disabled: true + disabled: true, }, { updateOn: 'change', - validators: this.validator.bind(this) + validators: this.validator.bind(this), } ); } @@ -108,7 +111,7 @@ export abstract class JsonFormsAbstractControl< rootSchema, visible, path, - config + config, } = props; this.label = computeLabel( label, @@ -128,7 +131,7 @@ export abstract class JsonFormsAbstractControl< this.form.setValue(data); this.propsPath = path; this.mapAdditionalProps(props); - } + }, }); this.triggerValidation(); } @@ -137,8 +140,7 @@ export abstract class JsonFormsAbstractControl< return this.error ? { error: this.error } : null; }; - // @ts-ignore - mapAdditionalProps(props: Props) { + mapAdditionalProps(_props: Props) { // do nothing by default } @@ -157,7 +159,7 @@ export abstract class JsonFormsAbstractControl< uischema: this.uischema, schema: this.schema, path: this.path, - id: this.id + id: this.id, }; if (this.disabled !== undefined) { props.enabled = !this.disabled; diff --git a/packages/angular/src/array-control.ts b/packages/angular/src/array-control.ts index 3b2a60d18..013f6cd61 100644 --- a/packages/angular/src/array-control.ts +++ b/packages/angular/src/array-control.ts @@ -25,14 +25,15 @@ import { JsonFormsState, mapStateToArrayControlProps, - StatePropsOfArrayControl + StatePropsOfArrayControl, } from '@jsonforms/core'; import type { OnDestroy, OnInit } from '@angular/core'; import { JsonFormsAbstractControl } from './abstract-control'; export class JsonFormsArrayControl extends JsonFormsAbstractControl - implements OnInit, OnDestroy { + implements OnInit, OnDestroy +{ protected mapToProps(state: JsonFormsState): StatePropsOfArrayControl { const props = mapStateToArrayControlProps(state, this.getOwnProps()); return { ...props }; diff --git a/packages/angular/src/base.renderer.ts b/packages/angular/src/base.renderer.ts index 2c080dc67..44ff40172 100644 --- a/packages/angular/src/base.renderer.ts +++ b/packages/angular/src/base.renderer.ts @@ -22,11 +22,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { Directive, Input } from '@angular/core'; +import { Directive, Input } from '@angular/core'; import { JsonSchema, OwnPropsOfRenderer, - UISchemaElement + UISchemaElement, } from '@jsonforms/core'; @Directive() @@ -39,7 +39,7 @@ export class JsonFormsBaseRenderer { return { uischema: this.uischema, schema: this.schema, - path: this.path + path: this.path, }; } } diff --git a/packages/angular/src/control.ts b/packages/angular/src/control.ts index 712bd05aa..80aa16664 100644 --- a/packages/angular/src/control.ts +++ b/packages/angular/src/control.ts @@ -27,14 +27,15 @@ import { mapStateToControlProps, mapStateToControlWithDetailProps, StatePropsOfControl, - StatePropsOfControlWithDetail + StatePropsOfControlWithDetail, } from '@jsonforms/core'; import type { OnDestroy, OnInit } from '@angular/core'; import { JsonFormsAbstractControl } from './abstract-control'; export class JsonFormsControl extends JsonFormsAbstractControl - implements OnInit, OnDestroy { + implements OnInit, OnDestroy +{ protected mapToProps(state: JsonFormsState): StatePropsOfControl { const props = mapStateToControlProps(state, this.getOwnProps()); return { ...props }; @@ -43,7 +44,8 @@ export class JsonFormsControl export class JsonFormsControlWithDetail extends JsonFormsAbstractControl - implements OnInit, OnDestroy { + implements OnInit, OnDestroy +{ protected mapToProps(state: JsonFormsState): StatePropsOfControlWithDetail { const props = mapStateToControlWithDetailProps(state, this.getOwnProps()); return { ...props }; diff --git a/packages/angular/src/jsonforms-root.component.ts b/packages/angular/src/jsonforms-root.component.ts index f38380637..2172a3573 100644 --- a/packages/angular/src/jsonforms-root.component.ts +++ b/packages/angular/src/jsonforms-root.component.ts @@ -23,146 +23,174 @@ THE SOFTWARE. */ import { - Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges + Component, + DoCheck, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, + SimpleChanges, } from '@angular/core'; -import { Actions, JsonFormsI18nState, JsonFormsRendererRegistryEntry, JsonSchema, UISchemaElement, UISchemaTester, ValidationMode } from '@jsonforms/core'; +import { + Actions, + JsonFormsI18nState, + JsonFormsRendererRegistryEntry, + JsonSchema, + UISchemaElement, + UISchemaTester, + ValidationMode, +} from '@jsonforms/core'; import Ajv, { ErrorObject } from 'ajv'; import { JsonFormsAngularService, USE_STATE_VALUE } from './jsonforms.service'; + +// TODO Can this be rewritten to not use DoCheck and OnChanges? +/* eslint-disable @angular-eslint/no-conflicting-lifecycle */ @Component({ - selector: 'jsonforms', - template: '', - providers: [JsonFormsAngularService] + selector: 'jsonforms', + template: '', + providers: [JsonFormsAngularService], }) -export class JsonForms implements OnChanges, OnInit { - - @Input() uischema: UISchemaElement; - @Input() schema: JsonSchema; - @Input() data: any; - @Input() renderers: JsonFormsRendererRegistryEntry[]; - @Input() uischemas: { tester: UISchemaTester; uischema: UISchemaElement; }[]; - @Output() dataChange = new EventEmitter(); - @Input() readonly: boolean; - @Input() validationMode: ValidationMode; - @Input() ajv: Ajv; - @Input() config: any; - @Input() i18n: JsonFormsI18nState; - @Input() additionalErrors: ErrorObject[]; - @Output() errors = new EventEmitter(); - - private previousData:any; - private previousErrors:ErrorObject[]; - - private initialized = false; - oldI18N: JsonFormsI18nState; - - constructor(private jsonformsService: JsonFormsAngularService) { +export class JsonForms implements DoCheck, OnChanges, OnInit { + @Input() uischema: UISchemaElement; + @Input() schema: JsonSchema; + @Input() data: any; + @Input() renderers: JsonFormsRendererRegistryEntry[]; + @Input() uischemas: { tester: UISchemaTester; uischema: UISchemaElement }[]; + @Output() dataChange = new EventEmitter(); + @Input() readonly: boolean; + @Input() validationMode: ValidationMode; + @Input() ajv: Ajv; + @Input() config: any; + @Input() i18n: JsonFormsI18nState; + @Input() additionalErrors: ErrorObject[]; + @Output() errors = new EventEmitter(); + + private previousData: any; + private previousErrors: ErrorObject[]; + + private initialized = false; + oldI18N: JsonFormsI18nState; + + constructor(private jsonformsService: JsonFormsAngularService) {} + + ngOnInit(): void { + this.jsonformsService.init({ + core: { + data: this.data, + uischema: this.uischema, + schema: this.schema, + ajv: this.ajv, + validationMode: this.validationMode, + additionalErrors: this.additionalErrors, + }, + uischemas: this.uischemas, + i18n: this.i18n, + renderers: this.renderers, + config: this.config, + readonly: this.readonly, + }); + this.jsonformsService.$state.subscribe((state) => { + const data = state?.jsonforms?.core?.data; + const errors = state?.jsonforms?.core?.errors; + if (this.previousData !== data) { + this.previousData = data; + this.dataChange.emit(data); + } + if (this.previousErrors !== errors) { + this.previousErrors = errors; + this.errors.emit(errors); + } + }); + this.oldI18N = this.i18n; + this.initialized = true; + } + + ngDoCheck(): void { + // we can't use ngOnChanges as then nested i18n changes will not be detected + // the update will result in a no-op when the parameters did not change + if ( + this.oldI18N?.locale !== this.i18n?.locale || + this.oldI18N?.translate !== this.i18n?.translate || + this.oldI18N?.translateError !== this.i18n?.translateError + ) { + this.jsonformsService.updateI18n( + Actions.updateI18n( + this.oldI18N?.locale === this.i18n?.locale + ? this.jsonformsService.getState().jsonforms.i18n.locale + : this.i18n?.locale, + this.oldI18N?.translate === this.i18n?.translate + ? this.jsonformsService.getState().jsonforms.i18n.translate + : this.i18n?.translate, + this.oldI18N?.translateError === this.i18n?.translateError + ? this.jsonformsService.getState().jsonforms.i18n.translateError + : this.i18n?.translateError + ) + ); + this.oldI18N = this.i18n; + } + } + + ngOnChanges(changes: SimpleChanges): void { + if (!this.initialized) { + return; + } + const newData = changes.data; + const newSchema = changes.schema; + const newUiSchema = changes.uischema; + const newRenderers = changes.renderers; + const newUischemas = changes.uischemas; + const newI18n = changes.i18n; + const newReadonly = changes.readonly; + const newValidationMode = changes.validationMode; + const newAjv = changes.ajv; + const newConfig = changes.config; + const newAdditionalErrors = changes.additionalErrors; + + if ( + newData || + newSchema || + newUiSchema || + newValidationMode || + newAjv || + newAdditionalErrors + ) { + this.jsonformsService.updateCoreState( + newData ? newData.currentValue : USE_STATE_VALUE, + newSchema ? newSchema.currentValue : USE_STATE_VALUE, + newUiSchema ? newUiSchema.currentValue : USE_STATE_VALUE, + newAjv ? newAjv.currentValue : USE_STATE_VALUE, + newValidationMode ? newValidationMode.currentValue : USE_STATE_VALUE, + newAdditionalErrors ? newAdditionalErrors.currentValue : USE_STATE_VALUE + ); + } + + if (newRenderers && !newRenderers.isFirstChange()) { + this.jsonformsService.setRenderers(newRenderers.currentValue); + } + + if (newUischemas && !newUischemas.isFirstChange()) { + this.jsonformsService.setUiSchemas(newUischemas.currentValue); } - ngOnInit(): void { - this.jsonformsService.init({ - core: { - data: this.data, - uischema: this.uischema, - schema: this.schema, - ajv: this.ajv, - validationMode: this.validationMode, - additionalErrors: this.additionalErrors - }, - uischemas: this.uischemas, - i18n: this.i18n, - renderers: this.renderers, - config: this.config, - readonly: this.readonly - }); - this.jsonformsService.$state.subscribe(state => { - const data = state?.jsonforms?.core?.data; - const errors = state?.jsonforms?.core?.errors; - if(this.previousData !== data) { - this.previousData = data; - this.dataChange.emit(data); - } - if(this.previousErrors !== errors) { - this.previousErrors = errors; - this.errors.emit(errors); - } - }); - this.oldI18N = this.i18n; - this.initialized = true; + if (newI18n && !newI18n.isFirstChange()) { + this.jsonformsService.updateI18n( + Actions.updateI18n( + newI18n.currentValue?.locale, + newI18n.currentValue?.translate, + newI18n.currentValue?.translateError + ) + ); } - ngDoCheck(): void { - // we can't use ngOnChanges as then nested i18n changes will not be detected - // the update will result in a no-op when the parameters did not change - if ( - this.oldI18N?.locale !== this.i18n?.locale || - this.oldI18N?.translate !== this.i18n?.translate || - this.oldI18N?.translateError !== this.i18n?.translateError - ) { - this.jsonformsService.updateI18n( - Actions.updateI18n( - this.oldI18N?.locale === this.i18n?.locale - ? this.jsonformsService.getState().jsonforms.i18n.locale - : this.i18n?.locale, - this.oldI18N?.translate === this.i18n?.translate - ? this.jsonformsService.getState().jsonforms.i18n.translate - : this.i18n?.translate, - this.oldI18N?.translateError === this.i18n?.translateError - ? this.jsonformsService.getState().jsonforms.i18n.translateError - : this.i18n?.translateError - ) - ); - this.oldI18N = this.i18n; - } + if (newReadonly && !newReadonly.isFirstChange()) { + this.jsonformsService.setReadonly(newReadonly.currentValue); } - // tslint:disable-next-line: cyclomatic-complexity - ngOnChanges(changes: SimpleChanges): void { - if (!this.initialized) { - return; - } - const newData = changes.data; - const newSchema = changes.schema; - const newUiSchema = changes.uischema; - const newRenderers = changes.renderers; - const newUischemas = changes.uischemas; - const newI18n = changes.i18n; - const newReadonly = changes.readonly; - const newValidationMode = changes.validationMode; - const newAjv = changes.ajv; - const newConfig = changes.config; - const newAdditionalErrors = changes.additionalErrors; - - if (newData || newSchema || newUiSchema || newValidationMode || newAjv || newAdditionalErrors) { - this.jsonformsService.updateCoreState( - newData ? newData.currentValue : USE_STATE_VALUE, - newSchema ? newSchema.currentValue : USE_STATE_VALUE, - newUiSchema ? newUiSchema.currentValue : USE_STATE_VALUE, - newAjv ? newAjv.currentValue : USE_STATE_VALUE, - newValidationMode ? newValidationMode.currentValue : USE_STATE_VALUE, - newAdditionalErrors ? newAdditionalErrors.currentValue : USE_STATE_VALUE - ); - } - - if (newRenderers && !newRenderers.isFirstChange()) { - this.jsonformsService.setRenderers(newRenderers.currentValue); - } - - if (newUischemas && !newUischemas.isFirstChange()) { - this.jsonformsService.setUiSchemas(newUischemas.currentValue); - } - - if (newI18n && !newI18n.isFirstChange()) { - this.jsonformsService.updateI18n( - Actions.updateI18n(newI18n.currentValue?.locale, newI18n.currentValue?.translate, newI18n.currentValue?.translateError) - ); - } - - if (newReadonly && !newReadonly.isFirstChange()) { - this.jsonformsService.setReadonly(newReadonly.currentValue); - } - - if (newConfig && !newConfig.isFirstChange()) { - this.jsonformsService.updateConfig(Actions.setConfig(newConfig.currentValue)); - } + if (newConfig && !newConfig.isFirstChange()) { + this.jsonformsService.updateConfig( + Actions.setConfig(newConfig.currentValue) + ); } + } } diff --git a/packages/angular/src/jsonforms.component.ts b/packages/angular/src/jsonforms.component.ts index 033ea2da8..2ac3014de 100644 --- a/packages/angular/src/jsonforms.component.ts +++ b/packages/angular/src/jsonforms.component.ts @@ -30,7 +30,7 @@ import { OnDestroy, OnInit, Type, - ViewContainerRef + ViewContainerRef, } from '@angular/core'; import { createId, @@ -42,7 +42,7 @@ import { mapStateToJsonFormsRendererProps, OwnPropsOfRenderer, StatePropsOfJsonFormsRenderer, - UISchemaElement + UISchemaElement, } from '@jsonforms/core'; import { UnknownRenderer } from './unknown.component'; import { JsonFormsBaseRenderer } from './base.renderer'; @@ -52,20 +52,27 @@ import { JsonFormsAngularService } from './jsonforms.service'; import { get, isEqual } from 'lodash'; -const areEqual = (prevProps: StatePropsOfJsonFormsRenderer, nextProps: StatePropsOfJsonFormsRenderer) => { - return get(prevProps, 'renderers.length') === get(nextProps, 'renderers.length') - && get(prevProps, 'cells.length') === get(nextProps, 'cells.length') - && get(prevProps, 'uischemas.length') === get(nextProps, 'uischemas.length') - && get(prevProps, 'schema') === get(nextProps, 'schema') - && isEqual(get(prevProps, 'uischema'), get(nextProps, 'uischema')) - && get(prevProps, 'path') === get(nextProps, 'path'); +const areEqual = ( + prevProps: StatePropsOfJsonFormsRenderer, + nextProps: StatePropsOfJsonFormsRenderer +) => { + return ( + get(prevProps, 'renderers.length') === get(nextProps, 'renderers.length') && + get(prevProps, 'cells.length') === get(nextProps, 'cells.length') && + get(prevProps, 'uischemas.length') === get(nextProps, 'uischemas.length') && + get(prevProps, 'schema') === get(nextProps, 'schema') && + isEqual(get(prevProps, 'uischema'), get(nextProps, 'uischema')) && + get(prevProps, 'path') === get(nextProps, 'path') + ); }; @Directive({ - selector: 'jsonforms-outlet' + selector: 'jsonforms-outlet', }) -export class JsonFormsOutlet extends JsonFormsBaseRenderer - implements OnInit, OnDestroy { +export class JsonFormsOutlet + extends JsonFormsBaseRenderer + implements OnInit, OnDestroy +{ private subscription: Subscription; private previousProps: StatePropsOfJsonFormsRenderer; @@ -87,7 +94,7 @@ export class JsonFormsOutlet extends JsonFormsBaseRenderer ngOnInit(): void { this.subscription = this.jsonformsService.$state.subscribe({ - next: (state: JsonFormsState) => this.update(state) + next: (state: JsonFormsState) => this.update(state), }); } @@ -95,7 +102,7 @@ export class JsonFormsOutlet extends JsonFormsBaseRenderer const props = mapStateToJsonFormsRendererProps(state, { schema: this.schema, uischema: this.uischema, - path: this.path + path: this.path, }); if (areEqual(this.previousProps, props)) { return; @@ -107,21 +114,29 @@ export class JsonFormsOutlet extends JsonFormsBaseRenderer const uischema = this.uischema || props.uischema; const testerContext = { rootSchema: props.rootSchema, - config: getConfig(state) + config: getConfig(state), }; - const renderer = maxBy(renderers, r => r.tester(uischema, schema, testerContext)); + const renderer = maxBy(renderers, (r) => + r.tester(uischema, schema, testerContext) + ); let bestComponent: Type = UnknownRenderer; - if (renderer !== undefined && renderer.tester(uischema, schema, testerContext) !== -1) { + if ( + renderer !== undefined && + renderer.tester(uischema, schema, testerContext) !== -1 + ) { bestComponent = renderer.renderer; } - const componentFactory = this.componentFactoryResolver.resolveComponentFactory(bestComponent); + const componentFactory = + this.componentFactoryResolver.resolveComponentFactory(bestComponent); this.viewContainerRef.clear(); - const currentComponentRef = this.viewContainerRef.createComponent(componentFactory); + const currentComponentRef = + this.viewContainerRef.createComponent(componentFactory); if (currentComponentRef.instance instanceof JsonFormsBaseRenderer) { - const instance = currentComponentRef.instance as JsonFormsBaseRenderer; + const instance = + currentComponentRef.instance as JsonFormsBaseRenderer; instance.uischema = uischema; instance.schema = schema; instance.path = this.path; diff --git a/packages/angular/src/jsonforms.module.ts b/packages/angular/src/jsonforms.module.ts index 70226d64b..abc5d256b 100644 --- a/packages/angular/src/jsonforms.module.ts +++ b/packages/angular/src/jsonforms.module.ts @@ -30,6 +30,6 @@ import { UnknownRenderer } from './unknown.component'; @NgModule({ declarations: [JsonFormsOutlet, UnknownRenderer, JsonForms], entryComponents: [UnknownRenderer], - exports: [JsonFormsOutlet, JsonForms] + exports: [JsonFormsOutlet, JsonForms], }) export class JsonFormsModule {} diff --git a/packages/angular/src/jsonforms.service.ts b/packages/angular/src/jsonforms.service.ts index acb18d682..36c3a2624 100644 --- a/packages/angular/src/jsonforms.service.ts +++ b/packages/angular/src/jsonforms.service.ts @@ -23,27 +23,27 @@ THE SOFTWARE. */ import { - Actions, - configReducer, - CoreActions, - coreReducer, - generateDefaultUISchema, - generateJsonSchema, - i18nReducer, - JsonFormsRendererRegistryEntry, - JsonFormsState, - JsonFormsSubStates, - JsonSchema, - I18nActions, - RankedTester, - setConfig, - SetConfigAction, - UISchemaActions, - UISchemaElement, - uischemaRegistryReducer, - UISchemaTester, - ValidationMode, - updateI18n + Actions, + configReducer, + CoreActions, + coreReducer, + generateDefaultUISchema, + generateJsonSchema, + i18nReducer, + JsonFormsRendererRegistryEntry, + JsonFormsState, + JsonFormsSubStates, + JsonSchema, + I18nActions, + RankedTester, + setConfig, + SetConfigAction, + UISchemaActions, + UISchemaElement, + uischemaRegistryReducer, + UISchemaTester, + ValidationMode, + updateI18n, } from '@jsonforms/core'; import { BehaviorSubject, Observable } from 'rxjs'; import type { JsonFormsBaseRenderer } from './base.renderer'; @@ -54,186 +54,257 @@ import type { ErrorObject } from 'ajv'; export const USE_STATE_VALUE = Symbol('Marker to use state value'); export class JsonFormsAngularService { + private _state: JsonFormsSubStates; + private state: BehaviorSubject; - private _state: JsonFormsSubStates; - private state: BehaviorSubject; - - init(initialState: JsonFormsSubStates = { core: { data: undefined, schema: undefined, uischema: undefined, validationMode: 'ValidateAndShow', additionalErrors: undefined } }) { - this._state = initialState; - this._state.config = configReducer(undefined, setConfig(this._state.config)); - this._state.i18n = i18nReducer(this._state.i18n, updateI18n(this._state.i18n?.locale, this._state.i18n?.translate, this._state.i18n?.translateError)); - this.state = new BehaviorSubject({ jsonforms: this._state }); - const data = initialState.core.data; - const schema = initialState.core.schema ?? generateJsonSchema(data); - const uischema = initialState.core.uischema ?? generateDefaultUISchema(schema); - this.updateCore(Actions.init(data, schema, uischema)); + init( + initialState: JsonFormsSubStates = { + core: { + data: undefined, + schema: undefined, + uischema: undefined, + validationMode: 'ValidateAndShow', + additionalErrors: undefined, + }, } + ) { + this._state = initialState; + this._state.config = configReducer( + undefined, + setConfig(this._state.config) + ); + this._state.i18n = i18nReducer( + this._state.i18n, + updateI18n( + this._state.i18n?.locale, + this._state.i18n?.translate, + this._state.i18n?.translateError + ) + ); + this.state = new BehaviorSubject({ jsonforms: this._state }); + const data = initialState.core.data; + const schema = initialState.core.schema ?? generateJsonSchema(data); + const uischema = + initialState.core.uischema ?? generateDefaultUISchema(schema); + this.updateCore(Actions.init(data, schema, uischema)); + } - get $state(): Observable { - if (!this.state) { - throw new Error('Please call init first!'); - } - return this.state.asObservable(); + get $state(): Observable { + if (!this.state) { + throw new Error('Please call init first!'); } + return this.state.asObservable(); + } - /** - * @deprecated use {@link JsonFormsAngularService.addRenderer} - */ - registerRenderer(renderer: JsonFormsBaseRenderer, tester: RankedTester): void { - this.addRenderer(renderer, tester); - } - addRenderer(renderer: JsonFormsBaseRenderer, tester: RankedTester): void { - this._state.renderers.push({ renderer, tester }); - this.updateSubject(); - } + /** + * @deprecated use {@link JsonFormsAngularService.addRenderer} + */ + registerRenderer( + renderer: JsonFormsBaseRenderer, + tester: RankedTester + ): void { + this.addRenderer(renderer, tester); + } + addRenderer( + renderer: JsonFormsBaseRenderer, + tester: RankedTester + ): void { + this._state.renderers.push({ renderer, tester }); + this.updateSubject(); + } - /** - * @deprecated use {@link JsonFormsAngularService.setRenderer} - */ - registerRenderers(renderers: JsonFormsRendererRegistryEntry[]): void { - this.setRenderers(renderers); - } - setRenderers(renderers: JsonFormsRendererRegistryEntry[]): void { - this._state.renderers = renderers; - this.updateSubject(); - } + /** + * @deprecated use {@link JsonFormsAngularService.setRenderer} + */ + registerRenderers(renderers: JsonFormsRendererRegistryEntry[]): void { + this.setRenderers(renderers); + } + setRenderers(renderers: JsonFormsRendererRegistryEntry[]): void { + this._state.renderers = renderers; + this.updateSubject(); + } - /** - * @deprecated use {@link JsonFormsAngularService.removeRenderer} - */ - unregisterRenderer(tester: RankedTester): void { - this.removeRenderer(tester); - } - removeRenderer(tester: RankedTester): void { - const findIndex = this._state.renderers.findIndex(v => v.tester === tester); - if (findIndex === -1) { - return; - } - const renderers = this._state.renderers.filter(v => v.tester !== tester); - this._state.renderers = renderers; - this.updateSubject(); + /** + * @deprecated use {@link JsonFormsAngularService.removeRenderer} + */ + unregisterRenderer(tester: RankedTester): void { + this.removeRenderer(tester); + } + removeRenderer(tester: RankedTester): void { + const findIndex = this._state.renderers.findIndex( + (v) => v.tester === tester + ); + if (findIndex === -1) { + return; } + const renderers = this._state.renderers.filter((v) => v.tester !== tester); + this._state.renderers = renderers; + this.updateSubject(); + } - updateValidationMode(validationMode: ValidationMode): void { - const coreState = coreReducer(this._state.core, Actions.setValidationMode(validationMode)); - this._state.core = coreState; - this.updateSubject(); - } - - updateI18n(i18nAction: T): T { - const i18nState = i18nReducer(this._state.i18n, i18nAction); - if (i18nState !== this._state.i18n) { - this._state.i18n = i18nState; - this.updateSubject(); - } - return i18nAction; - } + updateValidationMode(validationMode: ValidationMode): void { + const coreState = coreReducer( + this._state.core, + Actions.setValidationMode(validationMode) + ); + this._state.core = coreState; + this.updateSubject(); + } - updateCore(coreAction: T): T { - const coreState = coreReducer(this._state.core, coreAction); - if (coreState !== this._state.core) { - this._state.core = coreState; - this.updateSubject(); - } - return coreAction; + updateI18n(i18nAction: T): T { + const i18nState = i18nReducer(this._state.i18n, i18nAction); + if (i18nState !== this._state.i18n) { + this._state.i18n = i18nState; + this.updateSubject(); } + return i18nAction; + } - /** - * @deprecated use {@link JsonFormsAngularService.setUiSchemas} - */ - updateUiSchema(uischemaAction: T): T { - const uischemaState = uischemaRegistryReducer(this._state.uischemas, uischemaAction); - this._state.uischemas = uischemaState; - this.updateSubject(); - return uischemaAction; + updateCore(coreAction: T): T { + const coreState = coreReducer(this._state.core, coreAction); + if (coreState !== this._state.core) { + this._state.core = coreState; + this.updateSubject(); } + return coreAction; + } - setUiSchemas(uischemas: { tester: UISchemaTester; uischema: UISchemaElement; }[]): void { - this._state.uischemas = uischemas; - this.updateSubject(); - } + /** + * @deprecated use {@link JsonFormsAngularService.setUiSchemas} + */ + updateUiSchema(uischemaAction: T): T { + const uischemaState = uischemaRegistryReducer( + this._state.uischemas, + uischemaAction + ); + this._state.uischemas = uischemaState; + this.updateSubject(); + return uischemaAction; + } - updateConfig(setConfigAction: T): T { - const configState = configReducer(this._state.config, setConfigAction); - this._state.config = configState; - this.updateSubject(); - return setConfigAction; - } + setUiSchemas( + uischemas: { tester: UISchemaTester; uischema: UISchemaElement }[] + ): void { + this._state.uischemas = uischemas; + this.updateSubject(); + } - setUiSchema(uischema: UISchemaElement | undefined): void { - const newUiSchema = uischema ?? generateDefaultUISchema(this._state.core.schema); - const coreState = coreReducer(this._state.core, Actions.updateCore(this._state.core.data, this._state.core.schema, newUiSchema)); - if(coreState !== this._state.core) { - this._state.core = coreState; - this.updateSubject(); - } - } + updateConfig(setConfigAction: T): T { + const configState = configReducer(this._state.config, setConfigAction); + this._state.config = configState; + this.updateSubject(); + return setConfigAction; + } - setSchema(schema: JsonSchema | undefined): void { - const coreState = coreReducer(this._state.core, - Actions.updateCore(this._state.core.data, schema ?? generateJsonSchema(this._state.core.data), this._state.core.uischema) - ); - if(coreState !== this._state.core) { - this._state.core = coreState; - this.updateSubject(); - } + setUiSchema(uischema: UISchemaElement | undefined): void { + const newUiSchema = + uischema ?? generateDefaultUISchema(this._state.core.schema); + const coreState = coreReducer( + this._state.core, + Actions.updateCore( + this._state.core.data, + this._state.core.schema, + newUiSchema + ) + ); + if (coreState !== this._state.core) { + this._state.core = coreState; + this.updateSubject(); } + } - setData(data: any): void { - const coreState = coreReducer(this._state.core, Actions.updateCore(data, this._state.core.schema, this._state.core.uischema)); - if(coreState !== this._state.core) { - this._state.core = coreState; - this.updateSubject(); - } + setSchema(schema: JsonSchema | undefined): void { + const coreState = coreReducer( + this._state.core, + Actions.updateCore( + this._state.core.data, + schema ?? generateJsonSchema(this._state.core.data), + this._state.core.uischema + ) + ); + if (coreState !== this._state.core) { + this._state.core = coreState; + this.updateSubject(); } + } - getLocale(): string | undefined { - return this._state.i18n?.locale; + setData(data: any): void { + const coreState = coreReducer( + this._state.core, + Actions.updateCore( + data, + this._state.core.schema, + this._state.core.uischema + ) + ); + if (coreState !== this._state.core) { + this._state.core = coreState; + this.updateSubject(); } + } - setLocale(locale: string): void { - this._state.i18n.locale = locale; - this.updateSubject(); - } + getLocale(): string | undefined { + return this._state.i18n?.locale; + } - setReadonly(readonly: boolean): void { - this._state.readonly = readonly; - this.updateSubject(); - } + setLocale(locale: string): void { + this._state.i18n.locale = locale; + this.updateSubject(); + } - getState(): JsonFormsState { - return cloneDeep({ jsonforms: this._state }); - } + setReadonly(readonly: boolean): void { + this._state.readonly = readonly; + this.updateSubject(); + } - getConfig(): any { - return cloneDeep(this._state.config) - } + getState(): JsonFormsState { + return cloneDeep({ jsonforms: this._state }); + } - refresh(): void { - this.updateSubject(); - } + getConfig(): any { + return cloneDeep(this._state.config); + } - updateCoreState( - data: any | typeof USE_STATE_VALUE, - schema: JsonSchema | typeof USE_STATE_VALUE, - uischema: UISchemaElement | typeof USE_STATE_VALUE, - ajv: Ajv | typeof USE_STATE_VALUE, - validationMode: ValidationMode | typeof USE_STATE_VALUE, - additionalErrors: ErrorObject[] | typeof USE_STATE_VALUE, - ): void { - const newData = data === USE_STATE_VALUE ? this._state.core.data : data; - const newSchema = schema === USE_STATE_VALUE ? this._state.core.schema : schema ?? generateJsonSchema(newData); - const newUischema = uischema === USE_STATE_VALUE ? this._state.core.uischema : uischema ?? generateDefaultUISchema(newSchema); - const newAjv = ajv === USE_STATE_VALUE ? this._state.core.ajv : ajv; - const newValidationMode = validationMode === USE_STATE_VALUE ? this._state.core.validationMode : validationMode; - const newAdditionalErrors = additionalErrors === USE_STATE_VALUE ? this._state.core.additionalErrors : additionalErrors; - this.updateCore( - Actions.updateCore(newData, newSchema, newUischema, {ajv: newAjv, validationMode: newValidationMode, additionalErrors: newAdditionalErrors}) - ); - } + refresh(): void { + this.updateSubject(); + } - private updateSubject(): void { - this.state.next({ jsonforms: this._state }); - } + updateCoreState( + data: any | typeof USE_STATE_VALUE, + schema: JsonSchema | typeof USE_STATE_VALUE, + uischema: UISchemaElement | typeof USE_STATE_VALUE, + ajv: Ajv | typeof USE_STATE_VALUE, + validationMode: ValidationMode | typeof USE_STATE_VALUE, + additionalErrors: ErrorObject[] | typeof USE_STATE_VALUE + ): void { + const newData = data === USE_STATE_VALUE ? this._state.core.data : data; + const newSchema = + schema === USE_STATE_VALUE + ? this._state.core.schema + : schema ?? generateJsonSchema(newData); + const newUischema = + uischema === USE_STATE_VALUE + ? this._state.core.uischema + : uischema ?? generateDefaultUISchema(newSchema); + const newAjv = ajv === USE_STATE_VALUE ? this._state.core.ajv : ajv; + const newValidationMode = + validationMode === USE_STATE_VALUE + ? this._state.core.validationMode + : validationMode; + const newAdditionalErrors = + additionalErrors === USE_STATE_VALUE + ? this._state.core.additionalErrors + : additionalErrors; + this.updateCore( + Actions.updateCore(newData, newSchema, newUischema, { + ajv: newAjv, + validationMode: newValidationMode, + additionalErrors: newAdditionalErrors, + }) + ); + } + private updateSubject(): void { + this.state.next({ jsonforms: this._state }); + } } diff --git a/packages/angular/src/unknown.component.ts b/packages/angular/src/unknown.component.ts index 10c94f05c..cb51fbe01 100644 --- a/packages/angular/src/unknown.component.ts +++ b/packages/angular/src/unknown.component.ts @@ -25,6 +25,6 @@ import { Component } from '@angular/core'; @Component({ selector: 'unknown.renderer', - template: 'No applicable renderer found!' + template: 'No applicable renderer found!', }) export class UnknownRenderer {} diff --git a/packages/angular/test/tsconfig.test.json b/packages/angular/test/tsconfig.test.json index 46da1c60a..8b6cff6dc 100644 --- a/packages/angular/test/tsconfig.test.json +++ b/packages/angular/test/tsconfig.test.json @@ -5,14 +5,7 @@ "target": "es6", "inlineSourceMap": true }, - "include": [ - "**/*.ts", - "**/*.tsx" - ], - "exclude":[ - "node_modules" - ], - "files": [ - "../src/index.ts" - ] + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"], + "files": ["../src/index.ts"] } diff --git a/packages/angular/tsconfig.cjs.json b/packages/angular/tsconfig.cjs.json index b04d624eb..b0c215c3d 100644 --- a/packages/angular/tsconfig.cjs.json +++ b/packages/angular/tsconfig.cjs.json @@ -5,5 +5,5 @@ "sourceMap": true, "target": "es5", "module": "commonjs" - }, + } } diff --git a/packages/core/.eslintrc.js b/packages/core/.eslintrc.js new file mode 100644 index 000000000..dbc146dba --- /dev/null +++ b/packages/core/.eslintrc.js @@ -0,0 +1,36 @@ +/* eslint-env node */ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + // There is no file include in ESLint. Thus, ignore all and include files via negative ignore (!) + ignorePatterns: ['/*', '!/src', '!/test'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:prettier/recommended', + ], + rules: { + // Allow extending interfaces without additional properties to create marker interfaces + '@typescript-eslint/no-empty-interface': [ + 'error', + { + allowSingleExtends: true, + }, + ], + '@typescript-eslint/no-explicit-any': 'off', + 'no-prototype-builtins': 'off', + // Base rule must be disabled to avoid incorrect errors + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, +}; diff --git a/packages/core/.nycrc b/packages/core/.nycrc index beb1ac33c..e960adbe9 100644 --- a/packages/core/.nycrc +++ b/packages/core/.nycrc @@ -1,6 +1,6 @@ { - "extends": "@istanbuljs/nyc-config-typescript", - "lines": 40, - "all": true, - "check-coverage": true + "extends": "@istanbuljs/nyc-config-typescript", + "lines": 40, + "all": true, + "check-coverage": true } diff --git a/packages/core/.prettierrc.js b/packages/core/.prettierrc.js new file mode 100644 index 000000000..2c26853c4 --- /dev/null +++ b/packages/core/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + $schema: 'http://json.schemastore.org/prettierrc', + singleQuote: true, + jsxSingleQuote: true, + endOfLine: 'auto', +}; diff --git a/packages/core/README.md b/packages/core/README.md index ff6dfe8ca..933bfb881 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -1,6 +1,6 @@ # JSON Forms - More Forms. Less Code -*Complex forms in the blink of an eye* +_Complex forms in the blink of an eye_ JSON Forms eliminates the tedious task of writing fully-featured forms by hand by leveraging the capabilities of JSON, JSON Schema and Javascript. @@ -13,6 +13,7 @@ In order to use JSON Forms Core you need to decide which UI framework you would JSON Forms currently supports [React](https://github.com/eclipsesource/jsonforms/blob/master/packages/react), [Angular](https://github.com/eclipsesource/jsonforms/blob/master/packages/angular) and [Vue](https://github.com/eclipsesource/jsonforms/blob/master/packages/vue). The following seeds are available: + - [React Seed](https://github.com/eclipsesource/jsonforms-react-seed) - [Angular Seed](https://github.com/eclipsesource/jsonforms-angular-seed) - [Vue Seed](https://github.com/eclipsesource/jsonforms-vue-seed) @@ -44,7 +45,6 @@ For questions and discussions please use the [JSON Forms board](https://jsonform You can also reach us via [email](mailto:jsonforms@eclipsesource.com?subject=JSON%20Forms). In addition, EclipseSource also offers [professional support](https://jsonforms.io/support) for JSON Forms. - ## Migration -See our [migration guide](https://github.com/eclipsesource/jsonforms/blob/master/MIGRATION.md) when updating JSON Forms. \ No newline at end of file +See our [migration guide](https://github.com/eclipsesource/jsonforms/blob/master/MIGRATION.md) when updating JSON Forms. diff --git a/packages/core/package.json b/packages/core/package.json index f789b0d02..d03683799 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@jsonforms/core", - "version": "3.1.0-alpha.1", + "version": "3.1.0-alpha.2", "description": "Core module of JSON Forms", "repository": "https://github.com/eclipsesource/jsonforms", "bugs": "https://github.com/eclipsesource/jsonforms/issues", @@ -39,7 +39,8 @@ "scripts": { "build": "rollup -c rollup.config.js", "clean": "rimraf -rf lib coverage dist .nyc_output 2> /dev/null", - "lint": "tslint --project tsconfig.json --exclude src/models/jsonSchema.ts", + "lint": "eslint .", + "lint:fix": "eslint --fix .", "report": "nyc report --reporter=html", "test": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\",\\\"target\\\":\\\"es5\\\"} ava", "test-cov": "rimraf -rf .nyc_output && cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\",\\\"target\\\":\\\"es5\\\"} nyc ava", @@ -73,12 +74,19 @@ "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.2", "@types/redux-mock-store": "^1.0.1", + "@typescript-eslint/eslint-plugin": "^5.54.1", + "@typescript-eslint/parser": "^5.54.1", "ava": "~2.4.0", "cross-env": "^7.0.2", "document-register-element": "^1.14.3", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.7.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", "jsdom": "^15.2.1", "jsdom-global": "^3.0.2", "nyc": "^15.1.0", + "prettier": "^2.8.4", "redux": "^4.0.4", "redux-mock-store": "1.5.3", "rimraf": "^3.0.2", @@ -88,7 +96,6 @@ "rollup-plugin-visualizer": "^5.4.1", "source-map-support": "0.5.16", "ts-node": "^10.4.0", - "tslint": "^5.20.1", "typedoc": "^0.19.2", "typescript": "4.2.3" } diff --git a/packages/core/rollup.config.js b/packages/core/rollup.config.js index 1261f27b7..723854467 100644 --- a/packages/core/rollup.config.js +++ b/packages/core/rollup.config.js @@ -6,7 +6,7 @@ const packageJson = require('./package.json'); const baseConfig = { input: 'src/index.ts', - external: [...Object.keys(packageJson.dependencies), /^lodash\/.*/] + external: [...Object.keys(packageJson.dependencies), /^lodash\/.*/], }; export default [ @@ -15,30 +15,30 @@ export default [ output: { file: packageJson.module, format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ typescript(), cleanup({ extensions: ['js', 'ts', 'jsx', 'tsx'] }), - visualizer({ open: false }) - ] + visualizer({ open: false }), + ], }, { ...baseConfig, output: { file: packageJson.main, format: 'cjs', - sourcemap: true + sourcemap: true, }, plugins: [ typescript({ tsconfigOverride: { compilerOptions: { - target: 'ES5' - } - } + target: 'ES5', + }, + }, }), - cleanup({ extensions: ['js', 'ts', 'jsx', 'tsx'] }) - ] - } + cleanup({ extensions: ['js', 'ts', 'jsx', 'tsx'] }), + ], + }, ]; diff --git a/packages/core/src/Helpers.ts b/packages/core/src/Helpers.ts index 8c18a1eb1..e68546efa 100644 --- a/packages/core/src/Helpers.ts +++ b/packages/core/src/Helpers.ts @@ -34,5 +34,5 @@ export const Helpers: { convertToValidClassName(s: string): string; } = { createLabelDescriptionFrom, - convertToValidClassName + convertToValidClassName, }; diff --git a/packages/core/src/actions/actions.ts b/packages/core/src/actions/actions.ts index ede1fb3e0..c167dba19 100644 --- a/packages/core/src/actions/actions.ts +++ b/packages/core/src/actions/actions.ts @@ -32,34 +32,29 @@ import type { RankedTester } from '../testers'; import type { UISchemaTester, ValidationMode } from '../reducers'; import type { ErrorTranslator, Translator } from '../i18n'; -export const INIT: 'jsonforms/INIT' = 'jsonforms/INIT'; -export const UPDATE_CORE: 'jsonforms/UPDATE_CORE' = `jsonforms/UPDATE_CORE`; -export const SET_AJV: 'jsonforms/SET_AJV' = 'jsonforms/SET_AJV'; -export const UPDATE_DATA: 'jsonforms/UPDATE' = 'jsonforms/UPDATE'; -export const UPDATE_ERRORS: 'jsonforms/UPDATE_ERRORS' = - 'jsonforms/UPDATE_ERRORS'; -export const VALIDATE: 'jsonforms/VALIDATE' = 'jsonforms/VALIDATE'; -export const ADD_RENDERER: 'jsonforms/ADD_RENDERER' = 'jsonforms/ADD_RENDERER'; -export const REMOVE_RENDERER: 'jsonforms/REMOVE_RENDERER' = - 'jsonforms/REMOVE_RENDERER'; -export const ADD_CELL: 'jsonforms/ADD_CELL' = 'jsonforms/ADD_CELL'; -export const REMOVE_CELL: 'jsonforms/REMOVE_CELL' = 'jsonforms/REMOVE_CELL'; -export const SET_CONFIG: 'jsonforms/SET_CONFIG' = 'jsonforms/SET_CONFIG'; -export const ADD_UI_SCHEMA: 'jsonforms/ADD_UI_SCHEMA' = `jsonforms/ADD_UI_SCHEMA`; -export const REMOVE_UI_SCHEMA: 'jsonforms/REMOVE_UI_SCHEMA' = `jsonforms/REMOVE_UI_SCHEMA`; -export const SET_SCHEMA: 'jsonforms/SET_SCHEMA' = `jsonforms/SET_SCHEMA`; -export const SET_UISCHEMA: 'jsonforms/SET_UISCHEMA' = `jsonforms/SET_UISCHEMA`; -export const SET_VALIDATION_MODE: 'jsonforms/SET_VALIDATION_MODE' = - 'jsonforms/SET_VALIDATION_MODE'; - -export const SET_LOCALE: 'jsonforms/SET_LOCALE' = `jsonforms/SET_LOCALE`; -export const SET_TRANSLATOR: 'jsonforms/SET_TRANSLATOR' = - 'jsonforms/SET_TRANSLATOR'; -export const UPDATE_I18N: 'jsonforms/UPDATE_I18N' = - 'jsonforms/UPDATE_I18N'; - -export const ADD_DEFAULT_DATA: 'jsonforms/ADD_DEFAULT_DATA' = `jsonforms/ADD_DEFAULT_DATA`; -export const REMOVE_DEFAULT_DATA: 'jsonforms/REMOVE_DEFAULT_DATA' = `jsonforms/REMOVE_DEFAULT_DATA`; +export const INIT = 'jsonforms/INIT' as const; +export const UPDATE_CORE = 'jsonforms/UPDATE_CORE' as const; +export const SET_AJV = 'jsonforms/SET_AJV' as const; +export const UPDATE_DATA = 'jsonforms/UPDATE' as const; +export const UPDATE_ERRORS = 'jsonforms/UPDATE_ERRORS' as const; +export const VALIDATE = 'jsonforms/VALIDATE' as const; +export const ADD_RENDERER = 'jsonforms/ADD_RENDERER' as const; +export const REMOVE_RENDERER = 'jsonforms/REMOVE_RENDERER' as const; +export const ADD_CELL = 'jsonforms/ADD_CELL' as const; +export const REMOVE_CELL = 'jsonforms/REMOVE_CELL' as const; +export const SET_CONFIG = 'jsonforms/SET_CONFIG' as const; +export const ADD_UI_SCHEMA = 'jsonforms/ADD_UI_SCHEMA' as const; +export const REMOVE_UI_SCHEMA = 'jsonforms/REMOVE_UI_SCHEMA' as const; +export const SET_SCHEMA = 'jsonforms/SET_SCHEMA' as const; +export const SET_UISCHEMA = 'jsonforms/SET_UISCHEMA' as const; +export const SET_VALIDATION_MODE = 'jsonforms/SET_VALIDATION_MODE' as const; + +export const SET_LOCALE = 'jsonforms/SET_LOCALE' as const; +export const SET_TRANSLATOR = 'jsonforms/SET_TRANSLATOR' as const; +export const UPDATE_I18N = 'jsonforms/UPDATE_I18N' as const; + +export const ADD_DEFAULT_DATA = 'jsonforms/ADD_DEFAULT_DATA' as const; +export const REMOVE_DEFAULT_DATA = 'jsonforms/REMOVE_DEFAULT_DATA' as const; export type CoreActions = | InitAction @@ -105,8 +100,8 @@ export interface InitActionOptions { } export interface SetValidationModeAction { - type: 'jsonforms/SET_VALIDATION_MODE' - validationMode: ValidationMode + type: 'jsonforms/SET_VALIDATION_MODE'; + validationMode: ValidationMode; } export const init = ( @@ -120,7 +115,7 @@ export const init = ( schema, uischema: typeof uischema === 'object' ? uischema : generateDefaultUISchema(schema), - options + options, }); export const updateCore = ( @@ -133,7 +128,7 @@ export const updateCore = ( data, schema, uischema, - options + options, }); export interface RegisterDefaultDataAction { @@ -145,7 +140,7 @@ export interface RegisterDefaultDataAction { export const registerDefaultData = (schemaPath: string, data: any) => ({ type: ADD_DEFAULT_DATA, schemaPath, - data + data, }); export interface UnregisterDefaultDataAction { @@ -155,7 +150,7 @@ export interface UnregisterDefaultDataAction { export const unregisterDefaultData = (schemaPath: string) => ({ type: REMOVE_DEFAULT_DATA, - schemaPath + schemaPath, }); export interface SetAjvAction { @@ -165,7 +160,7 @@ export interface SetAjvAction { export const setAjv = (ajv: AJV) => ({ type: SET_AJV, - ajv + ajv, }); export const update = ( @@ -174,12 +169,12 @@ export const update = ( ): UpdateAction => ({ type: UPDATE_DATA, path, - updater + updater, }); export const updateErrors = (errors: ErrorObject[]): UpdateErrorsAction => ({ type: UPDATE_ERRORS, - errors + errors, }); export interface AddRendererAction { @@ -191,7 +186,7 @@ export interface AddRendererAction { export const registerRenderer = (tester: RankedTester, renderer: any) => ({ type: ADD_RENDERER, tester, - renderer + renderer, }); export interface AddCellRendererAction { @@ -203,7 +198,7 @@ export interface AddCellRendererAction { export const registerCell = (tester: RankedTester, cell: any) => ({ type: ADD_CELL, tester, - cell + cell, }); export interface RemoveCellRendererAction { @@ -215,7 +210,7 @@ export interface RemoveCellRendererAction { export const unregisterCell = (tester: RankedTester, cell: any) => ({ type: REMOVE_CELL, tester, - cell + cell, }); export interface RemoveRendererAction { @@ -227,7 +222,7 @@ export interface RemoveRendererAction { export const unregisterRenderer = (tester: RankedTester, renderer: any) => ({ type: REMOVE_RENDERER, tester, - renderer + renderer, }); export interface SetConfigAction { @@ -237,13 +232,15 @@ export interface SetConfigAction { export const setConfig = (config: any): SetConfigAction => ({ type: SET_CONFIG, - config + config, }); -export const setValidationMode = (validationMode: ValidationMode): SetValidationModeAction => ({ +export const setValidationMode = ( + validationMode: ValidationMode +): SetValidationModeAction => ({ type: SET_VALIDATION_MODE, - validationMode -}) + validationMode, +}); export type UISchemaActions = AddUISchemaAction | RemoveUISchemaAction; @@ -260,7 +257,7 @@ export const registerUISchema = ( return { type: ADD_UI_SCHEMA, tester, - uischema + uischema, }; }; @@ -274,14 +271,14 @@ export const unregisterUISchema = ( ): RemoveUISchemaAction => { return { type: REMOVE_UI_SCHEMA, - tester + tester, }; }; export type I18nActions = | SetLocaleAction | SetTranslatorAction - | UpdateI18nAction + | UpdateI18nAction; export interface SetLocaleAction { type: 'jsonforms/SET_LOCALE'; @@ -290,7 +287,7 @@ export interface SetLocaleAction { export const setLocale = (locale: string | undefined): SetLocaleAction => ({ type: SET_LOCALE, - locale + locale, }); export interface SetSchemaAction { @@ -300,13 +297,13 @@ export interface SetSchemaAction { export const setSchema = (schema: JsonSchema): SetSchemaAction => ({ type: SET_SCHEMA, - schema + schema, }); export interface SetTranslatorAction { type: 'jsonforms/SET_TRANSLATOR'; translator?: Translator; - errorTranslator?: ErrorTranslator; + errorTranslator?: ErrorTranslator; } export const setTranslator = ( @@ -315,14 +312,14 @@ export const setTranslator = ( ): SetTranslatorAction => ({ type: SET_TRANSLATOR, translator, - errorTranslator + errorTranslator, }); export interface UpdateI18nAction { type: 'jsonforms/UPDATE_I18N'; locale: string | undefined; translator: Translator | undefined; - errorTranslator: ErrorTranslator | undefined; + errorTranslator: ErrorTranslator | undefined; } export const updateI18n = ( @@ -333,7 +330,7 @@ export const updateI18n = ( type: UPDATE_I18N, locale, translator, - errorTranslator + errorTranslator, }); export interface SetUISchemaAction { @@ -343,5 +340,5 @@ export interface SetUISchemaAction { export const setUISchema = (uischema: UISchemaElement): SetUISchemaAction => ({ type: SET_UISCHEMA, - uischema + uischema, }); diff --git a/packages/core/src/configDefault.ts b/packages/core/src/configDefault.ts index fe3eb6bc2..3761c314e 100644 --- a/packages/core/src/configDefault.ts +++ b/packages/core/src/configDefault.ts @@ -44,5 +44,5 @@ export const configDefault = { /* * [text] if asterisks in labels for required fields should be hidden */ - hideRequiredAsterisk: false + hideRequiredAsterisk: false, }; diff --git a/packages/core/src/generators/Generate.ts b/packages/core/src/generators/Generate.ts index 474384284..25a63d500 100644 --- a/packages/core/src/generators/Generate.ts +++ b/packages/core/src/generators/Generate.ts @@ -28,6 +28,8 @@ import { createControlElement, generateDefaultUISchema } from './uischema'; import type { ControlElement, JsonSchema, UISchemaElement } from '../'; export const Generate: { + // TODO fix @typescript-eslint/ban-types + // eslint-disable-next-line @typescript-eslint/ban-types jsonSchema(instance: Object, options?: any): JsonSchema; uiSchema( jsonSchema: JsonSchema, @@ -39,5 +41,5 @@ export const Generate: { } = { jsonSchema: generateJsonSchema, uiSchema: generateDefaultUISchema, - controlElement: createControlElement + controlElement: createControlElement, }; diff --git a/packages/core/src/generators/schema.ts b/packages/core/src/generators/schema.ts index a70f5f73e..ddbf85add 100644 --- a/packages/core/src/generators/schema.ts +++ b/packages/core/src/generators/schema.ts @@ -36,7 +36,7 @@ const distinct = ( ): JsonSchema4[] => { const known: { [property: string]: boolean } = {}; - return properties.filter(item => { + return properties.filter((item) => { const discriminatorValue = discriminator(item); if (known.hasOwnProperty(discriminatorValue)) { return false; @@ -52,12 +52,14 @@ class Gen { private findOption: (props: Properties) => (optionName: string) => any ) {} + // TODO fix @typescript-eslint/ban-types + // eslint-disable-next-line @typescript-eslint/ban-types schemaObject = (data: Object): JsonSchema4 => { const props: Properties = this.properties(data); const schema: JsonSchema4 = { type: 'object', properties: props, - additionalProperties: this.findOption(props)(ADDITIONAL_PROPERTIES) + additionalProperties: this.findOption(props)(ADDITIONAL_PROPERTIES), }; const required = this.findOption(props)(REQUIRED_PROPERTIES); if (required.length > 0) { @@ -111,26 +113,26 @@ class Gen { schemaArray = (data: any[]): JsonSchema4 => { if (data.length > 0) { const allProperties: JsonSchema4[] = data.map(this.property); - const uniqueProperties = distinct(allProperties, prop => + const uniqueProperties = distinct(allProperties, (prop) => JSON.stringify(prop) ); if (uniqueProperties.length === 1) { return { type: 'array', - items: uniqueProperties[0] + items: uniqueProperties[0], }; } else { return { type: 'array', items: { - oneOf: uniqueProperties - } + oneOf: uniqueProperties, + }, }; } } else { return { type: 'array', - items: {} + items: {}, }; } }; @@ -143,29 +145,31 @@ class Gen { * @returns {JsonSchema} the generated schema */ export const generateJsonSchema = ( + // TODO fix @typescript-eslint/ban-types + // eslint-disable-next-line @typescript-eslint/ban-types instance: Object, options: any = {} ): JsonSchema4 => { - const findOption = (props: Properties) => ( - optionName: string - ): boolean | string[] => { - switch (optionName) { - case ADDITIONAL_PROPERTIES: - if (options.hasOwnProperty(ADDITIONAL_PROPERTIES)) { - return options[ADDITIONAL_PROPERTIES]; - } + const findOption = + (props: Properties) => + (optionName: string): boolean | string[] => { + switch (optionName) { + case ADDITIONAL_PROPERTIES: + if (options.hasOwnProperty(ADDITIONAL_PROPERTIES)) { + return options[ADDITIONAL_PROPERTIES]; + } - return true; - case REQUIRED_PROPERTIES: - if (options.hasOwnProperty(REQUIRED_PROPERTIES)) { - return options[REQUIRED_PROPERTIES](props); - } + return true; + case REQUIRED_PROPERTIES: + if (options.hasOwnProperty(REQUIRED_PROPERTIES)) { + return options[REQUIRED_PROPERTIES](props); + } - return Object.keys(props); - default: - return; - } - }; + return Object.keys(props); + default: + return; + } + }; const gen = new Gen(findOption); diff --git a/packages/core/src/generators/uischema.ts b/packages/core/src/generators/uischema.ts index be1164efc..10dea9fbc 100644 --- a/packages/core/src/generators/uischema.ts +++ b/packages/core/src/generators/uischema.ts @@ -33,7 +33,7 @@ import { JsonSchema, LabelElement, Layout, - UISchemaElement + UISchemaElement, } from '../models'; import { deriveTypes, encode, resolveSchema } from '../util'; @@ -44,7 +44,7 @@ import { deriveTypes, encode, resolveSchema } from '../util'; */ const createLayout = (layoutType: string): Layout => ({ type: layoutType, - elements: [] + elements: [], }); /** @@ -52,7 +52,7 @@ const createLayout = (layoutType: string): Layout => ({ */ export const createControlElement = (ref: string): ControlElement => ({ type: 'Control', - scope: ref + scope: ref, }); /** @@ -91,7 +91,7 @@ const addLabel = (layout: Layout, labelName: string) => { // add label with name const label: LabelElement = { type: 'Label', - text: fixedLabel + text: fixedLabel, }; layout.elements.push(label); } @@ -160,7 +160,7 @@ const generateUISchema = ( if (!isEmpty(jsonSchema.properties)) { // traverse properties const nextRef: string = currentRef + '/properties'; - Object.keys(jsonSchema.properties).map(propName => { + Object.keys(jsonSchema.properties).map((propName) => { let value = jsonSchema.properties[propName]; const ref = `${nextRef}/${encode(propName)}`; if (value.$ref !== undefined) { @@ -191,11 +191,12 @@ const generateUISchema = ( /* falls through */ case 'integer': /* falls through */ - case 'boolean': + case 'boolean': { const controlObject: ControlElement = createControlElement(currentRef); schemaElements.push(controlObject); return controlObject; + } default: throw new Error('Unknown type: ' + JSON.stringify(jsonSchema)); } diff --git a/packages/core/src/i18n/arrayTranslations.ts b/packages/core/src/i18n/arrayTranslations.ts new file mode 100644 index 000000000..f5cfee995 --- /dev/null +++ b/packages/core/src/i18n/arrayTranslations.ts @@ -0,0 +1,54 @@ +export interface ArrayDefaultTranslation { + key: ArrayTranslationEnum; + default: (variable?: string) => string; +} + +export enum ArrayTranslationEnum { + addTooltip = 'addTooltip', + addAriaLabel = 'addAriaLabel', + removeTooltip = 'removeTooltip', + upAriaLabel = 'upAriaLabel', + downAriaLabel = 'downAriaLabel', + noSelection = 'noSelection', + removeAriaLabel = 'removeAriaLabel', + noDataMessage = 'noDataMessage', + deleteDialogTitle = 'deleteDialogTitle', + deleteDialogMessage = 'deleteDialogMessage', + deleteDialogAccept = 'deleteDialogAccept', + deleteDialogDecline = 'deleteDialogDecline', + up = 'up', + down = 'down', +} + +export type ArrayTranslations = { + [key in ArrayTranslationEnum]?: string; +}; + +export const arrayDefaultTranslations: ArrayDefaultTranslation[] = [ + { + key: ArrayTranslationEnum.addTooltip, + default: (input) => (input ? `Add to ${input}` : 'Add'), + }, + { + key: ArrayTranslationEnum.addAriaLabel, + default: (input) => (input ? `Add to ${input} button` : 'Add button'), + }, + { key: ArrayTranslationEnum.removeTooltip, default: () => 'Delete' }, + { key: ArrayTranslationEnum.removeAriaLabel, default: () => 'Delete button' }, + { key: ArrayTranslationEnum.upAriaLabel, default: () => `Move item up` }, + { key: ArrayTranslationEnum.up, default: () => 'Up' }, + { key: ArrayTranslationEnum.down, default: () => 'Down' }, + { key: ArrayTranslationEnum.downAriaLabel, default: () => `Move item down` }, + { key: ArrayTranslationEnum.noDataMessage, default: () => 'No data' }, + { key: ArrayTranslationEnum.noSelection, default: () => 'No selection' }, + { + key: ArrayTranslationEnum.deleteDialogTitle, + default: () => 'Confirm Deletion', + }, + { + key: ArrayTranslationEnum.deleteDialogMessage, + default: () => 'Are you sure you want to delete the selected entry?', + }, + { key: ArrayTranslationEnum.deleteDialogAccept, default: () => 'Yes' }, + { key: ArrayTranslationEnum.deleteDialogDecline, default: () => 'No' }, +]; diff --git a/packages/core/src/i18n/i18nTypes.ts b/packages/core/src/i18n/i18nTypes.ts index f9aca1fe6..64002f393 100644 --- a/packages/core/src/i18n/i18nTypes.ts +++ b/packages/core/src/i18n/i18nTypes.ts @@ -2,12 +2,16 @@ import type { ErrorObject } from 'ajv'; import type { JsonSchema, UISchemaElement } from '../models'; export type Translator = { - (id: string, defaultMessage: string, values?: any): string; - (id: string, defaultMessage: undefined, values?: any): string | undefined; - (id: string, defaultMessage?: string, values?: any): string | undefined; -} + (id: string, defaultMessage: string, values?: any): string; + (id: string, defaultMessage: undefined, values?: any): string | undefined; + (id: string, defaultMessage?: string, values?: any): string | undefined; +}; -export type ErrorTranslator = (error: ErrorObject, translate: Translator, uischema?: UISchemaElement) => string; +export type ErrorTranslator = ( + error: ErrorObject, + translate: Translator, + uischema?: UISchemaElement +) => string; export interface JsonFormsI18nState { locale?: string; @@ -15,4 +19,4 @@ export interface JsonFormsI18nState { translateError?: ErrorTranslator; } -export type i18nJsonSchema = JsonSchema & {i18n?: string}; +export type i18nJsonSchema = JsonSchema & { i18n?: string }; diff --git a/packages/core/src/i18n/i18nUtil.ts b/packages/core/src/i18n/i18nUtil.ts index ee24eef58..26ba88941 100644 --- a/packages/core/src/i18n/i18nUtil.ts +++ b/packages/core/src/i18n/i18nUtil.ts @@ -3,6 +3,10 @@ import { isInternationalized, Labelable, UISchemaElement } from '../models'; import { getControlPath } from '../reducers'; import { formatErrorMessage } from '../util'; import type { i18nJsonSchema, ErrorTranslator, Translator } from './i18nTypes'; +import { + ArrayDefaultTranslation, + ArrayTranslations, +} from './arrayTranslations'; export const getI18nKeyPrefixBySchema = ( schema: i18nJsonSchema | undefined, @@ -22,7 +26,7 @@ export const transformPathToI18nPrefix = (path: string): string => { return ( path ?.split('.') - .filter(segment => !/^\d+$/.test(segment)) + .filter((segment) => !/^\d+$/.test(segment)) .join('.') || 'root' ); }; @@ -47,7 +51,17 @@ export const getI18nKey = ( return `${getI18nKeyPrefix(schema, uischema, path)}.${key}`; }; -export const defaultTranslator: Translator = (_id: string, defaultMessage: string | undefined) => defaultMessage; +export const addI18nKeyToPrefix = ( + i18nKeyPrefix: string, + key: string +): string => { + return `${i18nKeyPrefix}.${key}`; +}; + +export const defaultTranslator: Translator = ( + _id: string, + defaultMessage: string | undefined +) => defaultMessage; export const defaultErrorTranslator: ErrorTranslator = (error, t, uischema) => { // check whether there is a special keyword message @@ -57,13 +71,15 @@ export const defaultErrorTranslator: ErrorTranslator = (error, t, uischema) => { getControlPath(error), `error.${error.keyword}` ); - const specializedKeywordMessage = t(i18nKey, undefined, { error } ); + const specializedKeywordMessage = t(i18nKey, undefined, { error }); if (specializedKeywordMessage !== undefined) { return specializedKeywordMessage; } // check whether there is a generic keyword message - const genericKeywordMessage = t(`error.${error.keyword}`, undefined, { error }); + const genericKeywordMessage = t(`error.${error.keyword}`, undefined, { + error, + }); if (genericKeywordMessage !== undefined) { return genericKeywordMessage; } @@ -75,7 +91,10 @@ export const defaultErrorTranslator: ErrorTranslator = (error, t, uischema) => { } // rewrite required property messages (if they were not customized) as we place them next to the respective input - if (error.keyword === 'required' && error.message?.startsWith('must have required property')) { + if ( + error.keyword === 'required' && + error.message?.startsWith('must have required property') + ) { return t('is a required property', 'is a required property', { error }); } @@ -97,29 +116,60 @@ export const getCombinedErrorMessage = ( if (errors.length > 0 && t) { // check whether there is a special message which overwrites all others const customErrorKey = getI18nKey(schema, uischema, path, 'error.custom'); - const specializedErrorMessage = t(customErrorKey, undefined, {schema, uischema, path, errors}); + const specializedErrorMessage = t(customErrorKey, undefined, { + schema, + uischema, + path, + errors, + }); if (specializedErrorMessage !== undefined) { return specializedErrorMessage; } } - return formatErrorMessage( - errors.map(error => et(error, t, uischema)) - ); + return formatErrorMessage(errors.map((error) => et(error, t, uischema))); }; /** * This can be used to internationalize the label of the given Labelable (e.g. UI Schema elements). * This should not be used for controls as there we have additional context in the form of the JSON Schema available. */ -export const deriveLabelForUISchemaElement = (uischema: Labelable, t: Translator): string | undefined => { +export const deriveLabelForUISchemaElement = ( + uischema: Labelable, + t: Translator +): string | undefined => { if (uischema.label === false) { return undefined; } - if ((uischema.label === undefined || uischema.label === null || uischema.label === true) && !isInternationalized(uischema)) { + if ( + (uischema.label === undefined || + uischema.label === null || + uischema.label === true) && + !isInternationalized(uischema) + ) { return undefined; } - const stringifiedLabel = typeof uischema.label === 'string' ? uischema.label : JSON.stringify(uischema.label); + const stringifiedLabel = + typeof uischema.label === 'string' + ? uischema.label + : JSON.stringify(uischema.label); const i18nKeyPrefix = getI18nKeyPrefixBySchema(undefined, uischema); - const i18nKey = typeof i18nKeyPrefix === 'string' ? `${i18nKeyPrefix}.label` : stringifiedLabel; + const i18nKey = + typeof i18nKeyPrefix === 'string' + ? `${i18nKeyPrefix}.label` + : stringifiedLabel; return t(i18nKey, stringifiedLabel, { uischema: uischema }); -} +}; + +export const getArrayTranslations = ( + t: Translator, + defaultTranslations: ArrayDefaultTranslation[], + i18nKeyPrefix: string, + label: string +): ArrayTranslations => { + const translations: ArrayTranslations = {}; + defaultTranslations.forEach((controlElement) => { + const key = addI18nKeyToPrefix(i18nKeyPrefix, controlElement.key); + translations[controlElement.key] = t(key, controlElement.default(label)); + }); + return translations; +}; diff --git a/packages/core/src/i18n/index.ts b/packages/core/src/i18n/index.ts index 298d5f4d5..987aa3611 100644 --- a/packages/core/src/i18n/index.ts +++ b/packages/core/src/i18n/index.ts @@ -1,2 +1,3 @@ export * from './i18nTypes'; export * from './i18nUtil'; +export * from './arrayTranslations'; diff --git a/packages/core/src/models/draft4.ts b/packages/core/src/models/draft4.ts index 5d165f24e..7612ed741 100644 --- a/packages/core/src/models/draft4.ts +++ b/packages/core/src/models/draft4.ts @@ -31,14 +31,14 @@ export const Draft4 = { schemaArray: { type: 'array', minItems: 1, - items: { $ref: '#' } + items: { $ref: '#' }, }, positiveInteger: { type: 'integer', - minimum: 0 + minimum: 0, }, positiveIntegerDefault0: { - allOf: [{ $ref: '#/definitions/positiveInteger' }, { default: 0 }] + allOf: [{ $ref: '#/definitions/positiveInteger' }, { default: 0 }], }, simpleTypes: { enum: [ @@ -48,104 +48,104 @@ export const Draft4 = { 'null', 'number', 'object', - 'string' - ] + 'string', + ], }, stringArray: { type: 'array', items: { type: 'string' }, minItems: 1, - uniqueItems: true - } + uniqueItems: true, + }, }, type: 'object', properties: { id: { type: 'string', - format: 'uri' + format: 'uri', }, $schema: { type: 'string', - format: 'uri' + format: 'uri', }, title: { - type: 'string' + type: 'string', }, description: { - type: 'string' + type: 'string', }, default: {}, multipleOf: { type: 'number', minimum: 0, - exclusiveMinimum: true + exclusiveMinimum: true, }, maximum: { - type: 'number' + type: 'number', }, exclusiveMaximum: { type: 'boolean', - default: false + default: false, }, minimum: { - type: 'number' + type: 'number', }, exclusiveMinimum: { type: 'boolean', - default: false + default: false, }, maxLength: { $ref: '#/definitions/positiveInteger' }, minLength: { $ref: '#/definitions/positiveIntegerDefault0' }, pattern: { type: 'string', - format: 'regex' + format: 'regex', }, additionalItems: { anyOf: [{ type: 'boolean' }, { $ref: '#' }], - default: {} + default: {}, }, items: { anyOf: [{ $ref: '#' }, { $ref: '#/definitions/schemaArray' }], - default: {} + default: {}, }, maxItems: { $ref: '#/definitions/positiveInteger' }, minItems: { $ref: '#/definitions/positiveIntegerDefault0' }, uniqueItems: { type: 'boolean', - default: false + default: false, }, maxProperties: { $ref: '#/definitions/positiveInteger' }, minProperties: { $ref: '#/definitions/positiveIntegerDefault0' }, required: { $ref: '#/definitions/stringArray' }, additionalProperties: { anyOf: [{ type: 'boolean' }, { $ref: '#' }], - default: {} + default: {}, }, definitions: { type: 'object', additionalProperties: { $ref: '#' }, - default: {} + default: {}, }, properties: { type: 'object', additionalProperties: { $ref: '#' }, - default: {} + default: {}, }, patternProperties: { type: 'object', additionalProperties: { $ref: '#' }, - default: {} + default: {}, }, dependencies: { type: 'object', additionalProperties: { - anyOf: [{ $ref: '#' }, { $ref: '#/definitions/stringArray' }] - } + anyOf: [{ $ref: '#' }, { $ref: '#/definitions/stringArray' }], + }, }, enum: { type: 'array', minItems: 1, - uniqueItems: true + uniqueItems: true, }, type: { anyOf: [ @@ -154,18 +154,18 @@ export const Draft4 = { type: 'array', items: { $ref: '#/definitions/simpleTypes' }, minItems: 1, - uniqueItems: true - } - ] + uniqueItems: true, + }, + ], }, allOf: { $ref: '#/definitions/schemaArray' }, anyOf: { $ref: '#/definitions/schemaArray' }, oneOf: { $ref: '#/definitions/schemaArray' }, - not: { $ref: '#' } + not: { $ref: '#' }, }, dependencies: { exclusiveMaximum: ['maximum'], - exclusiveMinimum: ['minimum'] + exclusiveMinimum: ['minimum'], }, - default: {} + default: {}, }; diff --git a/packages/core/src/models/uischema.ts b/packages/core/src/models/uischema.ts index 09ba7b605..bde29ba2e 100644 --- a/packages/core/src/models/uischema.ts +++ b/packages/core/src/models/uischema.ts @@ -54,7 +54,7 @@ export interface Labelable { /** * Label for UI schema element. */ - label?: string|T; + label?: string | T; } /** @@ -108,7 +108,7 @@ export enum RuleEffect { /** * Effect that disables the associated element. */ - DISABLE = 'DISABLE' + DISABLE = 'DISABLE', } /** @@ -240,7 +240,11 @@ export interface LabelElement extends UISchemaElement, Internationalizable { * A control element. The scope property of the control determines * to which part of the schema the control should be bound. */ -export interface ControlElement extends UISchemaElement, Scoped, Labelable, Internationalizable { +export interface ControlElement + extends UISchemaElement, + Scoped, + Labelable, + Internationalizable { type: 'Control'; } @@ -256,7 +260,10 @@ export interface Category extends Layout, Labeled, Internationalizable { * A child element may either be itself a Categorization or a Category, hence * the categorization element can be used to represent recursive structures like trees. */ -export interface Categorization extends UISchemaElement, Labeled, Internationalizable { +export interface Categorization + extends UISchemaElement, + Labeled, + Internationalizable { type: 'Categorization'; /** * The child elements of this categorization which are either of type @@ -265,8 +272,12 @@ export interface Categorization extends UISchemaElement, Labeled, Internationali elements: (Category | Categorization)[]; } -export const isInternationalized = (element: unknown): element is Required => - typeof element === 'object' && element !== null && typeof (element as Internationalizable).i18n === 'string'; +export const isInternationalized = ( + element: unknown +): element is Required => + typeof element === 'object' && + element !== null && + typeof (element as Internationalizable).i18n === 'string'; export const isGroup = (layout: Layout): layout is GroupLayout => layout.type === 'Group'; diff --git a/packages/core/src/reducers/cells.ts b/packages/core/src/reducers/cells.ts index 01d033663..9e9119686 100644 --- a/packages/core/src/reducers/cells.ts +++ b/packages/core/src/reducers/cells.ts @@ -28,28 +28,29 @@ import { ADD_CELL, AddCellRendererAction, REMOVE_CELL, - RemoveCellRendererAction + RemoveCellRendererAction, } from '../actions'; import type { Reducer } from '../util'; type ValidCellReducerActions = AddCellRendererAction | RemoveCellRendererAction; -export type JsonFormsCellRendererRegistryState = JsonFormsCellRendererRegistryEntry[]; +export type JsonFormsCellRendererRegistryState = + JsonFormsCellRendererRegistryEntry[]; export interface JsonFormsCellRendererRegistryEntry { tester: RankedTester; cell: any; } -export const cellReducer: Reducer = ( - state = [], - { type, tester, cell } -) => { +export const cellReducer: Reducer< + JsonFormsCellRendererRegistryState, + ValidCellReducerActions +> = (state = [], { type, tester, cell }) => { switch (type) { case ADD_CELL: return state.concat([{ tester, cell }]); case REMOVE_CELL: - return state.filter(t => t.tester !== tester); + return state.filter((t) => t.tester !== tester); default: return state; } diff --git a/packages/core/src/reducers/core.ts b/packages/core/src/reducers/core.ts index d5f695ee3..0459889bb 100644 --- a/packages/core/src/reducers/core.ts +++ b/packages/core/src/reducers/core.ts @@ -43,12 +43,15 @@ import { UPDATE_DATA, UPDATE_ERRORS, UPDATE_CORE, - UpdateCoreAction + UpdateCoreAction, } from '../actions'; import { createAjv, Reducer } from '../util'; import type { JsonSchema, UISchemaElement } from '../models'; -export const validate = (validator: ValidateFunction | undefined, data: any): ErrorObject[] => { +export const validate = ( + validator: ValidateFunction | undefined, + data: any +): ErrorObject[] => { if (validator === undefined) { return []; } @@ -59,7 +62,10 @@ export const validate = (validator: ValidateFunction | undefined, data: any): Er return validator.errors; }; -export type ValidationMode = 'ValidateAndShow' | 'ValidateAndHide' | 'NoValidation'; +export type ValidationMode = + | 'ValidateAndShow' + | 'ValidateAndHide' + | 'NoValidation'; export interface JsonFormsCore { data: any; @@ -80,7 +86,7 @@ const initState: JsonFormsCore = { validator: undefined, ajv: undefined, validationMode: 'ValidateAndShow', - additionalErrors: [] + additionalErrors: [], }; const reuseAjvForSchema = (ajv: Ajv, schema: JsonSchema): Ajv => { @@ -90,14 +96,15 @@ const reuseAjvForSchema = (ajv: Ajv, schema: JsonSchema): Ajv => { return ajv; }; -const getOrCreateAjv = (state: JsonFormsCore, action?: InitAction | UpdateCoreAction): Ajv => { +const getOrCreateAjv = ( + state: JsonFormsCore, + action?: InitAction | UpdateCoreAction +): Ajv => { if (action) { if (hasAjvOption(action.options)) { // options object with ajv return action.options.ajv; - } else if ( - action.options !== undefined - ) { + } else if (action.options !== undefined) { // it is not an option object => should be ajv itself => check for compile function if (isFunction(action.options.compile)) { return action.options; @@ -136,7 +143,9 @@ const hasValidationModeOption = (option: any): option is InitActionOptions => { return false; }; -const hasAdditionalErrorsOption = (option: any): option is InitActionOptions => { +const hasAdditionalErrorsOption = ( + option: any +): option is InitActionOptions => { if (option) { return option.additionalErrors !== undefined; } @@ -153,7 +162,6 @@ const getAdditionalErrors = ( return state.additionalErrors; }; -// tslint:disable-next-line: cyclomatic-complexity export const coreReducer: Reducer = ( state = initState, action @@ -163,7 +171,10 @@ export const coreReducer: Reducer = ( const thisAjv = getOrCreateAjv(state, action); const validationMode = getValidationMode(state, action); - const v = validationMode === 'NoValidation' ? undefined : thisAjv.compile(action.schema); + const v = + validationMode === 'NoValidation' + ? undefined + : thisAjv.compile(action.schema); const e = validate(v, action.data); const additionalErrors = getAdditionalErrors(state, action); @@ -208,7 +219,7 @@ export const coreReducer: Reducer = ( state.errors !== errors || state.validator !== validator || state.validationMode !== validationMode || - state.additionalErrors !== additionalErrors + state.additionalErrors !== additionalErrors; return stateChanged ? { ...state, @@ -219,22 +230,26 @@ export const coreReducer: Reducer = ( errors: isEqual(errors, state.errors) ? state.errors : errors, validator: validator, validationMode: validationMode, - additionalErrors + additionalErrors, } : state; } case SET_AJV: { const currentAjv = action.ajv; - const validator = state.validationMode === 'NoValidation' ? undefined : currentAjv.compile(state.schema); + const validator = + state.validationMode === 'NoValidation' + ? undefined + : currentAjv.compile(state.schema); const errors = validate(validator, state.data); return { ...state, validator, - errors + errors, }; } case SET_SCHEMA: { - const needsNewValidator = action.schema && state.ajv && state.validationMode !== 'NoValidation'; + const needsNewValidator = + action.schema && state.ajv && state.validationMode !== 'NoValidation'; const v = needsNewValidator ? reuseAjvForSchema(state.ajv, action.schema).compile(action.schema) : state.validator; @@ -243,13 +258,13 @@ export const coreReducer: Reducer = ( ...state, validator: v, schema: action.schema, - errors + errors, }; } case SET_UISCHEMA: { return { ...state, - uischema: action.uischema + uischema: action.uischema, }; } case UPDATE_DATA: { @@ -262,7 +277,7 @@ export const coreReducer: Reducer = ( return { ...state, data: result, - errors + errors, }; } else { const oldData: any = get(state.data, action.path); @@ -276,14 +291,14 @@ export const coreReducer: Reducer = ( return { ...state, data: newState, - errors + errors, }; } } case UPDATE_ERRORS: { return { ...state, - errors: action.errors + errors: action.errors, }; } case SET_VALIDATION_MODE: { @@ -295,22 +310,24 @@ export const coreReducer: Reducer = ( return { ...state, errors, - validationMode: action.validationMode + validationMode: action.validationMode, }; } if (state.validationMode === 'NoValidation') { - const validator = reuseAjvForSchema(state.ajv, state.schema).compile(state.schema); + const validator = reuseAjvForSchema(state.ajv, state.schema).compile( + state.schema + ); const errors = validate(validator, state.data); return { ...state, validator, errors, - validationMode: action.validationMode + validationMode: action.validationMode, }; } return { ...state, - validationMode: action.validationMode + validationMode: action.validationMode, }; } default: @@ -342,62 +359,67 @@ export const getControlPath = (error: ErrorObject) => { return dataPath.replace(/\//g, '.').substr(1); } // dataPath was renamed to instancePath in AJV v8 - var controlPath: string = error.instancePath; + let controlPath: string = error.instancePath; // change '/' chars to '.' controlPath = controlPath.replace(/\//g, '.'); - + const invalidProperty = getInvalidProperty(error); if (invalidProperty !== undefined && !controlPath.endsWith(invalidProperty)) { controlPath = `${controlPath}.${invalidProperty}`; } - + // remove '.' chars at the beginning of paths controlPath = controlPath.replace(/^./, ''); return controlPath; -} +}; -export const errorsAt = ( - instancePath: string, - schema: JsonSchema, - matchPath: (path: string) => boolean -) => (errors: ErrorObject[]): ErrorObject[] => { - // Get data paths of oneOf and anyOf errors to later determine whether an error occurred inside a subschema of oneOf or anyOf. - const combinatorPaths = filter( - errors, - error => error.keyword === 'oneOf' || error.keyword === 'anyOf' - ).map(error => getControlPath(error)); - - return filter(errors, error => { +export const errorsAt = + ( + instancePath: string, + schema: JsonSchema, + matchPath: (path: string) => boolean + ) => + (errors: ErrorObject[]): ErrorObject[] => { + // Get data paths of oneOf and anyOf errors to later determine whether an error occurred inside a subschema of oneOf or anyOf. + const combinatorPaths = filter( + errors, + (error) => error.keyword === 'oneOf' || error.keyword === 'anyOf' + ).map((error) => getControlPath(error)); + + return filter(errors, (error) => { // Filter errors that match any keyword that we don't want to show in the UI if (filteredErrorKeywords.indexOf(error.keyword) !== -1) { return false; } - const controlPath = getControlPath(error); - let result = matchPath(controlPath); - // In anyOf and oneOf blocks with "primitive" (i.e. string, number etc.) or array subschemas, - // we want to make sure that errors are only shown for the correct subschema. - // Therefore, we compare the error's parent schema with the property's schema. - // In the primitive case the error's data path is the same for all subschemas: - // It directly points to the property defining the anyOf/oneOf. - // The same holds true for errors on the array level (e.g. min item amount). - // In contrast, this comparison must not be done for errors whose parent schema defines an object - // because the parent schema can never match the property schema (e.g. for 'required' checks). - const parentSchema: JsonSchema | undefined = error.parentSchema; - if (result && !isObjectSchema(parentSchema) - && combinatorPaths.findIndex(p => instancePath.startsWith(p)) !== -1) { - result = result && isEqual(parentSchema, schema); - } - return result; - }); -}; + const controlPath = getControlPath(error); + let result = matchPath(controlPath); + // In anyOf and oneOf blocks with "primitive" (i.e. string, number etc.) or array subschemas, + // we want to make sure that errors are only shown for the correct subschema. + // Therefore, we compare the error's parent schema with the property's schema. + // In the primitive case the error's data path is the same for all subschemas: + // It directly points to the property defining the anyOf/oneOf. + // The same holds true for errors on the array level (e.g. min item amount). + // In contrast, this comparison must not be done for errors whose parent schema defines an object + // because the parent schema can never match the property schema (e.g. for 'required' checks). + const parentSchema: JsonSchema | undefined = error.parentSchema; + if ( + result && + !isObjectSchema(parentSchema) && + combinatorPaths.findIndex((p) => instancePath.startsWith(p)) !== -1 + ) { + result = result && isEqual(parentSchema, schema); + } + return result; + }); + }; /** * @returns true if the schema describes an object. */ const isObjectSchema = (schema?: JsonSchema): boolean => { return schema?.type === 'object' || !!schema?.properties; -} +}; /** * The error-type of an AJV error is defined by its `keyword` property. @@ -410,19 +432,36 @@ const isObjectSchema = (schema?: JsonSchema): boolean => { * - anyOf: Indicates that an anyOf definition itself is not valid because none of its subschemas matches. * - oneOf: Indicates that an oneOf definition itself is not valid because not exactly one of its subschemas matches. */ -const filteredErrorKeywords = ['additionalProperties', 'allOf', 'anyOf', 'oneOf']; - -const getErrorsAt = ( - instancePath: string, - schema: JsonSchema, - matchPath: (path: string) => boolean -) => (state: JsonFormsCore): ErrorObject[] => { - const errors = state.errors ?? []; - const additionalErrors = state.additionalErrors ?? []; - return errorsAt(instancePath, schema, matchPath)(state.validationMode === 'ValidateAndHide' ? additionalErrors : [...errors, ...additionalErrors]); -} +const filteredErrorKeywords = [ + 'additionalProperties', + 'allOf', + 'anyOf', + 'oneOf', +]; + +const getErrorsAt = + ( + instancePath: string, + schema: JsonSchema, + matchPath: (path: string) => boolean + ) => + (state: JsonFormsCore): ErrorObject[] => { + const errors = state.errors ?? []; + const additionalErrors = state.additionalErrors ?? []; + return errorsAt( + instancePath, + schema, + matchPath + )( + state.validationMode === 'ValidateAndHide' + ? additionalErrors + : [...errors, ...additionalErrors] + ); + }; export const errorAt = (instancePath: string, schema: JsonSchema) => - getErrorsAt(instancePath, schema, path => path === instancePath); + getErrorsAt(instancePath, schema, (path) => path === instancePath); export const subErrorsAt = (instancePath: string, schema: JsonSchema) => - getErrorsAt(instancePath, schema, path => path.startsWith(instancePath + '.')); + getErrorsAt(instancePath, schema, (path) => + path.startsWith(instancePath + '.') + ); diff --git a/packages/core/src/reducers/default-data.ts b/packages/core/src/reducers/default-data.ts index 0ebc5982a..9e592788a 100644 --- a/packages/core/src/reducers/default-data.ts +++ b/packages/core/src/reducers/default-data.ts @@ -27,7 +27,7 @@ import { ADD_DEFAULT_DATA, RegisterDefaultDataAction, REMOVE_DEFAULT_DATA, - UnregisterDefaultDataAction + UnregisterDefaultDataAction, } from '../actions'; import type { Reducer } from '../util'; @@ -40,17 +40,17 @@ type ValidDefaultDataActions = | RegisterDefaultDataAction | UnregisterDefaultDataAction; -export const defaultDataReducer: Reducer = ( - state = [], - action -) => { +export const defaultDataReducer: Reducer< + JsonFormsDefaultDataRegistryEntry[], + ValidDefaultDataActions +> = (state = [], action) => { switch (action.type) { case ADD_DEFAULT_DATA: return state.concat([ - { schemaPath: action.schemaPath, data: action.data } + { schemaPath: action.schemaPath, data: action.data }, ]); case REMOVE_DEFAULT_DATA: - return state.filter(t => t.schemaPath !== action.schemaPath); + return state.filter((t) => t.schemaPath !== action.schemaPath); default: return state; } diff --git a/packages/core/src/reducers/i18n.ts b/packages/core/src/reducers/i18n.ts index 2fd8113a7..acb64de09 100644 --- a/packages/core/src/reducers/i18n.ts +++ b/packages/core/src/reducers/i18n.ts @@ -23,17 +23,29 @@ THE SOFTWARE. */ -import { defaultErrorTranslator, defaultTranslator, JsonFormsI18nState } from '../i18n'; -import { I18nActions, SET_LOCALE, SET_TRANSLATOR, UPDATE_I18N } from '../actions'; +import { + defaultErrorTranslator, + defaultTranslator, + JsonFormsI18nState, +} from '../i18n'; +import { + I18nActions, + SET_LOCALE, + SET_TRANSLATOR, + UPDATE_I18N, +} from '../actions'; import type { Reducer } from '../util'; export const defaultJsonFormsI18nState: Required = { locale: 'en', translate: defaultTranslator, - translateError: defaultErrorTranslator + translateError: defaultErrorTranslator, }; -export const i18nReducer: Reducer = (state = defaultJsonFormsI18nState, action) => { +export const i18nReducer: Reducer = ( + state = defaultJsonFormsI18nState, + action +) => { switch (action.type) { case UPDATE_I18N: { const locale = action.locale ?? defaultJsonFormsI18nState.locale; @@ -51,7 +63,7 @@ export const i18nReducer: Reducer = (state = de ...state, locale, translate, - translateError + translateError, }; } return state; @@ -60,12 +72,12 @@ export const i18nReducer: Reducer = (state = de return { ...state, translate: action.translator ?? defaultTranslator, - translateError: action.errorTranslator ?? defaultErrorTranslator + translateError: action.errorTranslator ?? defaultErrorTranslator, }; case SET_LOCALE: return { ...state, - locale: action.locale ?? navigator.languages[0] + locale: action.locale ?? navigator.languages[0], }; default: return state; @@ -84,11 +96,11 @@ export const fetchTranslator = (state?: JsonFormsI18nState) => { return defaultTranslator; } return state.translate; -} +}; export const fetchErrorTranslator = (state?: JsonFormsI18nState) => { if (state === undefined) { return defaultErrorTranslator; } return state.translateError; -} +}; diff --git a/packages/core/src/reducers/reducers.ts b/packages/core/src/reducers/reducers.ts index 5df467ef9..33b2508ad 100644 --- a/packages/core/src/reducers/reducers.ts +++ b/packages/core/src/reducers/reducers.ts @@ -24,24 +24,13 @@ */ import type { ControlElement, UISchemaElement } from '../models'; -import { - coreReducer, - errorAt, - subErrorsAt, -} from './core'; +import { coreReducer, errorAt, subErrorsAt } from './core'; import { defaultDataReducer } from './default-data'; import { rendererReducer } from './renderers'; import type { JsonFormsState } from '../store'; import type { JsonFormsUISchemaRegistryEntry } from './uischemas'; -import { - findMatchingUISchema, - uischemaRegistryReducer, -} from './uischemas'; -import { - fetchErrorTranslator, - fetchLocale, - i18nReducer, -} from './i18n'; +import { findMatchingUISchema, uischemaRegistryReducer } from './uischemas'; +import { fetchErrorTranslator, fetchLocale, i18nReducer } from './i18n'; import { Generate } from '../generators'; import type { JsonSchema } from '../models/jsonSchema'; @@ -84,7 +73,7 @@ export const findUISchema = ( if (typeof control.options.detail === 'string') { if (control.options.detail.toUpperCase() === 'GENERATE') { //use fallback generation function - if(typeof fallback === "function"){ + if (typeof fallback === 'function') { return fallback(); } // force generation of uischema @@ -104,7 +93,7 @@ export const findUISchema = ( const uiSchema = findMatchingUISchema(uischemas)(schema, schemaPath, path); if (uiSchema === undefined) { //use fallback generation function - if(typeof fallback === 'function'){ + if (typeof fallback === 'function') { return fallback(); } return Generate.uiSchema(schema, fallback, '#', rootSchema); @@ -112,25 +101,26 @@ export const findUISchema = ( return uiSchema; }; -export const getErrorAt = (instancePath: string, schema: JsonSchema) => ( - state: JsonFormsState -) => { - return errorAt(instancePath, schema)(state.jsonforms.core); -}; +export const getErrorAt = + (instancePath: string, schema: JsonSchema) => (state: JsonFormsState) => { + return errorAt(instancePath, schema)(state.jsonforms.core); + }; -export const getSubErrorsAt = (instancePath: string, schema: JsonSchema) => ( - state: JsonFormsState -) => subErrorsAt(instancePath, schema)(state.jsonforms.core); +export const getSubErrorsAt = + (instancePath: string, schema: JsonSchema) => (state: JsonFormsState) => + subErrorsAt(instancePath, schema)(state.jsonforms.core); export const getConfig = (state: JsonFormsState) => state.jsonforms.config; export const getLocale = (state: JsonFormsState) => fetchLocale(get(state, 'jsonforms.i18n')); -export const getTranslator = () => ( - state: JsonFormsState -): Translator => fetchTranslator(get(state, 'jsonforms.i18n')); +export const getTranslator = + () => + (state: JsonFormsState): Translator => + fetchTranslator(get(state, 'jsonforms.i18n')); -export const getErrorTranslator = () => ( - state: JsonFormsState -): ErrorTranslator => fetchErrorTranslator(get(state, 'jsonforms.i18n')); +export const getErrorTranslator = + () => + (state: JsonFormsState): ErrorTranslator => + fetchErrorTranslator(get(state, 'jsonforms.i18n')); diff --git a/packages/core/src/reducers/renderers.ts b/packages/core/src/reducers/renderers.ts index 923b56924..c9e595ff4 100644 --- a/packages/core/src/reducers/renderers.ts +++ b/packages/core/src/reducers/renderers.ts @@ -28,7 +28,7 @@ import { ADD_RENDERER, AddRendererAction, REMOVE_RENDERER, - RemoveRendererAction + RemoveRendererAction, } from '../actions'; import type { Reducer } from '../util'; @@ -39,17 +39,17 @@ export interface JsonFormsRendererRegistryEntry { type ValidRendererReducerActions = AddRendererAction | RemoveRendererAction; -export const rendererReducer: Reducer = ( - state = [], - action -) => { +export const rendererReducer: Reducer< + JsonFormsRendererRegistryEntry[], + ValidRendererReducerActions +> = (state = [], action) => { switch (action.type) { case ADD_RENDERER: return state.concat([ - { tester: action.tester, renderer: action.renderer } + { tester: action.tester, renderer: action.renderer }, ]); case REMOVE_RENDERER: - return state.filter(t => t.tester !== action.tester); + return state.filter((t) => t.tester !== action.tester); default: return state; } diff --git a/packages/core/src/reducers/selectors.ts b/packages/core/src/reducers/selectors.ts index ee4d11c26..53f724b36 100644 --- a/packages/core/src/reducers/selectors.ts +++ b/packages/core/src/reducers/selectors.ts @@ -35,7 +35,7 @@ import { } from './core'; import { extractDefaultData, - JsonFormsDefaultDataRegistryEntry + JsonFormsDefaultDataRegistryEntry, } from './default-data'; import type { JsonFormsRendererRegistryEntry } from './renderers'; import type { JsonFormsCellRendererRegistryEntry } from './cells'; @@ -47,9 +47,8 @@ export const getSchema = (state: JsonFormsState): JsonSchema => extractSchema(get(state, 'jsonforms.core')); export const getUiSchema = (state: JsonFormsState): UISchemaElement => extractUiSchema(get(state, 'jsonforms.core')); -export const getAjv = ( - state: JsonFormsState -): Ajv => extractAjv(get(state, 'jsonforms.core')); +export const getAjv = (state: JsonFormsState): Ajv => + extractAjv(get(state, 'jsonforms.core')); export const getDefaultData = ( state: JsonFormsState ): JsonFormsDefaultDataRegistryEntry[] => @@ -62,4 +61,4 @@ export const getCells = ( ): JsonFormsCellRendererRegistryEntry[] => get(state, 'jsonforms.cells'); export const getUISchemas = ( state: JsonFormsState -): JsonFormsUISchemaRegistryEntry[] => get(state, 'jsonforms.uischemas') +): JsonFormsUISchemaRegistryEntry[] => get(state, 'jsonforms.uischemas'); diff --git a/packages/core/src/reducers/uischemas.ts b/packages/core/src/reducers/uischemas.ts index ae2de0906..442eed7ad 100644 --- a/packages/core/src/reducers/uischemas.ts +++ b/packages/core/src/reducers/uischemas.ts @@ -41,39 +41,40 @@ export interface JsonFormsUISchemaRegistryEntry { uischema: UISchemaElement; } -export const uischemaRegistryReducer: Reducer = ( - state = [], - action -) => { +export const uischemaRegistryReducer: Reducer< + JsonFormsUISchemaRegistryEntry[], + UISchemaActions +> = (state = [], action) => { switch (action.type) { case ADD_UI_SCHEMA: return state .slice() .concat({ tester: action.tester, uischema: action.uischema }); - case REMOVE_UI_SCHEMA: + case REMOVE_UI_SCHEMA: { const copy = state.slice(); - remove(copy, entry => entry.tester === action.tester); + remove(copy, (entry) => entry.tester === action.tester); return copy; + } default: return state; } }; -export const findMatchingUISchema = ( - state: JsonFormsUISchemaRegistryEntry[] -) => ( - jsonSchema: JsonSchema, - schemaPath: string, - path: string -): UISchemaElement => { - const match = maxBy(state, entry => - entry.tester(jsonSchema, schemaPath, path) - ); - if ( - match !== undefined && - match.tester(jsonSchema, schemaPath, path) !== NOT_APPLICABLE - ) { - return match.uischema; - } - return undefined; -}; +export const findMatchingUISchema = + (state: JsonFormsUISchemaRegistryEntry[]) => + ( + jsonSchema: JsonSchema, + schemaPath: string, + path: string + ): UISchemaElement => { + const match = maxBy(state, (entry) => + entry.tester(jsonSchema, schemaPath, path) + ); + if ( + match !== undefined && + match.tester(jsonSchema, schemaPath, path) !== NOT_APPLICABLE + ) { + return match.uischema; + } + return undefined; + }; diff --git a/packages/core/src/store.ts b/packages/core/src/store.ts index a3983d664..445c54220 100644 --- a/packages/core/src/store.ts +++ b/packages/core/src/store.ts @@ -28,7 +28,7 @@ import type { JsonFormsCore, JsonFormsCellRendererRegistryEntry, JsonFormsRendererRegistryEntry, - JsonFormsUISchemaRegistryEntry + JsonFormsUISchemaRegistryEntry, } from './reducers'; import type { JsonFormsI18nState } from './i18n'; diff --git a/packages/core/src/testers/testers.ts b/packages/core/src/testers/testers.ts index b0e586c1d..92dc12918 100644 --- a/packages/core/src/testers/testers.ts +++ b/packages/core/src/testers/testers.ts @@ -35,7 +35,7 @@ import type { Categorization, ControlElement, JsonSchema, - UISchemaElement + UISchemaElement, } from '../models'; import { deriveTypes, hasType, resolveSchema } from '../util'; @@ -49,7 +49,11 @@ export const NOT_APPLICABLE = -1; * A tester is a function that receives an UI schema and a JSON schema and returns a boolean. * The rootSchema is handed over as context. Can be used to resolve references. */ -export type Tester = (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => boolean; +export type Tester = ( + uischema: UISchemaElement, + schema: JsonSchema, + context: TesterContext +) => boolean; /** * A ranked tester associates a tester with a number. @@ -83,50 +87,70 @@ export const isControl = (uischema: any): uischema is ControlElement => * @param {(JsonSchema) => boolean} predicate the predicate that should be * applied to the resolved sub-schema */ -export const schemaMatches = ( - predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean -): Tester => (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext): boolean => { - if (isEmpty(uischema) || !isControl(uischema)) { - return false; - } - if (isEmpty(schema)) { - return false; - } - const schemaPath = uischema.scope; - if (isEmpty(schemaPath)) { - return false; - } - let currentDataSchema = schema; - if (hasType(schema, 'object')) { - currentDataSchema = resolveSchema(schema, schemaPath, context?.rootSchema); - } - if (currentDataSchema === undefined) { - return false; - } - - return predicate(currentDataSchema, context?.rootSchema); -}; +export const schemaMatches = + ( + predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean + ): Tester => + ( + uischema: UISchemaElement, + schema: JsonSchema, + context: TesterContext + ): boolean => { + if (isEmpty(uischema) || !isControl(uischema)) { + return false; + } + if (isEmpty(schema)) { + return false; + } + const schemaPath = uischema.scope; + if (isEmpty(schemaPath)) { + return false; + } + let currentDataSchema = schema; + if (hasType(schema, 'object')) { + currentDataSchema = resolveSchema( + schema, + schemaPath, + context?.rootSchema + ); + } + if (currentDataSchema === undefined) { + return false; + } -export const schemaSubPathMatches = ( - subPath: string, - predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean -): Tester => (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext): boolean => { - if (isEmpty(uischema) || !isControl(uischema)) { - return false; - } - const schemaPath = uischema.scope; - let currentDataSchema: JsonSchema = schema; - if (hasType(schema, 'object')) { - currentDataSchema = resolveSchema(schema, schemaPath, context?.rootSchema); - } - currentDataSchema = get(currentDataSchema, subPath); + return predicate(currentDataSchema, context?.rootSchema); + }; + +export const schemaSubPathMatches = + ( + subPath: string, + predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean + ): Tester => + ( + uischema: UISchemaElement, + schema: JsonSchema, + context: TesterContext + ): boolean => { + if (isEmpty(uischema) || !isControl(uischema)) { + return false; + } + const schemaPath = uischema.scope; + let currentDataSchema: JsonSchema = schema; + if (hasType(schema, 'object')) { + currentDataSchema = resolveSchema( + schema, + schemaPath, + context?.rootSchema + ); + } + currentDataSchema = get(currentDataSchema, subPath); - if (currentDataSchema === undefined) { - return false; - } + if (currentDataSchema === undefined) { + return false; + } - return predicate(currentDataSchema, context?.rootSchema); -}; + return predicate(currentDataSchema, context?.rootSchema); + }; /** * Only applicable for Controls. @@ -138,7 +162,7 @@ export const schemaSubPathMatches = ( * @param {string} expectedType the expected type of the resolved sub-schema */ export const schemaTypeIs = (expectedType: string): Tester => - schemaMatches(schema => !isEmpty(schema) && hasType(schema, expectedType)); + schemaMatches((schema) => !isEmpty(schema) && hasType(schema, expectedType)); /** * Only applicable for Controls. @@ -151,7 +175,7 @@ export const schemaTypeIs = (expectedType: string): Tester => */ export const formatIs = (expectedFormat: string): Tester => schemaMatches( - schema => + (schema) => !isEmpty(schema) && schema.format === expectedFormat && hasType(schema, 'string') @@ -162,9 +186,10 @@ export const formatIs = (expectedFormat: string): Tester => * * @param {string} expected the expected UI schema type */ -export const uiTypeIs = (expected: string): Tester => ( - uischema: UISchemaElement -): boolean => !isEmpty(uischema) && uischema.type === expected; +export const uiTypeIs = + (expected: string): Tester => + (uischema: UISchemaElement): boolean => + !isEmpty(uischema) && uischema.type === expected; /** * Checks whether the given UI schema has an option with the given @@ -174,16 +199,16 @@ export const uiTypeIs = (expected: string): Tester => ( * @param {string} optionName the name of the option to check * @param {any} optionValue the expected value of the option */ -export const optionIs = (optionName: string, optionValue: any): Tester => ( - uischema: UISchemaElement -): boolean => { - if (isEmpty(uischema)) { - return false; - } +export const optionIs = + (optionName: string, optionValue: any): Tester => + (uischema: UISchemaElement): boolean => { + if (isEmpty(uischema)) { + return false; + } - const options = uischema.options; - return !isEmpty(options) && options[optionName] === optionValue; -}; + const options = uischema.options; + return !isEmpty(options) && options[optionName] === optionValue; + }; /** * Only applicable for Controls. @@ -192,15 +217,15 @@ export const optionIs = (optionName: string, optionValue: any): Tester => ( * * @param {string} expected the expected ending of the reference */ -export const scopeEndsWith = (expected: string): Tester => ( - uischema: UISchemaElement -): boolean => { - if (isEmpty(expected) || !isControl(uischema)) { - return false; - } +export const scopeEndsWith = + (expected: string): Tester => + (uischema: UISchemaElement): boolean => { + if (isEmpty(expected) || !isControl(uischema)) { + return false; + } - return endsWith(uischema.scope, expected); -}; + return endsWith(uischema.scope, expected); + }; /** * Only applicable for Controls. @@ -209,38 +234,42 @@ export const scopeEndsWith = (expected: string): Tester => ( * * @param {string} expected the expected ending of the reference */ -export const scopeEndIs = (expected: string): Tester => ( - uischema: UISchemaElement -): boolean => { - if (isEmpty(expected) || !isControl(uischema)) { - return false; - } - const schemaPath = uischema.scope; +export const scopeEndIs = + (expected: string): Tester => + (uischema: UISchemaElement): boolean => { + if (isEmpty(expected) || !isControl(uischema)) { + return false; + } + const schemaPath = uischema.scope; - return !isEmpty(schemaPath) && last(schemaPath.split('/')) === expected; -}; + return !isEmpty(schemaPath) && last(schemaPath.split('/')) === expected; + }; /** * A tester that allow composing other testers by && them. * * @param {Array} testers the testers to be composed */ -export const and = (...testers: Tester[]): Tester => ( - uischema: UISchemaElement, - schema: JsonSchema, - context: TesterContext -) => testers.reduce((acc, tester) => acc && tester(uischema, schema, context), true); +export const and = + (...testers: Tester[]): Tester => + (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => + testers.reduce( + (acc, tester) => acc && tester(uischema, schema, context), + true + ); /** * A tester that allow composing other testers by || them. * * @param {Array} testers the testers to be composed */ -export const or = (...testers: Tester[]): Tester => ( - uischema: UISchemaElement, - schema: JsonSchema, - context: TesterContext -) => testers.reduce((acc, tester) => acc || tester(uischema, schema, context), false); +export const or = + (...testers: Tester[]): Tester => + (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => + testers.reduce( + (acc, tester) => acc || tester(uischema, schema, context), + false + ); /** * Create a ranked tester that will associate a number with a given tester, if the * latter returns true. @@ -248,30 +277,34 @@ export const or = (...testers: Tester[]): Tester => ( * @param {number} rank the rank to be returned in case the tester returns true * @param {Tester} tester a tester */ -export const rankWith = (rank: number, tester: Tester) => ( - uischema: UISchemaElement, - schema: JsonSchema, - context: TesterContext -): number => { - if (tester(uischema, schema, context)) { - return rank; - } - - return NOT_APPLICABLE; -}; +export const rankWith = + (rank: number, tester: Tester) => + ( + uischema: UISchemaElement, + schema: JsonSchema, + context: TesterContext + ): number => { + if (tester(uischema, schema, context)) { + return rank; + } -export const withIncreasedRank = (by: number, rankedTester: RankedTester) => ( - uischema: UISchemaElement, - schema: JsonSchema, - context: TesterContext -): number => { - const rank = rankedTester(uischema, schema, context); - if (rank === NOT_APPLICABLE) { return NOT_APPLICABLE; - } + }; + +export const withIncreasedRank = + (by: number, rankedTester: RankedTester) => + ( + uischema: UISchemaElement, + schema: JsonSchema, + context: TesterContext + ): number => { + const rank = rankedTester(uischema, schema, context); + if (rank === NOT_APPLICABLE) { + return NOT_APPLICABLE; + } - return rank + by; -}; + return rank + by; + }; /** * Default tester for boolean. @@ -287,17 +320,17 @@ export const isObjectControl = and(uiTypeIs('Control'), schemaTypeIs('object')); export const isAllOfControl = and( uiTypeIs('Control'), - schemaMatches(schema => schema.hasOwnProperty('allOf')) + schemaMatches((schema) => schema.hasOwnProperty('allOf')) ); export const isAnyOfControl = and( uiTypeIs('Control'), - schemaMatches(schema => schema.hasOwnProperty('anyOf')) + schemaMatches((schema) => schema.hasOwnProperty('anyOf')) ); export const isOneOfControl = and( uiTypeIs('Control'), - schemaMatches(schema => schema.hasOwnProperty('oneOf')) + schemaMatches((schema) => schema.hasOwnProperty('oneOf')) ); /** @@ -308,8 +341,8 @@ export const isOneOfControl = and( export const isEnumControl = and( uiTypeIs('Control'), or( - schemaMatches(schema => schema.hasOwnProperty('enum')), - schemaMatches(schema => schema.hasOwnProperty('const')) + schemaMatches((schema) => schema.hasOwnProperty('enum')), + schemaMatches((schema) => schema.hasOwnProperty('const')) ) ); @@ -320,9 +353,10 @@ export const isEnumControl = and( */ export const isOneOfEnumControl = and( uiTypeIs('Control'), - schemaMatches(schema => - schema.hasOwnProperty('oneOf') && - (schema.oneOf as JsonSchema[]).every(s => s.const !== undefined) + schemaMatches( + (schema) => + schema.hasOwnProperty('oneOf') && + (schema.oneOf as JsonSchema[]).every((s) => s.const !== undefined) ) ); @@ -396,11 +430,15 @@ export const isDateTimeControl = and( */ export const isObjectArray = and( schemaMatches( - (schema, rootSchema) => hasType(schema, 'array') && !Array.isArray(resolveSchema(schema, 'items', rootSchema)) // we don't care about tuples + (schema, rootSchema) => + hasType(schema, 'array') && + !Array.isArray(resolveSchema(schema, 'items', rootSchema)) // we don't care about tuples ), schemaSubPathMatches('items', (schema, rootSchema) => { - const resolvedSchema = schema.$ref ? resolveSchema(rootSchema, schema.$ref, rootSchema) : schema; - return hasType(resolvedSchema, 'object') + const resolvedSchema = schema.$ref + ? resolveSchema(rootSchema, schema.$ref, rootSchema) + : schema; + return hasType(resolvedSchema, 'object'); }) ); @@ -417,7 +455,11 @@ const traverse = ( rootSchema: JsonSchema ): boolean => { if (isArray(any)) { - return reduce(any, (acc, el) => acc || traverse(el, pred, rootSchema), false); + return reduce( + any, + (acc, el) => acc || traverse(el, pred, rootSchema), + false + ); } if (pred(any)) { @@ -454,32 +496,43 @@ export const isObjectArrayWithNesting = ( return false; } const schemaPath = (uischema as ControlElement).scope; - const resolvedSchema = resolveSchema(schema, schemaPath, context?.rootSchema ?? schema); + const resolvedSchema = resolveSchema( + schema, + schemaPath, + context?.rootSchema ?? schema + ); let objectDepth = 0; if (resolvedSchema !== undefined && resolvedSchema.items !== undefined) { // check if nested arrays if ( - traverse(resolvedSchema.items, val => { - if (val === schema) { - return false; - } - if (val.$ref !== undefined) { - return false; - } - if (val.anyOf || val.oneOf || val.allOf) { - return true; - } - if (hasType(val, 'object')) { - objectDepth++; - if (objectDepth === 2) { + traverse( + resolvedSchema.items, + (val) => { + if (val === schema) { + return false; + } + if (val.$ref !== undefined) { + return false; + } + if (val.anyOf || val.allOf) { return true; } - } - if (hasType(val, 'array')) { - return true; - } - return false; - }, context?.rootSchema) + if (val.oneOf && !isOneOfEnumControl(uischema, val, context)) { + return true; + } + if (hasType(val, 'object')) { + objectDepth++; + if (objectDepth === 2) { + return true; + } + } + if (hasType(val, 'array')) { + return true; + } + return false; + }, + context?.rootSchema + ) ) { return true; } @@ -516,7 +569,9 @@ export const isPrimitiveArrayControl = and( !Array.isArray(resolveSchema(schema, 'items', rootSchema)) // we don't care about tuples ), schemaSubPathMatches('items', (schema, rootSchema) => { - const resolvedSchema = schema.$ref ? resolveSchema(rootSchema, schema.$ref, rootSchema) : schema; + const resolvedSchema = schema.$ref + ? resolveSchema(rootSchema, schema.$ref, rootSchema) + : schema; const types = deriveTypes(resolvedSchema); return ( types.length === 1 && @@ -535,7 +590,7 @@ export const isRangeControl = and( uiTypeIs('Control'), or(schemaTypeIs('number'), schemaTypeIs('integer')), schemaMatches( - schema => + (schema) => schema.hasOwnProperty('maximum') && schema.hasOwnProperty('minimum') && schema.hasOwnProperty('default') @@ -567,7 +622,7 @@ export const hasCategory = (categorization: Categorization): boolean => { } // all children of the categorization have to be categories return categorization.elements - .map(elem => + .map((elem) => isCategorization(elem) ? hasCategory(elem) : isCategory(elem) ) .reduce((prev, curr) => prev && curr, true); @@ -576,9 +631,7 @@ export const hasCategory = (categorization: Categorization): boolean => { export const categorizationHasCategory = (uischema: UISchemaElement) => hasCategory(uischema as Categorization); -export const not = (tester: Tester): Tester => ( - uischema: UISchemaElement, - schema: JsonSchema, - context: TesterContext - -) => !tester(uischema, schema, context); +export const not = + (tester: Tester): Tester => + (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => + !tester(uischema, schema, context); diff --git a/packages/core/src/util/cell.ts b/packages/core/src/util/cell.ts index 1e3cd4bbb..75869a090 100644 --- a/packages/core/src/util/cell.ts +++ b/packages/core/src/util/cell.ts @@ -24,9 +24,8 @@ */ import isEmpty from 'lodash/isEmpty'; -import union from 'lodash/union'; -import type { JsonFormsCellRendererRegistryEntry } from '../reducers'; import { + getErrorTranslator, getAjv, getConfig, getData, @@ -34,15 +33,10 @@ import { getSchema, getTranslator, } from '../reducers'; +import type { JsonFormsCellRendererRegistryEntry } from '../reducers'; import type { AnyAction, Dispatch } from './type'; -import { - formatErrorMessage, - Resolve, -} from './util'; -import { - isInherentlyEnabled, - isVisible, -} from './runtime'; +import { Resolve } from './util'; +import { isInherentlyEnabled, isVisible } from './runtime'; import { DispatchPropsOfControl, EnumOption, @@ -53,11 +47,9 @@ import { OwnPropsOfEnum, StatePropsOfScopedRenderer, } from './renderer'; +import { getCombinedErrorMessage, getI18nKeyPrefix } from '../i18n'; import type { JsonFormsState } from '../store'; import type { JsonSchema } from '../models'; -import { getI18nKeyPrefix } from '../i18n'; - -export type { JsonFormsCellRendererRegistryEntry }; export interface OwnPropsOfCell extends OwnPropsOfControl { data?: any; @@ -126,7 +118,7 @@ export const mapStateToCellProps = ( /* When determining the enabled state of cells we take a shortcut: At the * moment it's only possible to configure enablement and disablement at the - * control level. Therefore the renderer using the cell, for example a + * control level. Therefore the renderer using the cell, for example a * table renderer, determines whether a cell is enabled and should hand * over the prop themselves. If that prop was given, we prefer it over * anything else to save evaluation effort (except for the global readonly @@ -148,8 +140,15 @@ export const mapStateToCellProps = ( ); } - const errors = formatErrorMessage( - union(getErrorAt(path, schema)(state).map(error => error.message)) + const t = getTranslator()(state); + const te = getErrorTranslator()(state); + const errors = getCombinedErrorMessage( + getErrorAt(path, schema)(state), + te, + t, + schema, + uischema, + path ); const isValid = isEmpty(errors); @@ -166,7 +165,7 @@ export const mapStateToCellProps = ( config: getConfig(state), rootSchema, renderers, - cells + cells, }; }; @@ -175,11 +174,11 @@ export const mapStateToDispatchCellProps = ( ownProps: OwnPropsOfCell ): DispatchCellStateProps => { const props: StatePropsOfCell = mapStateToCellProps(state, ownProps); - const { renderers, cells, ...otherOwnProps } = ownProps; + const { renderers: _renderers, cells, ...otherOwnProps } = ownProps; return { ...props, ...otherOwnProps, - cells: cells || state.jsonforms.cells || [] + cells: cells || state.jsonforms.cells || [], }; }; @@ -198,7 +197,7 @@ export const defaultMapStateToEnumCellProps = ( const props: StatePropsOfCell = mapStateToCellProps(state, ownProps); const options: EnumOption[] = ownProps.options || - props.schema.enum?.map(e => + props.schema.enum?.map((e) => enumToEnumOptionMapper( e, getTranslator()(state), @@ -210,11 +209,11 @@ export const defaultMapStateToEnumCellProps = ( props.schema.const, getTranslator()(state), getI18nKeyPrefix(props.schema, props.uischema, props.path) - ) + ), ]); return { ...props, - options + options, }; }; @@ -231,7 +230,7 @@ export const mapStateToOneOfEnumCellProps = ( const props: StatePropsOfCell = mapStateToCellProps(state, ownProps); const options: EnumOption[] = ownProps.options || - (props.schema.oneOf as JsonSchema[])?.map(oneOfSubSchema => + (props.schema.oneOf as JsonSchema[])?.map((oneOfSubSchema) => oneOfToEnumOptionMapper( oneOfSubSchema, getTranslator()(state), @@ -240,11 +239,10 @@ export const mapStateToOneOfEnumCellProps = ( ); return { ...props, - options + options, }; }; - /** * Synonym for mapDispatchToControlProps. * @@ -264,6 +262,6 @@ export const defaultMapDispatchToControlProps = const { handleChange } = mapDispatchToCellProps(dispatch); return { - handleChange: ownProps.handleChange || handleChange + handleChange: ownProps.handleChange || handleChange, }; }; diff --git a/packages/core/src/util/combinators.ts b/packages/core/src/util/combinators.ts index b6c830f66..e502d229f 100644 --- a/packages/core/src/util/combinators.ts +++ b/packages/core/src/util/combinators.ts @@ -56,7 +56,9 @@ export const createCombinatorRenderInfos = ( uischemas: JsonFormsUISchemaRegistryEntry[] ): CombinatorSubSchemaRenderInfo[] => combinatorSubSchemas.map((subSchema, subSchemaIndex) => { - const schema = subSchema.$ref ? Resolve.schema(rootSchema, subSchema.$ref, rootSchema) : subSchema; + const schema = subSchema.$ref + ? Resolve.schema(rootSchema, subSchema.$ref, rootSchema) + : subSchema; return { schema, uischema: findUISchema( @@ -68,6 +70,6 @@ export const createCombinatorRenderInfos = ( control, rootSchema ), - label: createLabel(subSchema, subSchemaIndex, keyword) - } + label: createLabel(subSchema, subSchemaIndex, keyword), + }; }); diff --git a/packages/core/src/util/label.ts b/packages/core/src/util/label.ts index 06f89cfb5..c7592ed98 100644 --- a/packages/core/src/util/label.ts +++ b/packages/core/src/util/label.ts @@ -79,5 +79,5 @@ export const createLabelDescriptionFrom = ( const labelDescription = (text: string, show: boolean): LabelDescription => ({ text: text, - show: show + show: show, }); diff --git a/packages/core/src/util/path.ts b/packages/core/src/util/path.ts index ce3a05f5c..1dc9fa61f 100644 --- a/packages/core/src/util/path.ts +++ b/packages/core/src/util/path.ts @@ -65,14 +65,16 @@ export const toDataPathSegments = (schemaPath: string): string[] => { const startFromRoot = decodedSegments[0] === '#' || decodedSegments[0] === ''; const startIndex = startFromRoot ? 2 : 1; - return range(startIndex, decodedSegments.length, 2).map(idx => decodedSegments[idx]); + return range(startIndex, decodedSegments.length, 2).map( + (idx) => decodedSegments[idx] + ); }; /** * Convert a schema path (i.e. JSON pointer) to a data path. - * + * * Data paths can be used in field change event handlers like handleChange. - * + * * @example * toDataPath('#/properties/foo/properties/bar') === 'foo.bar') * @@ -81,7 +83,7 @@ export const toDataPathSegments = (schemaPath: string): string[] => { */ export const toDataPath = (schemaPath: string): string => { return toDataPathSegments(schemaPath).join('.'); - }; +}; export const composeWithUi = (scopableUi: Scopable, path: string): string => { if (!isScoped(scopableUi)) { @@ -99,11 +101,13 @@ export const composeWithUi = (scopableUi: Scopable, path: string): string => { /** * Encodes the given segment to be used as part of a JSON Pointer - * + * * JSON Pointer has special meaning for "/" and "~", therefore these must be encoded */ -export const encode = (segment: string) => segment?.replace(/~/g, '~0').replace(/\//g, '~1'); +export const encode = (segment: string) => + segment?.replace(/~/g, '~0').replace(/\//g, '~1'); /** * Decodes a given JSON Pointer segment to its "normal" representation */ -export const decode = (pointerSegment: string) => pointerSegment?.replace(/~1/g, '/').replace(/~0/, '~'); +export const decode = (pointerSegment: string) => + pointerSegment?.replace(/~1/g, '/').replace(/~0/, '~'); diff --git a/packages/core/src/util/renderer.ts b/packages/core/src/util/renderer.ts index 33678219a..6aba2bdcb 100644 --- a/packages/core/src/util/renderer.ts +++ b/packages/core/src/util/renderer.ts @@ -24,14 +24,16 @@ */ import get from 'lodash/get'; -import { ControlElement, isLabelable, JsonSchema, LabelElement, UISchemaElement } from '../models'; +import { + ControlElement, + isLabelable, + JsonSchema, + LabelElement, + UISchemaElement, +} from '../models'; import find from 'lodash/find'; import { getUISchemas, - JsonFormsCellRendererRegistryEntry, - JsonFormsRendererRegistryEntry, -} from '../reducers'; -import { getAjv, getCells, getConfig, @@ -43,6 +45,10 @@ import { getSubErrorsAt, getTranslator, getUiSchema, +} from '../reducers'; +import type { + JsonFormsCellRendererRegistryEntry, + JsonFormsRendererRegistryEntry, JsonFormsUISchemaRegistryEntry, } from '../reducers'; import type { RankedTester } from '../testers'; @@ -56,7 +62,19 @@ import { composePaths, composeWithUi } from './path'; import { CoreActions, update } from '../actions'; import type { ErrorObject } from 'ajv'; import type { JsonFormsState } from '../store'; -import { deriveLabelForUISchemaElement, getCombinedErrorMessage, getI18nKey, getI18nKeyPrefix, getI18nKeyPrefixBySchema, Translator } from '../i18n'; +import { + deriveLabelForUISchemaElement, + getCombinedErrorMessage, + getI18nKey, + getI18nKeyPrefix, + getI18nKeyPrefixBySchema, + getArrayTranslations, + Translator, +} from '../i18n'; +import { + arrayDefaultTranslations, + ArrayTranslations, +} from '../i18n/arrayTranslations'; const isRequired = ( schema: JsonSchema, @@ -98,7 +116,7 @@ export const computeLabel = ( required: boolean, hideRequiredAsterisk: boolean ): string => { - return `${label ?? ''}${ required && !hideRequiredAsterisk ? '*' : ''}`; + return `${label ?? ''}${required && !hideRequiredAsterisk ? '*' : ''}`; }; /** @@ -108,7 +126,7 @@ export const computeLabel = ( * @param {boolean} hideRequiredAsterisk applied UI Schema option * @returns {boolean} should the field be marked as required */ - export const showAsRequired = ( +export const showAsRequired = ( required: boolean, hideRequiredAsterisk: boolean ): boolean => { @@ -370,6 +388,8 @@ export interface StatePropsOfControl extends StatePropsOfScopedRenderer { */ required?: boolean; + i18nKeyPrefix?: string; + // TODO: renderers? } @@ -450,7 +470,7 @@ export const mapStateToControlProps = ( rootSchema ); const errors = getErrorAt(path, resolvedSchema)(state); - + const description = resolvedSchema !== undefined ? resolvedSchema.description : ''; const data = Resolve.data(rootData, path); @@ -469,9 +489,26 @@ export const mapStateToControlProps = ( const schema = resolvedSchema ?? rootSchema; const t = getTranslator()(state); const te = getErrorTranslator()(state); - const i18nLabel = t(getI18nKey(schema, uischema, path, 'label'), label, {schema, uischema, path, errors} ); - const i18nDescription = t(getI18nKey(schema, uischema, path, 'description'), description, {schema, uischema, path, errors}); - const i18nErrorMessage = getCombinedErrorMessage(errors, te, t, schema, uischema, path); + const i18nKeyPrefix = getI18nKeyPrefix(schema, uischema, path); + const i18nLabel = t(getI18nKey(schema, uischema, path, 'label'), label, { + schema, + uischema, + path, + errors, + }); + const i18nDescription = t( + getI18nKey(schema, uischema, path, 'description'), + description, + { schema, uischema, path, errors } + ); + const i18nErrorMessage = getCombinedErrorMessage( + errors, + te, + t, + schema, + uischema, + path + ); return { data, @@ -487,7 +524,8 @@ export const mapStateToControlProps = ( schema, config: getConfig(state), cells: ownProps.cells || state.jsonforms.cells, - rootSchema + rootSchema, + i18nKeyPrefix, }; }; @@ -503,7 +541,7 @@ export const mapDispatchToControlProps = ( ): DispatchPropsOfControl => ({ handleChange(path, value) { dispatch(update(path, () => value)); - } + }, }); /** @@ -519,7 +557,7 @@ export const mapStateToEnumControlProps = ( const props: StatePropsOfControl = mapStateToControlProps(state, ownProps); const options: EnumOption[] = ownProps.options || - props.schema.enum?.map(e => + props.schema.enum?.map((e) => enumToEnumOptionMapper( e, getTranslator()(state), @@ -531,11 +569,11 @@ export const mapStateToEnumControlProps = ( props.schema.const, getTranslator()(state), getI18nKeyPrefix(props.schema, props.uischema, props.path) - ) + ), ]); return { ...props, - options + options, }; }; @@ -552,7 +590,7 @@ export const mapStateToOneOfEnumControlProps = ( const props: StatePropsOfControl = mapStateToControlProps(state, ownProps); const options: EnumOption[] = ownProps.options || - (props.schema.oneOf as JsonSchema[])?.map(oneOfSubSchema => + (props.schema.oneOf as JsonSchema[])?.map((oneOfSubSchema) => oneOfToEnumOptionMapper( oneOfSubSchema, getTranslator()(state), @@ -561,7 +599,7 @@ export const mapStateToOneOfEnumControlProps = ( ); return { ...props, - options + options, }; }; @@ -580,14 +618,14 @@ export const mapStateToMultiEnumControlProps = ( const options: EnumOption[] = ownProps.options || (items?.oneOf && - (items.oneOf as JsonSchema[]).map(oneOfSubSchema => + (items.oneOf as JsonSchema[]).map((oneOfSubSchema) => oneOfToEnumOptionMapper( oneOfSubSchema, state.jsonforms.i18n?.translate, getI18nKeyPrefix(props.schema, props.uischema, props.path) ) )) || - items?.enum?.map(e => + items?.enum?.map((e) => enumToEnumOptionMapper( e, state.jsonforms.i18n?.translate, @@ -596,7 +634,7 @@ export const mapStateToMultiEnumControlProps = ( ); return { ...props, - options + options, }; }; @@ -612,7 +650,7 @@ export const mapStateToMasterListItemProps = ( ): StatePropsOfMasterItem => { const { schema, path, index } = ownProps; const firstPrimitiveProp = schema.properties - ? find(Object.keys(schema.properties), propName => { + ? find(Object.keys(schema.properties), (propName) => { const prop = schema.properties[propName]; return ( prop.type === 'string' || @@ -627,7 +665,7 @@ export const mapStateToMasterListItemProps = ( return { ...ownProps, - childLabel + childLabel, }; }; @@ -648,6 +686,7 @@ export interface OwnPropsOfMasterListItem { schema: JsonSchema; handleSelect(index: number): () => void; removeItem(path: string, value: number): () => void; + translations: ArrayTranslations; } export interface StatePropsOfMasterItem extends OwnPropsOfMasterListItem { @@ -669,7 +708,7 @@ export const mapStateToControlWithDetailProps = ( return { ...props, - uischemas: state.jsonforms.uischemas + uischemas: state.jsonforms.uischemas, }; }; @@ -682,6 +721,7 @@ export interface ControlWithDetailProps */ export interface StatePropsOfArrayControl extends StatePropsOfControlWithDetail { + translations: ArrayTranslations; childErrors?: ErrorObject[]; } @@ -696,22 +736,28 @@ export const mapStateToArrayControlProps = ( state: JsonFormsState, ownProps: OwnPropsOfControl ): StatePropsOfArrayControl => { - const { path, schema, uischema, ...props } = mapStateToControlWithDetailProps( - state, - ownProps - ); + const { path, schema, uischema, i18nKeyPrefix, label, ...props } = + mapStateToControlWithDetailProps(state, ownProps); const resolvedSchema = Resolve.schema(schema, 'items', props.rootSchema); const childErrors = getSubErrorsAt(path, resolvedSchema)(state); + const t = getTranslator()(state); return { ...props, + label, path, uischema, schema: resolvedSchema, childErrors, renderers: ownProps.renderers || getRenderers(state), - cells: ownProps.cells || getCells(state) + cells: ownProps.cells || getCells(state), + translations: getArrayTranslations( + t, + arrayDefaultTranslations, + i18nKeyPrefix, + label + ), }; }; @@ -736,7 +782,7 @@ export const mapDispatchToArrayControlProps = ( ): DispatchPropsOfArrayControl => ({ addItem: (path: string, value: any) => () => { dispatch( - update(path, array => { + update(path, (array) => { if (array === undefined || array === null) { return [value]; } @@ -748,18 +794,18 @@ export const mapDispatchToArrayControlProps = ( }, removeItems: (path: string, toDelete: number[]) => () => { dispatch( - update(path, array => { + update(path, (array) => { toDelete .sort() .reverse() - .forEach(s => array.splice(s, 1)); + .forEach((s) => array.splice(s, 1)); return array; }) ); }, moveUp: (path, toMove: number) => () => { dispatch( - update(path, array => { + update(path, (array) => { moveUp(array, toMove); return array; }) @@ -767,12 +813,12 @@ export const mapDispatchToArrayControlProps = ( }, moveDown: (path, toMove: number) => () => { dispatch( - update(path, array => { + update(path, (array) => { moveDown(array, toMove); return array; }) ); - } + }, }); export interface DispatchPropsOfMultiEnumControl { @@ -785,7 +831,7 @@ export const mapDispatchToMultiEnumProps = ( ): DispatchPropsOfMultiEnumControl => ({ addItem: (path: string, value: any) => { dispatch( - update(path, data => { + update(path, (data) => { if (data === undefined || data === null) { return [value]; } @@ -796,13 +842,13 @@ export const mapDispatchToMultiEnumProps = ( }, removeItem: (path: string, toDelete: any) => { dispatch( - update(path, data => { + update(path, (data) => { const indexInData = data.indexOf(toDelete); data.splice(indexInData, 1); return data; }) ); - } + }, }); /** @@ -821,7 +867,7 @@ export const layoutDefaultProps: { visible: true, enabled: true, path: '', - direction: 'column' + direction: 'column', }; const getDirection = (uischema: UISchemaElement) => { @@ -864,7 +910,9 @@ export const mapStateToLayoutProps = ( // some layouts have labels which might need to be translated const t = getTranslator()(state); - const label = isLabelable(uischema) ? deriveLabelForUISchemaElement(uischema, t) : undefined; + const label = isLabelable(uischema) + ? deriveLabelForUISchemaElement(uischema, t) + : undefined; return { ...layoutDefaultProps, @@ -878,7 +926,7 @@ export const mapStateToLayoutProps = ( schema: ownProps.schema, direction: ownProps.direction ?? getDirection(uischema), config, - label + label, }; }; @@ -906,13 +954,13 @@ export const mapStateToJsonFormsRendererProps = ( uischema: ownProps.uischema || getUiSchema(state), path: ownProps.path, enabled: ownProps.enabled, - config: getConfig(state) + config: getConfig(state), }; }; export const controlDefaultProps = { ...layoutDefaultProps, - errors: [] as string[] + errors: [] as string[], }; export interface StatePropsOfCombinator extends StatePropsOfControl { @@ -931,7 +979,7 @@ export const mapStateToCombinatorRendererProps = ( ): StatePropsOfCombinator => { const { data, schema, rootSchema, ...props } = mapStateToControlProps( state, - ownProps, + ownProps ); const ajv = state.jsonforms.core.ajv; @@ -940,13 +988,13 @@ export const mapStateToCombinatorRendererProps = ( 'additionalProperties', 'type', 'enum', - 'const' + 'const', ]; const dataIsValid = (errors: ErrorObject[]): boolean => { return ( !errors || errors.length === 0 || - !errors.find(e => structuralKeywords.indexOf(e.keyword) !== -1) + !errors.find((e) => structuralKeywords.indexOf(e.keyword) !== -1) ); }; let indexOfFittingSchema: number; @@ -956,9 +1004,8 @@ export const mapStateToCombinatorRendererProps = ( for (let i = 0; i < schema[keyword]?.length; i++) { try { let _schema = schema[keyword][i]; - if(_schema.$ref){ - _schema = Resolve.schema( rootSchema, _schema.$ref, rootSchema - ); + if (_schema.$ref) { + _schema = Resolve.schema(rootSchema, _schema.$ref, rootSchema); } const valFn = ajv.compile(_schema); valFn(data); @@ -967,7 +1014,9 @@ export const mapStateToCombinatorRendererProps = ( break; } } catch (error) { - console.debug("Combinator subschema is not self contained, can't hand it over to AJV"); + console.debug( + "Combinator subschema is not self contained, can't hand it over to AJV" + ); } } @@ -977,7 +1026,7 @@ export const mapStateToCombinatorRendererProps = ( rootSchema, ...props, indexOfFittingSchema, - uischemas: getUISchemas(state) + uischemas: getUISchemas(state), }; }; @@ -1012,6 +1061,7 @@ export const mapStateToOneOfProps = ( export interface StatePropsOfArrayLayout extends StatePropsOfControlWithDetail { data: number; + translations: ArrayTranslations; minItems?: number; } /** @@ -1025,21 +1075,16 @@ export const mapStateToArrayLayoutProps = ( state: JsonFormsState, ownProps: OwnPropsOfControl ): StatePropsOfArrayLayout => { - const { - path, - schema, - uischema, - errors, - ...props - } = mapStateToControlWithDetailProps(state, ownProps); + const { path, schema, uischema, errors, i18nKeyPrefix, label, ...props } = + mapStateToControlWithDetailProps(state, ownProps); const resolvedSchema = Resolve.schema(schema, 'items', props.rootSchema); - + const t = getTranslator()(state); // TODO Does not consider 'i18n' keys which are specified in the ui schemas of the sub errors const childErrors = getCombinedErrorMessage( getSubErrorsAt(path, resolvedSchema)(state), getErrorTranslator()(state), - getTranslator()(state), + t, undefined, undefined, undefined @@ -1051,12 +1096,19 @@ export const mapStateToArrayLayoutProps = ( childErrors; return { ...props, + label, path, uischema, schema: resolvedSchema, data: props.data ? props.data.length : 0, errors: allErrors, - minItems: schema.minItems + minItems: schema.minItems, + translations: getArrayTranslations( + t, + arrayDefaultTranslations, + i18nKeyPrefix, + label + ), }; }; @@ -1070,8 +1122,7 @@ export interface ArrayLayoutProps export interface StatePropsOfLabel extends StatePropsOfRenderer { text?: string; } -export interface LabelProps extends StatePropsOfLabel{ -} +export interface LabelProps extends StatePropsOfLabel {} export const mapStateToLabelProps = ( state: JsonFormsState, @@ -1089,12 +1140,12 @@ export const mapStateToLabelProps = ( const i18nKeyPrefix = getI18nKeyPrefixBySchema(undefined, uischema); const i18nKey = i18nKeyPrefix ? `${i18nKeyPrefix}.text` : text ?? ''; const i18nText = t(i18nKey, text, { uischema }); - + return { text: i18nText, visible, config: getConfig(state), renderers: props.renderers || getRenderers(state), cells: props.cells || getCells(state), - } -} + }; +}; diff --git a/packages/core/src/util/resolvers.ts b/packages/core/src/util/resolvers.ts index aca152087..10deb7631 100644 --- a/packages/core/src/util/resolvers.ts +++ b/packages/core/src/util/resolvers.ts @@ -48,15 +48,13 @@ export const resolveData = (instance: any, dataPath: string): any => { } const dataPathSegments = dataPath.split('.'); - return dataPathSegments - .map(segment => decodeURIComponent(segment)) - .reduce((curInstance, decodedSegment) => { - if (!curInstance || !curInstance.hasOwnProperty(decodedSegment)) { - return undefined; - } + return dataPathSegments.reduce((curInstance, decodedSegment) => { + if (!curInstance || !curInstance.hasOwnProperty(decodedSegment)) { + return undefined; + } - return curInstance[decodedSegment]; - }, instance); + return curInstance[decodedSegment]; + }, instance); }; /** @@ -73,7 +71,7 @@ export const findAllRefs = ( resolveTuples = false ): ReferenceSchemaMap => { if (isObjectSchema(schema)) { - Object.keys(schema.properties).forEach(key => + Object.keys(schema.properties).forEach((key) => findAllRefs(schema.properties[key], result) ); } @@ -81,7 +79,7 @@ export const findAllRefs = ( if (Array.isArray(schema.items)) { if (resolveTuples) { const items: JsonSchema[] = schema.items; - items.forEach(child => findAllRefs(child, result)); + items.forEach((child) => findAllRefs(child, result)); } } else { findAllRefs(schema.items, result); @@ -89,7 +87,7 @@ export const findAllRefs = ( } if (Array.isArray(schema.anyOf)) { const anyOf: JsonSchema[] = schema.anyOf; - anyOf.forEach(child => findAllRefs(child, result)); + anyOf.forEach((child) => findAllRefs(child, result)); } if (schema.$ref !== undefined) { result[schema.$ref] = schema; @@ -142,7 +140,11 @@ const resolveSchemaWithSegments = ( const singleSegmentResolveSchema = get(schema, segment); - const resolvedSchema = resolveSchemaWithSegments(singleSegmentResolveSchema, remainingSegments, rootSchema); + const resolvedSchema = resolveSchemaWithSegments( + singleSegmentResolveSchema, + remainingSegments, + rootSchema + ); if (resolvedSchema) { return resolvedSchema; } @@ -175,4 +177,4 @@ const resolveSchemaWithSegments = ( } return undefined; -} +}; diff --git a/packages/core/src/util/runtime.ts b/packages/core/src/util/runtime.ts index 0b592b2fd..2db828eb4 100644 --- a/packages/core/src/util/runtime.ts +++ b/packages/core/src/util/runtime.ts @@ -33,7 +33,7 @@ import { RuleEffect, SchemaBasedCondition, Scopable, - UISchemaElement + UISchemaElement, } from '../models'; import { resolveData } from './resolvers'; import { composeWithUi } from './path'; @@ -191,7 +191,7 @@ export const isInherentlyEnabled = ( state: JsonFormsState, ownProps: any, uischema: UISchemaElement, - schema: JsonSchema & { readOnly?: boolean } | undefined, + schema: (JsonSchema & { readOnly?: boolean }) | undefined, rootData: any, config: any ) => { diff --git a/packages/core/src/util/schema.ts b/packages/core/src/util/schema.ts index 9ade7803b..e8e6dd650 100644 --- a/packages/core/src/util/schema.ts +++ b/packages/core/src/util/schema.ts @@ -27,7 +27,7 @@ import find from 'lodash/find'; export const getFirstPrimitiveProp = (schema: any) => { if (schema.properties) { - return find(Object.keys(schema.properties), propName => { + return find(Object.keys(schema.properties), (propName) => { const prop = schema.properties[propName]; return ( prop.type === 'string' || diff --git a/packages/core/src/util/type.ts b/packages/core/src/util/type.ts index 7cdc8e71d..c01745773 100644 --- a/packages/core/src/util/type.ts +++ b/packages/core/src/util/type.ts @@ -62,7 +62,9 @@ export interface AnyAction extends Action { * @template A The type of things (actions or otherwise) which may be * dispatched. */ -export type Dispatch = (action: T) => T; +export type Dispatch = ( + action: T +) => T; // Copied from https://github.com/reduxjs/redux/blob/master/src/types/store.ts /** @@ -171,7 +173,7 @@ export type Observable = { * emission of values from the observable. */ subscribe(observer: Observer): { unsubscribe: Unsubscribe }; - [Symbol.observable](): Observable + [Symbol.observable](): Observable; }; // Copied from https://github.com/reduxjs/redux/blob/master/src/types/store.ts @@ -180,7 +182,7 @@ export type Observable = { * an argument to subscribe. */ export type Observer = { - next?(value: T): void + next?(value: T): void; }; // Copied from https://github.com/reduxjs/redux/blob/master/src/types/reducers.ts diff --git a/packages/core/src/util/uischema.ts b/packages/core/src/util/uischema.ts index 0d409fe97..05410bd83 100644 --- a/packages/core/src/util/uischema.ts +++ b/packages/core/src/util/uischema.ts @@ -28,14 +28,14 @@ import { isLayout, UISchemaElement } from '../models'; export type IterateCallback = (uischema: UISchemaElement) => void; -const setReadonlyPropertyValue = (value: boolean): IterateCallback => ( - child: UISchemaElement -): void => { - if (!child.options) { - child.options = {}; - } - child.options.readonly = value; -}; +const setReadonlyPropertyValue = + (value: boolean): IterateCallback => + (child: UISchemaElement): void => { + if (!child.options) { + child.options = {}; + } + child.options.readonly = value; + }; export const setReadonly = (uischema: UISchemaElement): void => { iterateSchema(uischema, setReadonlyPropertyValue(true)); }; @@ -50,7 +50,7 @@ export const iterateSchema = ( return; } if (isLayout(uischema)) { - uischema.elements.forEach(child => iterateSchema(child, toApply)); + uischema.elements.forEach((child) => iterateSchema(child, toApply)); return; } toApply(uischema); diff --git a/packages/core/src/util/util.ts b/packages/core/src/util/util.ts index 156a0582a..467cc8ec0 100644 --- a/packages/core/src/util/util.ts +++ b/packages/core/src/util/util.ts @@ -41,87 +41,87 @@ import type Ajv from 'ajv'; * @returns {string} the escaped string */ export const convertToValidClassName = (s: string): string => -s.replace('#', 'root').replace(new RegExp('/', 'g'), '_'); + s.replace('#', 'root').replace(new RegExp('/', 'g'), '_'); export const formatErrorMessage = (errors: string[]) => { - if (errors === undefined || errors === null) { - return ''; - } + if (errors === undefined || errors === null) { + return ''; + } - return errors.join('\n'); + return errors.join('\n'); }; export const hasType = (jsonSchema: JsonSchema, expected: string): boolean => { - return includes(deriveTypes(jsonSchema), expected); + return includes(deriveTypes(jsonSchema), expected); }; /** * Derives the type of the jsonSchema element */ export const deriveTypes = (jsonSchema: JsonSchema): string[] => { - if (isEmpty(jsonSchema)) { - return []; - } - if (!isEmpty(jsonSchema.type) && typeof jsonSchema.type === 'string') { - return [jsonSchema.type]; - } - if (isArray(jsonSchema.type)) { - return jsonSchema.type; - } - if ( - !isEmpty(jsonSchema.properties) || - !isEmpty(jsonSchema.additionalProperties) - ) { - return ['object']; - } - if (!isEmpty(jsonSchema.items)) { - return ['array']; - } + if (isEmpty(jsonSchema)) { + return []; + } + if (!isEmpty(jsonSchema.type) && typeof jsonSchema.type === 'string') { + return [jsonSchema.type]; + } + if (isArray(jsonSchema.type)) { + return jsonSchema.type; + } + if ( + !isEmpty(jsonSchema.properties) || + !isEmpty(jsonSchema.additionalProperties) + ) { + return ['object']; + } + if (!isEmpty(jsonSchema.items)) { + return ['array']; + } - if (!isEmpty(jsonSchema.allOf)) { - const allOfType = find( - jsonSchema.allOf, - (schema: JsonSchema) => deriveTypes(schema).length !== 0 - ); + if (!isEmpty(jsonSchema.allOf)) { + const allOfType = find( + jsonSchema.allOf, + (schema: JsonSchema) => deriveTypes(schema).length !== 0 + ); - if (allOfType) { - return deriveTypes(allOfType); - } - } - // ignore all remaining cases - return []; + if (allOfType) { + return deriveTypes(allOfType); + } + } + // ignore all remaining cases + return []; }; /** * Convenience wrapper around resolveData and resolveSchema. */ export const Resolve: { - schema( - schema: JsonSchema, - schemaPath: string, - rootSchema: JsonSchema - ): JsonSchema; - data(data: any, path: string): any; + schema( + schema: JsonSchema, + schemaPath: string, + rootSchema: JsonSchema + ): JsonSchema; + data(data: any, path: string): any; } = { - schema: resolveSchema, - data: resolveData + schema: resolveSchema, + data: resolveData, }; // Paths -- const fromScoped = (scopable: Scoped): string => - toDataPathSegments(scopable.scope).join('.'); + toDataPathSegments(scopable.scope).join('.'); export const Paths = { - compose: composePaths, - fromScoped + compose: composePaths, + fromScoped, }; // Runtime -- export const Runtime = { - isEnabled(uischema: UISchemaElement, data: any, ajv: Ajv): boolean { - return isEnabled(uischema, data, undefined, ajv); - }, - isVisible(uischema: UISchemaElement, data: any, ajv: Ajv): boolean { - return isVisible(uischema, data, undefined, ajv); - } + isEnabled(uischema: UISchemaElement, data: any, ajv: Ajv): boolean { + return isEnabled(uischema, data, undefined, ajv); + }, + isVisible(uischema: UISchemaElement, data: any, ajv: Ajv): boolean { + return isVisible(uischema, data, undefined, ajv); + }, }; diff --git a/packages/core/src/util/validator.ts b/packages/core/src/util/validator.ts index d658ee151..c3628a0f9 100644 --- a/packages/core/src/util/validator.ts +++ b/packages/core/src/util/validator.ts @@ -31,7 +31,7 @@ export const createAjv = (options?: Options) => { allErrors: true, verbose: true, strict: false, - ...options + ...options, }); addFormats(ajv); return ajv; diff --git a/packages/core/test/actions/actions.test.ts b/packages/core/test/actions/actions.test.ts index 5a36a2d19..35ffe3deb 100644 --- a/packages/core/test/actions/actions.test.ts +++ b/packages/core/test/actions/actions.test.ts @@ -28,56 +28,56 @@ import { JsonSchema, UISchemaElement, ControlElement, - VerticalLayout + VerticalLayout, } from '../../src'; -test('Init Action generates schema when not provided', t => { +test('Init Action generates schema when not provided', (t) => { const schema: JsonSchema = { type: 'object', properties: { name: { - type: 'string' - } + type: 'string', + }, }, additionalProperties: true, - required: ['name'] + required: ['name'], }; const init = Actions.init({ name: 'foobar' }); t.deepEqual(init.schema, schema); }); -test('Init Action generates ui schema when not provided', t => { +test('Init Action generates ui schema when not provided', (t) => { const schema: JsonSchema = { type: 'object', properties: { name: { - type: 'string' - } - } + type: 'string', + }, + }, }; const uischema: VerticalLayout = { type: 'VerticalLayout', elements: [ { type: 'Control', - scope: '#/properties/name' - } as ControlElement - ] + scope: '#/properties/name', + } as ControlElement, + ], }; const init = Actions.init({}, schema); t.deepEqual(init.uischema, uischema); }); -test('Init Action generates ui schema when not valid', t => { +test('Init Action generates ui schema when not valid', (t) => { const schema: JsonSchema = { type: 'object', properties: { name: { - type: 'string' - } - } + type: 'string', + }, + }, }; const init = Actions.init({}, schema, false as any); @@ -86,8 +86,8 @@ test('Init Action generates ui schema when not valid', t => { elements: [ { type: 'Control', - scope: '#/properties/name' - } - ] + scope: '#/properties/name', + }, + ], } as UISchemaElement); }); diff --git a/packages/core/test/generators/schema.test.ts b/packages/core/test/generators/schema.test.ts index 386e93adf..2171f51a0 100644 --- a/packages/core/test/generators/schema.test.ts +++ b/packages/core/test/generators/schema.test.ts @@ -26,14 +26,14 @@ import test from 'ava'; import { generateJsonSchema } from '../../src/generators/schema'; -test('default schema generation basic types', t => { +test('default schema generation basic types', (t) => { const instance: any = { boolean: false, number: 3.14, integer: 3, string: 'PI', null: null, - undefined: undefined + undefined: undefined, }; const schema = generateJsonSchema(instance); // FIXME: Should a property be generated for properties with undefined? @@ -41,34 +41,34 @@ test('default schema generation basic types', t => { type: 'object', properties: { boolean: { - type: 'boolean' + type: 'boolean', }, number: { - type: 'number' + type: 'number', }, integer: { - type: 'integer' + type: 'integer', }, string: { - type: 'string' + type: 'string', }, null: { - type: 'null' + type: 'null', }, - undefined: {} + undefined: {}, }, additionalProperties: true, - required: ['boolean', 'number', 'integer', 'string', 'null', 'undefined'] + required: ['boolean', 'number', 'integer', 'string', 'null', 'undefined'], }); }); -test('default schema generation array types', t => { +test('default schema generation array types', (t) => { const instance: any = { emptyArray: [], booleanArray: [false, false], numberArray: [3.14, 2.71], integerArray: [3, 2], stringArray: ['PI', 'e'], - nullArray: [null, null] + nullArray: [null, null], }; const schema = generateJsonSchema(instance); t.deepEqual(schema, { @@ -76,28 +76,28 @@ test('default schema generation array types', t => { properties: { emptyArray: { type: 'array', - items: {} + items: {}, }, booleanArray: { type: 'array', - items: { type: 'boolean' } + items: { type: 'boolean' }, }, numberArray: { type: 'array', - items: { type: 'number' } + items: { type: 'number' }, }, integerArray: { type: 'array', - items: { type: 'integer' } + items: { type: 'integer' }, }, stringArray: { type: 'array', - items: { type: 'string' } + items: { type: 'string' }, }, nullArray: { type: 'array', - items: { type: 'null' } - } + items: { type: 'null' }, + }, }, additionalProperties: true, required: [ @@ -106,11 +106,11 @@ test('default schema generation array types', t => { 'numberArray', 'integerArray', 'stringArray', - 'nullArray' - ] + 'nullArray', + ], }); }); -test.failing('default schema generation tuple array types', t => { +test.failing('default schema generation tuple array types', (t) => { const instance: any = { tupleArray: [3.14, 'PI'] }; const schema = generateJsonSchema(instance); // FIXME: This assumption is the correct one, but we crteate a oneOf in this case @@ -119,26 +119,26 @@ test.failing('default schema generation tuple array types', t => { properties: { tupleArray: { type: 'array', - items: [{ type: 'number' }, { type: 'string' }] - } + items: [{ type: 'number' }, { type: 'string' }], + }, }, additionalProperties: true, - required: ['tupleArray'] + required: ['tupleArray'], }); }); -test('default schema generation ', t => { +test('default schema generation ', (t) => { const instance: any = { address: { streetAddress: '21 2nd Street', - city: 'New York' + city: 'New York', }, phoneNumber: [ { location: 'home', code: 44, - private: true - } - ] + private: true, + }, + ], }; const schema = generateJsonSchema(instance); t.deepEqual(schema, { @@ -148,14 +148,14 @@ test('default schema generation ', t => { type: 'object', properties: { streetAddress: { - type: 'string' + type: 'string', }, city: { - type: 'string' - } + type: 'string', + }, }, additionalProperties: true, - required: ['streetAddress', 'city'] + required: ['streetAddress', 'city'], }, phoneNumber: { type: 'array', @@ -163,31 +163,31 @@ test('default schema generation ', t => { type: 'object', properties: { location: { - type: 'string' + type: 'string', }, code: { - type: 'integer' + type: 'integer', }, private: { - type: 'boolean' - } + type: 'boolean', + }, }, additionalProperties: true, - required: ['location', 'code', 'private'] - } - } + required: ['location', 'code', 'private'], + }, + }, }, additionalProperties: true, - required: ['address', 'phoneNumber'] + required: ['address', 'phoneNumber'], }); }); -test('schema generation with options ', t => { +test('schema generation with options ', (t) => { const instance: any = { address: { streetAddress: '21 2nd Street', - city: 'New York' - } + city: 'New York', + }, }; const schema = generateJsonSchema(instance, { additionalProperties: false, @@ -198,7 +198,7 @@ test('schema generation with options ', t => { } else { return []; } - } + }, }); t.deepEqual(schema, { @@ -208,17 +208,17 @@ test('schema generation with options ', t => { type: 'object', properties: { streetAddress: { - type: 'string' + type: 'string', }, city: { - type: 'string' - } + type: 'string', + }, }, additionalProperties: false, - required: ['streetAddress'] - } + required: ['streetAddress'], + }, }, additionalProperties: false, - required: ['address'] + required: ['address'], }); }); diff --git a/packages/core/test/generators/uischema.test.ts b/packages/core/test/generators/uischema.test.ts index 7cc2350d3..f178a0e86 100644 --- a/packages/core/test/generators/uischema.test.ts +++ b/packages/core/test/generators/uischema.test.ts @@ -27,311 +27,311 @@ import { generateDefaultUISchema } from '../../src/generators/uischema'; import { ControlElement, Layout, - VerticalLayout + VerticalLayout, } from '../../src/models/uischema'; import { JsonSchema } from '../../src'; -test('generate ui schema for Control element by resolving refs', t => { +test('generate ui schema for Control element by resolving refs', (t) => { const schema: JsonSchema = { type: 'object', properties: { type: { type: 'string', const: 'Control', - default: 'Control' + default: 'Control', }, label: { - type: 'string' + type: 'string', }, scope: { - $ref: '#/definitions/scope' + $ref: '#/definitions/scope', }, rule: { - $ref: '#/definitions/rule' - } + $ref: '#/definitions/rule', + }, }, required: ['type', 'scope'], definitions: { scope: { type: 'string', - pattern: '^#\\/properties\\/{1}' + pattern: '^#\\/properties\\/{1}', }, rule: { type: 'object', properties: { effect: { type: 'string', - enum: ['HIDE', 'SHOW', 'DISABLE', 'ENABLE'] + enum: ['HIDE', 'SHOW', 'DISABLE', 'ENABLE'], }, condition: { type: 'object', properties: { type: { type: 'string', - const: 'LEAF' + const: 'LEAF', }, scope: { - $ref: '#/definitions/scope' + $ref: '#/definitions/scope', }, expectedValue: { - type: ['string', 'integer', 'number', 'boolean'] - } + type: ['string', 'integer', 'number', 'boolean'], + }, }, - required: ['type', 'scope', 'expectedValue'] - } + required: ['type', 'scope', 'expectedValue'], + }, }, - required: ['effect', 'condition'] - } - } + required: ['effect', 'condition'], + }, + }, }; const typeControl: ControlElement = { type: 'Control', - scope: '#/properties/type' + scope: '#/properties/type', }; const labelControl: ControlElement = { type: 'Control', - scope: '#/properties/label' + scope: '#/properties/label', }; const scopeControl: ControlElement = { type: 'Control', - scope: '#/properties/scope' + scope: '#/properties/scope', }; const ruleControl: ControlElement = { type: 'Control', - scope: '#/properties/rule' + scope: '#/properties/rule', }; const uischema: VerticalLayout = { type: 'VerticalLayout', - elements: [typeControl, labelControl, scopeControl, ruleControl] + elements: [typeControl, labelControl, scopeControl, ruleControl], }; const generatedUiSchema = generateDefaultUISchema(schema); t.deepEqual(generatedUiSchema, uischema); }); -test('generate ui schema for schema w/o properties', t => { +test('generate ui schema for schema w/o properties', (t) => { const schema: JsonSchema = { - type: 'object' + type: 'object', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [] + elements: [], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate ui schema for schema with one property', t => { +test('generate ui schema for schema with one property', (t) => { const schema: JsonSchema = { type: 'object', properties: { name: { - type: 'string' - } - } + type: 'string', + }, + }, }; const control = { type: 'Control', - scope: '#/properties/name' + scope: '#/properties/name', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate ui schema for schema without object root', t => { +test('generate ui schema for schema without object root', (t) => { const schema: JsonSchema = { - type: 'string' + type: 'string', }; const control: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate ui schema for schema with unspecified object root', t => { +test('generate ui schema for schema with unspecified object root', (t) => { const schema: JsonSchema = { properties: { age: { - type: 'integer' - } - } + type: 'integer', + }, + }, }; const controlElement = { type: 'Control', - scope: '#/properties/age' + scope: '#/properties/age', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [controlElement] + elements: [controlElement], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test(`nested object not expanded`, t => { +test(`nested object not expanded`, (t) => { const schema = { type: 'object', properties: { id: { - type: 'string' + type: 'string', }, private: { type: 'object', properties: { name: { - type: 'string' - } - } - } - } + type: 'string', + }, + }, + }, + }, }; const idControl: ControlElement = { type: 'Control', - scope: '#/properties/id' + scope: '#/properties/id', }; const privateControl: ControlElement = { type: 'Control', - scope: '#/properties/private' + scope: '#/properties/private', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [idControl, privateControl] + elements: [idControl, privateControl], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test(`don't ignore non-json-schema id attributes`, t => { +test(`don't ignore non-json-schema id attributes`, (t) => { const schema = { type: 'object', properties: { id: { - type: 'string' + type: 'string', }, name: { - type: 'string' - } - } + type: 'string', + }, + }, }; const idControl: ControlElement = { type: 'Control', - scope: '#/properties/id' + scope: '#/properties/id', }; const nameControl: ControlElement = { type: 'Control', - scope: '#/properties/name' + scope: '#/properties/name', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [idControl, nameControl] + elements: [idControl, nameControl], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate ui schema for schema with multiple properties', t => { +test('generate ui schema for schema with multiple properties', (t) => { const schema: JsonSchema = { type: 'object', properties: { id: { type: 'string', - format: 'objectId' + format: 'objectId', }, lastName: { - type: 'string' + type: 'string', }, email: { - type: 'string' + type: 'string', }, firstName: { - type: 'string' + type: 'string', }, gender: { type: 'string', - enum: ['Male', 'Female'] + enum: ['Male', 'Female'], }, active: { - type: 'boolean' + type: 'boolean', }, registrationTime: { type: 'string', - format: 'date-time' + format: 'date-time', }, weight: { - type: 'number' + type: 'number', }, height: { - type: 'integer' + type: 'integer', }, nationality: { type: 'string', - enum: ['German', 'French', 'UK', 'US', 'Spanish', 'Italian', 'Russian'] + enum: ['German', 'French', 'UK', 'US', 'Spanish', 'Italian', 'Russian'], }, birthDate: { type: 'string', - format: 'date-time' - } + format: 'date-time', + }, }, additionalProperties: false, - required: ['id', 'lastName', 'email'] + required: ['id', 'lastName', 'email'], }; const uischema: Layout = { type: 'VerticalLayout', elements: [ { type: 'Control', - scope: '#/properties/id' + scope: '#/properties/id', }, { type: 'Control', - scope: '#/properties/lastName' + scope: '#/properties/lastName', }, { type: 'Control', - scope: '#/properties/email' + scope: '#/properties/email', }, { type: 'Control', - scope: '#/properties/firstName' + scope: '#/properties/firstName', }, { type: 'Control', - scope: '#/properties/gender' + scope: '#/properties/gender', }, { type: 'Control', - scope: '#/properties/active' + scope: '#/properties/active', }, { type: 'Control', - scope: '#/properties/registrationTime' + scope: '#/properties/registrationTime', }, { type: 'Control', - scope: '#/properties/weight' + scope: '#/properties/weight', }, { type: 'Control', - scope: '#/properties/height' + scope: '#/properties/height', }, { type: 'Control', - scope: '#/properties/nationality' + scope: '#/properties/nationality', }, { type: 'Control', - scope: '#/properties/birthDate' - } - ] as ControlElement[] + scope: '#/properties/birthDate', + }, + ] as ControlElement[], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate named array control', t => { +test('generate named array control', (t) => { const schema: JsonSchema = { type: 'object', properties: { @@ -339,159 +339,159 @@ test('generate named array control', t => { type: 'array', items: { properties: { - msg: { type: 'string' } - } - } - } - } + msg: { type: 'string' }, + }, + }, + }, + }, }; const control: ControlElement = { type: 'Control', - scope: '#/properties/comments' + scope: '#/properties/comments', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate unnamed array control', t => { +test('generate unnamed array control', (t) => { const schema: JsonSchema = { type: 'array', items: { properties: { - msg: { type: 'string' } - } - } + msg: { type: 'string' }, + }, + }, }; const control: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate unnamed array control w/o type', t => { +test('generate unnamed array control w/o type', (t) => { const schema: JsonSchema = { items: { properties: { - msg: { type: 'string' } - } - } + msg: { type: 'string' }, + }, + }, }; const control = { type: 'Control', - scope: '#' + scope: '#', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate for empty schema', t => { +test('generate for empty schema', (t) => { const schema: JsonSchema = {}; const uischema: Layout = null; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate for null schema', t => { +test('generate for null schema', (t) => { const schema: JsonSchema = null; const uischema: Layout = null; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate for undefined schema', t => { +test('generate for undefined schema', (t) => { const schema: JsonSchema = undefined; const uischema: Layout = null; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate control for oneOf', t => { +test('generate control for oneOf', (t) => { const schema: JsonSchema = { oneOf: [ { properties: { name: { - type: 'string' - } - } + type: 'string', + }, + }, }, { - type: 'number' - } - ] + type: 'number', + }, + ], }; const control = { type: 'Control', - scope: '#' + scope: '#', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate control for anyOf', t => { +test('generate control for anyOf', (t) => { const schema: JsonSchema = { anyOf: [ { properties: { name: { - type: 'string' - } - } + type: 'string', + }, + }, }, { - type: 'number' - } - ] + type: 'number', + }, + ], }; const control = { type: 'Control', - scope: '#' + scope: '#', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate control for allOf', t => { +test('generate control for allOf', (t) => { const schema: JsonSchema = { allOf: [ { properties: { name: { - type: 'string' - } - } + type: 'string', + }, + }, }, { - type: 'number' - } - ] + type: 'number', + }, + ], }; const control = { type: 'Control', - scope: '#' + scope: '#', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('no separate control for oneOf in array', t => { +test('no separate control for oneOf in array', (t) => { const schema: JsonSchema = { properties: { myarray: { @@ -500,30 +500,30 @@ test('no separate control for oneOf in array', t => { { properties: { name: { - type: 'string' - } - } + type: 'string', + }, + }, }, { - type: 'number' - } - ] - } - } - } + type: 'number', + }, + ], + }, + }, + }, }; const control = { type: 'Control', - scope: '#/properties/myarray' + scope: '#/properties/myarray', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('generate control for nested oneOf', t => { +test('generate control for nested oneOf', (t) => { const schema: JsonSchema = { properties: { myarray: { @@ -533,44 +533,46 @@ test('generate control for nested oneOf', t => { { properties: { name: { - type: 'string' - } - } + type: 'string', + }, + }, }, { - type: 'number' - } - ] - } - } - } - } + type: 'number', + }, + ], + }, + }, + }, + }, }; const control = { type: 'Control', - scope: '#/properties/myarray' + scope: '#/properties/myarray', }; const uischema: Layout = { type: 'VerticalLayout', - elements: [control] + elements: [control], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); -test('encode "/" in generated ui schema', t => { +test('encode "/" in generated ui schema', (t) => { const schema: JsonSchema = { properties: { 'some / initial / value': { - type : 'integer' - } - } + type: 'integer', + }, + }, }; const uischema: Layout = { type: 'VerticalLayout', - elements: [{ - type: 'Control', - scope: '#/properties/some ~1 initial ~1 value' - }] as ControlElement[] + elements: [ + { + type: 'Control', + scope: '#/properties/some ~1 initial ~1 value', + }, + ] as ControlElement[], }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); diff --git a/packages/core/test/i18n/i18nUtil.test.ts b/packages/core/test/i18n/i18nUtil.test.ts index d2a1c5db3..177eac73c 100644 --- a/packages/core/test/i18n/i18nUtil.test.ts +++ b/packages/core/test/i18n/i18nUtil.test.ts @@ -24,19 +24,24 @@ */ import test from 'ava'; -import { ControlElement, getI18nKeyPrefixBySchema, i18nJsonSchema, transformPathToI18nPrefix } from '../../src'; +import { + ControlElement, + getI18nKeyPrefixBySchema, + i18nJsonSchema, + transformPathToI18nPrefix, +} from '../../src'; -test('transformPathToI18nPrefix returns root when empty', t => { +test('transformPathToI18nPrefix returns root when empty', (t) => { t.is(transformPathToI18nPrefix(''), 'root'); }); -test('transformPathToI18nPrefix does not modify non-array paths', t => { +test('transformPathToI18nPrefix does not modify non-array paths', (t) => { t.is(transformPathToI18nPrefix('foo'), 'foo'); t.is(transformPathToI18nPrefix('foo.bar'), 'foo.bar'); t.is(transformPathToI18nPrefix('bar3.foo2'), 'bar3.foo2'); }); -test('transformPathToI18nPrefix removes array indices', t => { +test('transformPathToI18nPrefix removes array indices', (t) => { t.is(transformPathToI18nPrefix('foo.2.bar'), 'foo.bar'); t.is(transformPathToI18nPrefix('foo.234324234.bar'), 'foo.bar'); t.is(transformPathToI18nPrefix('foo.0.bar'), 'foo.bar'); @@ -47,42 +52,42 @@ test('transformPathToI18nPrefix removes array indices', t => { t.is(transformPathToI18nPrefix('3'), 'root'); }); -test('getI18nKeyPrefixBySchema gets key from uischema over schema', t => { +test('getI18nKeyPrefixBySchema gets key from uischema over schema', (t) => { const control: ControlElement = { type: 'Control', scope: '#/properties/foo', - i18n: 'controlFoo' + i18n: 'controlFoo', }; const schema: i18nJsonSchema = { type: 'string', - i18n: 'schemaFoo' - } + i18n: 'schemaFoo', + }; t.is(getI18nKeyPrefixBySchema(schema, control), 'controlFoo'); }); -test('getI18nKeyPrefixBySchema gets schema key for missing uischema key', t => { +test('getI18nKeyPrefixBySchema gets schema key for missing uischema key', (t) => { const control: ControlElement = { type: 'Control', scope: '#/properties/foo', }; const schema: i18nJsonSchema = { type: 'string', - i18n: 'schemaFoo' - } + i18n: 'schemaFoo', + }; t.is(getI18nKeyPrefixBySchema(schema, control), 'schemaFoo'); }); -test('getI18nKeyPrefixBySchema returns undefined for missing uischema and schema keys', t => { +test('getI18nKeyPrefixBySchema returns undefined for missing uischema and schema keys', (t) => { const control: ControlElement = { type: 'Control', scope: '#/properties/foo', }; const schema: i18nJsonSchema = { type: 'string', - } + }; t.is(getI18nKeyPrefixBySchema(schema, control), undefined); }); -test('getI18nKeyPrefixBySchema returns undefined for undefined parameters', t => { +test('getI18nKeyPrefixBySchema returns undefined for undefined parameters', (t) => { t.is(getI18nKeyPrefixBySchema(undefined, undefined), undefined); -}); \ No newline at end of file +}); diff --git a/packages/core/test/reducers/core.test.ts b/packages/core/test/reducers/core.test.ts index 6f1606916..27079a5f8 100644 --- a/packages/core/test/reducers/core.test.ts +++ b/packages/core/test/reducers/core.test.ts @@ -25,33 +25,40 @@ import test from 'ava'; import Ajv from 'ajv'; import { coreReducer } from '../../src/reducers'; -import { init, setSchema, setValidationMode, update, updateCore, updateErrors } from '../../src/actions'; +import { + init, + setSchema, + setValidationMode, + update, + updateCore, + updateErrors, +} from '../../src/actions'; import { JsonSchema } from '../../src/models/jsonSchema'; import { errorAt, JsonFormsCore, validate, - subErrorsAt + subErrorsAt, } from '../../src/reducers/core'; import { cloneDeep } from 'lodash'; import { createAjv } from '../../src/util/validator'; -test('core reducer should support v7', t => { +test('core reducer should support v7', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; const after = coreReducer( undefined, init( { - foo: 'baz' + foo: 'baz', }, schema ) @@ -59,98 +66,100 @@ test('core reducer should support v7', t => { t.is(after.errors.length, 1); }); -test('core reducer - no previous state - init without options should create new ajv', t => { +test('core reducer - no previous state - init without options should create new ajv', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; const after = coreReducer(undefined, init({}, schema, undefined, undefined)); t.true(after.ajv !== undefined); }); -test('core reducer - no previous state - init with ajv as options object should use it', t => { +test('core reducer - no previous state - init with ajv as options object should use it', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; const myAjv = new Ajv(); const after = coreReducer(undefined, init({}, schema, undefined, myAjv)); t.deepEqual(after.ajv, myAjv); }); -test('core reducer - no previous state - init with empty options object', t => { +test('core reducer - no previous state - init with empty options object', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; const after = coreReducer(undefined, init({}, schema, undefined, {})); t.true(after.ajv !== undefined); }); -test('core reducer - no previous state - init with options object with ajv', t => { +test('core reducer - no previous state - init with options object with ajv', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; const myAjv = new Ajv(); const after = coreReducer( undefined, init({}, schema, undefined, { - ajv: myAjv + ajv: myAjv, }) ); t.deepEqual(after.ajv, myAjv); }); -test('core reducer - previous state - init without options should keep previous objects', t => { +test('core reducer - previous state - init without options should keep previous objects', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; const myAjv = new Ajv(); - const additionalErrors = [{ - instancePath: '', - dataPath: '', - schemaPath: '#/required', - keyword: 'required', - params: { - missingProperty: 'foo' + const additionalErrors = [ + { + instancePath: '', + dataPath: '', + schemaPath: '#/required', + keyword: 'required', + params: { + missingProperty: 'foo', + }, }, - }]; + ]; const after = coreReducer( { data: {}, schema: {}, uischema: { - type: 'Label' + type: 'Label', }, ajv: myAjv, - additionalErrors + additionalErrors, }, init({}, schema) ); @@ -158,15 +167,15 @@ test('core reducer - previous state - init without options should keep previous t.deepEqual(after.additionalErrors, additionalErrors); }); -test('core reducer - previous state - init with ajv options object should overwrite ajv', t => { +test('core reducer - previous state - init with ajv options object should overwrite ajv', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; const previousAjv = new Ajv(); const newAjv = new Ajv(); @@ -175,7 +184,7 @@ test('core reducer - previous state - init with ajv options object should overwr data: {}, schema: {}, uischema: { - type: 'Label' + type: 'Label', }, ajv: previousAjv, }, @@ -184,78 +193,84 @@ test('core reducer - previous state - init with ajv options object should overwr t.deepEqual(after.ajv, newAjv); }); -test('core reducer - previous state - init with additionalErrors option object should overwrite additionalErrors', t => { +test('core reducer - previous state - init with additionalErrors option object should overwrite additionalErrors', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; - const prevAdditionalErrors = [{ - instancePath: '', - dataPath: '', - schemaPath: '#/required', - keyword: 'required', - params: { - missingProperty: 'foo' - }, - }]; - const currentAdditionalErrors = [{ - instancePath: '', - dataPath: '', - schemaPath: '#/required', - keyword: 'required', - params: { - missingProperty: 'bar' + const prevAdditionalErrors = [ + { + instancePath: '', + dataPath: '', + schemaPath: '#/required', + keyword: 'required', + params: { + missingProperty: 'foo', + }, }, - }]; + ]; + const currentAdditionalErrors = [ + { + instancePath: '', + dataPath: '', + schemaPath: '#/required', + keyword: 'required', + params: { + missingProperty: 'bar', + }, + }, + ]; const after = coreReducer( { data: {}, schema: {}, uischema: { - type: 'Label' + type: 'Label', }, - additionalErrors: prevAdditionalErrors + additionalErrors: prevAdditionalErrors, }, init({}, schema, undefined, { additionalErrors: currentAdditionalErrors }) ); t.deepEqual(after.additionalErrors, currentAdditionalErrors); }); -test('core reducer - previous state - init with empty options should not overwrite', t => { +test('core reducer - previous state - init with empty options should not overwrite', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }; const myAjv = new Ajv(); - const additionalErrors = [{ - instancePath: '', - dataPath: '', - schemaPath: '#/required', - keyword: 'required', - params: { - missingProperty: 'foo' + const additionalErrors = [ + { + instancePath: '', + dataPath: '', + schemaPath: '#/required', + keyword: 'required', + params: { + missingProperty: 'foo', + }, }, - }]; + ]; const after = coreReducer( { data: {}, schema: {}, uischema: { - type: 'Label' + type: 'Label', }, ajv: myAjv, - additionalErrors + additionalErrors, }, init({}, schema, undefined, {}) ); @@ -263,17 +278,17 @@ test('core reducer - previous state - init with empty options should not overwri t.deepEqual(after.additionalErrors, additionalErrors); }); -test('core reducer - previous state - init with undefined data should not change data', t => { +test('core reducer - previous state - init with undefined data should not change data', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' + type: 'string', }, color: { - type: 'string' - } - } + type: 'string', + }, + }, }; const after = coreReducer( @@ -281,23 +296,23 @@ test('core reducer - previous state - init with undefined data should not change data: undefined, schema: {}, uischema: { - type: 'Label' - } + type: 'Label', + }, }, init(undefined, schema, undefined, {}) ); t.deepEqual(after.data, undefined); }); -test('core reducer - previous state - init schema with id', t => { +test('core reducer - previous state - init schema with id', (t) => { const schema: JsonSchema = { $id: 'https://www.jsonforms.io/example.json', type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const updatedSchema = cloneDeep(schema); updatedSchema.properties.animal.minLength = 5; @@ -314,63 +329,63 @@ test('core reducer - previous state - init schema with id', t => { t.is(after.schema.properties.animal.minLength, 5); }); -test('core reducer - update - undefined data should update for given path', t => { +test('core reducer - update - undefined data should update for given path', (t) => { const schema = { type: 'object', properties: { foo: { - type: 'string' - } - } + type: 'string', + }, + }, }; const before: JsonFormsCore = { data: undefined, schema: schema, uischema: { - type: 'Label' + type: 'Label', }, errors: [], - validator: new Ajv().compile(schema) + validator: new Ajv().compile(schema), }; const after = coreReducer( before, - update('foo', _ => { + update('foo', (_) => { return 'bar'; }) ); t.not(before, after); t.not(before.data, after.data); - t.deepEqual(after, { ...before, data: { foo: 'bar'} }); + t.deepEqual(after, { ...before, data: { foo: 'bar' } }); }); -test('core reducer - update - path is undefined state should remain same', t => { +test('core reducer - update - path is undefined state should remain same', (t) => { const before: JsonFormsCore = { data: { foo: 'bar', baz: { - bar: 'bar' - } + bar: 'bar', + }, }, schema: { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }, uischema: { - type: 'Label' - } + type: 'Label', + }, }; const after = coreReducer( before, - update(undefined, _ => { + update(undefined, (_) => { return { foo: 'anything' }; }) ); @@ -381,31 +396,31 @@ test('core reducer - update - path is undefined state should remain same', t => t.deepEqual(before, after); }); -test('core reducer - update - path is null state should remain same', t => { +test('core reducer - update - path is null state should remain same', (t) => { const before: JsonFormsCore = { data: { foo: 'bar', baz: { - bar:'bar' - } + bar: 'bar', + }, }, schema: { type: 'object', properties: { foo: { type: 'string', - const: 'bar' - } - } + const: 'bar', + }, + }, }, uischema: { - type: 'Label' - } + type: 'Label', + }, }; const after = coreReducer( before, - update(null, _ => { + update(null, (_) => { return { foo: 'anything' }; }) ); @@ -416,34 +431,34 @@ test('core reducer - update - path is null state should remain same', t => { t.deepEqual(before, after); }); -test('core reducer - update - empty path should update root state', t => { +test('core reducer - update - empty path should update root state', (t) => { const schema = { type: 'object', properties: { foo: { - type: 'string' - } - } + type: 'string', + }, + }, }; const before: JsonFormsCore = { data: { foo: 'bar', baz: { - bar:'bar' - } + bar: 'bar', + }, }, errors: [], schema, uischema: { - type: 'Label' + type: 'Label', }, - validator: new Ajv().compile(schema) + validator: new Ajv().compile(schema), }; const after = coreReducer( before, - update('', _ => { + update('', (_) => { return { foo: 'xyz' }; }) ); @@ -453,17 +468,17 @@ test('core reducer - update - empty path should update root state', t => { t.deepEqual(after, { ...before, data: { foo: 'xyz' } }); }); -test('core reducer - update - providing a path should update data only belonging to path', t => { +test('core reducer - update - providing a path should update data only belonging to path', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' + type: 'string', }, color: { - type: 'string' - } - } + type: 'string', + }, + }, }; const before: JsonFormsCore = { @@ -471,20 +486,20 @@ test('core reducer - update - providing a path should update data only belonging animal: 'Sloth', color: 'Blue', baz: { - bar: 'bar' - } + bar: 'bar', + }, }, errors: [], schema, uischema: { - type: 'Label' + type: 'Label', }, - validator: new Ajv().compile(schema) + validator: new Ajv().compile(schema), }; const after = coreReducer( before, - update('color', _ => { + update('color', (_) => { return 'Green'; }) ); @@ -495,18 +510,18 @@ test('core reducer - update - providing a path should update data only belonging t.deepEqual(after, { ...before, data: { ...before.data, color: 'Green' } }); }); -test('core reducer - update - should update errors', t => { +test('core reducer - update - should update errors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' + type: 'string', }, color: { type: 'string', - enum: ['Blue', 'Green'] - } - } + enum: ['Blue', 'Green'], + }, + }, }; const before: JsonFormsCore = { @@ -517,14 +532,14 @@ test('core reducer - update - should update errors', t => { errors: [], schema, uischema: { - type: 'Label' + type: 'Label', }, - validator: new Ajv().compile(schema) + validator: new Ajv().compile(schema), }; const after = coreReducer( before, - update('color', _ => { + update('color', (_) => { return 'Yellow'; }) ); @@ -538,31 +553,31 @@ test('core reducer - update - should update errors', t => { keyword: 'enum', message: 'must be equal to one of the allowed values', params: { - allowedValues: ['Blue', 'Green'] + allowedValues: ['Blue', 'Green'], }, - schemaPath: '#/properties/color/enum' - } - ] + schemaPath: '#/properties/color/enum', + }, + ], }); }); -test('core reducer - updateErrors - should update errors with empty list', t => { +test('core reducer - updateErrors - should update errors with empty list', (t) => { const before: JsonFormsCore = { data: {}, schema: {}, - uischema: undefined + uischema: undefined, }; const after = coreReducer(before, updateErrors([])); t.deepEqual(after, { ...before, errors: [] }); }); -test('core reducer - updateErrors - should update errors with error', t => { +test('core reducer - updateErrors - should update errors with error', (t) => { const before: JsonFormsCore = { data: {}, schema: {}, uischema: undefined, - errors: [] + errors: [], }; const error = { @@ -570,41 +585,41 @@ test('core reducer - updateErrors - should update errors with error', t => { keyword: 'enum', message: 'should be equal to one of the allowed values', params: { - allowedValues: ['Blue', 'Green'] + allowedValues: ['Blue', 'Green'], }, - schemaPath: '#/properties/color/enum' + schemaPath: '#/properties/color/enum', }; const after = coreReducer(before, updateErrors([error])); t.deepEqual(after, { ...before, errors: [error] }); }); -test('core reducer - updateErrors - should update errors with undefined', t => { +test('core reducer - updateErrors - should update errors with undefined', (t) => { const before: JsonFormsCore = { data: {}, schema: {}, uischema: undefined, - errors: [] + errors: [], }; const after = coreReducer(before, updateErrors(undefined)); t.deepEqual(after, { ...before, errors: undefined }); }); -test('errorAt filters enum', t => { +test('errorAt filters enum', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', properties: { bar: { type: 'string', - enum: ['f', 'b'] + enum: ['f', 'b'], }, foo: { type: 'string', - enum: ['f', 'b'] - } - } + enum: ['f', 'b'], + }, + }, }; const data = { foo: '', bar: '' }; const v = ajv.compile(schema); @@ -614,28 +629,28 @@ test('errorAt filters enum', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt('foo', schema.properties.foo)(state); t.is(filtered.length, 1); t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters required', t => { +test('errorAt filters required', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', properties: { bar: { type: 'string', - enum: ['f', 'b'] + enum: ['f', 'b'], }, foo: { type: 'string', - enum: ['f', 'b'] - } + enum: ['f', 'b'], + }, }, - required: ['bar', 'foo'] + required: ['bar', 'foo'], }; const data = {}; const v = ajv.compile(schema); @@ -645,14 +660,14 @@ test('errorAt filters required', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt('foo', schema.properties.foo)(state); t.is(filtered.length, 1); t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters required in oneOf object', t => { +test('errorAt filters required in oneOf object', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -664,29 +679,29 @@ test('errorAt filters required in oneOf object', t => { type: 'object', properties: { foo: { - type: 'string' - } + type: 'string', + }, }, required: ['foo'], - additionalProperties: false + additionalProperties: false, }, { title: 'Bar', type: 'object', properties: { bar: { - type: 'number' - } + type: 'number', + }, }, required: ['bar'], - additionalProperties: false - } - ] - } + additionalProperties: false, + }, + ], + }, }, - additionalProperties: false + additionalProperties: false, }; - const data = { fooOrBar: { } }; + const data = { fooOrBar: {} }; const v = ajv.compile(schema); const errors = validate(v, data); @@ -694,7 +709,7 @@ test('errorAt filters required in oneOf object', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt( 'fooOrBar.foo', @@ -704,7 +719,7 @@ test('errorAt filters required in oneOf object', t => { t.deepEqual(filtered[0].keyword, 'required'); }); -test('errorAt filters required in anyOf object', t => { +test('errorAt filters required in anyOf object', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -716,29 +731,29 @@ test('errorAt filters required in anyOf object', t => { type: 'object', properties: { foo: { - type: 'string' - } + type: 'string', + }, }, required: ['foo'], - additionalProperties: false + additionalProperties: false, }, { title: 'Bar', type: 'object', properties: { bar: { - type: 'number' - } + type: 'number', + }, }, required: ['bar'], - additionalProperties: false - } - ] - } + additionalProperties: false, + }, + ], + }, }, - additionalProperties: false + additionalProperties: false, }; - const data = { fooOrBar: { } }; + const data = { fooOrBar: {} }; const v = ajv.compile(schema); const errors = validate(v, data); @@ -746,7 +761,7 @@ test('errorAt filters required in anyOf object', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt( 'fooOrBar.foo', @@ -756,7 +771,7 @@ test('errorAt filters required in anyOf object', t => { t.deepEqual(filtered[0].keyword, 'required'); }); -test('errorAt filters array minItems', t => { +test('errorAt filters array minItems', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -767,9 +782,9 @@ test('errorAt filters array minItems', t => { items: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, - minItems: 1 + minItems: 1, }, colours: { title: 'Colours', @@ -777,15 +792,15 @@ test('errorAt filters array minItems', t => { items: { title: 'Type', type: 'string', - enum: ['Red', 'Green', 'Blue'] + enum: ['Red', 'Green', 'Blue'], }, - minItems: 1 - } - } + minItems: 1, + }, + }, }; const data: { colours: string[]; numbers: string[] } = { colours: [], - numbers: [] + numbers: [], }; const v = ajv.compile(schema); const errors = validate(v, data); @@ -794,14 +809,14 @@ test('errorAt filters array minItems', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt('colours', schema.properties.colours)(state); t.is(filtered.length, 1); t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters array inner value', t => { +test('errorAt filters array inner value', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -812,9 +827,9 @@ test('errorAt filters array inner value', t => { items: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, - minItems: 1 + minItems: 1, }, colours: { title: 'Colours', @@ -822,15 +837,15 @@ test('errorAt filters array inner value', t => { items: { title: 'Type', type: 'string', - enum: ['Red', 'Green', 'Blue'] + enum: ['Red', 'Green', 'Blue'], }, - minItems: 1 - } - } + minItems: 1, + }, + }, }; const data: { colours: string[]; numbers: string[] } = { colours: ['Foo'], - numbers: ['Bar'] + numbers: ['Bar'], }; const v = ajv.compile(schema); const errors = validate(v, data); @@ -839,14 +854,14 @@ test('errorAt filters array inner value', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt('colours.0', schema.properties.colours)(state); t.is(filtered.length, 1); t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters oneOf simple', t => { +test('errorAt filters oneOf simple', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -856,16 +871,16 @@ test('errorAt filters oneOf simple', t => { { title: 'Numbers', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, { title: 'Colours', type: 'string', - enum: ['Red', 'Green', 'Blue'] - } - ] - } - } + enum: ['Red', 'Green', 'Blue'], + }, + ], + }, + }, }; const data: { coloursOrNumbers: string } = { coloursOrNumbers: 'Foo' }; const v = ajv.compile(schema); @@ -875,7 +890,7 @@ test('errorAt filters oneOf simple', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt( 'coloursOrNumbers', @@ -885,7 +900,7 @@ test('errorAt filters oneOf simple', t => { t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters anyOf simple', t => { +test('errorAt filters anyOf simple', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -895,16 +910,16 @@ test('errorAt filters anyOf simple', t => { { title: 'Numbers', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, { title: 'Colours', type: 'string', - enum: ['Red', 'Green', 'Blue'] - } - ] - } - } + enum: ['Red', 'Green', 'Blue'], + }, + ], + }, + }, }; const data: { coloursOrNumbers: string } = { coloursOrNumbers: 'Foo' }; const v = ajv.compile(schema); @@ -914,7 +929,7 @@ test('errorAt filters anyOf simple', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt( 'coloursOrNumbers', @@ -924,7 +939,7 @@ test('errorAt filters anyOf simple', t => { t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters oneOf objects', t => { +test('errorAt filters oneOf objects', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -938,10 +953,10 @@ test('errorAt filters oneOf objects', t => { number: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] - } + enum: ['One', 'Two', 'Three'], + }, }, - additionalProperties: false + additionalProperties: false, }, { title: 'Colours', @@ -950,15 +965,15 @@ test('errorAt filters oneOf objects', t => { colour: { title: 'Type', type: 'string', - enum: ['Red', 'Green', 'Blue'] - } + enum: ['Red', 'Green', 'Blue'], + }, }, - additionalProperties: false - } - ] - } + additionalProperties: false, + }, + ], + }, }, - additionalProperties: false + additionalProperties: false, }; const data = { coloursOrNumbers: { colour: 'Foo' } }; const v = ajv.compile(schema); @@ -968,7 +983,7 @@ test('errorAt filters oneOf objects', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt( 'coloursOrNumbers.colour', @@ -979,7 +994,7 @@ test('errorAt filters oneOf objects', t => { t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters oneOf objects same properties', t => { +test('errorAt filters oneOf objects same properties', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -993,9 +1008,9 @@ test('errorAt filters oneOf objects same properties', t => { colourOrNumber: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] - } - } + enum: ['One', 'Two', 'Three'], + }, + }, }, { title: 'Colours', @@ -1004,13 +1019,13 @@ test('errorAt filters oneOf objects same properties', t => { colourOrNumber: { title: 'Type', type: 'string', - enum: ['Red', 'Green', 'Blue'] - } - } - } - ] - } - } + enum: ['Red', 'Green', 'Blue'], + }, + }, + }, + ], + }, + }, }; const data = { coloursOrNumbers: { colourOrNumber: 'Foo' } }; const v = ajv.compile(schema); @@ -1020,7 +1035,7 @@ test('errorAt filters oneOf objects same properties', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt( 'coloursOrNumbers.colourOrNumber', @@ -1030,7 +1045,7 @@ test('errorAt filters oneOf objects same properties', t => { t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters oneOf array', t => { +test('errorAt filters oneOf array', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -1043,9 +1058,9 @@ test('errorAt filters oneOf array', t => { items: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, - minItems: 1 + minItems: 1, }, { title: 'Colours', @@ -1053,13 +1068,13 @@ test('errorAt filters oneOf array', t => { items: { title: 'Type', type: 'string', - enum: ['Red', 'Green', 'Blue'] + enum: ['Red', 'Green', 'Blue'], }, - minItems: 1 - } - ] - } - } + minItems: 1, + }, + ], + }, + }, }; const data: { coloursOrNumbers: string[] } = { coloursOrNumbers: [] }; const v = ajv.compile(schema); @@ -1069,7 +1084,7 @@ test('errorAt filters oneOf array', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt( 'coloursOrNumbers', @@ -1079,7 +1094,7 @@ test('errorAt filters oneOf array', t => { t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt filters oneOf array inner', t => { +test('errorAt filters oneOf array inner', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -1092,9 +1107,9 @@ test('errorAt filters oneOf array inner', t => { items: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, - minItems: 1 + minItems: 1, }, { title: 'Colours', @@ -1102,13 +1117,13 @@ test('errorAt filters oneOf array inner', t => { items: { title: 'Type', type: 'string', - enum: ['Red', 'Green', 'Blue'] + enum: ['Red', 'Green', 'Blue'], }, - minItems: 1 - } - ] - } - } + minItems: 1, + }, + ], + }, + }, }; const data: { coloursOrNumbers: string[] } = { coloursOrNumbers: ['Foo'] }; const v = ajv.compile(schema); @@ -1118,7 +1133,7 @@ test('errorAt filters oneOf array inner', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = errorAt( 'coloursOrNumbers', @@ -1127,7 +1142,7 @@ test('errorAt filters oneOf array inner', t => { t.is(filtered.length, 0); }); -test('subErrorsAt filters array inner', t => { +test('subErrorsAt filters array inner', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -1138,9 +1153,9 @@ test('subErrorsAt filters array inner', t => { items: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, - minItems: 1 + minItems: 1, }, colours: { title: 'Colours', @@ -1148,15 +1163,15 @@ test('subErrorsAt filters array inner', t => { items: { title: 'Type', type: 'string', - enum: ['Red', 'Green', 'Blue'] + enum: ['Red', 'Green', 'Blue'], }, - minItems: 1 - } - } + minItems: 1, + }, + }, }; const data: { colours: string[]; numbers: string[] } = { colours: ['Foo'], - numbers: ['Bar'] + numbers: ['Bar'], }; const v = ajv.compile(schema); const errors = validate(v, data); @@ -1165,7 +1180,7 @@ test('subErrorsAt filters array inner', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = subErrorsAt( 'colours', @@ -1175,7 +1190,7 @@ test('subErrorsAt filters array inner', t => { t.deepEqual(filtered[0], state.errors[1]); }); -test('subErrorsAt only returning suberrors', t => { +test('subErrorsAt only returning suberrors', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -1187,13 +1202,13 @@ test('subErrorsAt only returning suberrors', t => { items: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, - } - } + }, + }, }; const data: { numbers: string[] } = { - numbers: [] + numbers: [], }; const v = ajv.compile(schema); const errors = validate(v, data); @@ -1202,7 +1217,7 @@ test('subErrorsAt only returning suberrors', t => { data, schema, uischema: undefined, - errors + errors, }; const subErrors = subErrorsAt( 'numbers', @@ -1211,7 +1226,7 @@ test('subErrorsAt only returning suberrors', t => { t.is(subErrors.length, 0); }); -test('subErrorsAt filters oneOf array inner', t => { +test('subErrorsAt filters oneOf array inner', (t) => { const ajv = createAjv(); const schema: JsonSchema = { type: 'object', @@ -1224,9 +1239,9 @@ test('subErrorsAt filters oneOf array inner', t => { items: { title: 'Type', type: 'string', - enum: ['One', 'Two', 'Three'] + enum: ['One', 'Two', 'Three'], }, - minItems: 1 + minItems: 1, }, { title: 'Colours', @@ -1234,13 +1249,13 @@ test('subErrorsAt filters oneOf array inner', t => { items: { title: 'Type', type: 'string', - enum: ['Red', 'Green', 'Blue'] + enum: ['Red', 'Green', 'Blue'], }, - minItems: 1 - } - ] - } - } + minItems: 1, + }, + ], + }, + }, }; const data: { coloursOrNumbers: string[] } = { coloursOrNumbers: ['Foo'] }; const v = ajv.compile(schema); @@ -1250,7 +1265,7 @@ test('subErrorsAt filters oneOf array inner', t => { data, schema, uischema: undefined, - errors + errors, }; const filtered = subErrorsAt( 'coloursOrNumbers', @@ -1260,18 +1275,18 @@ test('subErrorsAt filters oneOf array inner', t => { t.deepEqual(filtered[0], state.errors[1]); }); -test('errorAt respects hide validation mode', t => { +test('errorAt respects hide validation mode', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; const core: JsonFormsCore = coreReducer( @@ -1280,31 +1295,33 @@ test('errorAt respects hide validation mode', t => { ); t.is(core.errors.length, 1); t.is(errorAt('animal', schema)(core).length, 0); -}) +}); -test('errorAt contains additionalErrors', t => { +test('errorAt contains additionalErrors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; - const additionalErrors = [{ - instancePath: '', - dataPath: '', - schemaPath: '#/required', - keyword: 'required', - params: { - missingProperty: 'animal' + const additionalErrors = [ + { + instancePath: '', + dataPath: '', + schemaPath: '#/required', + keyword: 'required', + params: { + missingProperty: 'animal', + }, }, - }]; + ]; const core: JsonFormsCore = coreReducer( undefined, init(data, schema, undefined, { additionalErrors }) @@ -1316,32 +1333,37 @@ test('errorAt contains additionalErrors', t => { t.true(errorsAt.indexOf(additionalErrors[0]) > -1); }); -test('errorAt contains additionalErrors for validation mode NoValidation ', t => { +test('errorAt contains additionalErrors for validation mode NoValidation ', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; - const additionalErrors = [{ - instancePath: '', - dataPath: '', - schemaPath: '#/required', - keyword: 'required', - params: { - missingProperty: 'animal' + const additionalErrors = [ + { + instancePath: '', + dataPath: '', + schemaPath: '#/required', + keyword: 'required', + params: { + missingProperty: 'animal', + }, }, - }]; + ]; const core: JsonFormsCore = coreReducer( undefined, - init(data, schema, undefined, { additionalErrors, validationMode: 'NoValidation' }) + init(data, schema, undefined, { + additionalErrors, + validationMode: 'NoValidation', + }) ); t.is(core.errors.length, 0); t.is(core.additionalErrors.length, 1); @@ -1350,32 +1372,37 @@ test('errorAt contains additionalErrors for validation mode NoValidation ', t => t.is(errorsAt.indexOf(additionalErrors[0]), 0); }); -test('errorAt contains additionalErrors for validation mode ValidateAndHide ', t => { +test('errorAt contains additionalErrors for validation mode ValidateAndHide ', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; - const additionalErrors = [{ - instancePath: '', - dataPath: '', - schemaPath: '#/required', - keyword: 'required', - params: { - missingProperty: 'animal' + const additionalErrors = [ + { + instancePath: '', + dataPath: '', + schemaPath: '#/required', + keyword: 'required', + params: { + missingProperty: 'animal', + }, }, - }]; + ]; const core: JsonFormsCore = coreReducer( undefined, - init(data, schema, undefined, { additionalErrors, validationMode: 'ValidateAndHide' }) + init(data, schema, undefined, { + additionalErrors, + validationMode: 'ValidateAndHide', + }) ); t.is(core.errors.length, 1); t.is(core.additionalErrors.length, 1); @@ -1384,18 +1411,18 @@ test('errorAt contains additionalErrors for validation mode ValidateAndHide ', t t.is(errorsAt.indexOf(additionalErrors[0]), 0); }); -test('core reducer - setValidationMode - No validation should not produce errors', t => { +test('core reducer - setValidationMode - No validation should not produce errors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; const core: JsonFormsCore = coreReducer( @@ -1406,18 +1433,18 @@ test('core reducer - setValidationMode - No validation should not produce errors t.is(core.validationMode, 'NoValidation'); }); -test('core reducer - setValidationMode - No validation should remove errors', t => { +test('core reducer - setValidationMode - No validation should remove errors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; const before: JsonFormsCore = coreReducer(undefined, init(data, schema)); @@ -1428,27 +1455,27 @@ test('core reducer - setValidationMode - No validation should remove errors', t t.is(after.validationMode, 'NoValidation'); }); -test('core reducer - init - ValidateAndShow should be default validationMode', t => { +test('core reducer - init - ValidateAndShow should be default validationMode', (t) => { const data = { - animal: 100 + animal: 100, }; const core: JsonFormsCore = coreReducer(undefined, init(data)); t.is(core.validationMode, 'ValidateAndShow'); }); -test('core reducer - init - Validation should produce errors', t => { +test('core reducer - init - Validation should produce errors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; const coreShow: JsonFormsCore = coreReducer( @@ -1466,18 +1493,18 @@ test('core reducer - init - Validation should produce errors', t => { t.is(coreHide.validationMode, 'ValidateAndHide'); }); -test('core reducer - setValidationMode - Validation should produce errors', t => { +test('core reducer - setValidationMode - Validation should produce errors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; const before: JsonFormsCore = coreReducer( @@ -1499,24 +1526,21 @@ test('core reducer - setValidationMode - Validation should produce errors', t => t.is(coreHide.errors.length, 1); }); -test('core reducer - setValidationMode - Hide validation should preserve errors', t => { +test('core reducer - setValidationMode - Hide validation should preserve errors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 100 + animal: 100, }; - const before: JsonFormsCore = coreReducer( - undefined, - init(data, schema) - ); + const before: JsonFormsCore = coreReducer(undefined, init(data, schema)); t.is(before.errors.length, 1); const after: JsonFormsCore = coreReducer( @@ -1526,18 +1550,18 @@ test('core reducer - setValidationMode - Hide validation should preserve errors' t.is(after.errors.length, 1); }); -test('core reducer - update - NoValidation should not produce errors', t => { +test('core reducer - update - NoValidation should not produce errors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 'dog' + animal: 'dog', }; const before: JsonFormsCore = coreReducer( @@ -1553,18 +1577,18 @@ test('core reducer - update - NoValidation should not produce errors', t => { t.is(after.errors.length, 0); }); -test('core reducer - update - ValidateAndHide should produce errors', t => { +test('core reducer - update - ValidateAndHide should produce errors', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 'dog' + animal: 'dog', }; const before: JsonFormsCore = coreReducer( @@ -1580,23 +1604,20 @@ test('core reducer - update - ValidateAndHide should produce errors', t => { t.is(after.errors.length, 1); }); -test('core reducer - update core - state should be unchanged when nothing changes', t => { +test('core reducer - update core - state should be unchanged when nothing changes', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 'dog' + animal: 'dog', }; - const before: JsonFormsCore = coreReducer( - undefined, - init(data, schema) - ); + const before: JsonFormsCore = coreReducer(undefined, init(data, schema)); const after: JsonFormsCore = coreReducer( before, @@ -1605,29 +1626,31 @@ test('core reducer - update core - state should be unchanged when nothing change t.true(before === after); }); -test('core reducer - update core - unchanged state properties should be unchanged when state changes', t => { +test('core reducer - update core - unchanged state properties should be unchanged when state changes', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 'dog' + animal: 'dog', }; - const before: JsonFormsCore = coreReducer( - undefined, - init(data, schema) - ); + const before: JsonFormsCore = coreReducer(undefined, init(data, schema)); const afterDataUpdate: JsonFormsCore = coreReducer( before, - updateCore({ - animal: 'cat' - }, before.schema, before.uischema, { ajv: before.ajv, additionalErrors: before.additionalErrors }) + updateCore( + { + animal: 'cat', + }, + before.schema, + before.uischema, + { ajv: before.ajv, additionalErrors: before.additionalErrors } + ) ); t.true(before.schema === afterDataUpdate.schema); t.true(before.ajv === afterDataUpdate.ajv); @@ -1641,64 +1664,68 @@ test('core reducer - update core - unchanged state properties should be unchange type: 'object', properties: { animal: { - type: 'string' + type: 'string', }, id: { - type: 'number' - } - } + type: 'number', + }, + }, }; // check that data stays unchanged as well - const afterSchemaUpdate : JsonFormsCore = coreReducer( + const afterSchemaUpdate: JsonFormsCore = coreReducer( before, updateCore(before.data, updatedSchema, before.uischema, before.ajv) ); t.true(before.data === afterSchemaUpdate.data); }); -test('core reducer - update core - additionalErrors should update', t => { +test('core reducer - update core - additionalErrors should update', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const data = { - animal: 'dog' + animal: 'dog', }; const before: JsonFormsCore = coreReducer( undefined, init(data, schema, undefined, { additionalErrors: [] }) ); - const additionalErrors = [{ - instancePath: '', - dataPath: '', - schemaPath: '#/required', - keyword: 'required', - params: { - missingProperty: 'animal' + const additionalErrors = [ + { + instancePath: '', + dataPath: '', + schemaPath: '#/required', + keyword: 'required', + params: { + missingProperty: 'animal', + }, }, - }]; + ]; const after: JsonFormsCore = coreReducer( before, - updateCore(before.data, before.schema, before.uischema, { additionalErrors }) + updateCore(before.data, before.schema, before.uischema, { + additionalErrors, + }) ); t.true(after.additionalErrors === additionalErrors); }); -test('core reducer - setSchema - schema with id', t => { +test('core reducer - setSchema - schema with id', (t) => { const schema: JsonSchema = { $id: 'https://www.jsonforms.io/example.json', type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const updatedSchema = cloneDeep(schema); updatedSchema.properties.animal.minLength = 5; @@ -1708,11 +1735,6 @@ test('core reducer - setSchema - schema with id', t => { init(undefined, schema, undefined, undefined) ); - const after: JsonFormsCore = coreReducer( - before, - setSchema(updatedSchema) - ); + const after: JsonFormsCore = coreReducer(before, setSchema(updatedSchema)); t.is(after.schema.properties.animal.minLength, 5); }); - - diff --git a/packages/core/test/reducers/uischemas.test.ts b/packages/core/test/reducers/uischemas.test.ts index 623b449af..9eec9638c 100644 --- a/packages/core/test/reducers/uischemas.test.ts +++ b/packages/core/test/reducers/uischemas.test.ts @@ -29,30 +29,30 @@ import configureStore from 'redux-mock-store'; import { findMatchingUISchema, uischemaRegistryReducer, - UISchemaTester + UISchemaTester, } from '../../src/reducers/uischemas'; import { registerUISchema, RemoveUISchemaAction, - unregisterUISchema + unregisterUISchema, } from '../../src/actions'; import { findUISchema, getSchema } from '../../src/reducers'; import { Generate } from '../../src/generators'; import { JsonFormsState } from '../../src'; -test('init state empty', t => { +test('init state empty', (t) => { const dummyAction: RemoveUISchemaAction = { type: 'jsonforms/REMOVE_UI_SCHEMA', - tester: undefined + tester: undefined, }; t.deepEqual(uischemaRegistryReducer(undefined, dummyAction), []); }); -test('add ui schema', t => { +test('add ui schema', (t) => { const tester: UISchemaTester = () => 1; const control = { type: 'Control', - scope: '#/definitions/foo' + scope: '#/definitions/foo', }; const after = uischemaRegistryReducer( undefined, @@ -61,46 +61,46 @@ test('add ui schema', t => { t.is(after.length, 1); }); -test('remove ui schema', t => { +test('remove ui schema', (t) => { const tester: UISchemaTester = () => 1; const control = { type: 'Control', - scope: '#/definitions/foo' + scope: '#/definitions/foo', }; const after = uischemaRegistryReducer( [ { tester, - uischema: control - } + uischema: control, + }, ], unregisterUISchema(tester) ); t.is(after.length, 0); }); -test('findMatchingUISchema', t => { +test('findMatchingUISchema', (t) => { const testerA: UISchemaTester = (_schema, schemaPath) => _.endsWith(schemaPath, 'foo') ? 1 : 0; const testerB: UISchemaTester = (_schema, schemaPath) => _.endsWith(schemaPath, 'bar') ? 1 : 0; const controlA = { type: 'Control', - scope: '#/definitions/foo' + scope: '#/definitions/foo', }; const controlB = { type: 'Control', - scope: '#/definitions/bar' + scope: '#/definitions/bar', }; const before = [ { tester: testerA, - uischema: controlA + uischema: controlA, }, { tester: testerB, - uischema: controlB - } + uischema: controlB, + }, ]; t.deepEqual( findMatchingUISchema(before)(undefined, '#/defintions/foo', undefined), @@ -112,7 +112,7 @@ test('findMatchingUISchema', t => { ); }); -test('findUISchema returns generated UI schema if no match has been found', t => { +test('findUISchema returns generated UI schema if no match has been found', (t) => { const middlewares: Redux.Middleware[] = []; const mockStore = configureStore(middlewares); const store = mockStore({ @@ -121,15 +121,15 @@ test('findUISchema returns generated UI schema if no match has been found', t => schema: { definitions: { baz: { - type: 'number' - } - } + type: 'number', + }, + }, }, data: undefined, - uischema: undefined + uischema: undefined, }, - uischemas: [] - } + uischemas: [], + }, }); t.deepEqual( @@ -143,28 +143,28 @@ test('findUISchema returns generated UI schema if no match has been found', t => ); }); -test('findMatchingUISchema with highest priority', t => { +test('findMatchingUISchema with highest priority', (t) => { const testerA: UISchemaTester = (_schema, schemaPath) => _.endsWith(schemaPath, 'foo') ? 2 : 0; const testerB: UISchemaTester = (_schema, schemaPath) => _.endsWith(schemaPath, 'foo') ? 1 : 0; const controlA = { type: 'Control', - scope: '#/definitions/foo' + scope: '#/definitions/foo', }; const controlB = { type: 'Control', - scope: '#/definitions/foo' + scope: '#/definitions/foo', }; const before = [ { tester: testerA, - uischema: controlA + uischema: controlA, }, { tester: testerB, - uischema: controlB - } + uischema: controlB, + }, ]; t.deepEqual( findMatchingUISchema(before)(undefined, '#/definitions/foo', undefined), diff --git a/packages/core/test/testers.test.ts b/packages/core/test/testers.test.ts index 4d9a6563c..fcbf8cf9e 100644 --- a/packages/core/test/testers.test.ts +++ b/packages/core/test/testers.test.ts @@ -47,280 +47,300 @@ import { scopeEndsWith, uiTypeIs, isOneOfEnumControl, - TesterContext + TesterContext, } from '../src/testers'; import { ControlElement, JsonSchema, LabelElement, - UISchemaElement + UISchemaElement, } from '../src'; const test = anyTest as TestInterface<{ uischema: ControlElement }>; -const createTesterContext = - (rootSchema: JsonSchema, config?: any): TesterContext => ({ rootSchema, config }); +const createTesterContext = ( + rootSchema: JsonSchema, + config?: any +): TesterContext => ({ rootSchema, config }); -test.beforeEach(t => { +test.beforeEach((t) => { t.context.uischema = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; }); -test('schemaTypeIs should check type sub-schema of control', t => { +test('schemaTypeIs should check type sub-schema of control', (t) => { const schema: JsonSchema = { type: 'object', properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const testerContext = createTesterContext(schema); t.true(schemaTypeIs('string')(uischema, schema, testerContext)); t.false(schemaTypeIs('integer')(uischema, schema, testerContext)); }); -test('schemaTypeIs should return false for non-control UI schema elements', t => { +test('schemaTypeIs should return false for non-control UI schema elements', (t) => { const schema: JsonSchema = { type: 'object', properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const label: LabelElement = { type: 'Label', - text: 'some text' + text: 'some text', }; const testerContext = createTesterContext(schema); t.false(schemaTypeIs('integer')(label, schema, testerContext)); }); -test('schemaTypeIs should return false for control pointing to invalid sub-schema', t => { +test('schemaTypeIs should return false for control pointing to invalid sub-schema', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/bar' + scope: '#/properties/bar', }; const schema: JsonSchema = { type: 'object', properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const testerContext = createTesterContext(schema); t.false(schemaTypeIs('string')(uischema, schema, testerContext)); }); -test('schemaTypeIs should return true for array type', t => { +test('schemaTypeIs should return true for array type', (t) => { const schema: JsonSchema = { type: 'object', properties: { - foo: { type: ['string', 'integer'] } - } + foo: { type: ['string', 'integer'] }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const testerContext = createTesterContext(schema); t.true(schemaTypeIs('string')(uischema, schema, testerContext)); t.true(schemaTypeIs('integer')(uischema, schema, testerContext)); }); -test('formatIs should check the format of a resolved sub-schema', t => { +test('formatIs should check the format of a resolved sub-schema', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const schema: JsonSchema = { type: 'object', properties: { foo: { type: 'string', - format: 'date-time' - } - } + format: 'date-time', + }, + }, }; const testerContext = createTesterContext(schema); t.true(formatIs('date-time')(uischema, schema, testerContext)); }); -test('uiTypeIs', t => { +test('uiTypeIs', (t) => { const control: ControlElement = { type: 'Control', - scope: '#/properties/bar' + scope: '#/properties/bar', }; t.true(uiTypeIs('Control')(control, undefined, undefined)); }); -test('optionIs should check for options', t => { +test('optionIs should check for options', (t) => { const control: ControlElement = { type: 'Control', scope: '#/properties/bar', options: { - answer: 42 - } + answer: 42, + }, }; t.true(optionIs('answer', 42)(control, undefined, undefined)); }); -test('optionIs should not fail if uischema is undefined or null', t => { +test('optionIs should not fail if uischema is undefined or null', (t) => { const uischema: UISchemaElement = null; t.false(optionIs('answer', 42)(uischema, undefined, undefined)); t.false(optionIs('answer', 42)(uischema, undefined, undefined)); }); -test('optionIs should return false for UI schema elements without options cell', t => { +test('optionIs should return false for UI schema elements without options cell', (t) => { const control: ControlElement = { type: 'Control', - scope: '#/properties/bar' + scope: '#/properties/bar', }; t.false(optionIs('answer', 42)(control, undefined, undefined)); }); -test('schemaMatches should check type sub-schema of control via predicate', t => { +test('schemaMatches should check type sub-schema of control via predicate', (t) => { const schema: JsonSchema = { type: 'object', properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const testerContext = createTesterContext(schema); t.true( - schemaMatches(subSchema => subSchema.type === 'string')(uischema, schema, testerContext) + schemaMatches((subSchema) => subSchema.type === 'string')( + uischema, + schema, + testerContext + ) ); }); -test('schemaMatches should check type sub-schema of control via predicate also without explicit type', t => { +test('schemaMatches should check type sub-schema of control via predicate also without explicit type', (t) => { const schema: JsonSchema = { properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const testerContext = createTesterContext(schema); t.true( - schemaMatches(subSchema => subSchema.type === 'string')(uischema, schema, testerContext) + schemaMatches((subSchema) => subSchema.type === 'string')( + uischema, + schema, + testerContext + ) ); }); -test('schemaMatches should return false for non-control UI schema elements', t => { +test('schemaMatches should return false for non-control UI schema elements', (t) => { const schema: JsonSchema = { type: 'object', properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const label: LabelElement = { type: 'Label', - text: 'some text' + text: 'some text', }; const testerContext = createTesterContext(schema); t.false(schemaMatches(() => false)(label, schema, testerContext)); }); -test('schemaMatches should return false for control pointing to invalid subschema', t => { +test('schemaMatches should return false for control pointing to invalid subschema', (t) => { const schema: JsonSchema = { type: 'object', properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/bar' + scope: '#/properties/bar', }; const testerContext = createTesterContext(schema); t.false(schemaMatches(() => false)(uischema, schema, testerContext)); }); -test('scopeEndsWith checks whether the ref of a control ends with a certain string', t => { +test('scopeEndsWith checks whether the ref of a control ends with a certain string', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/bar' + scope: '#/properties/bar', }; t.true(scopeEndsWith('properties/bar')(uischema, undefined, undefined)); }); -test('scopeEndsWith should return false for non-control UI schema elements', t => { +test('scopeEndsWith should return false for non-control UI schema elements', (t) => { const label: LabelElement = { type: 'Label', - text: 'some text' + text: 'some text', }; t.false(scopeEndsWith('properties/bar')(label, undefined, undefined)); }); -test('refEndIs checks whether the last segment a control ref equals a certain string', t => { +test('refEndIs checks whether the last segment a control ref equals a certain string', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/bar' + scope: '#/properties/bar', }; t.true(scopeEndIs('bar')(uischema, undefined, undefined)); }); -test('refEndIs should return false for non-control UI schema elements', t => { +test('refEndIs should return false for non-control UI schema elements', (t) => { const label: LabelElement = { type: 'Label', - text: 'some text' + text: 'some text', }; t.false(scopeEndIs('bar')(label, undefined, undefined)); }); -test('and should allow to compose multiple testers', t => { +test('and should allow to compose multiple testers', (t) => { const schema: JsonSchema = { type: 'object', properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const testerContext = createTesterContext(schema); - t.true(and(schemaTypeIs('string'), scopeEndIs('foo'))(uischema, schema, testerContext)); + t.true( + and(schemaTypeIs('string'), scopeEndIs('foo'))( + uischema, + schema, + testerContext + ) + ); }); -test('or should allow to compose multiple testers', t => { +test('or should allow to compose multiple testers', (t) => { const schema: JsonSchema = { type: 'object', properties: { - foo: { type: 'integer' } - } + foo: { type: 'integer' }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const testerContext = createTesterContext(schema); t.true( - or(schemaTypeIs('integer'), optionIs('slider', true))(uischema, schema, testerContext) + or(schemaTypeIs('integer'), optionIs('slider', true))( + uischema, + schema, + testerContext + ) ); }); -test('tester isPrimitiveArrayControl', t => { +test('tester isPrimitiveArrayControl', (t) => { const control: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const schema = { type: 'object', properties: { foo: { type: 'array', - items: { type: 'integer' } - } - } + items: { type: 'integer' }, + }, + }, }; t.true( isPrimitiveArrayControl(control, schema, createTesterContext(schema)), @@ -332,12 +352,16 @@ test('tester isPrimitiveArrayControl', t => { properties: { foo: { type: 'array', - items: { $ref: '#/definitions/int' } - } - } + items: { $ref: '#/definitions/int' }, + }, + }, }; t.true( - isPrimitiveArrayControl(control, schemaWithRefs, createTesterContext(schemaWithRefs)), + isPrimitiveArrayControl( + control, + schemaWithRefs, + createTesterContext(schemaWithRefs) + ), `Primitive array tester was not triggered for 'integer' schema type with refs` ); const objectSchema = { @@ -345,60 +369,83 @@ test('tester isPrimitiveArrayControl', t => { properties: { foo: { type: 'array', - items: { type: 'object' } - } - } + items: { type: 'object' }, + }, + }, }; t.false( - isPrimitiveArrayControl(control, objectSchema, createTesterContext(objectSchema)), + isPrimitiveArrayControl( + control, + objectSchema, + createTesterContext(objectSchema) + ), `Primitive array tester was not triggered for 'object' schema type` ); }); -test('tester isObjectArrayControl', t => { +test('tester isObjectArrayControl', (t) => { t.false(isObjectArrayControl({ type: 'Foo' }, null, null)); const control: ControlElement = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; - t.false(isObjectArrayControl(control, undefined, undefined), 'No Schema not checked!'); + t.false( + isObjectArrayControl(control, undefined, undefined), + 'No Schema not checked!' + ); t.false( - isObjectArrayControl(control, { - type: 'object', - properties: { bar: { type: 'integer' } } - }, undefined), + isObjectArrayControl( + control, + { + type: 'object', + properties: { bar: { type: 'integer' } }, + }, + undefined + ), 'Wrong Schema Type not checked!' ); t.false( - isObjectArrayControl(control, { - type: 'object', - properties: { foo: { type: 'array' } } - }, undefined), + isObjectArrayControl( + control, + { + type: 'object', + properties: { foo: { type: 'array' } }, + }, + undefined + ), 'Array Schema Type without items not checked!' ); t.false( - isObjectArrayControl(control, { - type: 'object', - properties: { - foo: { - type: 'array', - items: [{ type: 'integer' }, { type: 'string' }] - } - } - }, undefined), + isObjectArrayControl( + control, + { + type: 'object', + properties: { + foo: { + type: 'array', + items: [{ type: 'integer' }, { type: 'string' }], + }, + }, + }, + undefined + ), 'Array Schema Type with tuples not checked!' ); t.false( - isObjectArrayControl(control, { - type: 'object', - properties: { - foo: { - type: 'array', - items: { type: 'integer' } - } - } - }, undefined), + isObjectArrayControl( + control, + { + type: 'object', + properties: { + foo: { + type: 'array', + items: { type: 'integer' }, + }, + }, + }, + undefined + ), 'Array Schema Type with wrong item type not checked!' ); const schema: JsonSchema = { @@ -410,11 +457,11 @@ test('tester isObjectArrayControl', t => { type: 'object', properties: { x: { type: 'integer' }, - y: { type: 'integer' } - } - } - } - } + y: { type: 'integer' }, + }, + }, + }, + }, }; t.true(isObjectArrayControl(control, schema, createTesterContext(schema))); const schema_noType: JsonSchema = { @@ -425,13 +472,19 @@ test('tester isObjectArrayControl', t => { type: 'object', properties: { x: { type: 'integer' }, - y: { type: 'integer' } - } - } - } - } + y: { type: 'integer' }, + }, + }, + }, + }, }; - t.true(isObjectArrayControl(control, schema_noType, createTesterContext(schema_noType))); + t.true( + isObjectArrayControl( + control, + schema_noType, + createTesterContext(schema_noType) + ) + ); const schema_innerAllOf: JsonSchema = { type: 'object', properties: { @@ -441,20 +494,26 @@ test('tester isObjectArrayControl', t => { allOf: [ { properties: { - x: { type: 'integer' } - } + x: { type: 'integer' }, + }, }, { properties: { - y: { type: 'integer' } - } - } - ] - } - } - } + y: { type: 'integer' }, + }, + }, + ], + }, + }, + }, }; - t.true(isObjectArrayControl(control, schema_innerAllOf, createTesterContext(schema_innerAllOf))); + t.true( + isObjectArrayControl( + control, + schema_innerAllOf, + createTesterContext(schema_innerAllOf) + ) + ); const schemaWithRefs = { definitions: { @@ -462,244 +521,344 @@ test('tester isObjectArrayControl', t => { type: 'object', properties: { x: { type: 'integer' }, - y: { type: 'integer' } - } - } + y: { type: 'integer' }, + }, + }, }, type: 'object', properties: { foo: { type: 'array', items: { - $ref: '#/definitions/order' - } - } - } - } + $ref: '#/definitions/order', + }, + }, + }, + }; const testerContext = createTesterContext(schemaWithRefs); t.true(isObjectArrayControl(control, schemaWithRefs, testerContext)); }); -test('isBooleanControl', t => { +test('isBooleanControl', (t) => { t.false(isBooleanControl(undefined, undefined, undefined)); t.false(isBooleanControl(null, undefined, undefined)); t.false(isBooleanControl({ type: 'Foo' }, undefined, undefined)); t.false(isBooleanControl({ type: 'Control' }, undefined, undefined)); t.false( - isBooleanControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isBooleanControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); t.false( - isBooleanControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' }, bar: { type: 'boolean' } } - }, undefined) + isBooleanControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' }, bar: { type: 'boolean' } }, + }, + undefined + ) ); t.true( - isBooleanControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'boolean' } } - }, undefined) + isBooleanControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'boolean' } }, + }, + undefined + ) ); }); -test('test isDateControl', t => { +test('test isDateControl', (t) => { t.false(isDateControl(undefined, undefined, undefined)); t.false(isDateControl(null, undefined, undefined)); t.false(isDateControl({ type: 'Foo' }, undefined, undefined)); t.false(isDateControl({ type: 'Control' }, undefined, undefined)); t.false( - isDateControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isDateControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); t.false( - isDateControl(t.context.uischema, { - type: 'object', - properties: { - foo: { type: 'string' }, - bar: { - type: 'string', - format: 'date' - } - } - }, undefined) + isDateControl( + t.context.uischema, + { + type: 'object', + properties: { + foo: { type: 'string' }, + bar: { + type: 'string', + format: 'date', + }, + }, + }, + undefined + ) ); t.true( - isDateControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string', format: 'date' } } - }, undefined) + isDateControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string', format: 'date' } }, + }, + undefined + ) ); }); -test('test isEnumControl', t => { +test('test isEnumControl', (t) => { t.false(isEnumControl(undefined, undefined, undefined)); t.false(isEnumControl(null, undefined, undefined)); t.false(isEnumControl({ type: 'Foo' }, undefined, undefined)); t.false(isEnumControl({ type: 'Control' }, undefined, undefined)); t.false( - isEnumControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isEnumControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); t.false( - isEnumControl(t.context.uischema, { - type: 'object', - properties: { - foo: { - type: 'string' + isEnumControl( + t.context.uischema, + { + type: 'object', + properties: { + foo: { + type: 'string', + }, + bar: { + type: 'string', + enum: ['a', 'b'], + }, }, - bar: { - type: 'string', - enum: ['a', 'b'] - } - } - }, undefined) + }, + undefined + ) ); t.true( - isEnumControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string', enum: ['a', 'b'] } } - }, undefined) + isEnumControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string', enum: ['a', 'b'] } }, + }, + undefined + ) ); t.true( - isEnumControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'number', enum: [1, 2] } } - }, undefined) + isEnumControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'number', enum: [1, 2] } }, + }, + undefined + ) ); t.true( - isEnumControl(t.context.uischema, { - type: 'object', - properties: { foo: { const: '1.0' } } - }, undefined) + isEnumControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { const: '1.0' } }, + }, + undefined + ) ); }); -test('test isIntegerControl', t => { +test('test isIntegerControl', (t) => { t.false(isIntegerControl(undefined, undefined, undefined)); t.false(isIntegerControl(null, undefined, undefined)); t.false(isIntegerControl({ type: 'Foo' }, undefined, undefined)); t.false(isIntegerControl({ type: 'Control' }, undefined, undefined)); t.false( - isIntegerControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isIntegerControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); t.false( - isIntegerControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' }, bar: { type: 'integer' } } - }, undefined) + isIntegerControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' }, bar: { type: 'integer' } }, + }, + undefined + ) ); t.true( - isIntegerControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'integer' } } - }, undefined) + isIntegerControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'integer' } }, + }, + undefined + ) ); }); -test('test isNumberControl', t => { +test('test isNumberControl', (t) => { t.false(isNumberControl(undefined, undefined, undefined)); t.false(isNumberControl(null, undefined, undefined)); t.false(isNumberControl({ type: 'Foo' }, undefined, undefined)); t.false(isNumberControl({ type: 'Control' }, undefined, undefined)); t.false( - isNumberControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isNumberControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); t.false( - isNumberControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' }, bar: { type: 'number' } } - }, undefined) + isNumberControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' }, bar: { type: 'number' } }, + }, + undefined + ) ); t.true( - isNumberControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'number' } } - }, undefined) + isNumberControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'number' } }, + }, + undefined + ) ); }); -test('tester isStringControl', t => { +test('tester isStringControl', (t) => { t.false(isStringControl(undefined, undefined, undefined)); t.false(isStringControl(null, undefined, undefined)); t.false(isStringControl({ type: 'Foo' }, undefined, undefined)); t.false(isStringControl({ type: 'Control' }, undefined, undefined)); t.false( - isStringControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'number' } } - }, undefined) + isStringControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'number' } }, + }, + undefined + ) ); t.false( - isStringControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'number' }, bar: { type: 'string' } } - }, undefined) + isStringControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'number' }, bar: { type: 'string' } }, + }, + undefined + ) ); t.true( - isStringControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isStringControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); }); -test('test isTimeControl', t => { +test('test isTimeControl', (t) => { t.false(isTimeControl(undefined, undefined, undefined)); t.false(isTimeControl(null, undefined, undefined)); t.false(isTimeControl({ type: 'Foo' }, undefined, undefined)); t.false(isTimeControl({ type: 'Control' }, undefined, undefined)); t.false( - isTimeControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isTimeControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); t.false( - isTimeControl(t.context.uischema, { - type: 'object', - properties: { - foo: { type: 'string' }, - bar: { type: 'string', format: 'time' } - } - }, undefined) + isTimeControl( + t.context.uischema, + { + type: 'object', + properties: { + foo: { type: 'string' }, + bar: { type: 'string', format: 'time' }, + }, + }, + undefined + ) ); t.true( - isTimeControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string', format: 'time' } } - }, undefined) + isTimeControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string', format: 'time' } }, + }, + undefined + ) ); }); -test('tester isMultiLineControl', t => { +test('tester isMultiLineControl', (t) => { t.false(isMultiLineControl(undefined, undefined, undefined)); t.false(isMultiLineControl(null, undefined, undefined)); t.false(isMultiLineControl({ type: 'Foo' }, undefined, undefined)); t.false(isMultiLineControl({ type: 'Control' }, undefined, undefined)); t.false( - isMultiLineControl(t.context.uischema, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isMultiLineControl( + t.context.uischema, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); const control = t.context.uischema; control.options = { multi: true }; t.true( - isMultiLineControl(control, { - type: 'object', - properties: { foo: { type: 'string' } } - }, undefined) + isMultiLineControl( + control, + { + type: 'object', + properties: { foo: { type: 'string' } }, + }, + undefined + ) ); }); -test('tester isObjectArrayWithNesting', t => { +test('tester isObjectArrayWithNesting', (t) => { const schema = { type: 'array', items: { @@ -707,25 +866,25 @@ test('tester isObjectArrayWithNesting', t => { properties: { message: { type: 'string', - maxLength: 3 + maxLength: 3, }, done: { - type: 'boolean' - } - } - } + type: 'boolean', + }, + }, + }, }; const nestedSchema = { type: 'array', items: { - ...schema - } + ...schema, + }, }; const uischema = { type: 'Control', - scope: '#' + scope: '#', }; const nestedSchema2 = { @@ -739,13 +898,13 @@ test('tester isObjectArrayWithNesting', t => { choices: { type: 'array', items: { - type: 'string' - } - } - } - } - } - } + type: 'string', + }, + }, + }, + }, + }, + }, }; const nestedSchema3 = { type: 'array', @@ -756,73 +915,83 @@ test('tester isObjectArrayWithNesting', t => { type: 'object', properties: { Level3: { - type: 'string' - } - } - } - } - } + type: 'string', + }, + }, + }, + }, + }, }; - const nestedSchemaWithRef = - { + const nestedSchemaWithRef = { definitions: { itemsType: { ...schema } }, type: 'array', items: { - $ref: '#/definitions/itemsType' - } + $ref: '#/definitions/itemsType', + }, }; const nestedSchemaWithAnyOf = { - type: "array", + type: 'array', items: { anyOf: [ { - type: "object", + type: 'object', properties: { value: { - type: "string" - } + type: 'string', + }, }, - required: ["value"] + required: ['value'], }, { - type: "object", + type: 'object', properties: { value: { - type: "number" - } + type: 'number', + }, }, - required: ["value"] - } - ] - } + required: ['value'], + }, + ], + }, }; const nestedSchemaWithOneOf = { - type: "array", + type: 'array', items: { oneOf: [ { - type: "object", + type: 'object', properties: { value: { - type: "string" - } + type: 'string', + }, }, - required: ["value"] + required: ['value'], }, { - type: "object", + type: 'object', properties: { value: { - type: "number" - } + type: 'number', + }, }, - required: ["value"] - } - ] - } + required: ['value'], + }, + ], + }, + }; + + const schemaWithOneOfEnum = { + type: 'array', + items: { + type: 'string', + oneOf: [ + { const: 'A', title: 'ENUM A' }, + { const: 'B', title: 'ENUM B' }, + ], + }, }; const uischemaOptions: { @@ -834,15 +1003,15 @@ test('tester isObjectArrayWithNesting', t => { type: 'Control', scope: '#', options: { - detail: 'DEFAULT' - } + detail: 'DEFAULT', + }, }, generate: { type: 'Control', scope: '#', options: { - detail: 'GENERATE' - } + detail: 'GENERATE', + }, }, inline: { type: 'Control', @@ -853,12 +1022,12 @@ test('tester isObjectArrayWithNesting', t => { elements: [ { type: 'Control', - scope: '#/properties/message' - } - ] - } - } - } + scope: '#/properties/message', + }, + ], + }, + }, + }, }; t.false(isObjectArrayWithNesting(undefined, undefined, undefined)); @@ -869,7 +1038,13 @@ test('tester isObjectArrayWithNesting', t => { t.true(isObjectArrayWithNesting(uischema, nestedSchema, undefined)); t.true(isObjectArrayWithNesting(uischema, nestedSchema2, undefined)); t.true(isObjectArrayWithNesting(uischema, nestedSchema3, undefined)); - t.true(isObjectArrayWithNesting(uischema, nestedSchemaWithRef, createTesterContext(nestedSchemaWithRef))); + t.true( + isObjectArrayWithNesting( + uischema, + nestedSchemaWithRef, + createTesterContext(nestedSchemaWithRef) + ) + ); t.false(isObjectArrayWithNesting(uischemaOptions.default, schema, undefined)); t.true(isObjectArrayWithNesting(uischemaOptions.generate, schema, undefined)); @@ -877,23 +1052,25 @@ test('tester isObjectArrayWithNesting', t => { t.true(isObjectArrayWithNesting(uischema, nestedSchemaWithAnyOf, undefined)); t.true(isObjectArrayWithNesting(uischema, nestedSchemaWithOneOf, undefined)); + + t.false(isObjectArrayWithNesting(undefined, schemaWithOneOfEnum, undefined)); }); -test('tester schemaSubPathMatches', t => { +test('tester schemaSubPathMatches', (t) => { const schema = { title: 'Things', type: 'array', items: { - type: 'number' - } + type: 'number', + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; t.true( - schemaSubPathMatches('items', items => items.type === 'number')( + schemaSubPathMatches('items', (items) => items.type === 'number')( uischema, schema, undefined @@ -901,48 +1078,58 @@ test('tester schemaSubPathMatches', t => { ); }); -test('tester not', t => { +test('tester not', (t) => { t.false( - not(isBooleanControl)(t.context.uischema, { - type: 'boolean' - }, undefined) + not(isBooleanControl)( + t.context.uischema, + { + type: 'boolean', + }, + undefined + ) ); }); -test('tester isOneOfEnumControl', t => { +test('tester isOneOfEnumControl', (t) => { const control: ControlElement = { type: 'Control', - scope: '#/properties/country' + scope: '#/properties/country', }; const oneOfSchema = { type: 'string', oneOf: [ { const: 'AU', - title: 'Australia' + title: 'Australia', }, { const: 'NZ', - title: 'New Zealand' - } - ] + title: 'New Zealand', + }, + ], }; - t.true(isOneOfEnumControl(control, { - type: 'object', - properties: { - country: oneOfSchema - } - }, undefined)); + t.true( + isOneOfEnumControl( + control, + { + type: 'object', + properties: { + country: oneOfSchema, + }, + }, + undefined + ) + ); const schemaWithRefs = { definitions: { country: oneOfSchema }, type: 'object', properties: { country: { - $ref: '#/definitions/country' - } - } - } + $ref: '#/definitions/country', + }, + }, + }; const testerContext = createTesterContext(schemaWithRefs); t.true(isOneOfEnumControl(control, schemaWithRefs, testerContext)); }); diff --git a/packages/core/test/util/array.test.ts b/packages/core/test/util/array.test.ts index 443ab5338..3ca2201b3 100644 --- a/packages/core/test/util/array.test.ts +++ b/packages/core/test/util/array.test.ts @@ -3,26 +3,26 @@ import anyTest, { TestInterface } from 'ava'; const test = anyTest as TestInterface<{ array: number[] }>; -test.beforeEach(t => { +test.beforeEach((t) => { t.context.array = [1, 2, 3, 4, 5]; }); -test('Move up should move item up by one index', t => { +test('Move up should move item up by one index', (t) => { moveUp(t.context.array, 2); t.deepEqual(t.context.array, [1, 3, 2, 4, 5]); }); -test('Move up should not change array if item to move is the first item ', t => { +test('Move up should not change array if item to move is the first item ', (t) => { moveUp(t.context.array, 0); t.deepEqual(t.context.array, [1, 2, 3, 4, 5]); }); -test('Move down should move item down by one index', t => { +test('Move down should move item down by one index', (t) => { moveDown(t.context.array, 2); t.deepEqual(t.context.array, [1, 2, 4, 3, 5]); }); -test('Move down should not change array if item to move is the last item ', t => { +test('Move down should not change array if item to move is the last item ', (t) => { moveDown(t.context.array, 4); t.deepEqual(t.context.array, [1, 2, 3, 4, 5]); }); diff --git a/packages/core/test/util/cell.test.ts b/packages/core/test/util/cell.test.ts index e0e2447e7..71abafc1d 100644 --- a/packages/core/test/util/cell.test.ts +++ b/packages/core/test/util/cell.test.ts @@ -30,15 +30,20 @@ import { defaultMapDispatchToControlProps, defaultMapStateToEnumCellProps, DispatchPropsOfCell, - mapStateToCellProps, mapStateToOneOfEnumCellProps, oneOfToEnumOptionMapper + mapStateToCellProps, + mapStateToOneOfEnumCellProps, + oneOfToEnumOptionMapper, } from '../../src/util'; import { UPDATE_DATA, UpdateAction } from '../../src/actions'; import configureStore from 'redux-mock-store'; import { ControlElement, + createAjv, JsonFormsState, + JsonSchema, RuleEffect, - UISchemaElement + UISchemaElement, + validate, } from '../../src'; import { enumToEnumOptionMapper } from '../../src/util/renderer'; @@ -50,8 +55,8 @@ const hideRule = { condition: { type: 'LEAF', scope: '#/properties/firstName', - expectedValue: 'Homer' - } + expectedValue: 'Homer', + }, }; const disableRule = { @@ -59,8 +64,8 @@ const disableRule = { condition: { type: 'LEAF', scope: '#/properties/firstName', - expectedValue: 'Homer' - } + expectedValue: 'Homer', + }, }; const enableRule = { @@ -68,13 +73,13 @@ const enableRule = { condition: { type: 'LEAF', scope: '#/properties/firstName', - expectedValue: 'Homer' - } + expectedValue: 'Homer', + }, }; const coreUISchema: ControlElement = { type: 'Control', - scope: '#/properties/firstName' + scope: '#/properties/firstName', }; const createState = (uischema: UISchemaElement): JsonFormsState => ({ @@ -87,64 +92,64 @@ const createState = (uischema: UISchemaElement): JsonFormsState => ({ lastName: { type: 'string' }, nationality: { type: 'string', - enum: ['DE', 'IT', 'JP', 'US', 'RU', 'Other'] - } - } + enum: ['DE', 'IT', 'JP', 'US', 'RU', 'Other'], + }, + }, }, data: { - firstName: 'Homer' + firstName: 'Homer', }, uischema, - errors: [] - } - } + errors: [], + }, + }, }); -test('mapStateToCellProps - visible via ownProps ', t => { +test('mapStateToCellProps - visible via ownProps ', (t) => { const uischema: ControlElement = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { visible: true, - uischema + uischema, }; const props = mapStateToCellProps(createState(uischema), ownProps); t.true(props.visible); }); -test('mapStateToCellProps - hidden via ownProps ', t => { +test('mapStateToCellProps - hidden via ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { visible: false, - uischema + uischema, }; const props = mapStateToCellProps(createState(uischema), ownProps); t.false(props.visible); }); -test('mapStateToCellProps - hidden via state ', t => { +test('mapStateToCellProps - hidden via state ', (t) => { const uischema = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { - uischema + uischema, }; const props = mapStateToCellProps(createState(uischema), ownProps); t.false(props.visible); }); -test('mapStateToCellProps - visible via state ', t => { +test('mapStateToCellProps - visible via state ', (t) => { const uischema = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { - uischema + uischema, }; const clonedState = _.cloneDeep(createState(uischema)); clonedState.jsonforms.core.data.firstName = 'Lisa'; @@ -152,51 +157,51 @@ test('mapStateToCellProps - visible via state ', t => { t.true(props.visible); }); -test('mapStateToCellProps - enabled via ownProps ', t => { +test('mapStateToCellProps - enabled via ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { enabled: true, - uischema + uischema, }; const props = mapStateToCellProps(createState(uischema), ownProps); t.true(props.enabled); }); -test('mapStateToCellProps - disabled via ownProps ', t => { +test('mapStateToCellProps - disabled via ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { enabled: false, - uischema + uischema, }; const props = mapStateToCellProps(createState(uischema), ownProps); t.false(props.enabled); }); -test('mapStateToCellProps - disabled via state ', t => { +test('mapStateToCellProps - disabled via state ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { - uischema + uischema, }; const props = mapStateToCellProps(createState(uischema), ownProps); t.false(props.enabled); }); -test('mapStateToCellProps - enabled via state ', t => { +test('mapStateToCellProps - enabled via state ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { - uischema + uischema, }; const clonedState = _.cloneDeep(createState(uischema)); clonedState.jsonforms.core.data.firstName = 'Lisa'; @@ -204,9 +209,9 @@ test('mapStateToCellProps - enabled via state ', t => { t.true(props.enabled); }); -test('mapStateToCellProps - disabled via global readonly', t => { +test('mapStateToCellProps - disabled via global readonly', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.readonly = true; @@ -215,10 +220,10 @@ test('mapStateToCellProps - disabled via global readonly', t => { t.false(props.enabled); }); -test('mapStateToCellProps - disabled via global readonly beats enabled via ownProps', t => { +test('mapStateToCellProps - disabled via global readonly beats enabled via ownProps', (t) => { const ownProps = { uischema: coreUISchema, - enabled: true + enabled: true, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.readonly = true; @@ -227,13 +232,13 @@ test('mapStateToCellProps - disabled via global readonly beats enabled via ownPr t.false(props.enabled); }); -test('mapStateToCellProps - disabled via global readonly beats enabled via rule', t => { +test('mapStateToCellProps - disabled via global readonly beats enabled via rule', (t) => { const uischema = { ...coreUISchema, - rule: enableRule + rule: enableRule, }; const ownProps = { - uischema + uischema, }; const state: JsonFormsState = createState(uischema); state.jsonforms.readonly = true; @@ -242,93 +247,126 @@ test('mapStateToCellProps - disabled via global readonly beats enabled via rule' t.false(props.enabled); }); -test('mapStateToCellProps - path', t => { +test('mapStateToCellProps - path', (t) => { const ownProps = { uischema: coreUISchema, - path: 'firstName' + path: 'firstName', }; const props = mapStateToCellProps(createState(coreUISchema), ownProps); t.is(props.path, 'firstName'); }); -test('mapStateToCellProps - data', t => { +test('mapStateToCellProps - data', (t) => { const ownProps = { uischema: coreUISchema, - path: 'firstName' + path: 'firstName', }; const props = mapStateToCellProps(createState(coreUISchema), ownProps); t.is(props.data, 'Homer'); }); -test('mapStateToCellProps - id', t => { +test('mapStateToCellProps - id', (t) => { clearAllIds(); const ownProps = { uischema: coreUISchema, - id: '#/properties/firstName' + id: '#/properties/firstName', }; const props = mapStateToCellProps(createState(coreUISchema), ownProps); t.is(props.id, '#/properties/firstName'); }); -test('mapStateToEnumCellProps - set default options for dropdown list', t => { +test('mapStateToCellProps - translated error', (t) => { + const ownProps = { + uischema: coreUISchema, + id: '#/properties/firstName', + path: 'firstName', + }; + const state = createState(coreUISchema); + if (state.jsonforms.core === undefined) { + fail('Failed to create jsonforms core state'); + } + const schema = state.jsonforms.core?.schema as JsonSchema; + const data = state.jsonforms.core?.data as any; + // mark firstName as required, delete the value from data, then get errors from ajv from the compiled schema + schema.required = ['firstName']; + delete data.firstName; + const ajv = createAjv(); + const v = ajv.compile(schema); + state.jsonforms.core.errors = validate(v, data); + // add a mock i18n state to verify that the error gets translated + state.jsonforms.i18n = { + translateError: (error) => `i18n-error:${error.keyword}`, + }; + const props = mapStateToCellProps(state, ownProps); + t.is(props.errors, 'i18n-error:required'); +}); + +test('mapStateToEnumCellProps - set default options for dropdown list', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/nationality' + scope: '#/properties/nationality', }; const ownProps = { schema: { - enum: ['DE', 'IT', 'JP', 'US', 'RU', 'Other'] + enum: ['DE', 'IT', 'JP', 'US', 'RU', 'Other'], }, uischema, - path: 'nationality' + path: 'nationality', }; const props = defaultMapStateToEnumCellProps(createState(uischema), ownProps); t.deepEqual( props.options, - ['DE', 'IT', 'JP', 'US', 'RU', 'Other'].map(e => enumToEnumOptionMapper(e)) + ['DE', 'IT', 'JP', 'US', 'RU', 'Other'].map((e) => + enumToEnumOptionMapper(e) + ) ); t.is(props.data, undefined); }); - -test('mapStateToOneOfEnumCellProps - set one of options for dropdown list', t => { +test('mapStateToOneOfEnumCellProps - set one of options for dropdown list', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/country' + scope: '#/properties/country', }; const ownProps = { schema: { oneOf: [ { const: 'AU', - title: 'Australia' + title: 'Australia', }, { const: 'NZ', - title: 'New Zealand' - } - ] + title: 'New Zealand', + }, + ], }, uischema, - path: 'country' + path: 'country', }; const props = mapStateToOneOfEnumCellProps(createState(uischema), ownProps); - t.deepEqual(props.options, [{title: 'Australia' , const: 'AU', }, { title: 'New Zealand', const: 'NZ' }].map(schema => oneOfToEnumOptionMapper(schema))); + t.deepEqual( + props.options, + [ + { title: 'Australia', const: 'AU' }, + { title: 'New Zealand', const: 'NZ' }, + ].map((schema) => oneOfToEnumOptionMapper(schema)) + ); t.is(props.data, undefined); }); -test('defaultMapDispatchToControlProps, initialized with custom handleChange', t => { +test('defaultMapDispatchToControlProps, initialized with custom handleChange', (t) => { let didChange = false; const uiSchema = { type: 'Control', - scope: '#/properties/nationality' + scope: '#/properties/nationality', }; const ownProps = { handleChange: () => { didChange = true; - } + }, }; const store = mockStore(createState(uiSchema)); const props: DispatchPropsOfCell = defaultMapDispatchToControlProps( @@ -339,10 +377,10 @@ test('defaultMapDispatchToControlProps, initialized with custom handleChange', t t.true(didChange); }); -test('defaultMapDispatchToControlProps, with default handleChange', t => { +test('defaultMapDispatchToControlProps, with default handleChange', (t) => { const uiSchema = { type: 'Control', - scope: '#/properties/nationality' + scope: '#/properties/nationality', }; const store = mockStore(createState(uiSchema)); const props = defaultMapDispatchToControlProps(store.dispatch, {}); diff --git a/packages/core/test/util/derivetype.test.ts b/packages/core/test/util/derivetype.test.ts index b2cfac449..0772d36cb 100644 --- a/packages/core/test/util/derivetype.test.ts +++ b/packages/core/test/util/derivetype.test.ts @@ -27,74 +27,74 @@ import test from 'ava'; import { JsonSchema } from '../../src/models/jsonSchema'; import { deriveTypes } from '../../src/util/index'; -test('derive type with type', t => { +test('derive type with type', (t) => { const schema: JsonSchema = { - type: 'string' + type: 'string', }; t.is(deriveTypes(schema).length, 1); t.is(deriveTypes(schema)[0], 'string'); }); -test('derive type w/o type - properties object', t => { +test('derive type w/o type - properties object', (t) => { const schema: JsonSchema = { properties: { - foo: { type: 'string' } - } + foo: { type: 'string' }, + }, }; t.is(deriveTypes(schema).length, 1); t.is(deriveTypes(schema)[0], 'object'); }); -test('derive type w/o type - additionalProperties object', t => { +test('derive type w/o type - additionalProperties object', (t) => { const schema: JsonSchema = { additionalProperties: { - type: 'string' - } + type: 'string', + }, }; t.is(deriveTypes(schema).length, 1); t.is(deriveTypes(schema)[0], 'object'); }); -test('derive type w/o type - items array', t => { +test('derive type w/o type - items array', (t) => { const schema: JsonSchema = { items: { - type: 'string' - } + type: 'string', + }, }; t.is(deriveTypes(schema).length, 1); t.is(deriveTypes(schema)[0], 'array'); }); -test('derive type with type - union', t => { +test('derive type with type - union', (t) => { const schema: JsonSchema = { - type: ['string', 'number'] + type: ['string', 'number'], }; t.is(deriveTypes(schema).length, 2); t.is(deriveTypes(schema), schema.type); }); -test('derive type with type - allOf first has type', t => { +test('derive type with type - allOf first has type', (t) => { const schema: JsonSchema = { - allOf: [{ type: 'string' }, { enum: ['foo', 'bar'] }] + allOf: [{ type: 'string' }, { enum: ['foo', 'bar'] }], }; t.is(deriveTypes(schema).length, 1); t.is(deriveTypes(schema)[0], 'string'); }); -test('derive type with type - allOf other has type', t => { +test('derive type with type - allOf other has type', (t) => { const schema: JsonSchema = { - allOf: [{ enum: ['foo', 'bar'] }, { type: 'string' }] + allOf: [{ enum: ['foo', 'bar'] }, { type: 'string' }], }; t.is(deriveTypes(schema).length, 1); t.is(deriveTypes(schema)[0], 'string'); }); -test('derive type w/o type - allOf other has type', t => { +test('derive type w/o type - allOf other has type', (t) => { const schema: JsonSchema = { allOf: [ { properties: { foo: { type: 'string' } } }, - { properties: { bar: { type: 'string' } } } - ] + { properties: { bar: { type: 'string' } } }, + ], }; t.is(deriveTypes(schema).length, 1); t.is(deriveTypes(schema)[0], 'object'); diff --git a/packages/core/test/util/label.test.ts b/packages/core/test/util/label.test.ts index 3cc7f23e7..93f36d6a0 100644 --- a/packages/core/test/util/label.test.ts +++ b/packages/core/test/util/label.test.ts @@ -28,335 +28,335 @@ import { ControlElement } from '../../src'; import { createLabelDescriptionFrom } from '../../src/util'; import { JsonSchema } from '../../src/models/jsonSchema'; -test('control relative - no schema', t => { +test('control relative - no schema', (t) => { const controlElement: ControlElement = { type: 'Control', - scope: '/properties/foo' + scope: '/properties/foo', }; const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control without label string, camel split - no schema', t => { +test('control without label string, camel split - no schema', (t) => { const controlElement: ControlElement = { type: 'Control', - scope: '#/properties/fooBarBaz' + scope: '#/properties/fooBarBaz', }; const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo Bar Baz'); }); -test('control with label string - no schema', t => { +test('control with label string - no schema', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: 'bar' + label: 'bar', }; const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'bar'); }); -test('control with label boolean - no schema', t => { +test('control with label boolean - no schema', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: true + label: true, }; const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, empty - no schema', t => { +test('control with label object, empty - no schema', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: {} + label: {}, }; const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, text-only - no schema', t => { +test('control with label object, text-only - no schema', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { - text: 'mega bar' - } + text: 'mega bar', + }, }; const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'mega bar'); }); -test('control with label object, visible-only - no schema', t => { +test('control with label object, visible-only - no schema', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { - show: true - } + show: true, + }, }; const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, full - no schema', t => { +test('control with label object, full - no schema', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { show: false, - text: 'mega bar' - } + text: 'mega bar', + }, }; const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, false); t.is(labelObject.text, 'mega bar'); }); -test('control relative - schema without title', t => { +test('control relative - schema without title', (t) => { const controlElement: ControlElement = { type: 'Control', - scope: '/properties/foo' + scope: '/properties/foo', }; const schema: JsonSchema = { - type: 'string' + type: 'string', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control without label string, camel split - schema without title', t => { +test('control without label string, camel split - schema without title', (t) => { const controlElement: ControlElement = { type: 'Control', - scope: '#/properties/fooBarBaz' + scope: '#/properties/fooBarBaz', }; const schema: JsonSchema = { - type: 'string' + type: 'string', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo Bar Baz'); }); -test('control with label string - schema without title', t => { +test('control with label string - schema without title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: 'bar' + label: 'bar', }; const schema: JsonSchema = { - type: 'string' + type: 'string', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'bar'); }); -test('control with label boolean - schema without title', t => { +test('control with label boolean - schema without title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: true + label: true, }; const schema: JsonSchema = { - type: 'string' + type: 'string', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, empty - schema without title', t => { +test('control with label object, empty - schema without title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: {} + label: {}, }; const schema: JsonSchema = { - type: 'string' + type: 'string', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, text-only - schema without title', t => { +test('control with label object, text-only - schema without title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { - text: 'mega bar' - } + text: 'mega bar', + }, }; const schema: JsonSchema = { - type: 'string' + type: 'string', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'mega bar'); }); -test('control with label object, visible-only - schema without title', t => { +test('control with label object, visible-only - schema without title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { - show: true - } + show: true, + }, }; const schema: JsonSchema = { - type: 'string' + type: 'string', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, full - schema without title', t => { +test('control with label object, full - schema without title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { show: false, - text: 'mega bar' - } + text: 'mega bar', + }, }; const schema: JsonSchema = { - type: 'string' + type: 'string', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, false); t.is(labelObject.text, 'mega bar'); }); -test('control relative - schema with title', t => { +test('control relative - schema with title', (t) => { const controlElement: ControlElement = { type: 'Control', - scope: '/properties/foo' + scope: '/properties/foo', }; const schema: JsonSchema = { type: 'string', - title: 'Schema Title' + title: 'Schema Title', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Schema Title'); }); -test('control without label string, camel split - schema with title', t => { +test('control without label string, camel split - schema with title', (t) => { const controlElement: ControlElement = { type: 'Control', - scope: '#/properties/fooBarBaz' + scope: '#/properties/fooBarBaz', }; const schema: JsonSchema = { type: 'string', - title: 'Schema Title' + title: 'Schema Title', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Schema Title'); }); -test('control with label string - schema with title', t => { +test('control with label string - schema with title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: 'bar' + label: 'bar', }; const schema: JsonSchema = { type: 'string', - title: 'Schema Title' + title: 'Schema Title', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'bar'); }); -test('control with label boolean - schema with title', t => { +test('control with label boolean - schema with title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: true + label: true, }; const schema: JsonSchema = { type: 'string', - title: 'Schema Title' + title: 'Schema Title', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Schema Title'); }); -test('control with label object, empty - schema with title', t => { +test('control with label object, empty - schema with title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', - label: {} + label: {}, }; const schema: JsonSchema = { type: 'string', - title: 'Schema Title' + title: 'Schema Title', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Schema Title'); }); -test('control with label object, text-only - schema with title', t => { +test('control with label object, text-only - schema with title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { - text: 'mega bar' - } + text: 'mega bar', + }, }; const schema: JsonSchema = { type: 'string', - title: 'Schema Title' + title: 'Schema Title', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'mega bar'); }); -test('control with label object, visible-only - schema with title', t => { +test('control with label object, visible-only - schema with title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { - show: true - } + show: true, + }, }; const schema: JsonSchema = { type: 'string', - title: 'Schema Title' + title: 'Schema Title', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, true); t.is(labelObject.text, 'Schema Title'); }); -test('control with label object, full - schema with title', t => { +test('control with label object, full - schema with title', (t) => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: { show: false, - text: 'mega bar' - } + text: 'mega bar', + }, }; const schema: JsonSchema = { type: 'string', - title: 'Schema Title' + title: 'Schema Title', }; const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, false); diff --git a/packages/core/test/util/path.test.ts b/packages/core/test/util/path.test.ts index d7299135d..c3a138927 100644 --- a/packages/core/test/util/path.test.ts +++ b/packages/core/test/util/path.test.ts @@ -26,60 +26,69 @@ import test from 'ava'; import { JsonSchema } from '../../src'; import { Resolve, toDataPath } from '../../src/util'; -test('resolve ', t => { +test('resolve ', (t) => { const schema: JsonSchema = { type: 'object', properties: { foo: { - type: 'integer' - } - } + type: 'integer', + }, + }, }; t.deepEqual(Resolve.schema(schema, '#/properties/foo', schema), { - type: 'integer' + type: 'integer', }); }); -test('toDataPath ', t => { +test('toDataPath ', (t) => { t.is(toDataPath('#/properties/foo/properties/bar'), 'foo.bar'); }); -test('toDataPath replace anyOf', t => { +test('toDataPath replace anyOf', (t) => { t.is(toDataPath('/anyOf/1/properties/foo/anyOf/1/properties/bar'), 'foo.bar'); }); -test('toDataPath replace anyOf in combination with conditional schema compositions', t => { +test('toDataPath replace anyOf in combination with conditional schema compositions', (t) => { t.is(toDataPath('/anyOf/1/then/properties/foo'), 'foo'); }); -test('toDataPath replace multiple directly nested anyOf in combination with conditional schema compositions', t => { +test('toDataPath replace multiple directly nested anyOf in combination with conditional schema compositions', (t) => { t.is(toDataPath('/anyOf/1/then/anyOf/0/then/properties/foo'), 'foo'); }); -test('toDataPath replace multiple nested properties with anyOf in combination with conditional schema compositions', t => { - t.is(toDataPath('/anyOf/1/properties/foo/anyOf/0/then/properties/bar'), 'foo.bar'); +test('toDataPath replace multiple nested properties with anyOf in combination with conditional schema compositions', (t) => { + t.is( + toDataPath('/anyOf/1/properties/foo/anyOf/0/then/properties/bar'), + 'foo.bar' + ); }); -test('toDataPath replace allOf', t => { +test('toDataPath replace allOf', (t) => { t.is(toDataPath('/allOf/1/properties/foo/allOf/1/properties/bar'), 'foo.bar'); }); -test('toDataPath replace allOf in combination with conditional schema compositions', t => { +test('toDataPath replace allOf in combination with conditional schema compositions', (t) => { t.is(toDataPath('/allOf/1/then/properties/foo'), 'foo'); }); -test('toDataPath replace multiple directly nested allOf in combination with conditional schema compositions', t => { +test('toDataPath replace multiple directly nested allOf in combination with conditional schema compositions', (t) => { t.is(toDataPath('/allOf/1/then/allOf/0/then/properties/foo'), 'foo'); }); -test('toDataPath replace multiple nested properties with allOf in combination with conditional schema compositions', t => { - t.is(toDataPath('/allOf/1/properties/foo/allOf/0/then/properties/bar'), 'foo.bar'); +test('toDataPath replace multiple nested properties with allOf in combination with conditional schema compositions', (t) => { + t.is( + toDataPath('/allOf/1/properties/foo/allOf/0/then/properties/bar'), + 'foo.bar' + ); }); -test('toDataPath replace oneOf', t => { +test('toDataPath replace oneOf', (t) => { t.is(toDataPath('/oneOf/1/properties/foo/oneOf/1/properties/bar'), 'foo.bar'); }); -test('toDataPath replace oneOf in combination with conditional schema compositions', t => { +test('toDataPath replace oneOf in combination with conditional schema compositions', (t) => { t.is(toDataPath('/oneOf/1/then/properties/foo'), 'foo'); }); -test('toDataPath replace multiple directly nested oneOf in combination with conditional schema compositions', t => { +test('toDataPath replace multiple directly nested oneOf in combination with conditional schema compositions', (t) => { t.is(toDataPath('/oneOf/1/then/oneOf/0/then/properties/foo'), 'foo'); }); -test('toDataPath replace multiple nested properties with oneOf in combination with conditional schema compositions', t => { - t.is(toDataPath('/oneOf/1/properties/foo/oneOf/0/then/properties/bar'), 'foo.bar'); +test('toDataPath replace multiple nested properties with oneOf in combination with conditional schema compositions', (t) => { + t.is( + toDataPath('/oneOf/1/properties/foo/oneOf/0/then/properties/bar'), + 'foo.bar' + ); }); -test('toDataPath replace all combinators', t => { +test('toDataPath replace all combinators', (t) => { t.is( toDataPath( '/oneOf/1/properties/foo/anyOf/1/properties/bar/allOf/1/properties/foobar' @@ -87,53 +96,47 @@ test('toDataPath replace all combinators', t => { 'foo.bar.foobar' ); }); -test('toDataPath use of keywords', t => { +test('toDataPath use of keywords', (t) => { t.is(toDataPath('#/properties/properties'), 'properties'); }); -test('toDataPath use of encoded paths', t => { +test('toDataPath use of encoded paths', (t) => { const fooBar = encodeURIComponent('foo.bar'); t.is(toDataPath(`#/properties/${fooBar}`), `${fooBar}`); }); -test('toDataPath relative with /', t => { +test('toDataPath relative with /', (t) => { t.is(toDataPath('/properties/foo/properties/bar'), 'foo.bar'); }); -test('toDataPath use of keywords relative with /', t => { +test('toDataPath use of keywords relative with /', (t) => { t.is(toDataPath('/properties/properties'), 'properties'); }); -test('toDataPath use of encoded paths relative with /', t => { +test('toDataPath use of encoded paths relative with /', (t) => { const fooBar = encodeURIComponent('foo/bar'); t.is(toDataPath(`/properties/${fooBar}`), `${fooBar}`); }); -test('toDataPath relative without /', t => { +test('toDataPath relative without /', (t) => { t.is(toDataPath('properties/foo/properties/bar'), 'foo.bar'); }); -test('toDataPath use of keywords relative without /', t => { +test('toDataPath use of keywords relative without /', (t) => { t.is(toDataPath('properties/properties'), 'properties'); }); -test('toDataPath use of encoded paths relative without /', t => { +test('toDataPath use of encoded paths relative without /', (t) => { const fooBar = encodeURIComponent('foo/bar'); t.is(toDataPath(`properties/${fooBar}`), `${fooBar}`); }); -test('toDataPath use of encoded special character in pathname', t => { +test('toDataPath use of encoded special character in pathname', (t) => { t.is(toDataPath('properties/foo~0bar~1baz'), 'foo~bar/baz'); }); -test('resolve instance', t => { +test('resolve instance', (t) => { const instance = { foo: 123 }; const result = Resolve.data(instance, toDataPath('#/properties/foo')); t.is(result, 123); }); -test('resolve instance with keywords', t => { +test('resolve instance with keywords', (t) => { const instance = { properties: 123 }; const result = Resolve.data(instance, toDataPath('#/properties/properties')); t.is(result, 123); }); -test('resolve instance with encoded', t => { - const instance = { 'foo/bar': 123 }; - const fooBar = encodeURIComponent('foo/bar'); - const result = Resolve.data(instance, toDataPath(`#/properties/${fooBar}`)); - t.is(result, 123); -}); -test('resolve nested instance', t => { +test('resolve nested instance', (t) => { const instance = { foo: { bar: 123 } }; const result = Resolve.data( instance, @@ -141,7 +144,7 @@ test('resolve nested instance', t => { ); t.is(result, 123); }); -test('resolve uninitiated instance', t => { +test('resolve uninitiated instance', (t) => { const instance = {}; const result = Resolve.data( instance, @@ -149,27 +152,27 @@ test('resolve uninitiated instance', t => { ); t.is(result, undefined); }); -test('resolve $ref', t => { +test('resolve $ref', (t) => { const schema: JsonSchema = { definitions: { foo: { - type: 'string' - } + type: 'string', + }, }, type: 'object', properties: { foos: { type: 'array', items: { - $ref: '#/definitions/foo' - } - } - } + $ref: '#/definitions/foo', + }, + }, + }, }; const result = Resolve.schema(schema, '#/properties/foos/items', schema); t.deepEqual(result, { type: 'string' }); }); -test('resolve $ref simple', t => { +test('resolve $ref simple', (t) => { const schema: JsonSchema = { definitions: { foo: { @@ -178,21 +181,21 @@ test('resolve $ref simple', t => { bar: { type: 'array', items: { - $ref: '#/definitions/foo' - } - } - } - } + $ref: '#/definitions/foo', + }, + }, + }, + }, }, type: 'object', properties: { foos: { type: 'array', items: { - $ref: '#/definitions/foo' - } - } - } + $ref: '#/definitions/foo', + }, + }, + }, }; const result = Resolve.schema(schema, '#/properties/foos/items', schema); t.deepEqual(result, { @@ -201,14 +204,14 @@ test('resolve $ref simple', t => { bar: { type: 'array', items: { - $ref: '#/definitions/foo' - } - } - } + $ref: '#/definitions/foo', + }, + }, + }, }); t.not((schema.definitions.foo.properties.bar.items as JsonSchema).$ref, '#'); }); -test('resolve $ref complicated', t => { +test('resolve $ref complicated', (t) => { const schema: JsonSchema = { definitions: { foo: { @@ -217,10 +220,10 @@ test('resolve $ref complicated', t => { bar: { type: 'array', items: { - $ref: '#/definitions/foo2' - } - } - } + $ref: '#/definitions/foo2', + }, + }, + }, }, foo2: { type: 'object', @@ -228,21 +231,21 @@ test('resolve $ref complicated', t => { bar: { type: 'array', items: { - $ref: '#/definitions/foo' - } - } - } - } + $ref: '#/definitions/foo', + }, + }, + }, + }, }, type: 'object', properties: { foos: { type: 'array', items: { - $ref: '#/definitions/foo' - } - } - } + $ref: '#/definitions/foo', + }, + }, + }, }; const result = Resolve.schema(schema, '#/properties/foos/items', schema); t.deepEqual(result, { @@ -251,9 +254,9 @@ test('resolve $ref complicated', t => { bar: { type: 'array', items: { - $ref: '#/definitions/foo2' - } - } - } + $ref: '#/definitions/foo2', + }, + }, + }, }); }); diff --git a/packages/core/test/util/renderer.test.ts b/packages/core/test/util/renderer.test.ts index 53043f5db..64fdd4e03 100644 --- a/packages/core/test/util/renderer.test.ts +++ b/packages/core/test/util/renderer.test.ts @@ -31,9 +31,38 @@ import { ErrorObject } from 'ajv'; import { JsonFormsState } from '../../src/store'; import { coreReducer, JsonFormsCore } from '../../src/reducers/core'; import { Dispatch } from '../../src/util/type'; -import { CoreActions, init, setValidationMode, update, UpdateAction, UPDATE_DATA } from '../../src/actions/actions'; -import { ControlElement, LabelElement, RuleEffect, UISchemaElement } from '../../src/models/uischema'; -import { computeLabel, createDefaultValue, mapDispatchToArrayControlProps, mapDispatchToControlProps, mapDispatchToMultiEnumProps, mapStateToAnyOfProps, mapStateToArrayLayoutProps, mapStateToControlProps, mapStateToEnumControlProps, mapStateToJsonFormsRendererProps, mapStateToLabelProps, mapStateToLayoutProps, mapStateToMultiEnumControlProps, mapStateToOneOfEnumControlProps, mapStateToOneOfProps, OwnPropsOfControl } from '../../src/util/renderer'; +import { + CoreActions, + init, + setValidationMode, + update, + UpdateAction, + UPDATE_DATA, +} from '../../src/actions/actions'; +import { + ControlElement, + LabelElement, + RuleEffect, + UISchemaElement, +} from '../../src/models/uischema'; +import { + computeLabel, + createDefaultValue, + mapDispatchToArrayControlProps, + mapDispatchToControlProps, + mapDispatchToMultiEnumProps, + mapStateToAnyOfProps, + mapStateToArrayLayoutProps, + mapStateToControlProps, + mapStateToEnumControlProps, + mapStateToJsonFormsRendererProps, + mapStateToLabelProps, + mapStateToLayoutProps, + mapStateToMultiEnumControlProps, + mapStateToOneOfEnumControlProps, + mapStateToOneOfProps, + OwnPropsOfControl, +} from '../../src/util/renderer'; import { clearAllIds } from '../../src/util/ids'; import { JsonSchema } from '../../src/models/jsonSchema'; import { rankWith } from '../../src/testers/testers'; @@ -49,7 +78,9 @@ const mockDispatch = ( initialCore: JsonFormsCore ): [() => JsonFormsCore, Dispatch] => { const coreContainer = { core: initialCore }; - const dispatch: Dispatch = (action: T) : T => { + const dispatch: Dispatch = ( + action: T + ): T => { coreContainer.core = coreReducer(coreContainer.core, action); return action; }; @@ -62,8 +93,8 @@ const hideRule = { condition: { type: 'LEAF', scope: '#/properties/firstName', - expectedValue: 'Homer' - } + expectedValue: 'Homer', + }, }; const disableRule = { @@ -71,8 +102,8 @@ const disableRule = { condition: { type: 'LEAF', scope: '#/properties/firstName', - expectedValue: 'Homer' - } + expectedValue: 'Homer', + }, }; const enableRule = { @@ -80,13 +111,13 @@ const enableRule = { condition: { type: 'LEAF', scope: '#/properties/firstName', - expectedValue: 'Homer' - } + expectedValue: 'Homer', + }, }; const coreUISchema: ControlElement = { type: 'Control', - scope: '#/properties/firstName' + scope: '#/properties/firstName', }; const createState = (uischema: UISchemaElement) => ({ @@ -96,63 +127,63 @@ const createState = (uischema: UISchemaElement) => ({ type: 'object', properties: { firstName: { type: 'string' }, - lastName: { type: 'string' } - } + lastName: { type: 'string' }, + }, }, data: { - firstName: 'Homer' + firstName: 'Homer', }, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }); -test('mapStateToControlProps - visible via ownProps ', t => { +test('mapStateToControlProps - visible via ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { visible: true, - uischema + uischema, }; const props = mapStateToControlProps(createState(uischema), ownProps); t.false(props.visible); }); -test('mapStateToControlProps - hidden via ownProps ', t => { +test('mapStateToControlProps - hidden via ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { visible: false, - uischema + uischema, }; const props = mapStateToControlProps(createState(uischema), ownProps); t.false(props.visible); }); -test('mapStateToControlProps - hidden via state ', t => { +test('mapStateToControlProps - hidden via state ', (t) => { const uischema = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { - uischema + uischema, }; const props = mapStateToControlProps(createState(uischema), ownProps); t.false(props.visible); }); -test('mapStateToControlProps - visible via state ', t => { +test('mapStateToControlProps - visible via state ', (t) => { const uischema = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { - uischema + uischema, }; const clonedState = _.cloneDeep(createState(uischema)); clonedState.jsonforms.core.data.firstName = 'Lisa'; @@ -160,14 +191,14 @@ test('mapStateToControlProps - visible via state ', t => { t.true(props.visible); }); -test('mapStateToControlProps - visible via state with path from ownProps ', t => { +test('mapStateToControlProps - visible via state with path from ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: hideRule + rule: hideRule, }; const ownProps = { uischema, - path: 'foo' + path: 'foo', }; const state = { jsonforms: { @@ -176,24 +207,24 @@ test('mapStateToControlProps - visible via state with path from ownProps ', t => type: 'object', properties: { firstName: { type: 'string' }, - lastName: { type: 'string' } - } + lastName: { type: 'string' }, + }, }, data: { - foo: { firstName: 'Lisa' } + foo: { firstName: 'Lisa' }, }, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const props = mapStateToControlProps(state, ownProps); t.true(props.visible); }); -test('mapStateToControlProps - disabled via global readonly', t => { +test('mapStateToControlProps - disabled via global readonly', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.readonly = true; @@ -202,10 +233,10 @@ test('mapStateToControlProps - disabled via global readonly', t => { t.false(props.enabled); }); -test('mapStateToControlProps - disabled via global readonly beats enabled via ownProps', t => { +test('mapStateToControlProps - disabled via global readonly beats enabled via ownProps', (t) => { const ownProps = { uischema: coreUISchema, - enabled: true + enabled: true, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.readonly = true; @@ -214,13 +245,13 @@ test('mapStateToControlProps - disabled via global readonly beats enabled via ow t.false(props.enabled); }); -test('mapStateToControlProps - disabled via global readonly beats enabled via rule', t => { +test('mapStateToControlProps - disabled via global readonly beats enabled via rule', (t) => { const uischema = { ...coreUISchema, - rule: enableRule + rule: enableRule, }; const ownProps = { - uischema + uischema, }; const state: JsonFormsState = createState(uischema); state.jsonforms.readonly = true; @@ -229,15 +260,15 @@ test('mapStateToControlProps - disabled via global readonly beats enabled via ru t.false(props.enabled); }); -test('mapStateToControlProps - enabled via state with path from ownProps ', t => { +test('mapStateToControlProps - enabled via state with path from ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { visible: true, uischema, - path: 'foo' + path: 'foo', }; const state = { jsonforms: { @@ -246,66 +277,66 @@ test('mapStateToControlProps - enabled via state with path from ownProps ', t => type: 'object', properties: { firstName: { type: 'string' }, - lastName: { type: 'string' } - } + lastName: { type: 'string' }, + }, }, data: { - foo: { firstName: 'Lisa' } + foo: { firstName: 'Lisa' }, }, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const props = mapStateToControlProps(state, ownProps); t.true(props.enabled); }); -test('mapStateToControlProps - enabled via ownProps ', t => { +test('mapStateToControlProps - enabled via ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { enabled: true, - uischema + uischema, }; const props = mapStateToControlProps(createState(uischema), ownProps); t.false(props.enabled); }); -test('mapStateToControlProps - disabled via ownProps ', t => { +test('mapStateToControlProps - disabled via ownProps ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { enabled: false, - uischema + uischema, }; const props = mapStateToControlProps(createState(uischema), ownProps); t.false(props.enabled); }); -test('mapStateToControlProps - disabled via state ', t => { +test('mapStateToControlProps - disabled via state ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { - uischema + uischema, }; const props = mapStateToControlProps(createState(uischema), ownProps); t.false(props.enabled); }); -test('mapStateToControlProps - enabled via state ', t => { +test('mapStateToControlProps - enabled via state ', (t) => { const uischema = { ...coreUISchema, - rule: disableRule + rule: disableRule, }; const ownProps = { - uischema + uischema, }; const clonedState = _.cloneDeep(createState(uischema)); clonedState.jsonforms.core.data.firstName = 'Lisa'; @@ -313,55 +344,55 @@ test('mapStateToControlProps - enabled via state ', t => { t.true(props.enabled); }); -test('mapStateToControlProps - path', t => { +test('mapStateToControlProps - path', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const props = mapStateToControlProps(createState(coreUISchema), ownProps); t.is(props.path, 'firstName'); }); -test('mapStateToControlProps - compose path with ownProps.path', t => { +test('mapStateToControlProps - compose path with ownProps.path', (t) => { const ownProps = { uischema: coreUISchema, - path: 'yo' + path: 'yo', }; const props = mapStateToControlProps(createState(coreUISchema), ownProps); t.is(props.path, 'yo.firstName'); }); -test('mapStateToControlProps - derive label', t => { +test('mapStateToControlProps - derive label', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const props = mapStateToControlProps(createState(coreUISchema), ownProps); t.is(props.label, 'First Name'); }); -test('mapStateToControlProps - do not show label', t => { +test('mapStateToControlProps - do not show label', (t) => { const ownProps = { uischema: { ...coreUISchema, label: { - show: false - } - } + show: false, + }, + }, }; const props = mapStateToControlProps(createState(coreUISchema), ownProps); t.is(props.label, ''); }); -test('mapStateToControlProps - data', t => { +test('mapStateToControlProps - data', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const props = mapStateToControlProps(createState(coreUISchema), ownProps); t.is(props.data, 'Homer'); }); -test('mapStateToControlProps - errors', t => { +test('mapStateToControlProps - errors', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const clonedState = _.cloneDeep(createState(coreUISchema)); const error: ErrorObject = { @@ -370,24 +401,24 @@ test('mapStateToControlProps - errors', t => { keyword: 'whatever', schemaPath: '', params: undefined, - parentSchema: { type: 'string' } + parentSchema: { type: 'string' }, }; clonedState.jsonforms.core.errors = [error]; const props = mapStateToControlProps(clonedState, ownProps); t.is(props.errors, 'Duff beer'); }); -test('mapStateToControlProps - no duplicate error messages', t => { +test('mapStateToControlProps - no duplicate error messages', (t) => { const schema = { type: 'object', properties: { firstName: { anyOf: [ { type: 'string', minLength: 5 }, - { type: 'string', enum: ['foo', 'bar'] } - ] - } - } + { type: 'string', enum: ['foo', 'bar'] }, + ], + }, + }, }; const initCoreState = coreReducer(undefined, init({}, schema, coreUISchema)); const updateCoreState = coreReducer( @@ -401,34 +432,37 @@ test('mapStateToControlProps - no duplicate error messages', t => { t.is(props.errors.split('\n').length, 1); }); -test('mapStateToControlProps - id', t => { +test('mapStateToControlProps - id', (t) => { clearAllIds(); const ownProps = { uischema: coreUISchema, - id: '#/properties/firstName' + id: '#/properties/firstName', }; const props = mapStateToControlProps(createState(coreUISchema), ownProps); t.is(props.id, '#/properties/firstName'); }); -test('mapStateToControlProps - hide errors in hide validation mode', t => { +test('mapStateToControlProps - hide errors in hide validation mode', (t) => { const schema = { type: 'object', properties: { animal: { - type: 'string' - } - } + type: 'string', + }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#/properties/animal' + scope: '#/properties/animal', }; - const initCoreState = coreReducer(undefined, init({ animal: 100 }, schema, uischema)); + const initCoreState = coreReducer( + undefined, + init({ animal: 100 }, schema, uischema) + ); t.is(initCoreState.errors.length, 1); const ownProps = { - uischema + uischema, }; const props = mapStateToControlProps( { jsonforms: { core: initCoreState } }, @@ -449,7 +483,7 @@ test('mapStateToControlProps - hide errors in hide validation mode', t => { t.is(hideErrorsProps.errors, ''); }); -test('mapDispatchToControlProps', t => { +test('mapDispatchToControlProps', (t) => { const store = mockStore(createState(coreUISchema)); const props = mapDispatchToControlProps(store.dispatch); props.handleChange('foo', 42); @@ -459,12 +493,12 @@ test('mapDispatchToControlProps', t => { t.is(updateAction.updater(), 42); }); -test('createDefaultValue', t => { +test('createDefaultValue', (t) => { t.true( _.isDate( createDefaultValue({ type: 'string', - format: 'date' + format: 'date', }) ) ); @@ -472,7 +506,7 @@ test('createDefaultValue', t => { _.isDate( createDefaultValue({ type: 'string', - format: 'date-time' + format: 'date-time', }) ) ); @@ -480,7 +514,7 @@ test('createDefaultValue', t => { _.isDate( createDefaultValue({ type: 'string', - format: 'time' + format: 'time', }) ) ); @@ -494,69 +528,69 @@ test('createDefaultValue', t => { t.deepEqual(createDefaultValue({ type: 'something' }), {}); }); -test(`mapStateToJsonFormsRendererProps should use registered UI schema given ownProps schema`, t => { +test(`mapStateToJsonFormsRendererProps should use registered UI schema given ownProps schema`, (t) => { const store = mockStore(createState(coreUISchema)); const schema = { type: 'object', properties: { bar: { - type: 'number' - } - } + type: 'number', + }, + }, }; const props = mapStateToJsonFormsRendererProps(store.getState(), { schema }); t.deepEqual(props.uischema, coreUISchema); }); -test(`mapStateToJsonFormsRendererProps should use registered UI schema given no ownProps`, t => { +test(`mapStateToJsonFormsRendererProps should use registered UI schema given no ownProps`, (t) => { const store = mockStore(createState(coreUISchema)); const props = mapStateToJsonFormsRendererProps(store.getState(), {}); t.deepEqual(props.uischema, coreUISchema); }); -test(`mapStateToJsonFormsRendererProps should use UI schema if given via ownProps`, t => { +test(`mapStateToJsonFormsRendererProps should use UI schema if given via ownProps`, (t) => { const store = mockStore(createState(coreUISchema)); const schema = { type: 'object', properties: { foo: { - type: 'string' + type: 'string', }, bar: { - type: 'number' - } - } + type: 'number', + }, + }, }; const uischema = { type: 'Control', - scope: '#/properties/foo' + scope: '#/properties/foo', }; const props = mapStateToJsonFormsRendererProps(store.getState(), { schema, - uischema + uischema, }); t.deepEqual(props.uischema, uischema); }); -test('mapDispatchToArrayControlProps should adding items to array', t => { +test('mapDispatchToArrayControlProps should adding items to array', (t) => { const data: any = ['foo']; const schema: JsonSchema = { type: 'array', items: { - type: 'string' - } + type: 'string', + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; const initCore: JsonFormsCore = { uischema, schema, data, - errors: [] as ErrorObject[] + errors: [] as ErrorObject[], }; const [getCore, dispatch] = mockDispatch(initCore); dispatch(init(data, schema, uischema)); @@ -565,23 +599,23 @@ test('mapDispatchToArrayControlProps should adding items to array', t => { t.is(getCore().data.length, 2); }); -test('mapDispatchToArrayControlProps should remove items from array', t => { +test('mapDispatchToArrayControlProps should remove items from array', (t) => { const data = ['foo', 'bar', 'quux']; const schema: JsonSchema = { type: 'array', items: { - type: 'string' - } + type: 'string', + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; const initCore: JsonFormsCore = { uischema, schema, data, - errors: [] as ErrorObject[] + errors: [] as ErrorObject[], }; const [getCore, dispatch] = mockDispatch(initCore); dispatch(init(data, schema, uischema)); @@ -591,15 +625,15 @@ test('mapDispatchToArrayControlProps should remove items from array', t => { t.is(getCore().data[0], 'quux'); }); -test('mapStateToLayoutProps - visible via state with path from ownProps ', t => { +test('mapStateToLayoutProps - visible via state with path from ownProps ', (t) => { const uischema = { type: 'VerticalLayout', elements: [coreUISchema], - rule: hideRule + rule: hideRule, }; const ownProps = { uischema, - path: 'foo' + path: 'foo', }; const state = { jsonforms: { @@ -608,22 +642,22 @@ test('mapStateToLayoutProps - visible via state with path from ownProps ', t => type: 'object', properties: { firstName: { type: 'string' }, - lastName: { type: 'string' } - } + lastName: { type: 'string' }, + }, }, data: { - foo: { firstName: 'Lisa' } + foo: { firstName: 'Lisa' }, }, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const props = mapStateToLayoutProps(state, ownProps); t.true(props.visible); }); -test('mapStateToArrayLayoutProps - should include minItems in array layout props', t => { +test('mapStateToArrayLayoutProps - should include minItems in array layout props', (t) => { const schema: JsonSchema = { type: 'array', minItems: 42, @@ -632,15 +666,15 @@ test('mapStateToArrayLayoutProps - should include minItems in array layout props properties: { message: { type: 'string', - default: 'foo' - } - } - } + default: 'foo', + }, + }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; const state = { @@ -649,23 +683,23 @@ test('mapStateToArrayLayoutProps - should include minItems in array layout props schema, data: {}, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const ownProps = { - uischema + uischema, }; const props = mapStateToArrayLayoutProps(state, ownProps); t.is(props.minItems, 42); }); -test('mapStateToLayoutProps should return renderers prop via ownProps', t => { +test('mapStateToLayoutProps should return renderers prop via ownProps', (t) => { const uischema = { type: 'VerticalLayout', - elements: [] as UISchemaElement[] + elements: [] as UISchemaElement[], }; const state = { jsonforms: { @@ -674,16 +708,16 @@ test('mapStateToLayoutProps should return renderers prop via ownProps', t => { type: 'object', properties: { firstName: { type: 'string' }, - lastName: { type: 'string' } - } + lastName: { type: 'string' }, + }, }, data: { - foo: { firstName: 'Homer' } + foo: { firstName: 'Homer' }, }, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const props = mapStateToLayoutProps(state, { uischema, @@ -691,20 +725,20 @@ test('mapStateToLayoutProps should return renderers prop via ownProps', t => { renderers: [ { tester: rankWith(1, () => true), - renderer: undefined - } - ] + renderer: undefined, + }, + ], }); t.is(props.renderers.length, 1); }); -test('mapStateToLayoutProps - disabled via global readonly', t => { +test('mapStateToLayoutProps - disabled via global readonly', (t) => { const uischema = { type: 'VerticalLayout', elements: [coreUISchema], }; const ownProps = { - uischema + uischema, }; const state: JsonFormsState = createState(uischema); state.jsonforms.readonly = true; @@ -713,14 +747,14 @@ test('mapStateToLayoutProps - disabled via global readonly', t => { t.false(props.enabled); }); -test('mapStateToLayoutProps - disabled via global readonly beats enabled via ownProps', t => { +test('mapStateToLayoutProps - disabled via global readonly beats enabled via ownProps', (t) => { const uischema = { type: 'VerticalLayout', elements: [coreUISchema], }; const ownProps = { uischema, - enabled: true + enabled: true, }; const state: JsonFormsState = createState(uischema); state.jsonforms.readonly = true; @@ -729,14 +763,14 @@ test('mapStateToLayoutProps - disabled via global readonly beats enabled via own t.false(props.enabled); }); -test('mapStateToLayoutProps - disabled via global readonly beats enabled via rule', t => { +test('mapStateToLayoutProps - disabled via global readonly beats enabled via rule', (t) => { const uischema = { type: 'VerticalLayout', elements: [coreUISchema], - rule: enableRule + rule: enableRule, }; const ownProps = { - uischema + uischema, }; const state: JsonFormsState = createState(uischema); state.jsonforms.readonly = true; @@ -745,15 +779,15 @@ test('mapStateToLayoutProps - disabled via global readonly beats enabled via rul t.false(props.enabled); }); -test('mapStateToLayoutProps - hidden via state with path from ownProps ', t => { +test('mapStateToLayoutProps - hidden via state with path from ownProps ', (t) => { const uischema = { type: 'VerticalLayout', elements: [coreUISchema], - rule: hideRule + rule: hideRule, }; const ownProps = { uischema, - path: 'foo' + path: 'foo', }; const state = { jsonforms: { @@ -762,29 +796,29 @@ test('mapStateToLayoutProps - hidden via state with path from ownProps ', t => { type: 'object', properties: { firstName: { type: 'string' }, - lastName: { type: 'string' } - } + lastName: { type: 'string' }, + }, }, data: { - foo: { firstName: 'Homer' } + foo: { firstName: 'Homer' }, }, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const props = mapStateToLayoutProps(state, ownProps); t.false(props.visible); }); -test("mapStateToOneOfProps - indexOfFittingSchema should not select schema if enum doesn't match", t => { +test("mapStateToOneOfProps - indexOfFittingSchema should not select schema if enum doesn't match", (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/method' + scope: '#/properties/method', }; const ownProps = { - uischema + uischema, }; const state = { @@ -804,10 +838,10 @@ test("mapStateToOneOfProps - indexOfFittingSchema should not select schema if en title: 'Method', type: 'string', enum: ['Injection'], - default: 'Injection' - } + default: 'Injection', + }, }, - required: ['method'] + required: ['method'], }, { title: 'Infusion', @@ -817,33 +851,33 @@ test("mapStateToOneOfProps - indexOfFittingSchema should not select schema if en title: 'Method', type: 'string', enum: ['Infusion'], - default: 'Infusion' - } + default: 'Infusion', + }, }, - required: ['method'] - } - ] - } - } + required: ['method'], + }, + ], + }, + }, }, data: { method: { - method: 'Infusion' - } + method: 'Infusion', + }, }, - uischema - } - } + uischema, + }, + }, }; const oneOfProps = mapStateToOneOfProps(state, ownProps); t.is(oneOfProps.indexOfFittingSchema, 1); }); -test('mapStateToMultiEnumControlProps - oneOf items', t => { +test('mapStateToMultiEnumControlProps - oneOf items', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/colors' + scope: '#/properties/colors', }; const state = { jsonforms: { @@ -856,39 +890,39 @@ test('mapStateToMultiEnumControlProps - oneOf items', t => { items: { oneOf: [ { - const: 'red' + const: 'red', }, { const: 'pink', - title: 'almost red' - } - ] + title: 'almost red', + }, + ], }, - uniqueItems: true - } - } + uniqueItems: true, + }, + }, }, data: {}, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const ownProps = { uischema, - path: 'colors' + path: 'colors', }; const props = mapStateToMultiEnumControlProps(state, ownProps); t.deepEqual(props.options, [ { label: 'red', value: 'red' }, - { label: 'almost red', value: 'pink' } + { label: 'almost red', value: 'pink' }, ]); }); -test('mapStateToMultiEnumControlProps - enum items', t => { +test('mapStateToMultiEnumControlProps - enum items', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/colors' + scope: '#/properties/colors', }; const state = { jsonforms: { @@ -900,34 +934,34 @@ test('mapStateToMultiEnumControlProps - enum items', t => { type: 'array', items: { type: 'string', - enum: ['red', 'green', 'pink'] + enum: ['red', 'green', 'pink'], }, - uniqueItems: true - } - } + uniqueItems: true, + }, + }, }, data: {}, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const ownProps = { uischema, - path: 'colors' + path: 'colors', }; const props = mapStateToMultiEnumControlProps(state, ownProps); t.deepEqual(props.options, [ { label: 'red', value: 'red' }, { label: 'green', value: 'green' }, - { label: 'pink', value: 'pink' } + { label: 'pink', value: 'pink' }, ]); }); -test('mapDispatchToMultiEnumProps - enum schema - addItem', t => { +test('mapDispatchToMultiEnumProps - enum schema - addItem', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/colors' + scope: '#/properties/colors', }; const schema = { type: 'object', @@ -936,18 +970,18 @@ test('mapDispatchToMultiEnumProps - enum schema - addItem', t => { type: 'array', items: { type: 'string', - enum: ['red', 'green', 'pink'] + enum: ['red', 'green', 'pink'], }, - uniqueItems: true - } - } + uniqueItems: true, + }, + }, }; - const data = {colors:['green']}; - const initCore : JsonFormsCore = { + const data = { colors: ['green'] }; + const initCore: JsonFormsCore = { uischema, schema, data, - errors: [] as ErrorObject[] + errors: [] as ErrorObject[], }; const [getCore, dispatch] = mockDispatch(initCore); dispatch(init(data, schema, uischema, createAjv({ useDefaults: true }))); @@ -959,10 +993,10 @@ test('mapDispatchToMultiEnumProps - enum schema - addItem', t => { t.deepEqual(getCore().data.colors[1], 'pink'); }); -test('mapDispatchToMultiEnumProps - enum schema - removeItem', t => { +test('mapDispatchToMultiEnumProps - enum schema - removeItem', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/colors' + scope: '#/properties/colors', }; const schema = { type: 'object', @@ -971,18 +1005,18 @@ test('mapDispatchToMultiEnumProps - enum schema - removeItem', t => { type: 'array', items: { type: 'string', - enum: ['red', 'green', 'pink'] + enum: ['red', 'green', 'pink'], }, - uniqueItems: true - } - } + uniqueItems: true, + }, + }, }; - const data = {colors:['green', 'red']}; - const initCore : JsonFormsCore = { + const data = { colors: ['green', 'red'] }; + const initCore: JsonFormsCore = { uischema, schema, data, - errors: [] as ErrorObject[] + errors: [] as ErrorObject[], }; const [getCore, dispatch] = mockDispatch(initCore); dispatch(init(data, schema, uischema, createAjv({ useDefaults: true }))); @@ -993,10 +1027,10 @@ test('mapDispatchToMultiEnumProps - enum schema - removeItem', t => { t.deepEqual(getCore().data.colors[0], 'green'); }); -test('mapDispatchToMultiEnumProps - oneOf schema - addItem', t => { +test('mapDispatchToMultiEnumProps - oneOf schema - addItem', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/colors' + scope: '#/properties/colors', }; const schema = { type: 'object', @@ -1006,24 +1040,24 @@ test('mapDispatchToMultiEnumProps - oneOf schema - addItem', t => { items: { oneOf: [ { - const: 'red' + const: 'red', }, { const: 'pink', - title: 'almost red' - } - ] + title: 'almost red', + }, + ], }, - uniqueItems: true - } - } + uniqueItems: true, + }, + }, }; const data = {}; - const initCore : JsonFormsCore = { + const initCore: JsonFormsCore = { uischema, schema, data, - errors: [] as ErrorObject[] + errors: [] as ErrorObject[], }; const [getCore, dispatch] = mockDispatch(initCore); dispatch(init(data, schema, uischema, createAjv({ useDefaults: true }))); @@ -1034,10 +1068,10 @@ test('mapDispatchToMultiEnumProps - oneOf schema - addItem', t => { t.deepEqual(getCore().data.colors[0], 'pink'); }); -test('mapDispatchToMultiEnumProps - oneOf schema - removeItem', t => { +test('mapDispatchToMultiEnumProps - oneOf schema - removeItem', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#/properties/colors' + scope: '#/properties/colors', }; const schema = { type: 'object', @@ -1047,24 +1081,24 @@ test('mapDispatchToMultiEnumProps - oneOf schema - removeItem', t => { items: { oneOf: [ { - const: 'red' + const: 'red', }, { const: 'pink', - title: 'almost red' - } - ] + title: 'almost red', + }, + ], }, - uniqueItems: true - } - } + uniqueItems: true, + }, + }, }; - const data = {colors:['pink']}; - const initCore : JsonFormsCore = { + const data = { colors: ['pink'] }; + const initCore: JsonFormsCore = { uischema, schema, data, - errors: [] as ErrorObject[] + errors: [] as ErrorObject[], }; const [getCore, dispatch] = mockDispatch(initCore); dispatch(init(data, schema, uischema, createAjv({ useDefaults: true }))); @@ -1074,26 +1108,26 @@ test('mapDispatchToMultiEnumProps - oneOf schema - removeItem', t => { t.is(getCore().data.colors.length, 0); }); -test('should assign defaults to enum', t => { +test('should assign defaults to enum', (t) => { const schema: JsonSchema = { type: 'object', properties: { name: { type: 'string', - minLength: 1 + minLength: 1, }, color: { type: 'string', enum: ['red', 'green', 'blue'], - default: 'green' - } - } + default: 'green', + }, + }, }; const uischema: UISchemaElement = undefined; const data = { - name: 'foo' + name: 'foo', }; const initState: JsonFormsState = { @@ -1102,15 +1136,18 @@ test('should assign defaults to enum', t => { uischema, schema, data, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; - const newCore = coreReducer(initState.jsonforms.core, init(data, schema, uischema, createAjv({ useDefaults: true }))); + const newCore = coreReducer( + initState.jsonforms.core, + init(data, schema, uischema, createAjv({ useDefaults: true })) + ); t.is(newCore.data.color, 'green'); }); -test('should assign defaults to empty item within nested object of an array', t => { +test('should assign defaults to empty item within nested object of an array', (t) => { const schema: JsonSchema = { type: 'array', items: { @@ -1118,15 +1155,15 @@ test('should assign defaults to empty item within nested object of an array', t properties: { message: { type: 'string', - default: 'foo' - } - } - } + default: 'foo', + }, + }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; const data = [{}]; @@ -1137,17 +1174,20 @@ test('should assign defaults to empty item within nested object of an array', t uischema, schema, data, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; - const newCore = coreReducer(initState.jsonforms.core, init(data, schema, uischema, createAjv({ useDefaults: true }))); + const newCore = coreReducer( + initState.jsonforms.core, + init(data, schema, uischema, createAjv({ useDefaults: true })) + ); t.is(newCore.data.length, 1); t.deepEqual(newCore.data[0], { message: 'foo' }); }); -test('should assign defaults to newly added item within nested object of an array', t => { +test('should assign defaults to newly added item within nested object of an array', (t) => { const schema: JsonSchema = { type: 'array', items: { @@ -1155,15 +1195,15 @@ test('should assign defaults to newly added item within nested object of an arra properties: { message: { type: 'string', - default: 'foo' - } - } - } + default: 'foo', + }, + }, + }, }; const uischema: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; const data = [{}]; @@ -1172,7 +1212,7 @@ test('should assign defaults to newly added item within nested object of an arra uischema, schema, data, - errors: [] as ErrorObject[] + errors: [] as ErrorObject[], }; const [getCore, dispatch] = mockDispatch(initCore); dispatch(init(data, schema, uischema, createAjv({ useDefaults: true }))); @@ -1183,63 +1223,63 @@ test('should assign defaults to newly added item within nested object of an arra t.deepEqual(getCore().data[0], { message: 'foo' }); }); -test('computeLabel - should not edit label if not required and hideRequiredAsterisk is false', t => { +test('computeLabel - should not edit label if not required and hideRequiredAsterisk is false', (t) => { const computedLabel = computeLabel('Test Label', false, false); t.is(computedLabel, 'Test Label'); }); -test('computeLabel - should not edit label if not required and hideRequiredAsterisk is true', t => { +test('computeLabel - should not edit label if not required and hideRequiredAsterisk is true', (t) => { const computedLabel = computeLabel('Test Label', false, true); t.is(computedLabel, 'Test Label'); }); -test('computeLabel - should not edit label if required but hideRequiredAsterisk is true', t => { +test('computeLabel - should not edit label if required but hideRequiredAsterisk is true', (t) => { const computedLabel = computeLabel('Test Label', true, true); t.is(computedLabel, 'Test Label'); }); -test('computeLabel - should add asterisk if required but hideRequiredAsterisk is false', t => { +test('computeLabel - should add asterisk if required but hideRequiredAsterisk is false', (t) => { const computedLabel = computeLabel('Test Label', true, false); t.is(computedLabel, 'Test Label*'); }); -test('mapStateToAnyOfProps - const constraint in anyOf schema should return correct indexOfFittingSchema', t => { +test('mapStateToAnyOfProps - const constraint in anyOf schema should return correct indexOfFittingSchema', (t) => { const uischema: ControlElement = { type: 'Control', - scope: '#' + scope: '#', }; const schema: JsonSchema7 = { anyOf: [ { - type: "object", + type: 'object', properties: { type: { - const: "type1" - } - } + const: 'type1', + }, + }, }, { - type: "object", + type: 'object', properties: { type: { - const: "type2" - } - } + const: 'type2', + }, + }, }, { - type: "object", + type: 'object', properties: { type: { - const: "type3" - } - } - } - ] + const: 'type3', + }, + }, + }, + ], }; const ownProps: OwnPropsOfControl = { visible: true, uischema, - path: 'foo' + path: 'foo', }; const state = { jsonforms: { @@ -1247,20 +1287,20 @@ test('mapStateToAnyOfProps - const constraint in anyOf schema should return corr ajv: createAjv(), schema, data: { - foo: { type: "type3"} + foo: { type: 'type3' }, }, uischema, - errors: [] as ErrorObject[] - } - } + errors: [] as ErrorObject[], + }, + }, }; const props = mapStateToAnyOfProps(state, ownProps); t.is(props.indexOfFittingSchema, 2); }); -test('mapStateToControlProps - i18n - mapStateToControlProps should not crash without i18n', t => { +test('mapStateToControlProps - i18n - mapStateToControlProps should not crash without i18n', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.i18n = undefined; @@ -1269,9 +1309,9 @@ test('mapStateToControlProps - i18n - mapStateToControlProps should not crash wi t.is(props.label, 'First Name'); }); -test('mapStateToControlProps - i18n - default translation has no effect', t => { +test('mapStateToControlProps - i18n - default translation has no effect', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; @@ -1281,88 +1321,111 @@ test('mapStateToControlProps - i18n - default translation has no effect', t => { t.is(props.description, undefined); }); -test('mapStateToControlProps - i18n - translation via path key', t => { +test('mapStateToControlProps - i18n - translation via path key', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'firstName.label': return 'my translation'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'firstName.label': + return 'my translation'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.label, 'my translation'); t.is(props.description, undefined); }); -test('mapStateToControlProps - i18n - translation via default message', t => { +test('mapStateToControlProps - i18n - translation via default message', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (_key: string, defaultMessage: string | undefined) => { - switch(defaultMessage){ - case 'First Name': return 'my translation'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + _key: string, + defaultMessage: string | undefined + ) => { + switch (defaultMessage) { + case 'First Name': + return 'my translation'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.label, 'my translation'); t.is(props.description, undefined); }); -test('mapStateToControlProps - i18n - translation via JSON Schema i18n key', t => { +test('mapStateToControlProps - i18n - translation via JSON Schema i18n key', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; - (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = 'my-key'; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'my-key.label': return 'my label'; - case 'my-key.description': return 'my description'; - default: return defaultMessage; + (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = + 'my-key'; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'my-key.label': + return 'my label'; + case 'my-key.description': + return 'my description'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.label, 'my label'); t.is(props.description, 'my description'); }); -test('mapStateToControlProps - i18n - translation via UI Schema i18n key', t => { +test('mapStateToControlProps - i18n - translation via UI Schema i18n key', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; - ownProps.uischema = {...ownProps.uischema, i18n: 'my-key'}; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'my-key.label': return 'my label'; - case 'my-key.description': return 'my description'; - default: return defaultMessage; + ownProps.uischema = { ...ownProps.uischema, i18n: 'my-key' }; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'my-key.label': + return 'my label'; + case 'my-key.description': + return 'my description'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.label, 'my label'); t.is(props.description, 'my description'); }); -test('mapStateToControlProps - i18n errors - should not crash without i18n', t => { +test('mapStateToControlProps - i18n errors - should not crash without i18n', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.pattern = "[0-9]+" + state.jsonforms.core.schema.properties.firstName.pattern = '[0-9]+'; state.jsonforms.core = coreReducer( state.jsonforms.core, init( @@ -1378,12 +1441,12 @@ test('mapStateToControlProps - i18n errors - should not crash without i18n', t = t.is(props.errors, 'must match pattern "[0-9]+"'); }); -test('mapStateToControlProps - i18n errors - default translation has no effect', t => { +test('mapStateToControlProps - i18n errors - default translation has no effect', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.pattern = "[0-9]+" + state.jsonforms.core.schema.properties.firstName.pattern = '[0-9]+'; state.jsonforms.core = coreReducer( state.jsonforms.core, init( @@ -1399,12 +1462,12 @@ test('mapStateToControlProps - i18n errors - default translation has no effect', t.is(props.errors, 'must match pattern "[0-9]+"'); }); -test('mapStateToControlProps - i18n errors - translate via error message key', t => { +test('mapStateToControlProps - i18n errors - translate via error message key', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.pattern = "[0-9]+" + state.jsonforms.core.schema.properties.firstName.pattern = '[0-9]+'; state.jsonforms.core = coreReducer( state.jsonforms.core, init( @@ -1415,24 +1478,30 @@ test('mapStateToControlProps - i18n errors - translate via error message key', t ) ); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'must match pattern "[0-9]+"': return 'my error message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'must match pattern "[0-9]+"': + return 'my error message'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.errors, 'my error message'); }); -test('mapStateToControlProps - i18n errors - translate via i18 specialized error keyword key', t => { +test('mapStateToControlProps - i18n errors - translate via i18 specialized error keyword key', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.pattern = "[0-9]+"; - (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = 'my-key'; + state.jsonforms.core.schema.properties.firstName.pattern = '[0-9]+'; + (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = + 'my-key'; state.jsonforms.core = coreReducer( state.jsonforms.core, init( @@ -1443,24 +1512,30 @@ test('mapStateToControlProps - i18n errors - translate via i18 specialized error ) ); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'my-key.error.pattern': return 'my error message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'my-key.error.pattern': + return 'my error message'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.errors, 'my error message'); }); -test('mapStateToControlProps - i18n errors - translate via i18 general error keyword key', t => { +test('mapStateToControlProps - i18n errors - translate via i18 general error keyword key', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.pattern = "[0-9]+"; - (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = 'my-key'; + state.jsonforms.core.schema.properties.firstName.pattern = '[0-9]+'; + (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = + 'my-key'; state.jsonforms.core = coreReducer( state.jsonforms.core, init( @@ -1471,24 +1546,30 @@ test('mapStateToControlProps - i18n errors - translate via i18 general error key ) ); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'error.pattern': return 'my error message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'error.pattern': + return 'my error message'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.errors, 'my error message'); }); -test('mapStateToControlProps - i18n errors - specialized keyword wins over generic keyword', t => { +test('mapStateToControlProps - i18n errors - specialized keyword wins over generic keyword', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.pattern = "[0-9]+"; - (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = 'my-key'; + state.jsonforms.core.schema.properties.firstName.pattern = '[0-9]+'; + (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = + 'my-key'; state.jsonforms.core = coreReducer( state.jsonforms.core, init( @@ -1499,26 +1580,33 @@ test('mapStateToControlProps - i18n errors - specialized keyword wins over gener ) ); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'my-key.error.pattern': return 'my key error message'; - case 'error.pattern': return 'my error message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'my-key.error.pattern': + return 'my key error message'; + case 'error.pattern': + return 'my error message'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.errors, 'my key error message'); }); -test('mapStateToControlProps - i18n errors - multiple errors customization', t => { +test('mapStateToControlProps - i18n errors - multiple errors customization', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.pattern = "[0-9]+"; + state.jsonforms.core.schema.properties.firstName.pattern = '[0-9]+'; state.jsonforms.core.schema.properties.firstName.maxLength = 2; - (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = 'my-key'; + (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = + 'my-key'; state.jsonforms.core = coreReducer( state.jsonforms.core, init( @@ -1529,26 +1617,33 @@ test('mapStateToControlProps - i18n errors - multiple errors customization', t = ) ); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'error.maxLength': return 'max length message'; - case 'my-key.error.pattern': return 'my key error message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'error.maxLength': + return 'max length message'; + case 'my-key.error.pattern': + return 'my key error message'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.errors, 'max length message\nmy key error message'); }); -test('mapStateToControlProps - i18n errors - custom keyword wins over all other errors', t => { +test('mapStateToControlProps - i18n errors - custom keyword wins over all other errors', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.pattern = "[0-9]+"; + state.jsonforms.core.schema.properties.firstName.pattern = '[0-9]+'; state.jsonforms.core.schema.properties.firstName.maxLength = 2; - (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = 'my-key'; + (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = + 'my-key'; state.jsonforms.core = coreReducer( state.jsonforms.core, init( @@ -1559,22 +1654,29 @@ test('mapStateToControlProps - i18n errors - custom keyword wins over all other ) ); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'my-key.error.custom': return 'this is my error custom error message'; - case 'my-key.error.pattern': return 'my key error message'; - case 'error.pattern': return 'my error message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'my-key.error.custom': + return 'this is my error custom error message'; + case 'my-key.error.pattern': + return 'my key error message'; + case 'error.pattern': + return 'my error message'; + default: + return defaultMessage; } - } + }; const props = mapStateToControlProps(state, ownProps); t.is(props.errors, 'this is my error custom error message'); }); -test('mapStateToEnumControlProps - i18n - should not crash without i18n', t => { +test('mapStateToEnumControlProps - i18n - should not crash without i18n', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.core.schema.properties.firstName.enum = ['a', 'b']; @@ -1584,9 +1686,9 @@ test('mapStateToEnumControlProps - i18n - should not crash without i18n', t => { t.is(props.options[0].label, 'a'); }); -test('mapStateToEnumControlProps - i18n - default translation has no effect', t => { +test('mapStateToEnumControlProps - i18n - default translation has no effect', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.core.schema.properties.firstName.enum = ['a', 'b']; @@ -1596,149 +1698,193 @@ test('mapStateToEnumControlProps - i18n - default translation has no effect', t t.is(props.options[0].label, 'a'); }); -test('mapStateToEnumControlProps - i18n - path label translation', t => { +test('mapStateToEnumControlProps - i18n - path label translation', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.core.schema.properties.firstName.enum = ['a', 'b']; state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'firstName.a': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'firstName.a': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToEnumControlProps(state, ownProps); t.is(props.options[0].label, 'my message'); }); -test('mapStateToEnumControlProps - i18n - defaultMessage translation', t => { +test('mapStateToEnumControlProps - i18n - defaultMessage translation', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.core.schema.properties.firstName.enum = ['a', 'b']; state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (_key: string, defaultMessage: string | undefined) => { - switch(defaultMessage){ - case 'a': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + _key: string, + defaultMessage: string | undefined + ) => { + switch (defaultMessage) { + case 'a': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToEnumControlProps(state, ownProps); t.is(props.options[0].label, 'my message'); }); -test('mapStateToEnumControlProps - i18n - i18n key translation', t => { +test('mapStateToEnumControlProps - i18n - i18n key translation', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); state.jsonforms.core.schema.properties.firstName.enum = ['a', 'b']; - (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = 'my-key'; + (state.jsonforms.core.schema.properties.firstName as i18nJsonSchema).i18n = + 'my-key'; state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'my-key.a': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'my-key.a': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToEnumControlProps(state, ownProps); t.is(props.options[0].label, 'my message'); }); -test('mapStateToOneOfEnumControlProps - i18n - should not crash without i18n', t => { +test('mapStateToOneOfEnumControlProps - i18n - should not crash without i18n', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.oneOf = [{const: 'a', title: 'foo'}, {const: 'b', title: 'bar'}] + state.jsonforms.core.schema.properties.firstName.oneOf = [ + { const: 'a', title: 'foo' }, + { const: 'b', title: 'bar' }, + ]; state.jsonforms.i18n = undefined; const props = mapStateToOneOfEnumControlProps(state, ownProps); t.is(props.options[0].label, 'foo'); }); -test('mapStateToOneOfEnumControlProps- i18n - default translation has no effect', t => { +test('mapStateToOneOfEnumControlProps- i18n - default translation has no effect', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.oneOf = [{const: 'a', title: 'foo'}, {const: 'b', title: 'bar'}] + state.jsonforms.core.schema.properties.firstName.oneOf = [ + { const: 'a', title: 'foo' }, + { const: 'b', title: 'bar' }, + ]; state.jsonforms.i18n = defaultJsonFormsI18nState; const props = mapStateToOneOfEnumControlProps(state, ownProps); t.is(props.options[0].label, 'foo'); }); -test('mapStateToOneOfEnumControlProps - i18n - path label translation', t => { +test('mapStateToOneOfEnumControlProps - i18n - path label translation', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.oneOf = [{const: 'a', title: 'foo'}, {const: 'b', title: 'bar'}] + state.jsonforms.core.schema.properties.firstName.oneOf = [ + { const: 'a', title: 'foo' }, + { const: 'b', title: 'bar' }, + ]; state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'firstName.foo': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'firstName.foo': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToOneOfEnumControlProps(state, ownProps); t.is(props.options[0].label, 'my message'); }); -test('mapStateToOneOfEnumControlProps - i18n - default message translation', t => { +test('mapStateToOneOfEnumControlProps - i18n - default message translation', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - state.jsonforms.core.schema.properties.firstName.oneOf = [{const: 'a', title: 'foo'}, {const: 'b', title: 'bar'}] + state.jsonforms.core.schema.properties.firstName.oneOf = [ + { const: 'a', title: 'foo' }, + { const: 'b', title: 'bar' }, + ]; state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (_key: string, defaultMessage: string | undefined) => { - switch(defaultMessage){ - case 'foo': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + _key: string, + defaultMessage: string | undefined + ) => { + switch (defaultMessage) { + case 'foo': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToOneOfEnumControlProps(state, ownProps); t.is(props.options[0].label, 'my message'); }); -test('mapStateToOneOfEnumControlProps - i18n - i18n key translation', t => { +test('mapStateToOneOfEnumControlProps - i18n - i18n key translation', (t) => { const ownProps = { - uischema: coreUISchema + uischema: coreUISchema, }; const state: JsonFormsState = createState(coreUISchema); - (state.jsonforms.core.schema.properties.firstName.oneOf as any) = - [{const: 'a', title: 'foo', i18n: 'my-foo'}, {const: 'b', title: 'bar', i18n:'my-bar'}]; + (state.jsonforms.core.schema.properties.firstName.oneOf as any) = [ + { const: 'a', title: 'foo', i18n: 'my-foo' }, + { const: 'b', title: 'bar', i18n: 'my-bar' }, + ]; state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'my-foo': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'my-foo': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToOneOfEnumControlProps(state, ownProps); t.is(props.options[0].label, 'my message'); }); - -test('mapStateToLabelProps - i18n - should not crash without i18n', t => { - const labelUISchema : LabelElement = { +test('mapStateToLabelProps - i18n - should not crash without i18n', (t) => { + const labelUISchema: LabelElement = { type: 'Label', text: 'foo', - i18n: 'bar' - } + i18n: 'bar', + }; const ownProps = { - uischema: labelUISchema + uischema: labelUISchema, }; const state: JsonFormsState = createState(labelUISchema); state.jsonforms.i18n = undefined; @@ -1747,14 +1893,14 @@ test('mapStateToLabelProps - i18n - should not crash without i18n', t => { t.is(props.text, 'foo'); }); -test('mapStateToLabelProps - i18n - default translation has no effect', t => { - const labelUISchema : LabelElement = { +test('mapStateToLabelProps - i18n - default translation has no effect', (t) => { + const labelUISchema: LabelElement = { type: 'Label', text: 'foo', - i18n: 'bar' - } + i18n: 'bar', + }; const ownProps = { - uischema: labelUISchema + uischema: labelUISchema, }; const state: JsonFormsState = createState(labelUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; @@ -1763,67 +1909,81 @@ test('mapStateToLabelProps - i18n - default translation has no effect', t => { t.is(props.text, 'foo'); }); -test('mapStateToLabelProps - i18n - default key translation', t => { - const labelUISchema : LabelElement = { +test('mapStateToLabelProps - i18n - default key translation', (t) => { + const labelUISchema: LabelElement = { type: 'Label', - text: 'foo' - } + text: 'foo', + }; const ownProps = { - uischema: labelUISchema + uischema: labelUISchema, }; const state: JsonFormsState = createState(labelUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined) => { - switch(key){ - case 'foo': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ) => { + switch (key) { + case 'foo': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToLabelProps(state, ownProps); t.is(props.text, 'my message'); }); - -test('mapStateToLabelProps - i18n - default message translation', t => { - const labelUISchema : LabelElement = { +test('mapStateToLabelProps - i18n - default message translation', (t) => { + const labelUISchema: LabelElement = { type: 'Label', text: 'foo', - i18n: 'bar' - } + i18n: 'bar', + }; const ownProps = { - uischema: labelUISchema + uischema: labelUISchema, }; const state: JsonFormsState = createState(labelUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (_key: string, defaultMessage: string | undefined) => { - switch(defaultMessage){ - case 'foo': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + _key: string, + defaultMessage: string | undefined + ) => { + switch (defaultMessage) { + case 'foo': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToLabelProps(state, ownProps); t.is(props.text, 'my message'); }); -test('mapStateToLabelProps - i18n - i18n key translation', t => { - const labelUISchema : LabelElement = { +test('mapStateToLabelProps - i18n - i18n key translation', (t) => { + const labelUISchema: LabelElement = { type: 'Label', text: 'foo', - i18n: 'bar' - } + i18n: 'bar', + }; const ownProps = { - uischema: labelUISchema + uischema: labelUISchema, }; const state: JsonFormsState = createState(labelUISchema); state.jsonforms.i18n = defaultJsonFormsI18nState; - state.jsonforms.i18n.translate = (key: string, defaultMessage: string | undefined): string | undefined => { - switch(key){ - case 'bar.text': return 'my message'; - default: return defaultMessage; + state.jsonforms.i18n.translate = ( + key: string, + defaultMessage: string | undefined + ): string | undefined => { + switch (key) { + case 'bar.text': + return 'my message'; + default: + return defaultMessage; } - } + }; const props = mapStateToLabelProps(state, ownProps); t.is(props.text, 'my message'); diff --git a/packages/core/test/util/resolvers.test.ts b/packages/core/test/util/resolvers.test.ts index 0efc7dc31..5330338dd 100644 --- a/packages/core/test/util/resolvers.test.ts +++ b/packages/core/test/util/resolvers.test.ts @@ -22,19 +22,19 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { resolveSchema } from '../../src/util/resolvers'; +import { resolveData, resolveSchema } from '../../src/util/resolvers'; import test from 'ava'; -test('resolveSchema - resolves schema with any ', t => { +test('resolveSchema - resolves schema with any ', (t) => { const schema = { $defs: { Base: { type: 'object', properties: { width: { - type: 'integer' - } - } + type: 'integer', + }, + }, }, Child: { type: 'object', @@ -43,68 +43,72 @@ test('resolveSchema - resolves schema with any ', t => { { properties: { geometry: { - type: 'string' - } - } - } - ] - } + type: 'string', + }, + }, + }, + ], + }, }, type: 'object', properties: { description: { - oneOf: [{ - type: 'object', - properties: { - name: { - type: 'string' - } - } - }, { - type: 'object', - properties: { - index: { - type: 'number' - } - } - }, { - type: 'object', - properties: { - exist: { - type: 'boolean' - } - } - }, - { - type: 'object', - properties: { - element: { - $ref: '#/$defs/Child' - } - } - }] - } + oneOf: [ + { + type: 'object', + properties: { + name: { + type: 'string', + }, + }, + }, + { + type: 'object', + properties: { + index: { + type: 'number', + }, + }, + }, + { + type: 'object', + properties: { + exist: { + type: 'boolean', + }, + }, + }, + { + type: 'object', + properties: { + element: { + $ref: '#/$defs/Child', + }, + }, + }, + ], + }, }, anyOf: [ { if: { properties: { exist: { - const: true - } - } + const: true, + }, + }, }, then: { properties: { lastname: { - type: 'string' - } - } + type: 'string', + }, + }, }, else: { properties: { firstname: { - type: 'string' + type: 'string', }, address: { type: 'object', @@ -112,46 +116,118 @@ test('resolveSchema - resolves schema with any ', t => { { properties: { street: { - type: 'string' - } - } - } - ] - } - } - } - } - ] + type: 'string', + }, + }, + }, + ], + }, + }, + }, + }, + ], }; // test backward compatibility - t.deepEqual(resolveSchema(schema, '#/properties/description/oneOf/0/properties/name', schema), {type: 'string'}); - t.deepEqual(resolveSchema(schema, '#/properties/description/oneOf/1/properties/index', schema), {type: 'number'}); - t.deepEqual(resolveSchema(schema, '#/anyOf/0/then/properties/lastname', schema), {type: 'string'}); - t.deepEqual(resolveSchema(schema, '#/anyOf/0/else/properties/firstname', schema), {type: 'string'}); - t.deepEqual(resolveSchema(schema, '#/anyOf/0/else/properties/address/anyOf/0/properties/street', schema), {type: 'string'}); + t.deepEqual( + resolveSchema( + schema, + '#/properties/description/oneOf/0/properties/name', + schema + ), + { type: 'string' } + ); + t.deepEqual( + resolveSchema( + schema, + '#/properties/description/oneOf/1/properties/index', + schema + ), + { type: 'number' } + ); + t.deepEqual( + resolveSchema(schema, '#/anyOf/0/then/properties/lastname', schema), + { type: 'string' } + ); + t.deepEqual( + resolveSchema(schema, '#/anyOf/0/else/properties/firstname', schema), + { type: 'string' } + ); + t.deepEqual( + resolveSchema( + schema, + '#/anyOf/0/else/properties/address/anyOf/0/properties/street', + schema + ), + { type: 'string' } + ); // new simple approach - t.deepEqual(resolveSchema(schema, '#/properties/description/properties/name', schema), {type: 'string'}); - t.deepEqual(resolveSchema(schema, '#/properties/description/properties/index', schema), {type: 'number'}); - t.deepEqual(resolveSchema(schema, '#/properties/description/properties/exist', schema), {type: 'boolean'}); - t.deepEqual(resolveSchema(schema, '#/properties/lastname', schema), {type: 'string'}); - t.deepEqual(resolveSchema(schema, '#/properties/firstname', schema), {type: 'string'}); - t.deepEqual(resolveSchema(schema, '#/properties/address/properties/street', schema), {type: 'string'}); - t.is(resolveSchema(schema, '#/properties/description/properties/notfound', schema), undefined); + t.deepEqual( + resolveSchema(schema, '#/properties/description/properties/name', schema), + { type: 'string' } + ); + t.deepEqual( + resolveSchema(schema, '#/properties/description/properties/index', schema), + { type: 'number' } + ); + t.deepEqual( + resolveSchema(schema, '#/properties/description/properties/exist', schema), + { type: 'boolean' } + ); + t.deepEqual(resolveSchema(schema, '#/properties/lastname', schema), { + type: 'string', + }); + t.deepEqual(resolveSchema(schema, '#/properties/firstname', schema), { + type: 'string', + }); + t.deepEqual( + resolveSchema(schema, '#/properties/address/properties/street', schema), + { type: 'string' } + ); + t.is( + resolveSchema( + schema, + '#/properties/description/properties/notfound', + schema + ), + undefined + ); // refs - t.deepEqual(resolveSchema(schema, '#/properties/description/properties/element/properties/geometry', schema), {type: 'string'}); - t.deepEqual(resolveSchema(schema, '#/properties/description/properties/element/properties/width', schema), {type: 'integer'}); - + t.deepEqual( + resolveSchema( + schema, + '#/properties/description/properties/element/properties/geometry', + schema + ), + { type: 'string' } + ); + t.deepEqual( + resolveSchema( + schema, + '#/properties/description/properties/element/properties/width', + schema + ), + { type: 'integer' } + ); }); -test('resolveSchema - resolves schema with encoded characters', t => { +test('resolveSchema - resolves schema with encoded characters', (t) => { const schema = { type: 'object', properties: { 'foo / ~ bar': { - type: 'integer' - } - } + type: 'integer', + }, + }, }; - t.deepEqual(resolveSchema(schema, '#/properties/foo ~1 ~0 bar', schema), {type: 'integer'}); + t.deepEqual(resolveSchema(schema, '#/properties/foo ~1 ~0 bar', schema), { + type: 'integer', + }); t.is(resolveSchema(schema, '#/properties/foo / bar', schema), undefined); }); + +test('resolveData - resolves data with % characters', (t) => { + const data = { + 'foo%': '123', + }; + t.deepEqual(resolveData(data, 'foo%'), '123'); +}); diff --git a/packages/core/test/util/runtime.test.ts b/packages/core/test/util/runtime.test.ts index 19367c22f..6b554e646 100644 --- a/packages/core/test/util/runtime.test.ts +++ b/packages/core/test/util/runtime.test.ts @@ -32,195 +32,195 @@ import { LeafCondition, OrCondition, RuleEffect, - SchemaBasedCondition + SchemaBasedCondition, } from '../../src'; import { evalEnablement, evalVisibility } from '../../src/util/runtime'; -test('evalVisibility show valid case', t => { +test('evalVisibility show valid case', (t) => { const leafCondition: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue', - expectedValue: 'bar' + expectedValue: 'bar', }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.SHOW, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), true); }); -test('evalVisibility show valid case based on AndCondition', t => { +test('evalVisibility show valid case based on AndCondition', (t) => { const leafCondition1: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue1', - expectedValue: 'bar' + expectedValue: 'bar', }; const leafCondition2: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue2', - expectedValue: 'foo' + expectedValue: 'foo', }; const condition: AndCondition = { type: 'AND', - conditions: [leafCondition1, leafCondition2] + conditions: [leafCondition1, leafCondition2], }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.SHOW, - condition: condition - } + condition: condition, + }, }; const data = { value: 'hello', ruleValue1: 'bar', - ruleValue2: 'foo' + ruleValue2: 'foo', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), true); }); -test('evalVisibility show invalid case based on AndCondition', t => { +test('evalVisibility show invalid case based on AndCondition', (t) => { const leafCondition1: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue1', - expectedValue: 'bar' + expectedValue: 'bar', }; const leafCondition2: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue2', - expectedValue: 'bar' + expectedValue: 'bar', }; const condition: AndCondition = { type: 'AND', - conditions: [leafCondition1, leafCondition2] + conditions: [leafCondition1, leafCondition2], }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.SHOW, - condition: condition - } + condition: condition, + }, }; const data = { value: 'hello', ruleValue1: 'bar', - ruleValue2: 'foo' + ruleValue2: 'foo', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), false); }); -test('evalVisibility show valid case based on OrCondition', t => { +test('evalVisibility show valid case based on OrCondition', (t) => { const leafCondition1: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue1', - expectedValue: 'bar' + expectedValue: 'bar', }; const leafCondition2: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue2', - expectedValue: 'foo' + expectedValue: 'foo', }; const condition: OrCondition = { type: 'OR', - conditions: [leafCondition1, leafCondition2] + conditions: [leafCondition1, leafCondition2], }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.SHOW, - condition: condition - } + condition: condition, + }, }; const data = { value: 'hello', ruleValue1: 'bar1', - ruleValue2: 'foo' + ruleValue2: 'foo', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), true); }); -test('evalVisibility show invalid case based on OrCondition', t => { +test('evalVisibility show invalid case based on OrCondition', (t) => { const leafCondition1: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue1', - expectedValue: 'foo' + expectedValue: 'foo', }; const leafCondition2: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue2', - expectedValue: 'bar' + expectedValue: 'bar', }; const condition: OrCondition = { type: 'OR', - conditions: [leafCondition1, leafCondition2] + conditions: [leafCondition1, leafCondition2], }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.SHOW, - condition: condition - } + condition: condition, + }, }; const data = { value: 'hello', ruleValue1: 'bar', - ruleValue2: 'foo' + ruleValue2: 'foo', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), false); }); -test('evalVisibility show valid case based on schema condition', t => { +test('evalVisibility show valid case based on schema condition', (t) => { const condition: SchemaBasedCondition = { scope: '#/properties/ruleValue', schema: { - const: 'bar' - } + const: 'bar', + }, }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.SHOW, - condition - } + condition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), true); }); -test('evalVisibility show valid case based on schema condition and enum', t => { +test('evalVisibility show valid case based on schema condition and enum', (t) => { const condition: SchemaBasedCondition = { scope: '#/properties/ruleValue', schema: { - enum: ['bar', 'baz'] - } + enum: ['bar', 'baz'], + }, }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.SHOW, - condition - } + condition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), true); t.is( @@ -243,293 +243,293 @@ test('evalVisibility show valid case based on schema condition and enum', t => { ); }); -test('evalVisibility show invalid case', t => { +test('evalVisibility show invalid case', (t) => { const leafCondition: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue', - expectedValue: 'bar' + expectedValue: 'bar', }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.SHOW, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'foobar' + ruleValue: 'foobar', }; t.deepEqual(evalVisibility(uischema, data, undefined, createAjv()), false); }); -test('evalVisibility hide valid case', t => { +test('evalVisibility hide valid case', (t) => { const leafCondition: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue', - expectedValue: 'bar' + expectedValue: 'bar', }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.HIDE, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), false); }); -test('evalVisibility hide invalid case', t => { +test('evalVisibility hide invalid case', (t) => { const leafCondition: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue', - expectedValue: 'bar' + expectedValue: 'bar', }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.HIDE, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'foobar' + ruleValue: 'foobar', }; t.is(evalVisibility(uischema, data, undefined, createAjv()), true); }); -test('evalEnablement enable valid case', t => { +test('evalEnablement enable valid case', (t) => { const leafCondition: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue', - expectedValue: 'bar' + expectedValue: 'bar', }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.ENABLE, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), true); }); -test('evalEnablement show valid case based on AndCondition', t => { +test('evalEnablement show valid case based on AndCondition', (t) => { const leafCondition1: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue1', - expectedValue: 'bar' + expectedValue: 'bar', }; const leafCondition2: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue2', - expectedValue: 'foo' + expectedValue: 'foo', }; const condition: AndCondition = { type: 'AND', - conditions: [leafCondition1, leafCondition2] + conditions: [leafCondition1, leafCondition2], }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.ENABLE, - condition: condition - } + condition: condition, + }, }; const data = { value: 'hello', ruleValue1: 'bar', - ruleValue2: 'foo' + ruleValue2: 'foo', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), true); }); -test('evalEnablement show invalid case based on AndCondition', t => { +test('evalEnablement show invalid case based on AndCondition', (t) => { const leafCondition1: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue1', - expectedValue: 'bar' + expectedValue: 'bar', }; const leafCondition2: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue2', - expectedValue: 'bar' + expectedValue: 'bar', }; const condition: AndCondition = { type: 'AND', - conditions: [leafCondition1, leafCondition2] + conditions: [leafCondition1, leafCondition2], }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.ENABLE, - condition: condition - } + condition: condition, + }, }; const data = { value: 'hello', ruleValue1: 'bar', - ruleValue2: 'foo' + ruleValue2: 'foo', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), false); }); -test('evalEnablement show valid case based on OrCondition', t => { +test('evalEnablement show valid case based on OrCondition', (t) => { const leafCondition1: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue1', - expectedValue: 'bar' + expectedValue: 'bar', }; const leafCondition2: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue2', - expectedValue: 'foo' + expectedValue: 'foo', }; const condition: OrCondition = { type: 'OR', - conditions: [leafCondition1, leafCondition2] + conditions: [leafCondition1, leafCondition2], }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.ENABLE, - condition: condition - } + condition: condition, + }, }; const data = { value: 'hello', ruleValue1: 'bar1', - ruleValue2: 'foo' + ruleValue2: 'foo', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), true); }); -test('evalEnablement show invalid case based on OrCondition', t => { +test('evalEnablement show invalid case based on OrCondition', (t) => { const leafCondition1: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue1', - expectedValue: 'foo' + expectedValue: 'foo', }; const leafCondition2: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue2', - expectedValue: 'bar' + expectedValue: 'bar', }; const condition: OrCondition = { type: 'OR', - conditions: [leafCondition1, leafCondition2] + conditions: [leafCondition1, leafCondition2], }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.ENABLE, - condition: condition - } + condition: condition, + }, }; const data = { value: 'hello', ruleValue1: 'bar', - ruleValue2: 'foo' + ruleValue2: 'foo', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), false); }); -test('evalEnablement enable invalid case', t => { +test('evalEnablement enable invalid case', (t) => { const leafCondition: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue', - expectedValue: 'bar' + expectedValue: 'bar', }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.ENABLE, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'foobar' + ruleValue: 'foobar', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), false); }); -test('evalEnablement disable valid case', t => { +test('evalEnablement disable valid case', (t) => { const leafCondition: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue', - expectedValue: 'bar' + expectedValue: 'bar', }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.DISABLE, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), false); }); -test('evalEnablement disable invalid case', t => { +test('evalEnablement disable invalid case', (t) => { const leafCondition: LeafCondition = { type: 'LEAF', scope: '#/properties/ruleValue', - expectedValue: 'bar' + expectedValue: 'bar', }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.DISABLE, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'foobar' + ruleValue: 'foobar', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), true); }); -test('evalEnablement disable invalid case based on schema condition', t => { +test('evalEnablement disable invalid case based on schema condition', (t) => { const condition: SchemaBasedCondition = { scope: '#/properties/ruleValue', schema: { - enum: ['bar', 'baz'] - } + enum: ['bar', 'baz'], + }, }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.DISABLE, - condition - } + condition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.is(evalEnablement(uischema, data, undefined, createAjv()), false); t.is( @@ -552,7 +552,7 @@ test('evalEnablement disable invalid case based on schema condition', t => { ); }); -test('isInherentlyEnabled disabled globally', t => { +test('isInherentlyEnabled disabled globally', (t) => { t.false( isInherentlyEnabled( { jsonforms: { readonly: true } }, @@ -565,22 +565,22 @@ test('isInherentlyEnabled disabled globally', t => { ); }); -test('isInherentlyEnabled disabled by ownProps', t => { +test('isInherentlyEnabled disabled by ownProps', (t) => { t.false( isInherentlyEnabled(null, { enabled: false }, null, null, null, null) ); }); -test('isInherentlyEnabled enabled by ownProps', t => { +test('isInherentlyEnabled enabled by ownProps', (t) => { t.true(isInherentlyEnabled(null, { enabled: true }, null, null, null, null)); }); -test('isInherentlyEnabled disabled by uischema', t => { +test('isInherentlyEnabled disabled by uischema', (t) => { t.false( isInherentlyEnabled( null, null, - ({ options: { readonly: true } } as unknown) as ControlElement, + { options: { readonly: true } } as unknown as ControlElement, null, null, null @@ -588,12 +588,12 @@ test('isInherentlyEnabled disabled by uischema', t => { ); }); -test('isInherentlyEnabled disabled by uischema over ownProps', t => { +test('isInherentlyEnabled disabled by uischema over ownProps', (t) => { t.false( isInherentlyEnabled( null, { enabled: true }, - ({ options: { readonly: true } } as unknown) as ControlElement, + { options: { readonly: true } } as unknown as ControlElement, null, null, null @@ -601,12 +601,12 @@ test('isInherentlyEnabled disabled by uischema over ownProps', t => { ); }); -test('isInherentlyEnabled enabled by uischema over schema', t => { +test('isInherentlyEnabled enabled by uischema over schema', (t) => { t.true( isInherentlyEnabled( null, null, - ({ options: { readonly: false } } as unknown) as ControlElement, + { options: { readonly: false } } as unknown as ControlElement, { readOnly: true }, null, null @@ -614,11 +614,11 @@ test('isInherentlyEnabled enabled by uischema over schema', t => { ); }); -test('isInherentlyEnabled disabled by ownProps over schema enablement', t => { +test('isInherentlyEnabled disabled by ownProps over schema enablement', (t) => { t.false( isInherentlyEnabled( null, - { enabled: false}, + { enabled: false }, null, { readOnly: false }, null, @@ -627,12 +627,12 @@ test('isInherentlyEnabled disabled by ownProps over schema enablement', t => { ); }); -test('isInherentlyEnabled disabled by uischema over schema', t => { +test('isInherentlyEnabled disabled by uischema over schema', (t) => { t.false( isInherentlyEnabled( null, null, - ({ options: { readonly: true } } as unknown) as ControlElement, + { options: { readonly: true } } as unknown as ControlElement, { readOnly: false }, null, null @@ -640,13 +640,13 @@ test('isInherentlyEnabled disabled by uischema over schema', t => { ); }); -test('isInherentlyEnabled disabled by schema', t => { +test('isInherentlyEnabled disabled by schema', (t) => { t.false( isInherentlyEnabled(null, null, null, { readOnly: true }, null, null) ); }); -test('isInherentlyEnabled disabled by schema over ownProps', t => { +test('isInherentlyEnabled disabled by schema over ownProps', (t) => { t.false( isInherentlyEnabled( null, @@ -659,22 +659,22 @@ test('isInherentlyEnabled disabled by schema over ownProps', t => { ); }); -test('isInherentlyEnabled disabled by rule', t => { +test('isInherentlyEnabled disabled by rule', (t) => { const leafCondition: SchemaBasedCondition = { scope: '#/properties/ruleValue', - schema: { type: 'string', pattern: 'bar' } + schema: { type: 'string', pattern: 'bar' }, }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.DISABLE, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.false( @@ -689,22 +689,22 @@ test('isInherentlyEnabled disabled by rule', t => { ); }); -test('isInherentlyEnabled disabled by global over rule ', t => { +test('isInherentlyEnabled disabled by global over rule ', (t) => { const leafCondition: SchemaBasedCondition = { scope: '#/properties/ruleValue', - schema: { type: 'string', pattern: 'bar' } + schema: { type: 'string', pattern: 'bar' }, }; const uischema: ControlElement = { type: 'Control', scope: '#/properties/value', rule: { effect: RuleEffect.ENABLE, - condition: leafCondition - } + condition: leafCondition, + }, }; const data = { value: 'foo', - ruleValue: 'bar' + ruleValue: 'bar', }; t.false( @@ -712,8 +712,8 @@ test('isInherentlyEnabled disabled by global over rule ', t => { { jsonforms: { readonly: true, - core: { ajv: createAjv() } as JsonFormsCore - } + core: { ajv: createAjv() } as JsonFormsCore, + }, }, null, uischema, @@ -724,26 +724,26 @@ test('isInherentlyEnabled disabled by global over rule ', t => { ); }); -test('isInherentlyEnabled disabled by config', t => { +test('isInherentlyEnabled disabled by config', (t) => { t.false( isInherentlyEnabled(null, null, null, null, null, { readonly: true }) ); }); -test('isInherentlyEnabled enabled by config over ownProps', t => { +test('isInherentlyEnabled enabled by config over ownProps', (t) => { t.true( isInherentlyEnabled(null, { enabled: false }, null, null, null, { - readonly: false + readonly: false, }) ); }); -test('isInherentlyEnabled enabled by uischema over config', t => { +test('isInherentlyEnabled enabled by uischema over config', (t) => { t.true( isInherentlyEnabled( null, null, - ({ options: { readonly: false } } as unknown) as ControlElement, + { options: { readonly: false } } as unknown as ControlElement, null, null, { readonly: true } @@ -751,12 +751,14 @@ test('isInherentlyEnabled enabled by uischema over config', t => { ); }); -test('isInherentlyEnabled prefer readonly over readOnly', t => { +test('isInherentlyEnabled prefer readonly over readOnly', (t) => { t.true( isInherentlyEnabled( null, null, - ({ options: { readonly: false, readOnly: true } } as unknown) as ControlElement, + { + options: { readonly: false, readOnly: true }, + } as unknown as ControlElement, null, null, null @@ -766,7 +768,9 @@ test('isInherentlyEnabled prefer readonly over readOnly', t => { isInherentlyEnabled( null, null, - ({ options: { readonly: true, readOnly: false } } as unknown) as ControlElement, + { + options: { readonly: true, readOnly: false }, + } as unknown as ControlElement, null, null, null @@ -774,6 +778,6 @@ test('isInherentlyEnabled prefer readonly over readOnly', t => { ); }); -test('isInherentlyEnabled enabled', t => { +test('isInherentlyEnabled enabled', (t) => { t.true(isInherentlyEnabled(null, null, null, null, null, null)); }); diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 5c9f3f825..9af7ef8c9 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -4,10 +4,6 @@ "outDir": "./lib", "sourceMap": true }, - "exclude":[ - "node_modules" - ], - "files": [ - "./src/index.ts" - ] + "exclude": ["node_modules"], + "files": ["./src/index.ts"] } diff --git a/packages/examples-app/README.md b/packages/examples-app/README.md index c7112e3db..c1698de93 100644 --- a/packages/examples-app/README.md +++ b/packages/examples-app/README.md @@ -1,6 +1,6 @@ # JSON Forms - More Forms. Less Code -*Complex forms in the blink of an eye* +_Complex forms in the blink of an eye_ JSON Forms eliminates the tedious task of writing fully-featured forms by hand by leveraging the capabilities of JSON, JSON Schema and Javascript. diff --git a/packages/examples-app/index.html b/packages/examples-app/index.html index 75c9e2bf7..9fb592ffc 100644 --- a/packages/examples-app/index.html +++ b/packages/examples-app/index.html @@ -1,19 +1,18 @@ - + + + + JSON Forms Examples + + - - - JSON Forms Examples - - - - -

JSON Forms Examples

-
- - \ No newline at end of file + +

JSON Forms Examples

+ + + diff --git a/packages/examples-app/package.json b/packages/examples-app/package.json index 5be9076e6..f6d4d82e1 100644 --- a/packages/examples-app/package.json +++ b/packages/examples-app/package.json @@ -1,6 +1,6 @@ { "name": "@jsonforms/examples-app", - "version": "3.1.0-alpha.1", + "version": "3.1.0-alpha.2", "private": true, "license": "MIT", "type": "module", diff --git a/packages/examples-app/prepare-examples-app.js b/packages/examples-app/prepare-examples-app.js index 3db3b1ed8..22d2cacc2 100644 --- a/packages/examples-app/prepare-examples-app.js +++ b/packages/examples-app/prepare-examples-app.js @@ -14,8 +14,8 @@ const examples = { 'react-vanilla': join(packagesDir, 'vanilla-renderers', 'example', 'dist'), 'react-material': join(packagesDir, 'material-renderers', 'example', 'dist'), 'angular-material': join(packagesDir, 'angular-material', 'example', 'dist'), - 'vue-vanilla': join(packagesDir, 'vue', 'vue-vanilla', 'example', 'dist') -} + 'vue-vanilla': join(packagesDir, 'vue', 'vue-vanilla', 'example', 'dist'), +}; // Clean and recreate dist dir console.log('Clean and recreate dist dir...'); @@ -26,7 +26,7 @@ mkdirSync(distDir, { recursive: true }); console.log('Copy index.html...'); console.log('Copy example apps...'); copyFileSync(join(__dirname, 'index.html'), join(distDir, 'index.html')); -Object.keys(examples).forEach(key => { +Object.keys(examples).forEach((key) => { console.log(`Copying example ${key}...`); const path = examples[key]; copySync(path, join(distDir, key)); diff --git a/packages/examples-react/.eslintrc.js b/packages/examples-react/.eslintrc.js new file mode 100644 index 000000000..4db5e1f83 --- /dev/null +++ b/packages/examples-react/.eslintrc.js @@ -0,0 +1,40 @@ +/* eslint-env node */ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + // There is no file include in ESLint. Thus, ignore all and include files via negative ignore (!) + ignorePatterns: ['/*', '!/src'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:react/recommended', + 'plugin:prettier/recommended', + ], + rules: { + '@typescript-eslint/no-explicit-any': 'off', + 'no-prototype-builtins': 'off', + // Base rule must be disabled to avoid incorrect errors + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', // or "error" + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, + settings: { + react: { + version: 'detect', + }, + }, +}; diff --git a/packages/examples-react/.prettierrc.js b/packages/examples-react/.prettierrc.js new file mode 100644 index 000000000..2c26853c4 --- /dev/null +++ b/packages/examples-react/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + $schema: 'http://json.schemastore.org/prettierrc', + singleQuote: true, + jsxSingleQuote: true, + endOfLine: 'auto', +}; diff --git a/packages/examples-react/package.json b/packages/examples-react/package.json index 577f9b475..4bc8d2cbc 100644 --- a/packages/examples-react/package.json +++ b/packages/examples-react/package.json @@ -1,11 +1,11 @@ { "name": "@jsonforms/examples-react", - "version": "3.1.0-alpha.1", + "version": "3.1.0-alpha.2", "private": true, "dependencies": { - "@jsonforms/core": "^3.1.0-alpha.1", - "@jsonforms/examples": "^3.1.0-alpha.1", - "@jsonforms/react": "^3.1.0-alpha.1", + "@jsonforms/core": "^3.1.0-alpha.2", + "@jsonforms/examples": "^3.1.0-alpha.2", + "@jsonforms/react": "^3.1.0-alpha.2", "@mui/material": "~5.2.2", "@types/react-highlight": "^0.12.5", "@types/react-tabs": "^2.3.3", @@ -17,8 +17,20 @@ "react-highlight": "^0.14.0", "react-tabs": "^3.2.3" }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^5.54.1", + "@typescript-eslint/parser": "^5.54.1", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.7.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-react": "^7.32.2", + "prettier": "^2.8.4" + }, "scripts": { "build": "echo 'Nothing to do'", + "lint": "eslint .", + "lint:fix": "eslint --fix .", "test": "echo 'Nothing to do'" } } diff --git a/packages/examples-react/public/index.html b/packages/examples-react/public/index.html index ed0ebafa1..29aba544c 100644 --- a/packages/examples-react/public/index.html +++ b/packages/examples-react/public/index.html @@ -1,15 +1,18 @@ - - - + + + - - + +